зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2g-inbound.
This commit is contained in:
Коммит
5e8271d74b
|
@ -621,7 +621,7 @@ TextAttrsMgr::FontWeightTextAttr::
|
||||||
if (font->IsSyntheticBold())
|
if (font->IsSyntheticBold())
|
||||||
return 700;
|
return 700;
|
||||||
|
|
||||||
#ifdef MOZ_PANGO
|
#if defined(MOZ_WIDGET_GTK) || defined(MOZ_WIDGET_QT)
|
||||||
// On Linux, font->GetStyle()->weight will give the absolute weight requested
|
// On Linux, font->GetStyle()->weight will give the absolute weight requested
|
||||||
// of the font face. The Linux code uses the gfxFontEntry constructor which
|
// of the font face. The Linux code uses the gfxFontEntry constructor which
|
||||||
// doesn't initialize the weight field.
|
// doesn't initialize the weight field.
|
||||||
|
|
|
@ -377,11 +377,7 @@ function getPotentialLeaks() {
|
||||||
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
let mgr = Cc["@mozilla.org/memory-reporter-manager;1"].
|
||||||
getService(Ci.nsIMemoryReporterManager);
|
getService(Ci.nsIMemoryReporterManager);
|
||||||
|
|
||||||
let enm = mgr.enumerateReporters();
|
mgr.getReportsForThisProcess(logReporter, null);
|
||||||
while (enm.hasMoreElements()) {
|
|
||||||
let mr = enm.getNext().QueryInterface(Ci.nsIMemoryReporter);
|
|
||||||
mr.collectReports(logReporter, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return { compartments: compartments, windows: windows };
|
return { compartments: compartments, windows: windows };
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"use strict"
|
"use strict"
|
||||||
|
|
||||||
function debug(str) {
|
function debug(str) {
|
||||||
//dump("-*- ContentPermissionPrompt: " + str + "\n");
|
//dump("-*- ContentPermissionPrompt: " + s + "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
const Ci = Components.interfaces;
|
const Ci = Components.interfaces;
|
||||||
|
@ -13,14 +13,11 @@ const Cr = Components.results;
|
||||||
const Cu = Components.utils;
|
const Cu = Components.utils;
|
||||||
const Cc = Components.classes;
|
const Cc = Components.classes;
|
||||||
|
|
||||||
const PROMPT_FOR_UNKNOWN = ["audio-capture",
|
const PROMPT_FOR_UNKNOWN = ["geolocation", "desktop-notification",
|
||||||
"desktop-notification",
|
"audio-capture"];
|
||||||
"geolocation",
|
|
||||||
"video-capture"];
|
|
||||||
// Due to privary issue, permission requests like GetUserMedia should prompt
|
// Due to privary issue, permission requests like GetUserMedia should prompt
|
||||||
// every time instead of providing session persistence.
|
// every time instead of providing session persistence.
|
||||||
const PERMISSION_NO_SESSION = ["audio-capture", "video-capture"];
|
const PERMISSION_NO_SESSION = ["audio-capture"];
|
||||||
const ALLOW_MULTIPLE_REQUESTS = ["audio-capture", "video-capture"];
|
|
||||||
|
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
@ -44,21 +41,7 @@ XPCOMUtils.defineLazyServiceGetter(this,
|
||||||
"@mozilla.org/telephony/audiomanager;1",
|
"@mozilla.org/telephony/audiomanager;1",
|
||||||
"nsIAudioManager");
|
"nsIAudioManager");
|
||||||
|
|
||||||
/**
|
function rememberPermission(aPermission, aPrincipal, aSession)
|
||||||
* aTypesInfo is an array of {permission, access, action, deny} which keeps
|
|
||||||
* the information of each permission. This arrary is initialized in
|
|
||||||
* ContentPermissionPrompt.prompt and used among functions.
|
|
||||||
*
|
|
||||||
* aTypesInfo[].permission : permission name
|
|
||||||
* aTypesInfo[].access : permission name + request.access
|
|
||||||
* aTypesInfo[].action : the default action of this permission
|
|
||||||
* aTypesInfo[].deny : true if security manager denied this app's origin
|
|
||||||
* principal.
|
|
||||||
* Note:
|
|
||||||
* aTypesInfo[].permission will be sent to prompt only when
|
|
||||||
* aTypesInfo[].action is PROMPT_ACTION and aTypesInfo[].deny is false.
|
|
||||||
*/
|
|
||||||
function rememberPermission(aTypesInfo, aPrincipal, aSession)
|
|
||||||
{
|
{
|
||||||
function convertPermToAllow(aPerm, aPrincipal)
|
function convertPermToAllow(aPerm, aPrincipal)
|
||||||
{
|
{
|
||||||
|
@ -66,13 +49,12 @@ function rememberPermission(aTypesInfo, aPrincipal, aSession)
|
||||||
permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm);
|
permissionManager.testExactPermissionFromPrincipal(aPrincipal, aPerm);
|
||||||
if (type == Ci.nsIPermissionManager.PROMPT_ACTION ||
|
if (type == Ci.nsIPermissionManager.PROMPT_ACTION ||
|
||||||
(type == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
|
(type == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
|
||||||
PROMPT_FOR_UNKNOWN.indexOf(aPerm) >= 0)) {
|
PROMPT_FOR_UNKNOWN.indexOf(aPermission) >= 0)) {
|
||||||
debug("add " + aPerm + " to permission manager with ALLOW_ACTION");
|
|
||||||
if (!aSession) {
|
if (!aSession) {
|
||||||
permissionManager.addFromPrincipal(aPrincipal,
|
permissionManager.addFromPrincipal(aPrincipal,
|
||||||
aPerm,
|
aPerm,
|
||||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||||
} else if (PERMISSION_NO_SESSION.indexOf(aPerm) < 0) {
|
} else if (PERMISSION_NO_SESSION.indexOf(aPermission) < 0) {
|
||||||
permissionManager.addFromPrincipal(aPrincipal,
|
permissionManager.addFromPrincipal(aPrincipal,
|
||||||
aPerm,
|
aPerm,
|
||||||
Ci.nsIPermissionManager.ALLOW_ACTION,
|
Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||||
|
@ -81,18 +63,14 @@ function rememberPermission(aTypesInfo, aPrincipal, aSession)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i in aTypesInfo) {
|
// Expand the permission to see if we have multiple access properties to convert
|
||||||
// Expand the permission to see if we have multiple access properties
|
let access = PermissionsTable[aPermission].access;
|
||||||
// to convert
|
if (access) {
|
||||||
let perm = aTypesInfo[i].permission;
|
for (let idx in access) {
|
||||||
let access = PermissionsTable[perm].access;
|
convertPermToAllow(aPermission + "-" + access[idx], aPrincipal);
|
||||||
if (access) {
|
|
||||||
for (let idx in access) {
|
|
||||||
convertPermToAllow(perm + "-" + access[idx], aPrincipal);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
convertPermToAllow(perm, aPrincipal);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
convertPermToAllow(aPermission, aPrincipal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,66 +78,23 @@ function ContentPermissionPrompt() {}
|
||||||
|
|
||||||
ContentPermissionPrompt.prototype = {
|
ContentPermissionPrompt.prototype = {
|
||||||
|
|
||||||
handleExistingPermission: function handleExistingPermission(request,
|
handleExistingPermission: function handleExistingPermission(request) {
|
||||||
typesInfo) {
|
let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
|
||||||
typesInfo.forEach(function(type) {
|
request.type;
|
||||||
type.action =
|
let result = Services.perms.testExactPermissionFromPrincipal(request.principal, access);
|
||||||
Services.perms.testExactPermissionFromPrincipal(request.principal,
|
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||||
type.access);
|
|
||||||
if (type.action == Ci.nsIPermissionManager.UNKNOWN_ACTION &&
|
|
||||||
PROMPT_FOR_UNKNOWN.indexOf(type.access) >= 0) {
|
|
||||||
type.action = Ci.nsIPermissionManager.PROMPT_ACTION;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// If all permissions are allowed already, call allow() without prompting.
|
|
||||||
let checkAllowPermission = function(type) {
|
|
||||||
if (type.action == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (typesInfo.every(checkAllowPermission)) {
|
|
||||||
debug("all permission requests are allowed");
|
|
||||||
request.allow();
|
request.allow();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (result == Ci.nsIPermissionManager.DENY_ACTION ||
|
||||||
// If all permissions are DENY_ACTION or UNKNOWN_ACTION, call cancel()
|
result == Ci.nsIPermissionManager.UNKNOWN_ACTION && PROMPT_FOR_UNKNOWN.indexOf(access) < 0) {
|
||||||
// without prompting.
|
|
||||||
let checkDenyPermission = function(type) {
|
|
||||||
if (type.action == Ci.nsIPermissionManager.DENY_ACTION ||
|
|
||||||
type.action == Ci.nsIPermissionManager.UNKNOWN_ACTION) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (typesInfo.every(checkDenyPermission)) {
|
|
||||||
debug("all permission requests are denied");
|
|
||||||
request.cancel();
|
request.cancel();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
// multiple requests should be audio and video
|
handledByApp: function handledByApp(request) {
|
||||||
checkMultipleRequest: function checkMultipleRequest(typesInfo) {
|
|
||||||
if (typesInfo.length == 1) {
|
|
||||||
return true;
|
|
||||||
} else if (typesInfo.length > 1) {
|
|
||||||
let checkIfAllowMultiRequest = function(type) {
|
|
||||||
return (ALLOW_MULTIPLE_REQUESTS.indexOf(type.access) !== -1);
|
|
||||||
}
|
|
||||||
if (typesInfo.every(checkIfAllowMultiRequest)) {
|
|
||||||
debug("legal multiple requests");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
handledByApp: function handledByApp(request, typesInfo) {
|
|
||||||
if (request.principal.appId == Ci.nsIScriptSecurityManager.NO_APP_ID ||
|
if (request.principal.appId == Ci.nsIScriptSecurityManager.NO_APP_ID ||
|
||||||
request.principal.appId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) {
|
request.principal.appId == Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID) {
|
||||||
// This should not really happen
|
// This should not really happen
|
||||||
|
@ -171,94 +106,49 @@ ContentPermissionPrompt.prototype = {
|
||||||
.getService(Ci.nsIAppsService);
|
.getService(Ci.nsIAppsService);
|
||||||
let app = appsService.getAppByLocalId(request.principal.appId);
|
let app = appsService.getAppByLocalId(request.principal.appId);
|
||||||
|
|
||||||
// Check each permission if it's denied by permission manager with app's
|
let url = Services.io.newURI(app.origin, null, null);
|
||||||
// URL.
|
let principal = secMan.getAppCodebasePrincipal(url, request.principal.appId,
|
||||||
let notDenyAppPrincipal = function(type) {
|
/*mozbrowser*/false);
|
||||||
let url = Services.io.newURI(app.origin, null, null);
|
let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
|
||||||
let principal = secMan.getAppCodebasePrincipal(url,
|
request.type;
|
||||||
request.principal.appId,
|
let result = Services.perms.testExactPermissionFromPrincipal(principal, access);
|
||||||
/*mozbrowser*/false);
|
|
||||||
let result = Services.perms.testExactPermissionFromPrincipal(principal,
|
|
||||||
type.access);
|
|
||||||
|
|
||||||
if (result == Ci.nsIPermissionManager.ALLOW_ACTION ||
|
if (result == Ci.nsIPermissionManager.ALLOW_ACTION ||
|
||||||
result == Ci.nsIPermissionManager.PROMPT_ACTION) {
|
result == Ci.nsIPermissionManager.PROMPT_ACTION) {
|
||||||
type.deny = false;
|
return false;
|
||||||
}
|
|
||||||
return !type.deny;
|
|
||||||
}
|
|
||||||
if (typesInfo.filter(notDenyAppPrincipal).length === 0) {
|
|
||||||
request.cancel();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
request.cancel();
|
||||||
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
handledByPermissionType: function handledByPermissionType(request, typesInfo) {
|
handledByPermissionType: function handledByPermissionType(request) {
|
||||||
for (let i in typesInfo) {
|
return permissionSpecificChecker.hasOwnProperty(request.type)
|
||||||
if (permissionSpecificChecker.hasOwnProperty(typesInfo[i].permission) &&
|
? permissionSpecificChecker[request.type](request)
|
||||||
permissionSpecificChecker[typesInfo[i].permission](request)) {
|
: false;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_id: 0,
|
_id: 0,
|
||||||
prompt: function(request) {
|
prompt: function(request) {
|
||||||
if (secMan.isSystemPrincipal(request.principal)) {
|
if (secMan.isSystemPrincipal(request.principal)) {
|
||||||
request.allow();
|
request.allow();
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize the typesInfo and set the default value.
|
if (this.handledByApp(request) ||
|
||||||
let typesInfo = [];
|
this.handledByPermissionType(request)) {
|
||||||
let perms = request.types.QueryInterface(Ci.nsIArray);
|
|
||||||
for (let idx = 0; idx < perms.length; idx++) {
|
|
||||||
let perm = perms.queryElementAt(idx, Ci.nsIContentPermissionType);
|
|
||||||
let tmp = {
|
|
||||||
permission: perm.type,
|
|
||||||
access: (perm.access && perm.access !== "unused") ?
|
|
||||||
perm.type + "-" + perm.access : perm.type,
|
|
||||||
deny: true,
|
|
||||||
action: Ci.nsIPermissionManager.UNKNOWN_ACTION
|
|
||||||
};
|
|
||||||
typesInfo.push(tmp);
|
|
||||||
}
|
|
||||||
if (typesInfo.length == 0) {
|
|
||||||
request.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.checkMultipleRequest(typesInfo)) {
|
|
||||||
request.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.handledByApp(request, typesInfo) ||
|
|
||||||
this.handledByPermissionType(request, typesInfo)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if the request was handled
|
// returns true if the request was handled
|
||||||
if (this.handleExistingPermission(request, typesInfo)) {
|
if (this.handleExistingPermission(request))
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// prompt PROMPT_ACTION request only.
|
|
||||||
typesInfo.forEach(function(aType, aIndex) {
|
|
||||||
if (aType.action != Ci.nsIPermissionManager.PROMPT_ACTION || aType.deny) {
|
|
||||||
typesInfo.splice(aIndex);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let frame = request.element;
|
let frame = request.element;
|
||||||
let requestId = this._id++;
|
let requestId = this._id++;
|
||||||
|
|
||||||
if (!frame) {
|
if (!frame) {
|
||||||
this.delegatePrompt(request, requestId, typesInfo);
|
this.delegatePrompt(request, requestId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +163,7 @@ ContentPermissionPrompt.prototype = {
|
||||||
if (evt.detail.visible === true)
|
if (evt.detail.visible === true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
self.cancelPrompt(request, requestId, typesInfo);
|
self.cancelPrompt(request, requestId);
|
||||||
cancelRequest();
|
cancelRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +180,7 @@ ContentPermissionPrompt.prototype = {
|
||||||
// away but the request is still here.
|
// away but the request is still here.
|
||||||
frame.addEventListener("mozbrowservisibilitychange", onVisibilityChange);
|
frame.addEventListener("mozbrowservisibilitychange", onVisibilityChange);
|
||||||
|
|
||||||
self.delegatePrompt(request, requestId, typesInfo, function onCallback() {
|
self.delegatePrompt(request, requestId, function onCallback() {
|
||||||
frame.removeEventListener("mozbrowservisibilitychange", onVisibilityChange);
|
frame.removeEventListener("mozbrowservisibilitychange", onVisibilityChange);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -301,17 +191,22 @@ ContentPermissionPrompt.prototype = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
cancelPrompt: function(request, requestId, typesInfo) {
|
cancelPrompt: function(request, requestId) {
|
||||||
this.sendToBrowserWindow("cancel-permission-prompt", request, requestId,
|
this.sendToBrowserWindow("cancel-permission-prompt", request, requestId);
|
||||||
typesInfo);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
delegatePrompt: function(request, requestId, typesInfo, callback) {
|
delegatePrompt: function(request, requestId, callback) {
|
||||||
|
let access = (request.access && request.access !== "unused") ? request.type + "-" + request.access :
|
||||||
|
request.type;
|
||||||
|
let principal = request.principal;
|
||||||
|
|
||||||
this.sendToBrowserWindow("permission-prompt", request, requestId, typesInfo,
|
this._permission = access;
|
||||||
function(type, remember) {
|
this._uri = principal.URI.spec;
|
||||||
|
this._origin = principal.origin;
|
||||||
|
|
||||||
|
this.sendToBrowserWindow("permission-prompt", request, requestId, function(type, remember) {
|
||||||
if (type == "permission-allow") {
|
if (type == "permission-allow") {
|
||||||
rememberPermission(typesInfo, request.principal, !remember);
|
rememberPermission(request.type, principal, !remember);
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
@ -319,20 +214,14 @@ ContentPermissionPrompt.prototype = {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let addDenyPermission = function(type) {
|
if (remember) {
|
||||||
debug("add " + type.permission +
|
Services.perms.addFromPrincipal(principal, access,
|
||||||
" to permission manager with DENY_ACTION");
|
Ci.nsIPermissionManager.DENY_ACTION);
|
||||||
if (remember) {
|
} else {
|
||||||
Services.perms.addFromPrincipal(request.principal, type.access,
|
Services.perms.addFromPrincipal(principal, access,
|
||||||
Ci.nsIPermissionManager.DENY_ACTION);
|
Ci.nsIPermissionManager.DENY_ACTION,
|
||||||
} else if (PERMISSION_NO_SESSION.indexOf(aPerm) < 0) {
|
Ci.nsIPermissionManager.EXPIRE_SESSION, 0);
|
||||||
Services.perms.addFromPrincipal(request.principal, type.access,
|
|
||||||
Ci.nsIPermissionManager.DENY_ACTION,
|
|
||||||
Ci.nsIPermissionManager.EXPIRE_SESSION,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
typesInfo.forEach(addDenyPermission);
|
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
|
@ -341,7 +230,7 @@ ContentPermissionPrompt.prototype = {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
sendToBrowserWindow: function(type, request, requestId, typesInfo, callback) {
|
sendToBrowserWindow: function(type, request, requestId, callback) {
|
||||||
let browser = Services.wm.getMostRecentWindow("navigator:browser");
|
let browser = Services.wm.getMostRecentWindow("navigator:browser");
|
||||||
let content = browser.getContentWindow();
|
let content = browser.getContentWindow();
|
||||||
if (!content)
|
if (!content)
|
||||||
|
@ -364,15 +253,10 @@ ContentPermissionPrompt.prototype = {
|
||||||
principal.appStatus == Ci.nsIPrincipal.APP_STATUS_CERTIFIED)
|
principal.appStatus == Ci.nsIPrincipal.APP_STATUS_CERTIFIED)
|
||||||
? true
|
? true
|
||||||
: request.remember;
|
: request.remember;
|
||||||
let permissions = {};
|
|
||||||
for (let i in typesInfo) {
|
|
||||||
debug("prompt " + typesInfo[i].permission);
|
|
||||||
permissions[typesInfo[i].permission] = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
let details = {
|
let details = {
|
||||||
type: type,
|
type: type,
|
||||||
permissions: permissions,
|
permission: request.type,
|
||||||
id: requestId,
|
id: requestId,
|
||||||
origin: principal.origin,
|
origin: principal.origin,
|
||||||
isApp: isApp,
|
isApp: isApp,
|
||||||
|
@ -405,5 +289,6 @@ ContentPermissionPrompt.prototype = {
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
//module initialization
|
//module initialization
|
||||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]);
|
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentPermissionPrompt]);
|
||||||
|
|
|
@ -1056,11 +1056,6 @@ let CustomizableUIInternal = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aWidget.id == "switch-to-metro-button") {
|
|
||||||
let brandBundle = aDocument.getElementById("bundle_brand");
|
|
||||||
let brandShortName = brandBundle.getString("brandShortName");
|
|
||||||
additionalTooltipArguments = [brandShortName];
|
|
||||||
}
|
|
||||||
let tooltip = this.getLocalizedProperty(aWidget, "tooltiptext", additionalTooltipArguments);
|
let tooltip = this.getLocalizedProperty(aWidget, "tooltiptext", additionalTooltipArguments);
|
||||||
node.setAttribute("tooltiptext", tooltip);
|
node.setAttribute("tooltiptext", tooltip);
|
||||||
node.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional");
|
node.setAttribute("class", "toolbarbutton-1 chromeclass-toolbar-additional");
|
||||||
|
@ -1072,9 +1067,8 @@ let CustomizableUIInternal = {
|
||||||
|
|
||||||
// If the widget has a view, and has view showing / hiding listeners,
|
// If the widget has a view, and has view showing / hiding listeners,
|
||||||
// hook those up to this widget.
|
// hook those up to this widget.
|
||||||
if (aWidget.type == "view" &&
|
if (aWidget.type == "view") {
|
||||||
(aWidget.onViewShowing || aWidget.onViewHiding)) {
|
LOG("Widget " + aWidget.id + " has a view. Auto-registering event handlers.");
|
||||||
LOG("Widget " + aWidget.id + " has a view with showing and hiding events. Auto-registering event handlers.");
|
|
||||||
let viewNode = aDocument.getElementById(aWidget.viewId);
|
let viewNode = aDocument.getElementById(aWidget.viewId);
|
||||||
|
|
||||||
if (viewNode) {
|
if (viewNode) {
|
||||||
|
@ -1753,10 +1747,6 @@ let CustomizableUIInternal = {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aData.id == "switch-to-metro-button") {
|
|
||||||
widget.showInPrivateBrowsing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete widget.implementation.currentArea;
|
delete widget.implementation.currentArea;
|
||||||
widget.implementation.__defineGetter__("currentArea", function() widget.currentArea);
|
widget.implementation.__defineGetter__("currentArea", function() widget.currentArea);
|
||||||
|
|
||||||
|
@ -2270,8 +2260,8 @@ this.CustomizableUI = {
|
||||||
* and an onWidgetBeforeDOMChange and onWidgetAfterDOMChange notification
|
* and an onWidgetBeforeDOMChange and onWidgetAfterDOMChange notification
|
||||||
* for each window CustomizableUI knows about.
|
* for each window CustomizableUI knows about.
|
||||||
*
|
*
|
||||||
* @param aWidgetId the widget to add
|
* @param aWidgetId the ID of the widget to add
|
||||||
* @param aArea the area to add the widget to
|
* @param aArea the ID of the area to add the widget to
|
||||||
* @param aPosition the position at which to add the widget. If you do not
|
* @param aPosition the position at which to add the widget. If you do not
|
||||||
* pass a position, the widget will be added to the end
|
* pass a position, the widget will be added to the end
|
||||||
* of the area.
|
* of the area.
|
||||||
|
@ -2286,7 +2276,7 @@ this.CustomizableUI = {
|
||||||
* onWidgetAfterDOMChange notification for each window CustomizableUI knows
|
* onWidgetAfterDOMChange notification for each window CustomizableUI knows
|
||||||
* about.
|
* about.
|
||||||
*
|
*
|
||||||
* @param aWidgetId the widget to remove
|
* @param aWidgetId the ID of the widget to remove
|
||||||
*/
|
*/
|
||||||
removeWidgetFromArea: function(aWidgetId) {
|
removeWidgetFromArea: function(aWidgetId) {
|
||||||
CustomizableUIInternal.removeWidgetFromArea(aWidgetId);
|
CustomizableUIInternal.removeWidgetFromArea(aWidgetId);
|
||||||
|
@ -2300,7 +2290,7 @@ this.CustomizableUI = {
|
||||||
* and an onWidgetBeforeDOMChange and onWidgetAfterDOMChange notification for
|
* and an onWidgetBeforeDOMChange and onWidgetAfterDOMChange notification for
|
||||||
* each window CustomizableUI knows about.
|
* each window CustomizableUI knows about.
|
||||||
*
|
*
|
||||||
* @param aWidgetid the widget to move
|
* @param aWidgetId the ID of the widget to move
|
||||||
* @param aPosition the position to move the widget to.
|
* @param aPosition the position to move the widget to.
|
||||||
* Negative values or values greater than the number of
|
* Negative values or values greater than the number of
|
||||||
* widgets will be interpreted to mean moving the widget to
|
* widgets will be interpreted to mean moving the widget to
|
||||||
|
@ -2318,7 +2308,7 @@ this.CustomizableUI = {
|
||||||
* because it delegates to addWidgetToArea) or, worse, moving items in the
|
* because it delegates to addWidgetToArea) or, worse, moving items in the
|
||||||
* DOM yourself.
|
* DOM yourself.
|
||||||
*
|
*
|
||||||
* @param aWidgetId the widget that was just created
|
* @param aWidgetId the ID of the widget that was just created
|
||||||
* @param aWindow the window in which you want to ensure it was added.
|
* @param aWindow the window in which you want to ensure it was added.
|
||||||
*
|
*
|
||||||
* NB: why is this API per-window, you wonder? Because if you need this,
|
* NB: why is this API per-window, you wonder? Because if you need this,
|
||||||
|
@ -2335,7 +2325,7 @@ this.CustomizableUI = {
|
||||||
* Calls to begin/endBatchUpdate may be nested.
|
* Calls to begin/endBatchUpdate may be nested.
|
||||||
*
|
*
|
||||||
* Callers should ensure that NO MATTER WHAT they call endBatchUpdate once
|
* Callers should ensure that NO MATTER WHAT they call endBatchUpdate once
|
||||||
* for each call to endBatchUpdate, even if there are exceptions in the
|
* for each call to beginBatchUpdate, even if there are exceptions in the
|
||||||
* code in the batch update. Otherwise, for the duration of the
|
* code in the batch update. Otherwise, for the duration of the
|
||||||
* Firefox session, customization state is never saved. Typically, you
|
* Firefox session, customization state is never saved. Typically, you
|
||||||
* would do this using a try...finally block.
|
* would do this using a try...finally block.
|
||||||
|
@ -2406,6 +2396,7 @@ this.CustomizableUI = {
|
||||||
* mode (optional, default: true)
|
* mode (optional, default: true)
|
||||||
*
|
*
|
||||||
* @param aProperties the specifications for the widget.
|
* @param aProperties the specifications for the widget.
|
||||||
|
* @return a wrapper around the created widget (see getWidget)
|
||||||
*/
|
*/
|
||||||
createWidget: function(aProperties) {
|
createWidget: function(aProperties) {
|
||||||
return CustomizableUIInternal.wrapWidget(
|
return CustomizableUIInternal.wrapWidget(
|
||||||
|
@ -2421,20 +2412,105 @@ this.CustomizableUI = {
|
||||||
* in at the time. You can remove it from there yourself by calling
|
* in at the time. You can remove it from there yourself by calling
|
||||||
* CustomizableUI.removeWidgetFromArea(aWidgetId).
|
* CustomizableUI.removeWidgetFromArea(aWidgetId).
|
||||||
*
|
*
|
||||||
* @param aWidgetId the widget to destroy
|
* @param aWidgetId the ID of the widget to destroy
|
||||||
*/
|
*/
|
||||||
destroyWidget: function(aWidgetId) {
|
destroyWidget: function(aWidgetId) {
|
||||||
CustomizableUIInternal.destroyWidget(aWidgetId);
|
CustomizableUIInternal.destroyWidget(aWidgetId);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Get a wrapper object with information about the widget.
|
||||||
|
* The object provides the following properties
|
||||||
|
* (all read-only unless otherwise indicated):
|
||||||
|
*
|
||||||
|
* - id: the widget's ID;
|
||||||
|
* - type: the type of widget (button, view, custom). For
|
||||||
|
* XUL-provided widgets, this is always 'custom';
|
||||||
|
* - provider: the provider type of the widget, id est one of
|
||||||
|
* PROVIDER_API or PROVIDER_XUL;
|
||||||
|
* - forWindow(w): a method to obtain a single window wrapper for a widget,
|
||||||
|
* in the window w passed as the only argument;
|
||||||
|
* - instances: an array of all instances (single window wrappers)
|
||||||
|
* of the widget. This array is NOT live;
|
||||||
|
* - areaType: the type of the widget's current area
|
||||||
|
* - isGroup: true; will be false for wrappers around single widget nodes;
|
||||||
|
* - source: for API-provided widgets, whether they are built-in to
|
||||||
|
* Firefox or add-on-provided;
|
||||||
|
* - disabled: for API-provided widgets, whether the widget is currently
|
||||||
|
* disabled. NB: this property is writable, and will toggle
|
||||||
|
* all the widgets' disabled state;
|
||||||
|
* - label: for API-provied widgets, the label of the widget;
|
||||||
|
* - tooltiptext: for API-provided widgets, the tooltip of the widget;
|
||||||
|
* - showInPrivateBrowsing: for API-provided widgets, whether the widget is
|
||||||
|
* visible in private browsing;
|
||||||
|
*
|
||||||
|
* Single window wrappers obtained through forWindow(someWindow) or from the
|
||||||
|
* instances array have the following properties
|
||||||
|
* (all read-only unless otherwise indicated):
|
||||||
|
*
|
||||||
|
* - id: the widget's ID;
|
||||||
|
* - type: the type of widget (button, view, custom). For
|
||||||
|
* XUL-provided widgets, this is always 'custom';
|
||||||
|
* - provider: the provider type of the widget, id est one of
|
||||||
|
* PROVIDER_API or PROVIDER_XUL;
|
||||||
|
* - node: reference to the corresponding DOM node;
|
||||||
|
* - anchor: the anchor on which to anchor panels opened from this
|
||||||
|
* node. This will point to the overflow chevron on
|
||||||
|
* overflowable toolbars if and only if your widget node
|
||||||
|
* is overflowed, to the anchor for the panel menu
|
||||||
|
* if your widget is inside the panel menu, and to the
|
||||||
|
* node itself in all other cases;
|
||||||
|
* - overflowed: boolean indicating whether the node is currently in the
|
||||||
|
* overflow panel of the toolbar;
|
||||||
|
* - isGroup: false; will be true for the group widget;
|
||||||
|
* - label: for API-provided widgets, convenience getter for the
|
||||||
|
* label attribute of the DOM node;
|
||||||
|
* - tooltiptext: for API-provided widgets, convenience getter for the
|
||||||
|
* tooltiptext attribute of the DOM node;
|
||||||
|
* - disabled: for API-provided widgets, convenience getter *and setter*
|
||||||
|
* for the disabled state of this single widget. Note that
|
||||||
|
* you may prefer to use the group wrapper's getter/setter
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
|
* @param aWidgetId the ID of the widget whose information you need
|
||||||
|
* @return a wrapper around the widget as described above, or null if the
|
||||||
|
* widget is known not to exist (anymore). NB: non-null return
|
||||||
|
* is no guarantee the widget exists because we cannot know in
|
||||||
|
* advance if a XUL widget exists or not.
|
||||||
|
*/
|
||||||
getWidget: function(aWidgetId) {
|
getWidget: function(aWidgetId) {
|
||||||
return CustomizableUIInternal.wrapWidget(aWidgetId);
|
return CustomizableUIInternal.wrapWidget(aWidgetId);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Get an array of widget wrappers (see getWidget) for all the widgets
|
||||||
|
* which are currently not in any area (so which are in the palette).
|
||||||
|
*
|
||||||
|
* @param aWindowPalette the palette (and by extension, the window) in which
|
||||||
|
* CustomizableUI should look. This matters because of
|
||||||
|
* course XUL-provided widgets could be available in
|
||||||
|
* some windows but not others, and likewise
|
||||||
|
* API-provided widgets might not exist in a private
|
||||||
|
* window (because of the showInPrivateBrowsing
|
||||||
|
* property).
|
||||||
|
*
|
||||||
|
* @return an array of widget wrappers (see getWidget)
|
||||||
|
*/
|
||||||
getUnusedWidgets: function(aWindowPalette) {
|
getUnusedWidgets: function(aWindowPalette) {
|
||||||
return CustomizableUIInternal.getUnusedWidgets(aWindowPalette).map(
|
return CustomizableUIInternal.getUnusedWidgets(aWindowPalette).map(
|
||||||
CustomizableUIInternal.wrapWidget,
|
CustomizableUIInternal.wrapWidget,
|
||||||
CustomizableUIInternal
|
CustomizableUIInternal
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Get an array of all the widget IDs placed in an area. This is roughly
|
||||||
|
* equivalent to fetching the currentset attribute and splitting by commas
|
||||||
|
* in the legacy APIs. Modifying the array will not affect CustomizableUI.
|
||||||
|
*
|
||||||
|
* @param aArea the ID of the area whose placements you want to obtain.
|
||||||
|
* @return an array containing the widget IDs that are in the area.
|
||||||
|
*
|
||||||
|
* NB: will throw if called too early (before placements have been fetched)
|
||||||
|
* or if the area is not currently known to CustomizableUI.
|
||||||
|
*/
|
||||||
getWidgetIdsInArea: function(aArea) {
|
getWidgetIdsInArea: function(aArea) {
|
||||||
if (!gAreas.has(aArea)) {
|
if (!gAreas.has(aArea)) {
|
||||||
throw new Error("Unknown customization area: " + aArea);
|
throw new Error("Unknown customization area: " + aArea);
|
||||||
|
@ -2446,67 +2522,261 @@ this.CustomizableUI = {
|
||||||
// We need to clone this, as we don't want to let consumers muck with placements
|
// We need to clone this, as we don't want to let consumers muck with placements
|
||||||
return [...gPlacements.get(aArea)];
|
return [...gPlacements.get(aArea)];
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Get an array of widget wrappers for all the widgets in an area. This is
|
||||||
|
* the same as calling getWidgetIdsInArea and .map() ing the result through
|
||||||
|
* CustomizableUI.getWidget. Careful: this means that if there are IDs in there
|
||||||
|
* which don't have corresponding DOM nodes (like in the old-style currentset
|
||||||
|
* attribute), there might be nulls in this array, or items for which
|
||||||
|
* wrapper.forWindow(win) will return null.
|
||||||
|
*
|
||||||
|
* @param aArea the ID of the area whose widgets you want to obtain.
|
||||||
|
* @return an array of widget wrappers and/or null values for the widget IDs
|
||||||
|
* placed in an area.
|
||||||
|
*
|
||||||
|
* NB: will throw if called too early (before placements have been fetched)
|
||||||
|
* or if the area is not currently known to CustomizableUI.
|
||||||
|
*/
|
||||||
getWidgetsInArea: function(aArea) {
|
getWidgetsInArea: function(aArea) {
|
||||||
return this.getWidgetIdsInArea(aArea).map(
|
return this.getWidgetIdsInArea(aArea).map(
|
||||||
CustomizableUIInternal.wrapWidget,
|
CustomizableUIInternal.wrapWidget,
|
||||||
CustomizableUIInternal
|
CustomizableUIInternal
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Obtain an array of all the area IDs known to CustomizableUI.
|
||||||
|
* This array is created for you, so is modifiable without CustomizableUI
|
||||||
|
* being affected.
|
||||||
|
*/
|
||||||
get areas() {
|
get areas() {
|
||||||
return [area for ([area, props] of gAreas)];
|
return [area for ([area, props] of gAreas)];
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Check what kind of area (toolbar or menu panel) an area is. This is
|
||||||
|
* useful if you have a widget that needs to behave differently depending
|
||||||
|
* on its location. Note that widget wrappers have a convenience getter
|
||||||
|
* property (areaType) for this purpose.
|
||||||
|
*
|
||||||
|
* @param aArea the ID of the area whose type you want to know
|
||||||
|
* @return TYPE_TOOLBAR or TYPE_MENU_PANEL depending on the area, null if
|
||||||
|
* the area is unknown.
|
||||||
|
*/
|
||||||
getAreaType: function(aArea) {
|
getAreaType: function(aArea) {
|
||||||
let area = gAreas.get(aArea);
|
let area = gAreas.get(aArea);
|
||||||
return area ? area.get("type") : null;
|
return area ? area.get("type") : null;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Obtain the DOM node that is the customize target for an area in a
|
||||||
|
* specific window.
|
||||||
|
*
|
||||||
|
* Areas can have a customization target that does not correspond to the
|
||||||
|
* node itself. In particular, toolbars that have a customizationtarget
|
||||||
|
* attribute set will have their customization target set to that node.
|
||||||
|
* This means widgets will end up in the customization target, not in the
|
||||||
|
* DOM node with the ID that corresponds to the area ID. This is useful
|
||||||
|
* because it lets you have fixed content in a toolbar (e.g. the panel
|
||||||
|
* menu item in the navbar) and have all the customizable widgets use
|
||||||
|
* the customization target.
|
||||||
|
*
|
||||||
|
* Using this API yourself is discouraged; you should generally not need
|
||||||
|
* to be asking for the DOM container node used for a particular area.
|
||||||
|
* In particular, if you're wanting to check it in relation to a widget's
|
||||||
|
* node, your DOM node might not be a direct child of the customize target
|
||||||
|
* in a window if, for instance, the window is in customization mode, or if
|
||||||
|
* this is an overflowable toolbar and the widget has been overflowed.
|
||||||
|
*
|
||||||
|
* @param aArea the ID of the area whose customize target you want to have
|
||||||
|
* @param aWindow the window where you want to fetch the DOM node.
|
||||||
|
* @return the customize target DOM node for aArea in aWindow
|
||||||
|
*/
|
||||||
getCustomizeTargetForArea: function(aArea, aWindow) {
|
getCustomizeTargetForArea: function(aArea, aWindow) {
|
||||||
return CustomizableUIInternal.getCustomizeTargetForArea(aArea, aWindow);
|
return CustomizableUIInternal.getCustomizeTargetForArea(aArea, aWindow);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Reset the customization state back to its default.
|
||||||
|
*
|
||||||
|
* This is the nuclear option. You should never call this except if the user
|
||||||
|
* explicitly requests it. Firefox does this when the user clicks the
|
||||||
|
* "Restore Defaults" button in customize mode.
|
||||||
|
*/
|
||||||
reset: function() {
|
reset: function() {
|
||||||
CustomizableUIInternal.reset();
|
CustomizableUIInternal.reset();
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Get the placement of a widget. This is by far the best way to obtain
|
||||||
|
* information about what the state of your widget is. The internals of
|
||||||
|
* this call are cheap (no DOM necessary) and you will know where the user
|
||||||
|
* has put your widget.
|
||||||
|
*
|
||||||
|
* @param aWidgetId the ID of the widget whose placement you want to know
|
||||||
|
* @return
|
||||||
|
* {
|
||||||
|
* area: "somearea", // The ID of the area where the widget is placed
|
||||||
|
* position: 42 // the index in the placements array corresponding to
|
||||||
|
* // your widget.
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* OR
|
||||||
|
*
|
||||||
|
* null // if the widget is not placed anywhere (ie in the palette)
|
||||||
|
*/
|
||||||
getPlacementOfWidget: function(aWidgetId) {
|
getPlacementOfWidget: function(aWidgetId) {
|
||||||
return CustomizableUIInternal.getPlacementOfWidget(aWidgetId, true);
|
return CustomizableUIInternal.getPlacementOfWidget(aWidgetId, true);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Check if a widget can be removed from the area it's in.
|
||||||
|
*
|
||||||
|
* Note that if you're wanting to move the widget somewhere, you should
|
||||||
|
* generally be checking canWidgetMoveToArea, because that will return
|
||||||
|
* true if the widget is already in the area where you want to move it (!).
|
||||||
|
*
|
||||||
|
* NB: oh, also, this method might lie if the widget in question is a
|
||||||
|
* XUL-provided widget and there are no windows open, because it
|
||||||
|
* can obviously not check anything in this case. It will return
|
||||||
|
* true. You will be able to move the widget elsewhere. However,
|
||||||
|
* once the user reopens a window, the widget will move back to its
|
||||||
|
* 'proper' area automagically.
|
||||||
|
*
|
||||||
|
* @param aWidgetId a widget ID or DOM node to check
|
||||||
|
* @return true if the widget can be removed from its area,
|
||||||
|
* false otherwise.
|
||||||
|
*/
|
||||||
isWidgetRemovable: function(aWidgetId) {
|
isWidgetRemovable: function(aWidgetId) {
|
||||||
return CustomizableUIInternal.isWidgetRemovable(aWidgetId);
|
return CustomizableUIInternal.isWidgetRemovable(aWidgetId);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Check if a widget can be moved to a particular area. Like
|
||||||
|
* isWidgetRemovable but better, because it'll return true if the widget
|
||||||
|
* is already in the right area.
|
||||||
|
*
|
||||||
|
* @param aWidgetId the widget ID or DOM node you want to move somewhere
|
||||||
|
* @param aArea the area ID you want to move it to.
|
||||||
|
* @return true if this is possible, false if it is not. Same caveats as
|
||||||
|
* for isWidgetRemovable apply, however, if no windows are open.
|
||||||
|
*/
|
||||||
canWidgetMoveToArea: function(aWidgetId, aArea) {
|
canWidgetMoveToArea: function(aWidgetId, aArea) {
|
||||||
return CustomizableUIInternal.canWidgetMoveToArea(aWidgetId, aArea);
|
return CustomizableUIInternal.canWidgetMoveToArea(aWidgetId, aArea);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Whether we're in a default state.
|
||||||
|
*
|
||||||
|
* NB: this is a property with a getter. The getter is NOT cheap, because
|
||||||
|
* it does smart things with non-removable non-default items, non-existent
|
||||||
|
* items, and so forth. Please don't call unless necessary.
|
||||||
|
*/
|
||||||
get inDefaultState() {
|
get inDefaultState() {
|
||||||
return CustomizableUIInternal.inDefaultState;
|
return CustomizableUIInternal.inDefaultState;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Get a localized property off a (widget?) object.
|
||||||
|
*
|
||||||
|
* NB: this is unlikely to be useful unless you're in Firefox code, because
|
||||||
|
* this code uses the builtin widget stringbundle, and can't be told
|
||||||
|
* to use add-on-provided strings. It's mainly here as convenience for
|
||||||
|
* custom builtin widgets that build their own DOM but use the same
|
||||||
|
* stringbundle as the other builtin widgets.
|
||||||
|
*
|
||||||
|
* @param aWidget the object whose property we should use to fetch a
|
||||||
|
* localizable string;
|
||||||
|
* @param aProp the property on the object to use for the fetching;
|
||||||
|
* @param aFormatArgs (optional) any extra arguments to use for a formatted
|
||||||
|
* string;
|
||||||
|
* @param aDef (optional) the default to return if we don't find the
|
||||||
|
* string in the stringbundle;
|
||||||
|
*
|
||||||
|
* @return the localized string, or aDef if the string isn't in the bundle.
|
||||||
|
* If no default is provided,
|
||||||
|
* if aProp exists on aWidget, we'll return that,
|
||||||
|
* otherwise we'll return the empty string
|
||||||
|
*
|
||||||
|
*/
|
||||||
getLocalizedProperty: function(aWidget, aProp, aFormatArgs, aDef) {
|
getLocalizedProperty: function(aWidget, aProp, aFormatArgs, aDef) {
|
||||||
return CustomizableUIInternal.getLocalizedProperty(aWidget, aProp,
|
return CustomizableUIInternal.getLocalizedProperty(aWidget, aProp,
|
||||||
aFormatArgs, aDef);
|
aFormatArgs, aDef);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Given a node, walk up to the first panel in its ancestor chain, and
|
||||||
|
* close it.
|
||||||
|
*
|
||||||
|
* @param aNode a node whose panel should be closed;
|
||||||
|
*/
|
||||||
hidePanelForNode: function(aNode) {
|
hidePanelForNode: function(aNode) {
|
||||||
CustomizableUIInternal.hidePanelForNode(aNode);
|
CustomizableUIInternal.hidePanelForNode(aNode);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Check if a widget is a "special" widget: a spring, spacer or separator.
|
||||||
|
*
|
||||||
|
* @param aWidgetId the widget ID to check.
|
||||||
|
*/
|
||||||
isSpecialWidget: function(aWidgetId) {
|
isSpecialWidget: function(aWidgetId) {
|
||||||
return CustomizableUIInternal.isSpecialWidget(aWidgetId);
|
return CustomizableUIInternal.isSpecialWidget(aWidgetId);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Add listeners to a panel that will close it. For use from PanelUI and
|
||||||
|
* the overflowable toolbars, unlikely to be useful for consumers.
|
||||||
|
*
|
||||||
|
* @param aPanel the panel to which listeners should be attached.
|
||||||
|
*/
|
||||||
addPanelCloseListeners: function(aPanel) {
|
addPanelCloseListeners: function(aPanel) {
|
||||||
CustomizableUIInternal.addPanelCloseListeners(aPanel);
|
CustomizableUIInternal.addPanelCloseListeners(aPanel);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Remove close listeners that have been added to a panel with
|
||||||
|
* addPanelCloseListeners. For use from PanelUI and the overflowable
|
||||||
|
* toolbars, unlikely to be useful for consumers.
|
||||||
|
*
|
||||||
|
* @param aPanel the panel from which listeners should be removed.
|
||||||
|
*/
|
||||||
removePanelCloseListeners: function(aPanel) {
|
removePanelCloseListeners: function(aPanel) {
|
||||||
CustomizableUIInternal.removePanelCloseListeners(aPanel);
|
CustomizableUIInternal.removePanelCloseListeners(aPanel);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Notify listeners a widget is about to be dragged to an area. For use from
|
||||||
|
* Customize Mode only, do not use otherwise.
|
||||||
|
*
|
||||||
|
* @param aWidgetId the ID of the widget that is being dragged to an area.
|
||||||
|
* @param aArea the ID of the area to which the widget is being dragged.
|
||||||
|
*/
|
||||||
onWidgetDrag: function(aWidgetId, aArea) {
|
onWidgetDrag: function(aWidgetId, aArea) {
|
||||||
CustomizableUIInternal.notifyListeners("onWidgetDrag", aWidgetId, aArea);
|
CustomizableUIInternal.notifyListeners("onWidgetDrag", aWidgetId, aArea);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Notify listeners that a window is entering customize mode. For use from
|
||||||
|
* Customize Mode only, do not use otherwise.
|
||||||
|
* @param aWindow the window entering customize mode
|
||||||
|
*/
|
||||||
notifyStartCustomizing: function(aWindow) {
|
notifyStartCustomizing: function(aWindow) {
|
||||||
CustomizableUIInternal.notifyListeners("onCustomizeStart", aWindow);
|
CustomizableUIInternal.notifyListeners("onCustomizeStart", aWindow);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Notify listeners that a window is exiting customize mode. For use from
|
||||||
|
* Customize Mode only, do not use otherwise.
|
||||||
|
* @param aWindow the window exiting customize mode
|
||||||
|
*/
|
||||||
notifyEndCustomizing: function(aWindow) {
|
notifyEndCustomizing: function(aWindow) {
|
||||||
CustomizableUIInternal.notifyListeners("onCustomizeEnd", aWindow);
|
CustomizableUIInternal.notifyListeners("onCustomizeEnd", aWindow);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Check whether an area is overflowable.
|
||||||
|
*
|
||||||
|
* @param aAreaId the ID of an area to check for overflowable-ness
|
||||||
|
* @return true if the area is overflowable, false otherwise.
|
||||||
|
*/
|
||||||
isAreaOverflowable: function(aAreaId) {
|
isAreaOverflowable: function(aAreaId) {
|
||||||
let area = gAreas.get(aAreaId);
|
let area = gAreas.get(aAreaId);
|
||||||
return area ? area.get("type") == this.TYPE_TOOLBAR && area.get("overflowable")
|
return area ? area.get("type") == this.TYPE_TOOLBAR && area.get("overflowable")
|
||||||
: false;
|
: false;
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
* Obtain a string indicating the place of an element. This is intended
|
||||||
|
* for use from customize mode; You should generally use getPlacementOfWidget
|
||||||
|
* instead, which is cheaper because it does not use the DOM.
|
||||||
|
*
|
||||||
|
* @param aElement the DOM node whose place we need to check
|
||||||
|
* @return "toolbar" if the node is in a toolbar, "panel" if it is in the
|
||||||
|
* menu panel, "palette" if it is in the (visible!) customization
|
||||||
|
* palette, undefined otherwise.
|
||||||
|
*/
|
||||||
getPlaceForItem: function(aElement) {
|
getPlaceForItem: function(aElement) {
|
||||||
let place;
|
let place;
|
||||||
let node = aElement;
|
let node = aElement;
|
||||||
|
|
|
@ -17,6 +17,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "RecentlyClosedTabsAndWindowsMenuUtils",
|
||||||
XPCOMUtils.defineLazyServiceGetter(this, "CharsetManager",
|
XPCOMUtils.defineLazyServiceGetter(this, "CharsetManager",
|
||||||
"@mozilla.org/charset-converter-manager;1",
|
"@mozilla.org/charset-converter-manager;1",
|
||||||
"nsICharsetConverterManager");
|
"nsICharsetConverterManager");
|
||||||
|
XPCOMUtils.defineLazyGetter(this, "BrandBundle", function() {
|
||||||
|
const kBrandBundle = "chrome://branding/locale/brand.properties";
|
||||||
|
return Services.strings.createBundle(kBrandBundle);
|
||||||
|
});
|
||||||
|
|
||||||
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||||
const kPrefCustomizationDebug = "browser.uiCustomization.debug";
|
const kPrefCustomizationDebug = "browser.uiCustomization.debug";
|
||||||
|
@ -25,14 +29,6 @@ const kWidePanelItemClass = "panel-wide-item";
|
||||||
let gModuleName = "[CustomizableWidgets]";
|
let gModuleName = "[CustomizableWidgets]";
|
||||||
#include logging.js
|
#include logging.js
|
||||||
|
|
||||||
function isWin8OrHigher() {
|
|
||||||
let osName = Services.sysinfo.getProperty("name");
|
|
||||||
let version = Services.sysinfo.getProperty("version");
|
|
||||||
|
|
||||||
// Windows 8 is version >= 6.2
|
|
||||||
return osName == "Windows_NT" && Services.vc.compare(version, "6.2") >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setAttributes(aNode, aAttrs) {
|
function setAttributes(aNode, aAttrs) {
|
||||||
for (let [name, value] of Iterator(aAttrs)) {
|
for (let [name, value] of Iterator(aAttrs)) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
|
@ -796,17 +792,20 @@ const CustomizableWidgets = [{
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
#ifdef MOZ_METRO
|
#ifdef MOZ_METRO
|
||||||
if (isWin8OrHigher()) {
|
if (Services.sysinfo.getProperty("hasWindowsTouchInterface")) {
|
||||||
|
let widgetArgs = {tooltiptext: "switch-to-metro-button2.tooltiptext"};
|
||||||
|
let brandShortName = BrandBundle.GetStringFromName("brandShortName");
|
||||||
|
let metroTooltip = CustomizableUI.getLocalizedProperty(widgetArgs, "tooltiptext",
|
||||||
|
[brandShortName]);
|
||||||
CustomizableWidgets.push({
|
CustomizableWidgets.push({
|
||||||
id: "switch-to-metro-button",
|
id: "switch-to-metro-button",
|
||||||
label: "switch-to-metro-button2.label",
|
label: "switch-to-metro-button2.label",
|
||||||
tooltiptext: "switch-to-metro-button2.tooltiptext",
|
tooltiptext: metroTooltip,
|
||||||
removable: true,
|
removable: true,
|
||||||
defaultArea: CustomizableUI.AREA_PANEL,
|
defaultArea: CustomizableUI.AREA_PANEL,
|
||||||
|
showInPrivateBrowsing: false, /* See bug 928068 */
|
||||||
onCommand: function(aEvent) {
|
onCommand: function(aEvent) {
|
||||||
let win = aEvent.target &&
|
let win = aEvent.view;
|
||||||
aEvent.target.ownerDocument &&
|
|
||||||
aEvent.target.ownerDocument.defaultView;
|
|
||||||
if (win && typeof win.SwitchToMetro == "function") {
|
if (win && typeof win.SwitchToMetro == "function") {
|
||||||
win.SwitchToMetro();
|
win.SwitchToMetro();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1591,7 +1591,7 @@ BrowserGlue.prototype = {
|
||||||
// be set to the version it has been added in, we will compare its value
|
// be set to the version it has been added in, we will compare its value
|
||||||
// to users' smartBookmarksVersion and add new smart bookmarks without
|
// to users' smartBookmarksVersion and add new smart bookmarks without
|
||||||
// recreating old deleted ones.
|
// recreating old deleted ones.
|
||||||
const SMART_BOOKMARKS_VERSION = 5;
|
const SMART_BOOKMARKS_VERSION = 6;
|
||||||
const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
|
const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
|
||||||
const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
|
const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
|
||||||
|
|
||||||
|
@ -1653,7 +1653,10 @@ BrowserGlue.prototype = {
|
||||||
position: menuIndex++,
|
position: menuIndex++,
|
||||||
newInVersion: 1
|
newInVersion: 1
|
||||||
},
|
},
|
||||||
Windows8Touch: {
|
};
|
||||||
|
|
||||||
|
if (Services.sysinfo.getProperty("hasWindowsTouchInterface")) {
|
||||||
|
smartBookmarks.Windows8Touch = {
|
||||||
title: bundle.GetStringFromName("windows8TouchTitle"),
|
title: bundle.GetStringFromName("windows8TouchTitle"),
|
||||||
uri: NetUtil.newURI("place:folder=" +
|
uri: NetUtil.newURI("place:folder=" +
|
||||||
PlacesUtils.annotations.getItemsWithAnnotation('metro/bookmarksRoot', {})[0] +
|
PlacesUtils.annotations.getItemsWithAnnotation('metro/bookmarksRoot', {})[0] +
|
||||||
|
@ -1665,9 +1668,9 @@ BrowserGlue.prototype = {
|
||||||
"&excludeQueries=1"),
|
"&excludeQueries=1"),
|
||||||
parent: PlacesUtils.bookmarksMenuFolderId,
|
parent: PlacesUtils.bookmarksMenuFolderId,
|
||||||
position: menuIndex++,
|
position: menuIndex++,
|
||||||
newInVersion: 5
|
newInVersion: 6
|
||||||
},
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
// Set current itemId, parent and position if Smart Bookmark exists,
|
// Set current itemId, parent and position if Smart Bookmark exists,
|
||||||
// we will use these informations to create the new version at the same
|
// we will use these informations to create the new version at the same
|
||||||
|
@ -2030,21 +2033,13 @@ ContentPermissionPrompt.prototype = {
|
||||||
|
|
||||||
prompt: function CPP_prompt(request) {
|
prompt: function CPP_prompt(request) {
|
||||||
|
|
||||||
// Only allow exactly one permission rquest here.
|
|
||||||
let types = request.types.QueryInterface(Ci.nsIArray);
|
|
||||||
if (types.length != 1) {
|
|
||||||
request.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let perm = types.queryElementAt(0, Ci.nsIContentPermissionType);
|
|
||||||
|
|
||||||
const kFeatureKeys = { "geolocation" : "geo",
|
const kFeatureKeys = { "geolocation" : "geo",
|
||||||
"desktop-notification" : "desktop-notification",
|
"desktop-notification" : "desktop-notification",
|
||||||
"pointerLock" : "pointerLock",
|
"pointerLock" : "pointerLock",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make sure that we support the request.
|
// Make sure that we support the request.
|
||||||
if (!(perm.type in kFeatureKeys)) {
|
if (!(request.type in kFeatureKeys)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2056,7 +2051,7 @@ ContentPermissionPrompt.prototype = {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var autoAllow = false;
|
var autoAllow = false;
|
||||||
var permissionKey = kFeatureKeys[perm.type];
|
var permissionKey = kFeatureKeys[request.type];
|
||||||
var result = Services.perms.testExactPermissionFromPrincipal(requestingPrincipal, permissionKey);
|
var result = Services.perms.testExactPermissionFromPrincipal(requestingPrincipal, permissionKey);
|
||||||
|
|
||||||
if (result == Ci.nsIPermissionManager.DENY_ACTION) {
|
if (result == Ci.nsIPermissionManager.DENY_ACTION) {
|
||||||
|
@ -2067,7 +2062,7 @@ ContentPermissionPrompt.prototype = {
|
||||||
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||||
autoAllow = true;
|
autoAllow = true;
|
||||||
// For pointerLock, we still want to show a warning prompt.
|
// For pointerLock, we still want to show a warning prompt.
|
||||||
if (perm.type != "pointerLock") {
|
if (request.type != "pointerLock") {
|
||||||
request.allow();
|
request.allow();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2081,7 +2076,7 @@ ContentPermissionPrompt.prototype = {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Show the prompt.
|
// Show the prompt.
|
||||||
switch (perm.type) {
|
switch (request.type) {
|
||||||
case "geolocation":
|
case "geolocation":
|
||||||
this._promptGeo(request);
|
this._promptGeo(request);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -63,9 +63,10 @@ let (XULAppInfo = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smart bookmarks constants.
|
// Smart bookmarks constants.
|
||||||
const SMART_BOOKMARKS_VERSION = 5;
|
let isWin8OrHigher = Services.sysinfo.getProperty("hasWindowsTouchInterface");
|
||||||
|
const SMART_BOOKMARKS_VERSION = 6
|
||||||
const SMART_BOOKMARKS_ON_TOOLBAR = 1;
|
const SMART_BOOKMARKS_ON_TOOLBAR = 1;
|
||||||
const SMART_BOOKMARKS_ON_MENU = 4; // Takes in count the additional separator.
|
const SMART_BOOKMARKS_ON_MENU = isWin8OrHigher ? 4 : 3; // Takes in count the additional separator.
|
||||||
|
|
||||||
// Default bookmarks constants.
|
// Default bookmarks constants.
|
||||||
const DEFAULT_BOOKMARKS_ON_TOOLBAR = 1;
|
const DEFAULT_BOOKMARKS_ON_TOOLBAR = 1;
|
||||||
|
|
|
@ -78,6 +78,11 @@ const TAB_EVENTS = [
|
||||||
"TabUnpinned"
|
"TabUnpinned"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Browser events observed.
|
||||||
|
const BROWSER_EVENTS = [
|
||||||
|
"load", "SwapDocShells", "UserTypedValueChanged"
|
||||||
|
];
|
||||||
|
|
||||||
// The number of milliseconds in a day
|
// The number of milliseconds in a day
|
||||||
const MS_PER_DAY = 1000.0 * 60.0 * 60.0 * 24.0;
|
const MS_PER_DAY = 1000.0 * 60.0 * 60.0 * 24.0;
|
||||||
|
|
||||||
|
@ -1243,9 +1248,7 @@ let SessionStoreInternal = {
|
||||||
*/
|
*/
|
||||||
onTabAdd: function ssi_onTabAdd(aWindow, aTab, aNoNotification) {
|
onTabAdd: function ssi_onTabAdd(aWindow, aTab, aNoNotification) {
|
||||||
let browser = aTab.linkedBrowser;
|
let browser = aTab.linkedBrowser;
|
||||||
browser.addEventListener("load", this, true);
|
BROWSER_EVENTS.forEach(msg => browser.addEventListener(msg, this, true));
|
||||||
browser.addEventListener("SwapDocShells", this, true);
|
|
||||||
browser.addEventListener("UserTypedValueChanged", this, true);
|
|
||||||
|
|
||||||
let mm = browser.messageManager;
|
let mm = browser.messageManager;
|
||||||
MESSAGES.forEach(msg => mm.addMessageListener(msg, this));
|
MESSAGES.forEach(msg => mm.addMessageListener(msg, this));
|
||||||
|
@ -1271,9 +1274,7 @@ let SessionStoreInternal = {
|
||||||
*/
|
*/
|
||||||
onTabRemove: function ssi_onTabRemove(aWindow, aTab, aNoNotification) {
|
onTabRemove: function ssi_onTabRemove(aWindow, aTab, aNoNotification) {
|
||||||
let browser = aTab.linkedBrowser;
|
let browser = aTab.linkedBrowser;
|
||||||
browser.removeEventListener("load", this, true);
|
BROWSER_EVENTS.forEach(msg => browser.removeEventListener(msg, this, true));
|
||||||
browser.removeEventListener("SwapDocShells", this, true);
|
|
||||||
browser.removeEventListener("UserTypedValueChanged", this, true);
|
|
||||||
|
|
||||||
let mm = browser.messageManager;
|
let mm = browser.messageManager;
|
||||||
MESSAGES.forEach(msg => mm.removeMessageListener(msg, this));
|
MESSAGES.forEach(msg => mm.removeMessageListener(msg, this));
|
||||||
|
|
|
@ -237,8 +237,20 @@ Toolbox.prototype = {
|
||||||
}, true);
|
}, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_isResponsiveModeActive: function() {
|
||||||
|
let responsiveModeActive = false;
|
||||||
|
if (this.target.isLocalTab) {
|
||||||
|
let tab = this.target.tab;
|
||||||
|
let browserWindow = tab.ownerDocument.defaultView;
|
||||||
|
let responsiveUIManager = browserWindow.ResponsiveUI.ResponsiveUIManager;
|
||||||
|
responsiveModeActive = responsiveUIManager.isActiveForTab(tab);
|
||||||
|
}
|
||||||
|
return responsiveModeActive;
|
||||||
|
},
|
||||||
|
|
||||||
_splitConsoleOnKeypress: function(e) {
|
_splitConsoleOnKeypress: function(e) {
|
||||||
if (e.keyCode === e.DOM_VK_ESCAPE) {
|
let responsiveModeActive = this._isResponsiveModeActive();
|
||||||
|
if (e.keyCode === e.DOM_VK_ESCAPE && !responsiveModeActive) {
|
||||||
this.toggleSplitConsole();
|
this.toggleSplitConsole();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -176,7 +176,7 @@ function ResponsiveUI(aWindow, aTab)
|
||||||
// Events
|
// Events
|
||||||
this.tab.addEventListener("TabClose", this);
|
this.tab.addEventListener("TabClose", this);
|
||||||
this.tabContainer.addEventListener("TabSelect", this);
|
this.tabContainer.addEventListener("TabSelect", this);
|
||||||
this.mainWindow.document.addEventListener("keypress", this.bound_onKeypress, true);
|
this.mainWindow.document.addEventListener("keypress", this.bound_onKeypress, false);
|
||||||
|
|
||||||
this.buildUI();
|
this.buildUI();
|
||||||
this.checkMenus();
|
this.checkMenus();
|
||||||
|
@ -276,7 +276,7 @@ ResponsiveUI.prototype = {
|
||||||
this.stopResizing();
|
this.stopResizing();
|
||||||
|
|
||||||
// Remove listeners.
|
// Remove listeners.
|
||||||
this.mainWindow.document.removeEventListener("keypress", this.bound_onKeypress, true);
|
this.mainWindow.document.removeEventListener("keypress", this.bound_onKeypress, false);
|
||||||
this.menulist.removeEventListener("select", this.bound_presetSelected, true);
|
this.menulist.removeEventListener("select", this.bound_presetSelected, true);
|
||||||
this.tab.removeEventListener("TabClose", this);
|
this.tab.removeEventListener("TabClose", this);
|
||||||
this.tabContainer.removeEventListener("TabSelect", this);
|
this.tabContainer.removeEventListener("TabSelect", this);
|
||||||
|
|
|
@ -6,6 +6,7 @@ function test() {
|
||||||
|
|
||||||
let ruleView;
|
let ruleView;
|
||||||
let inspector;
|
let inspector;
|
||||||
|
let mgr = ResponsiveUI.ResponsiveUIManager;
|
||||||
|
|
||||||
waitForExplicitFinish();
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
@ -78,14 +79,22 @@ function test() {
|
||||||
ruleView.element.addEventListener("CssRuleViewRefreshed", function refresh() {
|
ruleView.element.addEventListener("CssRuleViewRefreshed", function refresh() {
|
||||||
ruleView.element.removeEventListener("CssRuleViewRefreshed", refresh, false);
|
ruleView.element.removeEventListener("CssRuleViewRefreshed", refresh, false);
|
||||||
is(numberOfRules(), 2, "Should have two rules after growing.");
|
is(numberOfRules(), 2, "Should have two rules after growing.");
|
||||||
finishUp();
|
testEscapeCloses();
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
instance.setSize(500, 500);
|
instance.setSize(500, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testEscapeCloses() {
|
||||||
|
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menu checked");
|
||||||
|
ok(!inspector._toolbox._splitConsole, "Console is not split.");
|
||||||
|
|
||||||
|
mgr.once("off", function() {executeSoon(finishUp)});
|
||||||
|
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||||
|
}
|
||||||
|
|
||||||
function finishUp() {
|
function finishUp() {
|
||||||
document.getElementById("Tools:ResponsiveUI").doCommand();
|
ok(!inspector._toolbox._splitConsole, "Console is still not split after pressing escape.");
|
||||||
|
|
||||||
// Menus are correctly updated?
|
// Menus are correctly updated?
|
||||||
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "false", "menu unchecked");
|
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "false", "menu unchecked");
|
||||||
|
|
|
@ -44,8 +44,6 @@ let IndexedDB = {
|
||||||
}
|
}
|
||||||
|
|
||||||
let prompt = Cc["@mozilla.org/content-permission/prompt;1"].createInstance(Ci.nsIContentPermissionPrompt);
|
let prompt = Cc["@mozilla.org/content-permission/prompt;1"].createInstance(Ci.nsIContentPermissionPrompt);
|
||||||
let types = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
|
|
||||||
types.appendElement({type: type, access: "unused"}, false);
|
|
||||||
|
|
||||||
// If the user waits a long time before responding, we default to UNKNOWN_ACTION.
|
// If the user waits a long time before responding, we default to UNKNOWN_ACTION.
|
||||||
let timeoutId = setTimeout(function() {
|
let timeoutId = setTimeout(function() {
|
||||||
|
@ -62,7 +60,7 @@ let IndexedDB = {
|
||||||
}
|
}
|
||||||
|
|
||||||
prompt.prompt({
|
prompt.prompt({
|
||||||
types: types,
|
type: type,
|
||||||
uri: Services.io.newURI(payload.location, null, null),
|
uri: Services.io.newURI(payload.location, null, null),
|
||||||
window: null,
|
window: null,
|
||||||
element: aMessage.target,
|
element: aMessage.target,
|
||||||
|
|
|
@ -56,8 +56,8 @@ ContentPermissionPrompt.prototype = {
|
||||||
return chromeWin.Browser.getNotificationBox(request.element);
|
return chromeWin.Browser.getNotificationBox(request.element);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleExistingPermission: function handleExistingPermission(request, type) {
|
handleExistingPermission: function handleExistingPermission(request) {
|
||||||
let result = Services.perms.testExactPermissionFromPrincipal(request.principal, type);
|
let result = Services.perms.testExactPermissionFromPrincipal(request.principal, request.type);
|
||||||
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
if (result == Ci.nsIPermissionManager.ALLOW_ACTION) {
|
||||||
request.allow();
|
request.allow();
|
||||||
return true;
|
return true;
|
||||||
|
@ -70,28 +70,20 @@ ContentPermissionPrompt.prototype = {
|
||||||
},
|
},
|
||||||
|
|
||||||
prompt: function(request) {
|
prompt: function(request) {
|
||||||
// Only allow exactly one permission rquest here.
|
|
||||||
let types = request.types.QueryInterface(Ci.nsIArray);
|
|
||||||
if (types.length != 1) {
|
|
||||||
request.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let perm = types.queryElementAt(0, Ci.nsIContentPermissionType);
|
|
||||||
|
|
||||||
// returns true if the request was handled
|
// returns true if the request was handled
|
||||||
if (this.handleExistingPermission(request, perm.type))
|
if (this.handleExistingPermission(request))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let pm = Services.perms;
|
let pm = Services.perms;
|
||||||
let notificationBox = this.getNotificationBoxForRequest(request);
|
let notificationBox = this.getNotificationBoxForRequest(request);
|
||||||
let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
|
let browserBundle = Services.strings.createBundle("chrome://browser/locale/browser.properties");
|
||||||
|
|
||||||
let notification = notificationBox.getNotificationWithValue(perm.type);
|
let notification = notificationBox.getNotificationWithValue(request.type);
|
||||||
if (notification)
|
if (notification)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let entityName = kEntities[perm.type];
|
let entityName = kEntities[request.type];
|
||||||
let icon = kIcons[perm.type] || "";
|
let icon = kIcons[request.type] || "";
|
||||||
|
|
||||||
let buttons = [{
|
let buttons = [{
|
||||||
label: browserBundle.GetStringFromName(entityName + ".allow"),
|
label: browserBundle.GetStringFromName(entityName + ".allow"),
|
||||||
|
@ -104,7 +96,7 @@ ContentPermissionPrompt.prototype = {
|
||||||
label: browserBundle.GetStringFromName("contentPermissions.alwaysForSite"),
|
label: browserBundle.GetStringFromName("contentPermissions.alwaysForSite"),
|
||||||
accessKey: "",
|
accessKey: "",
|
||||||
callback: function(notification) {
|
callback: function(notification) {
|
||||||
Services.perms.addFromPrincipal(request.principal, perm.type, Ci.nsIPermissionManager.ALLOW_ACTION);
|
Services.perms.addFromPrincipal(request.principal, request.type, Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||||
request.allow();
|
request.allow();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -112,7 +104,7 @@ ContentPermissionPrompt.prototype = {
|
||||||
label: browserBundle.GetStringFromName("contentPermissions.neverForSite"),
|
label: browserBundle.GetStringFromName("contentPermissions.neverForSite"),
|
||||||
accessKey: "",
|
accessKey: "",
|
||||||
callback: function(notification) {
|
callback: function(notification) {
|
||||||
Services.perms.addFromPrincipal(request.principal, perm.type, Ci.nsIPermissionManager.DENY_ACTION);
|
Services.perms.addFromPrincipal(request.principal, request.type, Ci.nsIPermissionManager.DENY_ACTION);
|
||||||
request.cancel();
|
request.cancel();
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
|
@ -120,12 +112,12 @@ ContentPermissionPrompt.prototype = {
|
||||||
let message = browserBundle.formatStringFromName(entityName + ".wantsTo",
|
let message = browserBundle.formatStringFromName(entityName + ".wantsTo",
|
||||||
[request.principal.URI.host], 1);
|
[request.principal.URI.host], 1);
|
||||||
let newBar = notificationBox.appendNotification(message,
|
let newBar = notificationBox.appendNotification(message,
|
||||||
perm.type,
|
request.type,
|
||||||
icon,
|
icon,
|
||||||
notificationBox.PRIORITY_WARNING_MEDIUM,
|
notificationBox.PRIORITY_WARNING_MEDIUM,
|
||||||
buttons);
|
buttons);
|
||||||
|
|
||||||
if (perm.type == "geolocation") {
|
if (request.type == "geolocation") {
|
||||||
// Add the "learn more" link.
|
// Add the "learn more" link.
|
||||||
let link = newBar.ownerDocument.createElement("label");
|
let link = newBar.ownerDocument.createElement("label");
|
||||||
link.setAttribute("value", browserBundle.GetStringFromName("geolocation.learnMore"));
|
link.setAttribute("value", browserBundle.GetStringFromName("geolocation.learnMore"));
|
||||||
|
|
|
@ -1,9 +0,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/.
|
|
||||||
|
|
||||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
|
||||||
MOCHITEST_BROWSER_FILES += \
|
|
||||||
browser_taskbar_preview.js \
|
|
||||||
$(NULL)
|
|
||||||
endif
|
|
|
@ -4,3 +4,5 @@
|
||||||
[browser_SignInToWebsite.js]
|
[browser_SignInToWebsite.js]
|
||||||
[browser_UITour.js]
|
[browser_UITour.js]
|
||||||
support-files = uitour.*
|
support-files = uitour.*
|
||||||
|
[browser_taskbar_preview.js]
|
||||||
|
run-if = os == "win"
|
||||||
|
|
|
@ -104,17 +104,6 @@ toolbarpaletteitem[place="toolbar"] {
|
||||||
margin-bottom: 25px;
|
margin-bottom: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#customization-palette > #wrapper-edit-controls,
|
|
||||||
#customization-palette > #wrapper-zoom-controls {
|
|
||||||
width: 225px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrapper-edit-controls[place="palette"] > .toolbarpaletteitem-box,
|
|
||||||
#wrapper-zoom-controls[place="palette"] > .toolbarpaletteitem-box {
|
|
||||||
width: 225px;
|
|
||||||
max-width: 225px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#wrapper-edit-controls[place="palette"] > #edit-controls > toolbarbutton,
|
#wrapper-edit-controls[place="palette"] > #edit-controls > toolbarbutton,
|
||||||
#wrapper-edit-controls[place="palette"] > #edit-controls > separator,
|
#wrapper-edit-controls[place="palette"] > #edit-controls > separator,
|
||||||
#wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton,
|
#wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton,
|
||||||
|
@ -126,21 +115,25 @@ toolbarpaletteitem[place="toolbar"] {
|
||||||
#wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton {
|
#wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
max-width: 70px;
|
max-width: 24px;
|
||||||
min-width: 70px;
|
min-width: 24px;
|
||||||
max-height: 24px;
|
max-height: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
}
|
padding: 4px;
|
||||||
|
|
||||||
#wrapper-edit-controls[place="palette"] > #edit-controls > toolbarbutton > .toolbarbutton-text,
|
|
||||||
#wrapper-zoom-controls[place="palette"] > #zoom-controls > #zoom-reset-button > .toolbarbutton-text {
|
|
||||||
display: inline;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#wrapper-edit-controls[place="palette"] > #edit-controls > toolbarbutton > .toolbarbutton-icon,
|
#wrapper-edit-controls[place="palette"] > #edit-controls > toolbarbutton > .toolbarbutton-icon,
|
||||||
#wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton > .toolbarbutton-icon {
|
#wrapper-zoom-controls[place="palette"] > #zoom-controls > toolbarbutton > .toolbarbutton-icon {
|
||||||
margin: 0;
|
width: 16px;
|
||||||
-moz-margin-start: 5px;
|
}
|
||||||
|
|
||||||
|
#wrapper-edit-controls > #edit-controls > toolbarbutton > .toolbarbutton-icon {
|
||||||
|
opacity: 1; /* To ensure these buttons always look enabled in customize mode */
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper-zoom-controls[place="palette"] > #zoom-controls > #zoom-reset-button,
|
||||||
|
#wrapper-zoom-controls[place="palette"] > #zoom-controls > #zoom-reset-button + separator {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
#customization-palette > toolbarpaletteitem > label {
|
#customization-palette > toolbarpaletteitem > label {
|
||||||
|
|
|
@ -12,11 +12,11 @@ public interface Assert {
|
||||||
void endTest();
|
void endTest();
|
||||||
|
|
||||||
void ok(boolean condition, String name, String diag);
|
void ok(boolean condition, String name, String diag);
|
||||||
void is(Object a, Object b, String name);
|
void is(Object actual, Object expected, String name);
|
||||||
void isnot(Object a, Object b, String name);
|
void isnot(Object actual, Object notExpected, String name);
|
||||||
void todo(boolean condition, String name, String diag);
|
void todo(boolean condition, String name, String diag);
|
||||||
void todo_is(Object a, Object b, String name);
|
void todo_is(Object actual, Object expected, String name);
|
||||||
void todo_isnot(Object a, Object b, String name);
|
void todo_isnot(Object actual, Object notExpected, String name);
|
||||||
void info(String name, String message);
|
void info(String name, String message);
|
||||||
|
|
||||||
// robocop-specific asserts
|
// robocop-specific asserts
|
||||||
|
|
|
@ -15,7 +15,7 @@ public class FennecMochitestAssert implements Assert {
|
||||||
private int mPassed = 0;
|
private int mPassed = 0;
|
||||||
private int mFailed = 0;
|
private int mFailed = 0;
|
||||||
private int mTodo = 0;
|
private int mTodo = 0;
|
||||||
|
|
||||||
// Used to write the first line of the test file
|
// Used to write the first line of the test file
|
||||||
private boolean mLogStarted = false;
|
private boolean mLogStarted = false;
|
||||||
|
|
||||||
|
@ -140,14 +140,14 @@ public class FennecMochitestAssert implements Assert {
|
||||||
mTestList.add(test);
|
mTestList.add(test);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void is(Object a, Object b, String name) {
|
public void is(Object actual, Object expected, String name) {
|
||||||
boolean pass = checkObjectsEqual(a,b);
|
boolean pass = checkObjectsEqual(actual, expected);
|
||||||
ok(pass, name, getEqualString(a,b, pass));
|
ok(pass, name, getEqualString(actual, expected, pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void isnot(Object a, Object b, String name) {
|
public void isnot(Object actual, Object notExpected, String name) {
|
||||||
boolean pass = checkObjectsNotEqual(a,b);
|
boolean pass = checkObjectsNotEqual(actual, notExpected);
|
||||||
ok(pass, name, getNotEqualString(a,b,pass));
|
ok(pass, name, getNotEqualString(actual, notExpected, pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ispixel(int actual, int r, int g, int b, String name) {
|
public void ispixel(int actual, int r, int g, int b, String name) {
|
||||||
|
@ -197,14 +197,14 @@ public class FennecMochitestAssert implements Assert {
|
||||||
mTestList.add(test);
|
mTestList.add(test);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void todo_is(Object a, Object b, String name) {
|
public void todo_is(Object actual, Object expected, String name) {
|
||||||
boolean pass = checkObjectsEqual(a,b);
|
boolean pass = checkObjectsEqual(actual, expected);
|
||||||
todo(pass, name, getEqualString(a,b,pass));
|
todo(pass, name, getEqualString(actual, expected, pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void todo_isnot(Object a, Object b, String name) {
|
public void todo_isnot(Object actual, Object notExpected, String name) {
|
||||||
boolean pass = checkObjectsNotEqual(a,b);
|
boolean pass = checkObjectsNotEqual(actual, notExpected);
|
||||||
todo(pass, name, getNotEqualString(a,b,pass));
|
todo(pass, name, getNotEqualString(actual, notExpected, pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkObjectsEqual(Object a, Object b) {
|
private boolean checkObjectsEqual(Object a, Object b) {
|
||||||
|
|
|
@ -6,7 +6,7 @@ package org.mozilla.gecko;
|
||||||
|
|
||||||
|
|
||||||
public class FennecTalosAssert implements Assert {
|
public class FennecTalosAssert implements Assert {
|
||||||
|
|
||||||
public FennecTalosAssert() { }
|
public FennecTalosAssert() { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,14 +38,14 @@ public class FennecTalosAssert implements Assert {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void is(Object a, Object b, String name) {
|
public void is(Object actual, Object expected, String name) {
|
||||||
boolean pass = (a == null ? b == null : a.equals(b));
|
boolean pass = (actual == null ? expected == null : actual.equals(expected));
|
||||||
ok(pass, name, "got " + a + ", expected " + b);
|
ok(pass, name, "got " + actual + ", expected " + expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void isnot(Object a, Object b, String name) {
|
public void isnot(Object actual, Object notExpected, String name) {
|
||||||
boolean fail = (a == null ? b == null : a.equals(b));
|
boolean fail = (actual == null ? notExpected == null : actual.equals(notExpected));
|
||||||
ok(!fail, name, "got " + a + ", expected not " + b);
|
ok(!fail, name, "got " + actual + ", expected not " + notExpected);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ispixel(int actual, int r, int g, int b, String name) {
|
public void ispixel(int actual, int r, int g, int b, String name) {
|
||||||
|
@ -60,11 +60,11 @@ public class FennecTalosAssert implements Assert {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void todo_is(Object a, Object b, String name) {
|
public void todo_is(Object actual, Object expected, String name) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void todo_isnot(Object a, Object b, String name) {
|
public void todo_isnot(Object actual, Object notExpected, String name) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ dir-tests := $(DEPTH)/$(mobile-tests)
|
||||||
ANDROID_APK_NAME := robocop-debug
|
ANDROID_APK_NAME := robocop-debug
|
||||||
|
|
||||||
ANDROID_EXTRA_JARS += \
|
ANDROID_EXTRA_JARS += \
|
||||||
$(srcdir)/robotium-solo-4.3.jar \
|
$(srcdir)/robotium-solo-4.3.1.jar \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
ANDROID_ASSETS_DIR := $(TESTPATH)/assets
|
ANDROID_ASSETS_DIR := $(TESTPATH)/assets
|
||||||
|
|
|
@ -4,7 +4,7 @@ Robotium is an open source tool licensed under the Apache 2.0 license and the or
|
||||||
source can be found here:
|
source can be found here:
|
||||||
http://code.google.com/p/robotium/
|
http://code.google.com/p/robotium/
|
||||||
|
|
||||||
We are including robotium-solo-4.3.jar as a binary and are not modifying it in any way
|
We are including robotium-solo-4.3.1.jar as a binary and are not modifying it in any way
|
||||||
from the original download found at:
|
from the original download found at:
|
||||||
http://code.google.com/p/robotium/
|
http://code.google.com/p/robotium/
|
||||||
|
|
||||||
|
|
Двоичный файл не отображается.
27
configure.in
27
configure.in
|
@ -3983,7 +3983,6 @@ LIBJPEG_TURBO_ASFLAGS=
|
||||||
LIBJPEG_TURBO_X86_ASM=
|
LIBJPEG_TURBO_X86_ASM=
|
||||||
LIBJPEG_TURBO_X64_ASM=
|
LIBJPEG_TURBO_X64_ASM=
|
||||||
LIBJPEG_TURBO_ARM_ASM=
|
LIBJPEG_TURBO_ARM_ASM=
|
||||||
MOZ_PANGO=1
|
|
||||||
MOZ_PERMISSIONS=1
|
MOZ_PERMISSIONS=1
|
||||||
MOZ_PLACES=1
|
MOZ_PLACES=1
|
||||||
MOZ_SOCIAL=1
|
MOZ_SOCIAL=1
|
||||||
|
@ -4731,34 +4730,16 @@ AC_DEFINE_UNQUOTED(MOZ_DISTRIBUTION_ID,"$MOZ_DISTRIBUTION_ID")
|
||||||
AC_SUBST(MOZ_DISTRIBUTION_ID)
|
AC_SUBST(MOZ_DISTRIBUTION_ID)
|
||||||
|
|
||||||
|
|
||||||
dnl ========================================================
|
|
||||||
dnl complex text support off by default
|
|
||||||
dnl ========================================================
|
|
||||||
MOZ_ARG_DISABLE_BOOL(pango,
|
|
||||||
[ --disable-pango Disable usage of Pango ],
|
|
||||||
MOZ_PANGO=,
|
|
||||||
MOZ_PANGO=1)
|
|
||||||
|
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
dnl = Pango
|
dnl = Pango
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
if test "$MOZ_ENABLE_GTK" -o "$MOZ_ENABLE_QT"
|
if test "$MOZ_ENABLE_GTK" -o "$MOZ_ENABLE_QT"
|
||||||
then
|
then
|
||||||
AC_SUBST(MOZ_PANGO)
|
PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION)
|
||||||
|
|
||||||
if test "$MOZ_PANGO"
|
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION pangocairo >= $PANGO_VERSION)
|
||||||
then
|
AC_SUBST(MOZ_PANGO_CFLAGS)
|
||||||
PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION)
|
AC_SUBST(MOZ_PANGO_LIBS)
|
||||||
|
|
||||||
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION pangocairo >= $PANGO_VERSION)
|
|
||||||
AC_SUBST(MOZ_PANGO_CFLAGS)
|
|
||||||
AC_SUBST(MOZ_PANGO_LIBS)
|
|
||||||
AC_DEFINE(MOZ_PANGO)
|
|
||||||
else
|
|
||||||
PKG_CHECK_MODULES(FT2, freetype2 > 6.1.0)
|
|
||||||
AC_SUBST(FT2_CFLAGS)
|
|
||||||
AC_SUBST(FT2_LIBS)
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
|
|
|
@ -642,13 +642,13 @@ nsDOMMemoryFile::DataOwner::sDataOwners;
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered;
|
nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered;
|
||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerMallocSizeOf)
|
MOZ_DEFINE_MALLOC_SIZE_OF(DOMMemoryFileDataOwnerMallocSizeOf)
|
||||||
|
|
||||||
class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
|
class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
|
||||||
: public MemoryMultiReporter
|
: public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsDOMMemoryFileDataOwnerMemoryReporter() {}
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
|
||||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback,
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCallback,
|
||||||
nsISupports *aClosure)
|
nsISupports *aClosure)
|
||||||
|
@ -723,6 +723,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsDOMMemoryFileDataOwnerMemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
/* static */ void
|
/* static */ void
|
||||||
nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
|
nsDOMMemoryFile::DataOwner::EnsureMemoryReporterRegistered()
|
||||||
{
|
{
|
||||||
|
|
|
@ -217,8 +217,6 @@
|
||||||
#include "mozilla/dom/XPathEvaluator.h"
|
#include "mozilla/dom/XPathEvaluator.h"
|
||||||
#include "nsIDocumentEncoder.h"
|
#include "nsIDocumentEncoder.h"
|
||||||
#include "nsIStructuredCloneContainer.h"
|
#include "nsIStructuredCloneContainer.h"
|
||||||
#include "nsIMutableArray.h"
|
|
||||||
#include "nsContentPermissionHelper.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
@ -10754,11 +10752,17 @@ NS_IMPL_ISUPPORTS_INHERITED1(nsPointerLockPermissionRequest,
|
||||||
nsIContentPermissionRequest)
|
nsIContentPermissionRequest)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsPointerLockPermissionRequest::GetTypes(nsIArray** aTypes)
|
nsPointerLockPermissionRequest::GetType(nsACString& aType)
|
||||||
{
|
{
|
||||||
return CreatePermissionArray(NS_LITERAL_CSTRING("pointerLock"),
|
aType = "pointerLock";
|
||||||
NS_LITERAL_CSTRING("unused"),
|
return NS_OK;
|
||||||
aTypes);
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsPointerLockPermissionRequest::GetAccess(nsACString& aAccess)
|
||||||
|
{
|
||||||
|
aAccess = "unused";
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -1130,13 +1130,11 @@ struct MessageManagerReferentCount
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class MessageManagerReporter MOZ_FINAL : public MemoryMultiReporter
|
class MessageManagerReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MessageManagerReporter() {}
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCallback,
|
|
||||||
nsISupports* aData);
|
|
||||||
|
|
||||||
static const size_t kSuspectReferentCount = 300;
|
static const size_t kSuspectReferentCount = 300;
|
||||||
protected:
|
protected:
|
||||||
|
@ -1144,6 +1142,8 @@ protected:
|
||||||
MessageManagerReferentCount* aReferentCount);
|
MessageManagerReferentCount* aReferentCount);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(MessageManagerReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
static PLDHashOperator
|
static PLDHashOperator
|
||||||
CollectMessageListenerData(const nsAString& aKey,
|
CollectMessageListenerData(const nsAString& aKey,
|
||||||
nsAutoTObserverArray<nsMessageListenerInfo, 1>* aListeners,
|
nsAutoTObserverArray<nsMessageListenerInfo, 1>* aListeners,
|
||||||
|
|
|
@ -85,7 +85,7 @@ WebGLMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED0(WebGLMemoryTracker, MemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(WebGLMemoryTracker, nsIMemoryReporter)
|
||||||
|
|
||||||
StaticRefPtr<WebGLMemoryTracker> WebGLMemoryTracker::sUniqueInstance;
|
StaticRefPtr<WebGLMemoryTracker> WebGLMemoryTracker::sUniqueInstance;
|
||||||
|
|
||||||
|
@ -113,7 +113,7 @@ WebGLMemoryTracker::~WebGLMemoryTracker()
|
||||||
UnregisterWeakMemoryReporter(this);
|
UnregisterWeakMemoryReporter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOf)
|
MOZ_DEFINE_MALLOC_SIZE_OF(WebGLBufferMallocSizeOf)
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
WebGLMemoryTracker::GetBufferCacheMemoryUsed() {
|
WebGLMemoryTracker::GetBufferCacheMemoryUsed() {
|
||||||
|
@ -131,7 +131,7 @@ WebGLMemoryTracker::GetBufferCacheMemoryUsed() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOf)
|
MOZ_DEFINE_MALLOC_SIZE_OF(WebGLShaderMallocSizeOf)
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
WebGLMemoryTracker::GetShaderSize() {
|
WebGLMemoryTracker::GetShaderSize() {
|
||||||
|
|
|
@ -19,9 +19,10 @@
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class WebGLMemoryTracker : public MemoryMultiReporter
|
class WebGLMemoryTracker : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
|
|
||||||
WebGLMemoryTracker();
|
WebGLMemoryTracker();
|
||||||
virtual ~WebGLMemoryTracker();
|
virtual ~WebGLMemoryTracker();
|
||||||
|
@ -55,9 +56,6 @@ class WebGLMemoryTracker : public MemoryMultiReporter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
|
|
||||||
nsISupports* aData);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int64_t GetTextureMemoryUsed() {
|
static int64_t GetTextureMemoryUsed() {
|
||||||
const ContextsArrayType & contexts = Contexts();
|
const ContextsArrayType & contexts = Contexts();
|
||||||
|
|
|
@ -54,9 +54,10 @@ PRLogModuleInfo* gMediaDecoderLog;
|
||||||
#define DECODER_LOG(type, msg)
|
#define DECODER_LOG(type, msg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class MediaMemoryTracker : public MemoryMultiReporter
|
class MediaMemoryTracker : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
|
|
||||||
MediaMemoryTracker();
|
MediaMemoryTracker();
|
||||||
virtual ~MediaMemoryTracker();
|
virtual ~MediaMemoryTracker();
|
||||||
|
@ -93,14 +94,11 @@ public:
|
||||||
sUniqueInstance = nullptr;
|
sUniqueInstance = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
|
|
||||||
nsISupports* aData);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
StaticRefPtr<MediaMemoryTracker> MediaMemoryTracker::sUniqueInstance;
|
StaticRefPtr<MediaMemoryTracker> MediaMemoryTracker::sUniqueInstance;
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_INHERITED0(MediaMemoryTracker, MemoryMultiReporter)
|
NS_IMPL_ISUPPORTS1(MediaMemoryTracker, nsIMemoryReporter)
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(MediaDecoder, nsIObserver)
|
NS_IMPL_ISUPPORTS1(MediaDecoder, nsIObserver)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#ifndef MEDIAENGINE_H_
|
#ifndef MEDIAENGINE_H_
|
||||||
#define MEDIAENGINE_H_
|
#define MEDIAENGINE_H_
|
||||||
|
|
||||||
#include "mozilla/RefPtr.h"
|
|
||||||
#include "nsIDOMFile.h"
|
#include "nsIDOMFile.h"
|
||||||
#include "DOMMediaStream.h"
|
#include "DOMMediaStream.h"
|
||||||
#include "MediaStreamGraph.h"
|
#include "MediaStreamGraph.h"
|
||||||
|
@ -36,7 +35,7 @@ enum {
|
||||||
kAudioTrack = 2
|
kAudioTrack = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
class MediaEngine : public RefCounted<MediaEngine>
|
class MediaEngine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~MediaEngine() {}
|
virtual ~MediaEngine() {}
|
||||||
|
|
|
@ -101,7 +101,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(nsTArray<nsRefPtr<MediaEngineVideoSourc
|
||||||
// We've already seen this device, just append.
|
// We've already seen this device, just append.
|
||||||
aVSources->AppendElement(vSource.get());
|
aVSources->AppendElement(vSource.get());
|
||||||
} else {
|
} else {
|
||||||
vSource = new MediaEngineWebRTCVideoSource(mCameraManager, i);
|
vSource = new MediaEngineWebRTCVideoSource(mCameraManager, i, mWindowId);
|
||||||
mVideoSources.Put(uuid, vSource); // Hashtable takes ownership.
|
mVideoSources.Put(uuid, vSource); // Hashtable takes ownership.
|
||||||
aVSources->AppendElement(vSource);
|
aVSources->AppendElement(vSource);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,6 @@
|
||||||
#include "ImageContainer.h"
|
#include "ImageContainer.h"
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
#include "prprf.h"
|
#include "prprf.h"
|
||||||
#include "nsProxyRelease.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "NullTransport.h"
|
#include "NullTransport.h"
|
||||||
|
@ -74,7 +73,7 @@ class GetCameraNameRunnable;
|
||||||
* mSources, mImageContainer, mSources, mState, mImage, mLastCapture
|
* mSources, mImageContainer, mSources, mState, mImage, mLastCapture
|
||||||
*
|
*
|
||||||
* MainThread:
|
* MainThread:
|
||||||
* mDOMCameraControl, mCaptureIndex, mCameraThread, mCameraManager,
|
* mDOMCameraControl, mCaptureIndex, mCameraThread, mWindowId, mCameraManager,
|
||||||
* mNativeCameraControl, mPreviewStream, mState, mLastCapture, mWidth, mHeight
|
* mNativeCameraControl, mPreviewStream, mState, mLastCapture, mWidth, mHeight
|
||||||
*
|
*
|
||||||
* Where mWidth, mHeight, mImage are protected by mMonitor
|
* Where mWidth, mHeight, mImage are protected by mMonitor
|
||||||
|
@ -97,10 +96,11 @@ class MediaEngineWebRTCVideoSource : public MediaEngineVideoSource
|
||||||
public:
|
public:
|
||||||
#ifdef MOZ_B2G_CAMERA
|
#ifdef MOZ_B2G_CAMERA
|
||||||
MediaEngineWebRTCVideoSource(nsDOMCameraManager* aCameraManager,
|
MediaEngineWebRTCVideoSource(nsDOMCameraManager* aCameraManager,
|
||||||
int aIndex)
|
int aIndex, uint64_t aWindowId)
|
||||||
: mCameraManager(aCameraManager)
|
: mCameraManager(aCameraManager)
|
||||||
, mNativeCameraControl(nullptr)
|
, mNativeCameraControl(nullptr)
|
||||||
, mPreviewStream(nullptr)
|
, mPreviewStream(nullptr)
|
||||||
|
, mWindowId(aWindowId)
|
||||||
, mCallbackMonitor("WebRTCCamera.CallbackMonitor")
|
, mCallbackMonitor("WebRTCCamera.CallbackMonitor")
|
||||||
, mCaptureIndex(aIndex)
|
, mCaptureIndex(aIndex)
|
||||||
, mMonitor("WebRTCCamera.Monitor")
|
, mMonitor("WebRTCCamera.Monitor")
|
||||||
|
@ -223,6 +223,7 @@ private:
|
||||||
nsRefPtr<nsDOMCameraControl> mDOMCameraControl;
|
nsRefPtr<nsDOMCameraControl> mDOMCameraControl;
|
||||||
nsRefPtr<nsGonkCameraControl> mNativeCameraControl;
|
nsRefPtr<nsGonkCameraControl> mNativeCameraControl;
|
||||||
nsRefPtr<DOMCameraPreview> mPreviewStream;
|
nsRefPtr<DOMCameraPreview> mPreviewStream;
|
||||||
|
uint64_t mWindowId;
|
||||||
mozilla::ReentrantMonitor mCallbackMonitor; // Monitor for camera callback handling
|
mozilla::ReentrantMonitor mCallbackMonitor; // Monitor for camera callback handling
|
||||||
nsRefPtr<nsIThread> mCameraThread;
|
nsRefPtr<nsIThread> mCameraThread;
|
||||||
nsRefPtr<nsIDOMFile> mLastCapture;
|
nsRefPtr<nsIDOMFile> mLastCapture;
|
||||||
|
@ -351,14 +352,15 @@ class MediaEngineWebRTC : public MediaEngine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#ifdef MOZ_B2G_CAMERA
|
#ifdef MOZ_B2G_CAMERA
|
||||||
MediaEngineWebRTC(nsDOMCameraManager* aCameraManager)
|
MediaEngineWebRTC(nsDOMCameraManager* aCameraManager, uint64_t aWindowId)
|
||||||
: mMutex("mozilla::MediaEngineWebRTC")
|
: mMutex("mozilla::MediaEngineWebRTC")
|
||||||
, mVideoEngine(nullptr)
|
, mVideoEngine(nullptr)
|
||||||
, mVoiceEngine(nullptr)
|
, mVoiceEngine(nullptr)
|
||||||
, mVideoEngineInit(false)
|
, mVideoEngineInit(false)
|
||||||
, mAudioEngineInit(false)
|
, mAudioEngineInit(false)
|
||||||
, mHasTabVideoSource(false)
|
|
||||||
, mCameraManager(aCameraManager)
|
, mCameraManager(aCameraManager)
|
||||||
|
, mWindowId(aWindowId)
|
||||||
|
, mHasTabVideoSource(false)
|
||||||
{
|
{
|
||||||
AsyncLatencyLogger::Get(true)->AddRef();
|
AsyncLatencyLogger::Get(true)->AddRef();
|
||||||
mLoadMonitor = new LoadMonitor();
|
mLoadMonitor = new LoadMonitor();
|
||||||
|
@ -399,8 +401,6 @@ private:
|
||||||
nsRefPtrHashtable<nsStringHashKey, MediaEngineWebRTCAudioSource > mAudioSources;
|
nsRefPtrHashtable<nsStringHashKey, MediaEngineWebRTCAudioSource > mAudioSources;
|
||||||
|
|
||||||
#ifdef MOZ_B2G_CAMERA
|
#ifdef MOZ_B2G_CAMERA
|
||||||
// XXX Should use nsMainThreadPtrHandle/etc
|
|
||||||
|
|
||||||
// MediaEngine hold this DOM object, and the MediaEngine is hold by Navigator
|
// MediaEngine hold this DOM object, and the MediaEngine is hold by Navigator
|
||||||
// Their life time is always much longer than this object. Use a raw-pointer
|
// Their life time is always much longer than this object. Use a raw-pointer
|
||||||
// here should be safe.
|
// here should be safe.
|
||||||
|
@ -409,6 +409,7 @@ private:
|
||||||
// avoid any bad thing do to addref/release DOM-object on other thread, we use
|
// avoid any bad thing do to addref/release DOM-object on other thread, we use
|
||||||
// raw-pointer for now.
|
// raw-pointer for now.
|
||||||
nsDOMCameraManager* mCameraManager;
|
nsDOMCameraManager* mCameraManager;
|
||||||
|
uint64_t mWindowId;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
nsRefPtr<LoadMonitor> mLoadMonitor;
|
nsRefPtr<LoadMonitor> mLoadMonitor;
|
||||||
|
|
|
@ -312,6 +312,7 @@ nsresult
|
||||||
MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
|
MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
|
||||||
{
|
{
|
||||||
LOG((__FUNCTION__));
|
LOG((__FUNCTION__));
|
||||||
|
int error = 0;
|
||||||
if (!mInitDone || !aStream) {
|
if (!mInitDone || !aStream) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -340,7 +341,7 @@ MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
mState = kStarted;
|
mState = kStarted;
|
||||||
int error = mViERender->AddRenderer(mCaptureIndex, webrtc::kVideoI420, (webrtc::ExternalRenderer*)this);
|
error = mViERender->AddRenderer(mCaptureIndex, webrtc::kVideoI420, (webrtc::ExternalRenderer*)this);
|
||||||
if (error == -1) {
|
if (error == -1) {
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -491,9 +492,12 @@ void
|
||||||
MediaEngineWebRTCVideoSource::AllocImpl() {
|
MediaEngineWebRTCVideoSource::AllocImpl() {
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
MOZ_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
ErrorResult rv;
|
mDOMCameraControl = new nsDOMCameraControl(mCaptureIndex,
|
||||||
mDOMCameraControl = mCameraManager->GetCameraControl(mCaptureIndex,
|
mCameraThread,
|
||||||
this, this, rv);
|
this,
|
||||||
|
this,
|
||||||
|
nsGlobalWindow::GetInnerWindowWithId(mWindowId));
|
||||||
|
mCameraManager->Register(mDOMCameraControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -502,7 +506,6 @@ MediaEngineWebRTCVideoSource::DeallocImpl() {
|
||||||
|
|
||||||
mNativeCameraControl->ReleaseHardware(this, this);
|
mNativeCameraControl->ReleaseHardware(this, this);
|
||||||
mNativeCameraControl = nullptr;
|
mNativeCameraControl = nullptr;
|
||||||
mDOMCameraControl = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -45,6 +45,7 @@ support-files =
|
||||||
skip-if = true # disabled-for-intermittent-failures--bug-701060
|
skip-if = true # disabled-for-intermittent-failures--bug-701060
|
||||||
[test_length.xhtml]
|
[test_length.xhtml]
|
||||||
skip-if = true
|
skip-if = true
|
||||||
|
[test_lengthParsing.html]
|
||||||
[test_nonAnimStrings.xhtml]
|
[test_nonAnimStrings.xhtml]
|
||||||
[test_non-scaling-stroke.html]
|
[test_non-scaling-stroke.html]
|
||||||
[test_pathAnimInterpolation.xhtml]
|
[test_pathAnimInterpolation.xhtml]
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<!--
|
||||||
|
https://bugzilla.mozilla.org/show_bug.cgi?id=946529
|
||||||
|
-->
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test transform parsing</title>
|
||||||
|
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=946529">Mozilla Bug 946529</a>
|
||||||
|
<p id="display"></p>
|
||||||
|
<div id="content" style="display: none">
|
||||||
|
<svg width="100%" height="1" id="svg">
|
||||||
|
<rect id="rect"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<pre id="test">
|
||||||
|
<script class="testbody" type="text/javascript">
|
||||||
|
// Test cases
|
||||||
|
checkParseOk("", 0);
|
||||||
|
checkParseOk("-.1", -0.1);
|
||||||
|
checkParseOk("1e1", 10);
|
||||||
|
checkParseOk("1em", 1, "em");
|
||||||
|
checkParseOk("1ex", 1, "ex");
|
||||||
|
checkParseOk("1e1em", 10, "em");
|
||||||
|
checkParseOk("1E+2", 100);
|
||||||
|
checkParseOk(".1e-2", 0.001);
|
||||||
|
|
||||||
|
// Fail cases
|
||||||
|
checkParseFail("1e");
|
||||||
|
checkParseFail("1 e");
|
||||||
|
checkParseFail("1 em");
|
||||||
|
checkParseFail("1ee");
|
||||||
|
|
||||||
|
function checkParseOk(spec, valueInUnits, units) {
|
||||||
|
var rect = document.getElementById("rect");
|
||||||
|
|
||||||
|
// Clear previous value
|
||||||
|
rect.removeAttribute("x");
|
||||||
|
rect.setAttribute("x", spec);
|
||||||
|
|
||||||
|
// Check number part
|
||||||
|
const tolerance = 1 / 65535;
|
||||||
|
var actual = rect.x.baseVal.valueInSpecifiedUnits;
|
||||||
|
ok(Math.abs(actual - valueInUnits) < tolerance,
|
||||||
|
spec + ' (value) - got ' + actual + ', expected ' + valueInUnits);
|
||||||
|
|
||||||
|
// Check unit part
|
||||||
|
var unitMapping = {
|
||||||
|
"unknown": SVGLength.SVG_LENGTHTYPE_UNKNOWN,
|
||||||
|
"": SVGLength.SVG_LENGTHTYPE_NUMBER,
|
||||||
|
"%": SVGLength.SVG_LENGTHTYPE_PERCENTAGE,
|
||||||
|
"em": SVGLength.SVG_LENGTHTYPE_EMS,
|
||||||
|
"ex": SVGLength.SVG_LENGTHTYPE_EXS,
|
||||||
|
"px": SVGLength.SVG_LENGTHTYPE_PX,
|
||||||
|
"cm": SVGLength.SVG_LENGTHTYPE_CM,
|
||||||
|
"mm": SVGLength.SVG_LENGTHTYPE_MM,
|
||||||
|
"in": SVGLength.SVG_LENGTHTYPE_IN,
|
||||||
|
"pt": SVGLength.SVG_LENGTHTYPE_PT,
|
||||||
|
"pc": SVGLength.SVG_LENGTHTYPE_PC
|
||||||
|
};
|
||||||
|
if (typeof units == "undefined") {
|
||||||
|
units = "";
|
||||||
|
}
|
||||||
|
ise(rect.x.baseVal.unitType, unitMapping[units], spec + " (unit)");
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkParseFail(spec) {
|
||||||
|
checkParseOk(spec, 0);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -323,11 +323,6 @@ this.PermissionsTable = { geolocation: {
|
||||||
privileged: DENY_ACTION,
|
privileged: DENY_ACTION,
|
||||||
certified: ALLOW_ACTION
|
certified: ALLOW_ACTION
|
||||||
},
|
},
|
||||||
"video-capture": {
|
|
||||||
app: PROMPT_ACTION,
|
|
||||||
privileged: PROMPT_ACTION,
|
|
||||||
certified: PROMPT_ACTION
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "mozilla/dom/quota/QuotaObject.h"
|
#include "mozilla/dom/quota/QuotaObject.h"
|
||||||
#include "mozilla/dom/quota/UsageInfo.h"
|
#include "mozilla/dom/quota/UsageInfo.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "nsContentUtils.h"
|
|
||||||
#include "nsIAtom.h"
|
#include "nsIAtom.h"
|
||||||
#include "nsIFile.h"
|
#include "nsIFile.h"
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
|
@ -975,7 +974,7 @@ DeallocEntryChild(PAsmJSCacheEntryChild* aActor)
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool
|
bool
|
||||||
OpenFile(JS::Handle<JSObject*> aGlobal,
|
OpenFile(nsIPrincipal* aPrincipal,
|
||||||
OpenMode aOpenMode,
|
OpenMode aOpenMode,
|
||||||
size_t aSizeToWrite,
|
size_t aSizeToWrite,
|
||||||
File::AutoClose* aFile)
|
File::AutoClose* aFile)
|
||||||
|
@ -998,17 +997,14 @@ OpenFile(JS::Handle<JSObject*> aGlobal,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This assumes a non-worker global.
|
|
||||||
nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal);
|
|
||||||
|
|
||||||
// If we are in a child process, we need to synchronously call into the
|
// If we are in a child process, we need to synchronously call into the
|
||||||
// parent process to open the file and interact with the QuotaManager. The
|
// parent process to open the file and interact with the QuotaManager. The
|
||||||
// child can then map the file into its address space to perform I/O.
|
// child can then map the file into its address space to perform I/O.
|
||||||
nsRefPtr<File> file;
|
nsRefPtr<File> file;
|
||||||
if (IsMainProcess()) {
|
if (IsMainProcess()) {
|
||||||
file = new SingleProcessRunnable(principal, aOpenMode, aSizeToWrite);
|
file = new SingleProcessRunnable(aPrincipal, aOpenMode, aSizeToWrite);
|
||||||
} else {
|
} else {
|
||||||
file = new ChildProcessRunnable(principal, aOpenMode, aSizeToWrite);
|
file = new ChildProcessRunnable(aPrincipal, aOpenMode, aSizeToWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file->BlockUntilOpen(aFile)) {
|
if (!file->BlockUntilOpen(aFile)) {
|
||||||
|
@ -1028,7 +1024,7 @@ static const uint32_t sAsmJSCookie = 0x600d600d;
|
||||||
static const size_t sMinCachedModuleLength = 10000;
|
static const size_t sMinCachedModuleLength = 10000;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
OpenEntryForRead(JS::Handle<JSObject*> aGlobal,
|
OpenEntryForRead(nsIPrincipal* aPrincipal,
|
||||||
const jschar* aBegin,
|
const jschar* aBegin,
|
||||||
const jschar* aLimit,
|
const jschar* aLimit,
|
||||||
size_t* aSize,
|
size_t* aSize,
|
||||||
|
@ -1040,7 +1036,7 @@ OpenEntryForRead(JS::Handle<JSObject*> aGlobal,
|
||||||
}
|
}
|
||||||
|
|
||||||
File::AutoClose file;
|
File::AutoClose file;
|
||||||
if (!OpenFile(aGlobal, eOpenForRead, 0, &file)) {
|
if (!OpenFile(aPrincipal, eOpenForRead, 0, &file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1082,7 +1078,7 @@ CloseEntryForRead(JS::Handle<JSObject*> global,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
OpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
OpenEntryForWrite(nsIPrincipal* aPrincipal,
|
||||||
const jschar* aBegin,
|
const jschar* aBegin,
|
||||||
const jschar* aEnd,
|
const jschar* aEnd,
|
||||||
size_t aSize,
|
size_t aSize,
|
||||||
|
@ -1097,7 +1093,7 @@ OpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
||||||
aSize += sizeof(AsmJSCookieType);
|
aSize += sizeof(AsmJSCookieType);
|
||||||
|
|
||||||
File::AutoClose file;
|
File::AutoClose file;
|
||||||
if (!OpenFile(aGlobal, eOpenForWrite, aSize, &file)) {
|
if (!OpenFile(aPrincipal, eOpenForWrite, aSize, &file)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,20 @@ enum OpenMode
|
||||||
NUM_OPEN_MODES
|
NUM_OPEN_MODES
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implementation of AsmJSCacheOps, installed by nsJSEnvironment:
|
// Implementation of AsmJSCacheOps, installed for the main JSRuntime by
|
||||||
|
// nsJSEnvironment.cpp and DOM Worker JSRuntimes in RuntimeService.cpp.
|
||||||
|
//
|
||||||
|
// The Open* functions cannot be called directly from AsmJSCacheOps: they take
|
||||||
|
// an nsIPrincipal as the first argument instead of a Handle<JSObject*>. The
|
||||||
|
// caller must map the object to an nsIPrincipal.
|
||||||
|
//
|
||||||
|
// These methods may be called off the main thread and guarantee not to
|
||||||
|
// access the given aPrincipal except on the main thread. In exchange, the
|
||||||
|
// caller must ensure the given principal is alive from when OpenEntryForX is
|
||||||
|
// called to when CloseEntryForX returns.
|
||||||
|
|
||||||
bool
|
bool
|
||||||
OpenEntryForRead(JS::Handle<JSObject*> aGlobal,
|
OpenEntryForRead(nsIPrincipal* aPrincipal,
|
||||||
const jschar* aBegin,
|
const jschar* aBegin,
|
||||||
const jschar* aLimit,
|
const jschar* aLimit,
|
||||||
size_t* aSize,
|
size_t* aSize,
|
||||||
|
@ -47,7 +57,7 @@ CloseEntryForRead(JS::Handle<JSObject*> aGlobal,
|
||||||
const uint8_t* aMemory,
|
const uint8_t* aMemory,
|
||||||
intptr_t aHandle);
|
intptr_t aHandle);
|
||||||
bool
|
bool
|
||||||
OpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
OpenEntryForWrite(nsIPrincipal* aPrincipal,
|
||||||
const jschar* aBegin,
|
const jschar* aBegin,
|
||||||
const jschar* aEnd,
|
const jschar* aEnd,
|
||||||
size_t aSize,
|
size_t aSize,
|
||||||
|
|
|
@ -6,156 +6,20 @@
|
||||||
#include "GonkPermission.h"
|
#include "GonkPermission.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#endif // MOZ_WIDGET_GONK
|
#endif // MOZ_WIDGET_GONK
|
||||||
|
#include "nsContentPermissionHelper.h"
|
||||||
|
#include "nsIContentPermissionPrompt.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsIDOMElement.h"
|
#include "nsIDOMElement.h"
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/PContentPermission.h"
|
|
||||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
|
||||||
#include "mozilla/dom/PContentPermissionRequestParent.h"
|
|
||||||
#include "mozilla/dom/TabParent.h"
|
#include "mozilla/dom/TabParent.h"
|
||||||
#include "mozilla/unused.h"
|
#include "mozilla/unused.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsArrayUtils.h"
|
|
||||||
#include "nsIMutableArray.h"
|
|
||||||
#include "nsContentPermissionHelper.h"
|
|
||||||
|
|
||||||
using mozilla::unused; // <snicker>
|
using mozilla::unused; // <snicker>
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace dom {
|
|
||||||
|
|
||||||
class ContentPermissionRequestParent : public PContentPermissionRequestParent
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
|
|
||||||
Element* element,
|
|
||||||
const IPC::Principal& principal);
|
|
||||||
virtual ~ContentPermissionRequestParent();
|
|
||||||
|
|
||||||
bool IsBeingDestroyed();
|
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
|
||||||
nsCOMPtr<Element> mElement;
|
|
||||||
nsCOMPtr<nsContentPermissionRequestProxy> mProxy;
|
|
||||||
nsTArray<PermissionRequest> mRequests;
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual bool Recvprompt();
|
|
||||||
virtual void ActorDestroy(ActorDestroyReason why);
|
|
||||||
};
|
|
||||||
|
|
||||||
ContentPermissionRequestParent::ContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
|
|
||||||
Element* aElement,
|
|
||||||
const IPC::Principal& aPrincipal)
|
|
||||||
{
|
|
||||||
MOZ_COUNT_CTOR(ContentPermissionRequestParent);
|
|
||||||
|
|
||||||
mPrincipal = aPrincipal;
|
|
||||||
mElement = aElement;
|
|
||||||
mRequests = aRequests;
|
|
||||||
}
|
|
||||||
|
|
||||||
ContentPermissionRequestParent::~ContentPermissionRequestParent()
|
|
||||||
{
|
|
||||||
MOZ_COUNT_DTOR(ContentPermissionRequestParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ContentPermissionRequestParent::Recvprompt()
|
|
||||||
{
|
|
||||||
mProxy = new nsContentPermissionRequestProxy();
|
|
||||||
NS_ASSERTION(mProxy, "Alloc of request proxy failed");
|
|
||||||
if (NS_FAILED(mProxy->Init(mRequests, this))) {
|
|
||||||
mProxy->Cancel();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ContentPermissionRequestParent::ActorDestroy(ActorDestroyReason why)
|
|
||||||
{
|
|
||||||
if (mProxy) {
|
|
||||||
mProxy->OnParentDestroyed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ContentPermissionRequestParent::IsBeingDestroyed()
|
|
||||||
{
|
|
||||||
// When TabParent::Destroy() is called, we are being destroyed. It's unsafe
|
|
||||||
// to send out any message now.
|
|
||||||
TabParent* tabParent = static_cast<TabParent*>(Manager());
|
|
||||||
return tabParent->IsDestroyed();
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(ContentPermissionType, nsIContentPermissionType)
|
|
||||||
|
|
||||||
ContentPermissionType::ContentPermissionType(const nsACString& aType,
|
|
||||||
const nsACString& aAccess)
|
|
||||||
{
|
|
||||||
mType = aType;
|
|
||||||
mAccess = aAccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
ContentPermissionType::~ContentPermissionType()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
ContentPermissionType::GetType(nsACString& aType)
|
|
||||||
{
|
|
||||||
aType = mType;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
ContentPermissionType::GetAccess(nsACString& aAccess)
|
|
||||||
{
|
|
||||||
aAccess = mAccess;
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
ConvertPermissionRequestToArray(nsTArray<PermissionRequest>& aSrcArray,
|
|
||||||
nsIMutableArray* aDesArray)
|
|
||||||
{
|
|
||||||
uint32_t len = aSrcArray.Length();
|
|
||||||
for (uint32_t i = 0; i < len; i++) {
|
|
||||||
nsRefPtr<ContentPermissionType> cpt =
|
|
||||||
new ContentPermissionType(aSrcArray[i].type(), aSrcArray[i].access());
|
|
||||||
aDesArray->AppendElement(cpt, false);
|
|
||||||
}
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
CreatePermissionArray(const nsACString& aType,
|
|
||||||
const nsACString& aAccess,
|
|
||||||
nsIArray** aTypesArray)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIMutableArray> types = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
|
||||||
nsRefPtr<ContentPermissionType> permType = new ContentPermissionType(aType,
|
|
||||||
aAccess);
|
|
||||||
types->AppendElement(permType, false);
|
|
||||||
types.forget(aTypesArray);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
PContentPermissionRequestParent*
|
|
||||||
CreateContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
|
|
||||||
Element* element,
|
|
||||||
const IPC::Principal& principal)
|
|
||||||
{
|
|
||||||
return new ContentPermissionRequestParent(aRequests, element, principal);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dom
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
nsContentPermissionRequestProxy::nsContentPermissionRequestProxy()
|
nsContentPermissionRequestProxy::nsContentPermissionRequestProxy()
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(nsContentPermissionRequestProxy);
|
MOZ_COUNT_CTOR(nsContentPermissionRequestProxy);
|
||||||
|
@ -167,12 +31,14 @@ nsContentPermissionRequestProxy::~nsContentPermissionRequestProxy()
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsContentPermissionRequestProxy::Init(const nsTArray<PermissionRequest>& requests,
|
nsContentPermissionRequestProxy::Init(const nsACString & type,
|
||||||
|
const nsACString & access,
|
||||||
ContentPermissionRequestParent* parent)
|
ContentPermissionRequestParent* parent)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(parent, "null parent");
|
NS_ASSERTION(parent, "null parent");
|
||||||
mParent = parent;
|
mParent = parent;
|
||||||
mPermissionRequests = requests;
|
mType = type;
|
||||||
|
mAccess = access;
|
||||||
|
|
||||||
nsCOMPtr<nsIContentPermissionPrompt> prompt = do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
|
nsCOMPtr<nsIContentPermissionPrompt> prompt = do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
|
||||||
if (!prompt) {
|
if (!prompt) {
|
||||||
|
@ -192,14 +58,17 @@ nsContentPermissionRequestProxy::OnParentDestroyed()
|
||||||
NS_IMPL_ISUPPORTS1(nsContentPermissionRequestProxy, nsIContentPermissionRequest)
|
NS_IMPL_ISUPPORTS1(nsContentPermissionRequestProxy, nsIContentPermissionRequest)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsContentPermissionRequestProxy::GetTypes(nsIArray** aTypes)
|
nsContentPermissionRequestProxy::GetType(nsACString & aType)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIMutableArray> types = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
aType = mType;
|
||||||
if (ConvertPermissionRequestToArray(mPermissionRequests, types)) {
|
return NS_OK;
|
||||||
types.forget(aTypes);
|
}
|
||||||
return NS_OK;
|
|
||||||
}
|
NS_IMETHODIMP
|
||||||
return NS_ERROR_FAILURE;
|
nsContentPermissionRequestProxy::GetAccess(nsACString & aAccess)
|
||||||
|
{
|
||||||
|
aAccess = mAccess;
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -267,18 +136,10 @@ nsContentPermissionRequestProxy::Allow()
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_WIDGET_GONK
|
#ifdef MOZ_WIDGET_GONK
|
||||||
uint32_t len = mPermissionRequests.Length();
|
if (mType.Equals("audio-capture")) {
|
||||||
for (uint32_t i = 0; i < len; i++) {
|
GonkPermissionService::GetInstance()->addGrantInfo(
|
||||||
if (mPermissionRequests[i].type().Equals("audio-capture")) {
|
"android.permission.RECORD_AUDIO",
|
||||||
GonkPermissionService::GetInstance()->addGrantInfo(
|
static_cast<TabParent*>(mParent->Manager())->Manager()->Pid());
|
||||||
"android.permission.RECORD_AUDIO",
|
|
||||||
static_cast<TabParent*>(mParent->Manager())->Manager()->Pid());
|
|
||||||
}
|
|
||||||
if (mPermissionRequests[i].type().Equals("video-capture")) {
|
|
||||||
GonkPermissionService::GetInstance()->addGrantInfo(
|
|
||||||
"android.permission.CAMERA",
|
|
||||||
static_cast<TabParent*>(mParent->Manager())->Manager()->Pid());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -286,3 +147,55 @@ nsContentPermissionRequestProxy::Allow()
|
||||||
mParent = nullptr;
|
mParent = nullptr;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
|
ContentPermissionRequestParent::ContentPermissionRequestParent(const nsACString& aType,
|
||||||
|
const nsACString& aAccess,
|
||||||
|
Element* aElement,
|
||||||
|
const IPC::Principal& aPrincipal)
|
||||||
|
{
|
||||||
|
MOZ_COUNT_CTOR(ContentPermissionRequestParent);
|
||||||
|
|
||||||
|
mPrincipal = aPrincipal;
|
||||||
|
mElement = aElement;
|
||||||
|
mType = aType;
|
||||||
|
mAccess = aAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentPermissionRequestParent::~ContentPermissionRequestParent()
|
||||||
|
{
|
||||||
|
MOZ_COUNT_DTOR(ContentPermissionRequestParent);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContentPermissionRequestParent::Recvprompt()
|
||||||
|
{
|
||||||
|
mProxy = new nsContentPermissionRequestProxy();
|
||||||
|
NS_ASSERTION(mProxy, "Alloc of request proxy failed");
|
||||||
|
if (NS_FAILED(mProxy->Init(mType, mAccess, this))) {
|
||||||
|
mProxy->Cancel();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ContentPermissionRequestParent::ActorDestroy(ActorDestroyReason why)
|
||||||
|
{
|
||||||
|
if (mProxy) {
|
||||||
|
mProxy->OnParentDestroyed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
ContentPermissionRequestParent::IsBeingDestroyed()
|
||||||
|
{
|
||||||
|
// When TabParent::Destroy() is called, we are being destroyed. It's unsafe
|
||||||
|
// to send out any message now.
|
||||||
|
TabParent* tabParent = static_cast<TabParent*>(Manager());
|
||||||
|
return tabParent->IsDestroyed();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dom
|
||||||
|
} // namespace mozilla
|
||||||
|
|
|
@ -6,75 +6,60 @@
|
||||||
#define nsContentPermissionHelper_h
|
#define nsContentPermissionHelper_h
|
||||||
|
|
||||||
#include "nsIContentPermissionPrompt.h"
|
#include "nsIContentPermissionPrompt.h"
|
||||||
#include "nsTArray.h"
|
#include "nsString.h"
|
||||||
#include "nsIMutableArray.h"
|
|
||||||
|
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||||
|
#include "mozilla/dom/PContentPermissionRequestParent.h"
|
||||||
|
|
||||||
class nsContentPermissionRequestProxy;
|
class nsContentPermissionRequestProxy;
|
||||||
|
|
||||||
// Forward declare IPC::Principal here which is defined in
|
|
||||||
// PermissionMessageUtils.h. Include this file will transitively includes
|
|
||||||
// "windows.h" and it defines
|
|
||||||
// #define CreateEvent CreateEventW
|
|
||||||
// #define LoadImage LoadImageW
|
|
||||||
// That will mess up windows build.
|
|
||||||
namespace IPC {
|
|
||||||
class Principal;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
class Element;
|
class Element;
|
||||||
class PermissionRequest;
|
|
||||||
class ContentPermissionRequestParent;
|
|
||||||
class PContentPermissionRequestParent;
|
|
||||||
|
|
||||||
class ContentPermissionType : public nsIContentPermissionType
|
class ContentPermissionRequestParent : public PContentPermissionRequestParent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
ContentPermissionRequestParent(const nsACString& type,
|
||||||
NS_DECL_NSICONTENTPERMISSIONTYPE
|
const nsACString& access,
|
||||||
|
Element* element,
|
||||||
|
const IPC::Principal& principal);
|
||||||
|
virtual ~ContentPermissionRequestParent();
|
||||||
|
|
||||||
ContentPermissionType(const nsACString& aType, const nsACString& aAccess);
|
bool IsBeingDestroyed();
|
||||||
virtual ~ContentPermissionType();
|
|
||||||
|
|
||||||
protected:
|
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||||
|
nsCOMPtr<Element> mElement;
|
||||||
|
nsCOMPtr<nsContentPermissionRequestProxy> mProxy;
|
||||||
nsCString mType;
|
nsCString mType;
|
||||||
nsCString mAccess;
|
nsCString mAccess;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual bool Recvprompt();
|
||||||
|
virtual void ActorDestroy(ActorDestroyReason why);
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t ConvertPermissionRequestToArray(nsTArray<PermissionRequest>& aSrcArray,
|
|
||||||
nsIMutableArray* aDesArray);
|
|
||||||
|
|
||||||
nsresult CreatePermissionArray(const nsACString& aType,
|
|
||||||
const nsACString& aAccess,
|
|
||||||
nsIArray** aTypesArray);
|
|
||||||
|
|
||||||
PContentPermissionRequestParent*
|
|
||||||
CreateContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
|
|
||||||
Element* element,
|
|
||||||
const IPC::Principal& principal);
|
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
class nsContentPermissionRequestProxy : public nsIContentPermissionRequest
|
class nsContentPermissionRequestProxy : public nsIContentPermissionRequest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
NS_DECL_NSICONTENTPERMISSIONREQUEST
|
|
||||||
|
|
||||||
nsContentPermissionRequestProxy();
|
nsContentPermissionRequestProxy();
|
||||||
virtual ~nsContentPermissionRequestProxy();
|
virtual ~nsContentPermissionRequestProxy();
|
||||||
|
|
||||||
nsresult Init(const nsTArray<mozilla::dom::PermissionRequest>& requests,
|
nsresult Init(const nsACString& type, const nsACString& access, mozilla::dom::ContentPermissionRequestParent* parent);
|
||||||
mozilla::dom::ContentPermissionRequestParent* parent);
|
|
||||||
void OnParentDestroyed();
|
void OnParentDestroyed();
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSICONTENTPERMISSIONREQUEST
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Non-owning pointer to the ContentPermissionRequestParent object which owns this proxy.
|
// Non-owning pointer to the ContentPermissionRequestParent object which owns this proxy.
|
||||||
mozilla::dom::ContentPermissionRequestParent* mParent;
|
mozilla::dom::ContentPermissionRequestParent* mParent;
|
||||||
nsTArray<mozilla::dom::PermissionRequest> mPermissionRequests;
|
nsCString mType;
|
||||||
|
nsCString mAccess;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // nsContentPermissionHelper_h
|
#endif // nsContentPermissionHelper_h
|
||||||
|
|
||||||
|
|
|
@ -1687,7 +1687,7 @@ ReportAndDump(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||||
|
|
||||||
dmd::ClearReports();
|
dmd::ClearReports();
|
||||||
fprintf(stderr, "DMD: running reporters...\n");
|
fprintf(stderr, "DMD: running reporters...\n");
|
||||||
dmd::RunReporters();
|
dmd::RunReportersForThisProcess();
|
||||||
dmd::Writer writer(FpWrite, fp);
|
dmd::Writer writer(FpWrite, fp);
|
||||||
dmd::Dump(writer);
|
dmd::Dump(writer);
|
||||||
|
|
||||||
|
@ -2831,6 +2831,32 @@ NS_DOMStructuredCloneError(JSContext* cx,
|
||||||
xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
|
||||||
|
const jschar* aBegin,
|
||||||
|
const jschar* aLimit,
|
||||||
|
size_t* aSize,
|
||||||
|
const uint8_t** aMemory,
|
||||||
|
intptr_t *aHandle)
|
||||||
|
{
|
||||||
|
nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal);
|
||||||
|
return asmjscache::OpenEntryForRead(principal, aBegin, aLimit, aSize, aMemory,
|
||||||
|
aHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
||||||
|
const jschar* aBegin,
|
||||||
|
const jschar* aEnd,
|
||||||
|
size_t aSize,
|
||||||
|
uint8_t** aMemory,
|
||||||
|
intptr_t* aHandle)
|
||||||
|
{
|
||||||
|
nsIPrincipal* principal = nsContentUtils::GetObjectPrincipal(aGlobal);
|
||||||
|
return asmjscache::OpenEntryForWrite(principal, aBegin, aEnd, aSize, aMemory,
|
||||||
|
aHandle);
|
||||||
|
}
|
||||||
|
|
||||||
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2879,9 +2905,9 @@ nsJSContext::EnsureStatics()
|
||||||
|
|
||||||
// Set up the asm.js cache callbacks
|
// Set up the asm.js cache callbacks
|
||||||
static JS::AsmJSCacheOps asmJSCacheOps = {
|
static JS::AsmJSCacheOps asmJSCacheOps = {
|
||||||
asmjscache::OpenEntryForRead,
|
AsmJSCacheOpenEntryForRead,
|
||||||
asmjscache::CloseEntryForRead,
|
asmjscache::CloseEntryForRead,
|
||||||
asmjscache::OpenEntryForWrite,
|
AsmJSCacheOpenEntryForWrite,
|
||||||
asmjscache::CloseEntryForWrite,
|
asmjscache::CloseEntryForWrite,
|
||||||
asmjscache::GetBuildId
|
asmjscache::GetBuildId
|
||||||
};
|
};
|
||||||
|
|
|
@ -166,7 +166,7 @@ AppendWindowURI(nsGlobalWindow *aWindow, nsACString& aStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WindowsMallocSizeOf)
|
MOZ_DEFINE_MALLOC_SIZE_OF(WindowsMallocSizeOf)
|
||||||
|
|
||||||
// The key is the window ID.
|
// The key is the window ID.
|
||||||
typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths;
|
typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths;
|
||||||
|
|
|
@ -7652,8 +7652,13 @@ class CGProxySpecialOperation(CGPerSignatureCall):
|
||||||
"""
|
"""
|
||||||
Base class for classes for calling an indexed or named special operation
|
Base class for classes for calling an indexed or named special operation
|
||||||
(don't use this directly, use the derived classes below).
|
(don't use this directly, use the derived classes below).
|
||||||
|
|
||||||
|
If checkFound is False, will just assert that the prop is found instead of
|
||||||
|
checking that it is before wrapping the value.
|
||||||
"""
|
"""
|
||||||
def __init__(self, descriptor, operation):
|
def __init__(self, descriptor, operation, checkFound=True):
|
||||||
|
self.checkFound = checkFound;
|
||||||
|
|
||||||
nativeName = MakeNativeName(descriptor.binaryNames.get(operation, operation))
|
nativeName = MakeNativeName(descriptor.binaryNames.get(operation, operation))
|
||||||
operation = descriptor.operations[operation]
|
operation = descriptor.operations[operation]
|
||||||
assert len(operation.signatures()) == 1
|
assert len(operation.signatures()) == 1
|
||||||
|
@ -7699,15 +7704,26 @@ class CGProxySpecialOperation(CGPerSignatureCall):
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
wrap = CGGeneric(wrapForType(self.returnType, self.descriptor, self.templateValues))
|
wrap = CGGeneric(wrapForType(self.returnType, self.descriptor, self.templateValues))
|
||||||
wrap = CGIfWrapper(wrap, "found")
|
if self.checkFound:
|
||||||
|
wrap = CGIfWrapper(wrap, "found")
|
||||||
|
else:
|
||||||
|
wrap = CGList([CGGeneric("MOZ_ASSERT(found);"), wrap], "\n")
|
||||||
return "\n" + wrap.define()
|
return "\n" + wrap.define()
|
||||||
|
|
||||||
class CGProxyIndexedOperation(CGProxySpecialOperation):
|
class CGProxyIndexedOperation(CGProxySpecialOperation):
|
||||||
"""
|
"""
|
||||||
Class to generate a call to an indexed operation.
|
Class to generate a call to an indexed operation.
|
||||||
|
|
||||||
|
If doUnwrap is False, the caller is responsible for making sure a variable
|
||||||
|
named 'self' holds the C++ object somewhere where the code we generate
|
||||||
|
will see it.
|
||||||
|
|
||||||
|
If checkFound is False, will just assert that the prop is found instead of
|
||||||
|
checking that it is before wrapping the value.
|
||||||
"""
|
"""
|
||||||
def __init__(self, descriptor, name):
|
def __init__(self, descriptor, name, doUnwrap=True, checkFound=True):
|
||||||
CGProxySpecialOperation.__init__(self, descriptor, name)
|
self.doUnwrap = doUnwrap
|
||||||
|
CGProxySpecialOperation.__init__(self, descriptor, name, checkFound)
|
||||||
def define(self):
|
def define(self):
|
||||||
# Our first argument is the id we're getting.
|
# Our first argument is the id we're getting.
|
||||||
argName = self.arguments[0].identifier.name
|
argName = self.arguments[0].identifier.name
|
||||||
|
@ -7716,18 +7732,30 @@ class CGProxyIndexedOperation(CGProxySpecialOperation):
|
||||||
setIndex = ""
|
setIndex = ""
|
||||||
else:
|
else:
|
||||||
setIndex = "uint32_t %s = index;\n" % argName
|
setIndex = "uint32_t %s = index;\n" % argName
|
||||||
return (setIndex +
|
if self.doUnwrap:
|
||||||
"%s* self = UnwrapProxy(proxy);\n" +
|
unwrap = "%s* self = UnwrapProxy(proxy);\n"
|
||||||
|
else:
|
||||||
|
unwrap = ""
|
||||||
|
return (setIndex + unwrap +
|
||||||
CGProxySpecialOperation.define(self))
|
CGProxySpecialOperation.define(self))
|
||||||
|
|
||||||
class CGProxyIndexedGetter(CGProxyIndexedOperation):
|
class CGProxyIndexedGetter(CGProxyIndexedOperation):
|
||||||
"""
|
"""
|
||||||
Class to generate a call to an indexed getter. If templateValues is not None
|
Class to generate a call to an indexed getter. If templateValues is not None
|
||||||
the returned value will be wrapped with wrapForType using templateValues.
|
the returned value will be wrapped with wrapForType using templateValues.
|
||||||
|
|
||||||
|
If doUnwrap is False, the caller is responsible for making sure a variable
|
||||||
|
named 'self' holds the C++ object somewhere where the code we generate
|
||||||
|
will see it.
|
||||||
|
|
||||||
|
If checkFound is False, will just assert that the prop is found instead of
|
||||||
|
checking that it is before wrapping the value.
|
||||||
"""
|
"""
|
||||||
def __init__(self, descriptor, templateValues=None):
|
def __init__(self, descriptor, templateValues=None, doUnwrap=True,
|
||||||
|
checkFound=True):
|
||||||
self.templateValues = templateValues
|
self.templateValues = templateValues
|
||||||
CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedGetter')
|
CGProxyIndexedOperation.__init__(self, descriptor, 'IndexedGetter',
|
||||||
|
doUnwrap, checkFound)
|
||||||
|
|
||||||
class CGProxyIndexedPresenceChecker(CGProxyIndexedGetter):
|
class CGProxyIndexedPresenceChecker(CGProxyIndexedGetter):
|
||||||
"""
|
"""
|
||||||
|
@ -8364,65 +8392,55 @@ class CGDOMJSProxyHandler_finalize(ClassMethod):
|
||||||
return ("%s self = UnwrapProxy(proxy);\n\n" % (self.descriptor.nativeType + "*") +
|
return ("%s self = UnwrapProxy(proxy);\n\n" % (self.descriptor.nativeType + "*") +
|
||||||
finalizeHook(self.descriptor, FINALIZE_HOOK_NAME, self.args[0].name).define())
|
finalizeHook(self.descriptor, FINALIZE_HOOK_NAME, self.args[0].name).define())
|
||||||
|
|
||||||
class CGDOMJSProxyHandler_getElementIfPresent(ClassMethod):
|
class CGDOMJSProxyHandler_slice(ClassMethod):
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
|
assert descriptor.supportsIndexedProperties()
|
||||||
|
|
||||||
args = [Argument('JSContext*', 'cx'),
|
args = [Argument('JSContext*', 'cx'),
|
||||||
Argument('JS::Handle<JSObject*>', 'proxy'),
|
Argument('JS::Handle<JSObject*>', 'proxy'),
|
||||||
Argument('JS::Handle<JSObject*>', 'receiver'),
|
Argument('uint32_t', 'begin'),
|
||||||
Argument('uint32_t', 'index'),
|
Argument('uint32_t', 'end'),
|
||||||
Argument('JS::MutableHandle<JS::Value>', 'vp'),
|
Argument('JS::Handle<JSObject*>', 'array')]
|
||||||
Argument('bool*', 'present')]
|
ClassMethod.__init__(self, "slice", "bool", args)
|
||||||
ClassMethod.__init__(self, "getElementIfPresent", "bool", args)
|
|
||||||
self.descriptor = descriptor
|
self.descriptor = descriptor
|
||||||
|
|
||||||
def getBody(self):
|
def getBody(self):
|
||||||
successCode = ("*present = found;\n"
|
# Just like getOwnPropertyNames we'll assume that we have no holes, so
|
||||||
"return true;")
|
# we have all properties from 0 to length. If that ever changes
|
||||||
templateValues = {'jsvalRef': 'vp', 'jsvalHandle': 'vp',
|
# (unlikely), we'll need to do something a bit more clever with how we
|
||||||
|
# forward on to our ancestor.
|
||||||
|
header = CGGeneric(
|
||||||
|
'JS::Rooted<JS::Value> temp(cx);\n'
|
||||||
|
'MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),\n'
|
||||||
|
' "Should not have a XrayWrapper here");\n'
|
||||||
|
'\n'
|
||||||
|
'%s* self = UnwrapProxy(proxy);\n'
|
||||||
|
'uint32_t length = self->Length();\n'
|
||||||
|
"// Compute the end of the indices we'll get ourselves\n"
|
||||||
|
'uint32_t ourEnd = std::max(begin, std::min(end, length));' %
|
||||||
|
self.descriptor.nativeType)
|
||||||
|
|
||||||
|
successCode = ("js::UnsafeDefineElement(cx, array, index - begin, temp);\n"
|
||||||
|
"continue;")
|
||||||
|
templateValues = {'jsvalRef': 'temp', 'jsvalHandle': '&temp',
|
||||||
'obj': 'proxy', 'successCode': successCode}
|
'obj': 'proxy', 'successCode': successCode}
|
||||||
if self.descriptor.supportsIndexedProperties():
|
get = CGProxyIndexedGetter(self.descriptor, templateValues, False, False)
|
||||||
get = (CGProxyIndexedGetter(self.descriptor, templateValues).define() + "\n"
|
|
||||||
"// We skip the expando object and any named getters if\n"
|
|
||||||
"// there is an indexed getter.\n" +
|
|
||||||
"\n") % (self.descriptor.nativeType)
|
|
||||||
else:
|
|
||||||
if self.descriptor.supportsNamedProperties():
|
|
||||||
get = CGProxyNamedGetter(self.descriptor, templateValues,
|
|
||||||
"UINT_TO_JSVAL(index)").define()
|
|
||||||
get += """
|
|
||||||
|
|
||||||
JS::Rooted<JSObject*> expando(cx, GetExpandoObject(proxy));
|
getOurElements = CGWrapper(
|
||||||
if (expando) {
|
CGIndenter(get),
|
||||||
bool isPresent;
|
pre="for (uint32_t index = begin; index < ourEnd; ++index) {\n",
|
||||||
if (!JS_GetElementIfPresent(cx, expando, index, expando, vp, &isPresent)) {
|
post="\n}")
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (isPresent) {
|
|
||||||
*present = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy),
|
getProtoElements = CGIfWrapper(
|
||||||
"Should not have a XrayWrapper here");
|
CGGeneric("JS::Rooted<JSObject*> proto(cx);\n"
|
||||||
|
"if (!js::GetObjectProto(cx, proxy, &proto)) {\n"
|
||||||
|
" return false;\n"
|
||||||
|
"}\n"
|
||||||
|
"return js::SliceSlowly(cx, proto, proxy, ourEnd, end, array);"),
|
||||||
|
"end > ourEnd")
|
||||||
|
|
||||||
""" + get + """
|
return CGList([header, getOurElements, getProtoElements,
|
||||||
JS::Rooted<JSObject*> proto(cx);
|
CGGeneric("return true;")], "\n\n").define();
|
||||||
if (!js::GetObjectProto(cx, proxy, &proto)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (proto) {
|
|
||||||
bool isPresent;
|
|
||||||
if (!JS_GetElementIfPresent(cx, proto, index, proxy, vp, &isPresent)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
*present = isPresent;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
*present = false;
|
|
||||||
// Can't Debug_SetValueRangeToCrashOnTouch because it's not public
|
|
||||||
return true;"""
|
|
||||||
|
|
||||||
class CGDOMJSProxyHandler_getInstance(ClassMethod):
|
class CGDOMJSProxyHandler_getInstance(ClassMethod):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -8446,9 +8464,11 @@ class CGDOMJSProxyHandler(CGClass):
|
||||||
CGDOMJSProxyHandler_className(descriptor),
|
CGDOMJSProxyHandler_className(descriptor),
|
||||||
CGDOMJSProxyHandler_finalizeInBackground(descriptor),
|
CGDOMJSProxyHandler_finalizeInBackground(descriptor),
|
||||||
CGDOMJSProxyHandler_finalize(descriptor),
|
CGDOMJSProxyHandler_finalize(descriptor),
|
||||||
CGDOMJSProxyHandler_getElementIfPresent(descriptor),
|
|
||||||
CGDOMJSProxyHandler_getInstance(),
|
CGDOMJSProxyHandler_getInstance(),
|
||||||
CGDOMJSProxyHandler_delete(descriptor)]
|
CGDOMJSProxyHandler_delete(descriptor)]
|
||||||
|
if descriptor.supportsIndexedProperties():
|
||||||
|
methods.append(CGDOMJSProxyHandler_slice(descriptor))
|
||||||
|
|
||||||
CGClass.__init__(self, 'DOMProxyHandler',
|
CGClass.__init__(self, 'DOMProxyHandler',
|
||||||
bases=[ClassBase('mozilla::dom::DOMProxyHandler')],
|
bases=[ClassBase('mozilla::dom::DOMProxyHandler')],
|
||||||
constructors=constructors,
|
constructors=constructors,
|
||||||
|
|
|
@ -105,31 +105,6 @@ nsDOMCameraManager::CreateInstance(nsPIDOMWindow* aWindow)
|
||||||
return cameraManager.forget();
|
return cameraManager.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
nsDOMCameraControl*
|
|
||||||
nsDOMCameraManager::GetCameraControl(uint32_t aDeviceNum,
|
|
||||||
nsICameraGetCameraCallback* onSuccess,
|
|
||||||
nsICameraErrorCallback* onError,
|
|
||||||
ErrorResult& aRv)
|
|
||||||
{
|
|
||||||
aRv = NS_OK;
|
|
||||||
|
|
||||||
// reuse the same camera thread to conserve resources
|
|
||||||
if (!mCameraThread) {
|
|
||||||
aRv = NS_NewThread(getter_AddRefs(mCameraThread));
|
|
||||||
if (aRv.Failed()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creating this object will trigger the onSuccess handler
|
|
||||||
nsDOMCameraControl* cameraControl = new nsDOMCameraControl(aDeviceNum, mCameraThread,
|
|
||||||
onSuccess, onError, mWindow);
|
|
||||||
if (cameraControl) {
|
|
||||||
Register(cameraControl);
|
|
||||||
}
|
|
||||||
return cameraControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
nsDOMCameraManager::GetCamera(const CameraSelector& aOptions,
|
nsDOMCameraManager::GetCamera(const CameraSelector& aOptions,
|
||||||
nsICameraGetCameraCallback* onSuccess,
|
nsICameraGetCameraCallback* onSuccess,
|
||||||
|
@ -141,10 +116,22 @@ nsDOMCameraManager::GetCamera(const CameraSelector& aOptions,
|
||||||
cameraId = 1;
|
cameraId = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reuse the same camera thread to conserve resources
|
||||||
|
if (!mCameraThread) {
|
||||||
|
aRv = NS_NewThread(getter_AddRefs(mCameraThread));
|
||||||
|
if (aRv.Failed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
DOM_CAMERA_LOGT("%s:%d\n", __func__, __LINE__);
|
||||||
|
|
||||||
|
// Creating this object will trigger the onSuccess handler
|
||||||
nsRefPtr<nsDOMCameraControl> cameraControl =
|
nsRefPtr<nsDOMCameraControl> cameraControl =
|
||||||
GetCameraControl(cameraId, onSuccess, onError.WasPassed() ? onError.Value() : nullptr, aRv);
|
new nsDOMCameraControl(cameraId, mCameraThread,
|
||||||
|
onSuccess, onError.WasPassed() ? onError.Value() : nullptr, mWindow);
|
||||||
|
|
||||||
|
Register(cameraControl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -49,11 +49,6 @@ public:
|
||||||
CreateInstance(nsPIDOMWindow* aWindow);
|
CreateInstance(nsPIDOMWindow* aWindow);
|
||||||
static bool IsWindowStillActive(uint64_t aWindowId);
|
static bool IsWindowStillActive(uint64_t aWindowId);
|
||||||
|
|
||||||
// Build us an nsDOMCameraControl
|
|
||||||
mozilla::nsDOMCameraControl* GetCameraControl(uint32_t aDeviceNum,
|
|
||||||
nsICameraGetCameraCallback* onSuccess,
|
|
||||||
nsICameraErrorCallback* onError,
|
|
||||||
mozilla::ErrorResult& aRv);
|
|
||||||
void Register(mozilla::nsDOMCameraControl* aDOMCameraControl);
|
void Register(mozilla::nsDOMCameraControl* aDOMCameraControl);
|
||||||
void OnNavigation(uint64_t aWindowId);
|
void OnNavigation(uint64_t aWindowId);
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@
|
||||||
#include "nsIStringBundle.h"
|
#include "nsIStringBundle.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include "nsContentPermissionHelper.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/DeviceStorageBinding.h"
|
#include "mozilla/dom/DeviceStorageBinding.h"
|
||||||
|
|
||||||
|
@ -1734,14 +1733,17 @@ nsDOMDeviceStorageCursor::GetStorageType(nsAString & aType)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDOMDeviceStorageCursor::GetTypes(nsIArray** aTypes)
|
nsDOMDeviceStorageCursor::GetType(nsACString & aType)
|
||||||
{
|
{
|
||||||
nsCString type;
|
return DeviceStorageTypeChecker::GetPermissionForType(mFile->mStorageType,
|
||||||
nsresult rv =
|
aType);
|
||||||
DeviceStorageTypeChecker::GetPermissionForType(mFile->mStorageType, type);
|
}
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
return CreatePermissionArray(type, NS_LITERAL_CSTRING("read"), aTypes);
|
NS_IMETHODIMP
|
||||||
|
nsDOMDeviceStorageCursor::GetAccess(nsACString & aAccess)
|
||||||
|
{
|
||||||
|
aAccess = NS_LITERAL_CSTRING("read");
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -2249,10 +2251,8 @@ public:
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
nsTArray<PermissionRequest> permArray;
|
|
||||||
permArray.AppendElement(PermissionRequest(type, access));
|
|
||||||
child->SendPContentPermissionRequestConstructor(
|
child->SendPContentPermissionRequestConstructor(
|
||||||
this, permArray, IPC::Principal(mPrincipal));
|
this, type, access, IPC::Principal(mPrincipal));
|
||||||
|
|
||||||
Sendprompt();
|
Sendprompt();
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -2266,23 +2266,26 @@ public:
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP GetTypes(nsIArray** aTypes)
|
NS_IMETHOD GetType(nsACString & aType)
|
||||||
{
|
{
|
||||||
nsCString type;
|
nsCString type;
|
||||||
nsresult rv =
|
nsresult rv
|
||||||
DeviceStorageTypeChecker::GetPermissionForType(mFile->mStorageType, type);
|
= DeviceStorageTypeChecker::GetPermissionForType(mFile->mStorageType,
|
||||||
|
aType);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsCString access;
|
NS_IMETHOD GetAccess(nsACString & aAccess)
|
||||||
rv = DeviceStorageTypeChecker::GetAccessForRequest(
|
{
|
||||||
DeviceStorageRequestType(mRequestType), access);
|
nsresult rv = DeviceStorageTypeChecker::GetAccessForRequest(
|
||||||
|
DeviceStorageRequestType(mRequestType), aAccess);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
return NS_OK;
|
||||||
return CreatePermissionArray(type, access, aTypes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
|
NS_IMETHOD GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
|
||||||
|
@ -3296,10 +3299,8 @@ nsDOMDeviceStorage::EnumerateInternal(const nsAString& aPath,
|
||||||
if (aRv.Failed()) {
|
if (aRv.Failed()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
nsTArray<PermissionRequest> permArray;
|
child->SendPContentPermissionRequestConstructor(r, type,
|
||||||
permArray.AppendElement(PermissionRequest(type, NS_LITERAL_CSTRING("read")));
|
NS_LITERAL_CSTRING("read"),
|
||||||
child->SendPContentPermissionRequestConstructor(r,
|
|
||||||
permArray,
|
|
||||||
IPC::Principal(mPrincipal));
|
IPC::Principal(mPrincipal));
|
||||||
|
|
||||||
r->Sendprompt();
|
r->Sendprompt();
|
||||||
|
|
|
@ -7,13 +7,15 @@
|
||||||
interface nsIPrincipal;
|
interface nsIPrincipal;
|
||||||
interface nsIDOMWindow;
|
interface nsIDOMWindow;
|
||||||
interface nsIDOMElement;
|
interface nsIDOMElement;
|
||||||
interface nsIArray;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface provides the request type and its access.
|
* Interface allows access to a content to request
|
||||||
|
* permission to perform a privileged operation such as
|
||||||
|
* geolocation.
|
||||||
*/
|
*/
|
||||||
[scriptable, builtinclass, uuid(384b6cc4-a66b-4bea-98e0-eb10562a9ba4)]
|
[scriptable, uuid(1de67000-2de8-11e2-81c1-0800200c9a66)]
|
||||||
interface nsIContentPermissionType : nsISupports {
|
interface nsIContentPermissionRequest : nsISupports {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of the permission request, such as
|
* The type of the permission request, such as
|
||||||
* "geolocation".
|
* "geolocation".
|
||||||
|
@ -25,22 +27,8 @@ interface nsIContentPermissionType : nsISupports {
|
||||||
* "read".
|
* "read".
|
||||||
*/
|
*/
|
||||||
readonly attribute ACString access;
|
readonly attribute ACString access;
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface allows access to a content to request
|
|
||||||
* permission to perform a privileged operation such as
|
|
||||||
* geolocation.
|
|
||||||
*/
|
|
||||||
[scriptable, uuid(69a39d88-d1c4-4ba9-9b19-bafc7a1bb783)]
|
|
||||||
interface nsIContentPermissionRequest : nsISupports {
|
|
||||||
/**
|
/**
|
||||||
* The array will include the request types. Elements of this array are
|
|
||||||
* nsIContentPermissionType object.
|
|
||||||
*/
|
|
||||||
readonly attribute nsIArray types;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The principal of the permission request.
|
* The principal of the permission request.
|
||||||
*/
|
*/
|
||||||
readonly attribute nsIPrincipal principal;
|
readonly attribute nsIPrincipal principal;
|
||||||
|
|
|
@ -497,19 +497,12 @@ ContentChild::RecvPMemoryReportRequestConstructor(
|
||||||
GetProcessName(process);
|
GetProcessName(process);
|
||||||
AppendProcessId(process);
|
AppendProcessId(process);
|
||||||
|
|
||||||
// Run each reporter. The callback will turn each measurement into a
|
// Run the reporters. The callback will turn each measurement into a
|
||||||
// MemoryReport.
|
// MemoryReport.
|
||||||
nsCOMPtr<nsISimpleEnumerator> e;
|
|
||||||
mgr->EnumerateReporters(getter_AddRefs(e));
|
|
||||||
nsRefPtr<MemoryReportsWrapper> wrappedReports =
|
nsRefPtr<MemoryReportsWrapper> wrappedReports =
|
||||||
new MemoryReportsWrapper(&reports);
|
new MemoryReportsWrapper(&reports);
|
||||||
nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process);
|
nsRefPtr<MemoryReportCallback> cb = new MemoryReportCallback(process);
|
||||||
bool more;
|
mgr->GetReportsForThisProcess(cb, wrappedReports);
|
||||||
while (NS_SUCCEEDED(e->HasMoreElements(&more)) && more) {
|
|
||||||
nsCOMPtr<nsIMemoryReporter> r;
|
|
||||||
e->GetNext(getter_AddRefs(r));
|
|
||||||
r->CollectReports(cb, wrappedReports);
|
|
||||||
}
|
|
||||||
|
|
||||||
child->Send__delete__(child, generation, reports);
|
child->Send__delete__(child, generation, reports);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -193,15 +193,15 @@ MemoryReportRequestParent::~MemoryReportRequestParent()
|
||||||
}
|
}
|
||||||
|
|
||||||
// A memory reporter for ContentParent objects themselves.
|
// A memory reporter for ContentParent objects themselves.
|
||||||
class ContentParentsMemoryReporter MOZ_FINAL : public MemoryMultiReporter
|
class ContentParentsMemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ContentParentsMemoryReporter() {}
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* cb,
|
|
||||||
nsISupports* aClosure);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(ContentParentsMemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
ContentParentsMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb,
|
ContentParentsMemoryReporter::CollectReports(nsIMemoryReporterCallback* cb,
|
||||||
nsISupports* aClosure)
|
nsISupports* aClosure)
|
||||||
|
|
|
@ -16,7 +16,6 @@ include protocol PIndexedDB;
|
||||||
include DOMTypes;
|
include DOMTypes;
|
||||||
include JavaScriptTypes;
|
include JavaScriptTypes;
|
||||||
include URIParams;
|
include URIParams;
|
||||||
include PContentPermission;
|
|
||||||
|
|
||||||
|
|
||||||
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
|
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
|
||||||
|
@ -207,8 +206,10 @@ parent:
|
||||||
* Initiates an asynchronous request for permission for the
|
* Initiates an asynchronous request for permission for the
|
||||||
* provided principal.
|
* provided principal.
|
||||||
*
|
*
|
||||||
* @param aRequests
|
* @param aType
|
||||||
* The array of permissions to request.
|
* The type of permission to request.
|
||||||
|
* @param aAccess
|
||||||
|
* Access type. "read" for example.
|
||||||
* @param aPrincipal
|
* @param aPrincipal
|
||||||
* The principal of the request.
|
* The principal of the request.
|
||||||
*
|
*
|
||||||
|
@ -216,7 +217,7 @@ parent:
|
||||||
* principals that can live in the content process should
|
* principals that can live in the content process should
|
||||||
* provided.
|
* provided.
|
||||||
*/
|
*/
|
||||||
PContentPermissionRequest(PermissionRequest[] aRequests, Principal aPrincipal);
|
PContentPermissionRequest(nsCString aType, nsCString aAccess, Principal principal);
|
||||||
|
|
||||||
PContentDialog(uint32_t aType, nsCString aName, nsCString aFeatures,
|
PContentDialog(uint32_t aType, nsCString aName, nsCString aFeatures,
|
||||||
int32_t[] aIntParams, nsString[] aStringParams);
|
int32_t[] aIntParams, nsString[] aStringParams);
|
||||||
|
|
|
@ -1,14 +0,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/. */
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace dom {
|
|
||||||
|
|
||||||
struct PermissionRequest {
|
|
||||||
nsCString type;
|
|
||||||
nsCString access;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace dom
|
|
||||||
} // namespace mozilla
|
|
|
@ -1157,11 +1157,12 @@ TabChild::ArraysToParams(const InfallibleTArray<int>& aIntParams,
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PContentPermissionRequestChild*
|
PContentPermissionRequestChild*
|
||||||
TabChild:: SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor,
|
TabChild:: SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor,
|
||||||
const InfallibleTArray<PermissionRequest>& aRequests,
|
const nsCString& aType,
|
||||||
|
const nsCString& aAccess,
|
||||||
const IPC::Principal& aPrincipal)
|
const IPC::Principal& aPrincipal)
|
||||||
{
|
{
|
||||||
PCOMContentPermissionRequestChild* child = static_cast<PCOMContentPermissionRequestChild*>(aActor);
|
PCOMContentPermissionRequestChild* child = static_cast<PCOMContentPermissionRequestChild*>(aActor);
|
||||||
PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aRequests, aPrincipal);
|
PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aType, aAccess, aPrincipal);
|
||||||
child->mIPCOpen = true;
|
child->mIPCOpen = true;
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
@ -2039,8 +2040,7 @@ TabChild::DeallocPContentDialogChild(PContentDialogChild* aDialog)
|
||||||
}
|
}
|
||||||
|
|
||||||
PContentPermissionRequestChild*
|
PContentPermissionRequestChild*
|
||||||
TabChild::AllocPContentPermissionRequestChild(const InfallibleTArray<PermissionRequest>& aRequests,
|
TabChild::AllocPContentPermissionRequestChild(const nsCString& aType, const nsCString& aAccess, const IPC::Principal&)
|
||||||
const IPC::Principal& aPrincipal)
|
|
||||||
{
|
{
|
||||||
NS_RUNTIMEABORT("unused");
|
NS_RUNTIMEABORT("unused");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -280,11 +280,13 @@ public:
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
virtual PContentPermissionRequestChild*
|
virtual PContentPermissionRequestChild*
|
||||||
SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor,
|
SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor,
|
||||||
const InfallibleTArray<PermissionRequest>& aRequests,
|
const nsCString& aType,
|
||||||
|
const nsCString& aAccess,
|
||||||
const IPC::Principal& aPrincipal);
|
const IPC::Principal& aPrincipal);
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
virtual PContentPermissionRequestChild* AllocPContentPermissionRequestChild(const InfallibleTArray<PermissionRequest>& aRequests,
|
virtual PContentPermissionRequestChild* AllocPContentPermissionRequestChild(const nsCString& aType,
|
||||||
|
const nsCString& aAccess,
|
||||||
const IPC::Principal& aPrincipal);
|
const IPC::Principal& aPrincipal);
|
||||||
virtual bool DeallocPContentPermissionRequestChild(PContentPermissionRequestChild* actor);
|
virtual bool DeallocPContentPermissionRequestChild(PContentPermissionRequestChild* actor);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "mozilla/BrowserElementParent.h"
|
#include "mozilla/BrowserElementParent.h"
|
||||||
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
#include "mozilla/docshell/OfflineCacheUpdateParent.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#include "mozilla/dom/PContentPermissionRequestParent.h"
|
|
||||||
#include "mozilla/Hal.h"
|
#include "mozilla/Hal.h"
|
||||||
#include "mozilla/ipc/DocumentRendererParent.h"
|
#include "mozilla/ipc/DocumentRendererParent.h"
|
||||||
#include "mozilla/layers/CompositorParent.h"
|
#include "mozilla/layers/CompositorParent.h"
|
||||||
|
@ -594,10 +593,9 @@ TabParent::DeallocPDocumentRendererParent(PDocumentRendererParent* actor)
|
||||||
}
|
}
|
||||||
|
|
||||||
PContentPermissionRequestParent*
|
PContentPermissionRequestParent*
|
||||||
TabParent::AllocPContentPermissionRequestParent(const InfallibleTArray<PermissionRequest>& aRequests,
|
TabParent::AllocPContentPermissionRequestParent(const nsCString& type, const nsCString& access, const IPC::Principal& principal)
|
||||||
const IPC::Principal& aPrincipal)
|
|
||||||
{
|
{
|
||||||
return CreateContentPermissionRequestParent(aRequests, mFrameElement, aPrincipal);
|
return new ContentPermissionRequestParent(type, access, mFrameElement, principal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -227,8 +227,7 @@ public:
|
||||||
virtual bool DeallocPDocumentRendererParent(PDocumentRendererParent* actor);
|
virtual bool DeallocPDocumentRendererParent(PDocumentRendererParent* actor);
|
||||||
|
|
||||||
virtual PContentPermissionRequestParent*
|
virtual PContentPermissionRequestParent*
|
||||||
AllocPContentPermissionRequestParent(const InfallibleTArray<PermissionRequest>& aRequests,
|
AllocPContentPermissionRequestParent(const nsCString& aType, const nsCString& aAccess, const IPC::Principal& aPrincipal);
|
||||||
const IPC::Principal& aPrincipal);
|
|
||||||
virtual bool DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor);
|
virtual bool DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor);
|
||||||
|
|
||||||
virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdateParent(
|
virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdateParent(
|
||||||
|
|
|
@ -68,7 +68,6 @@ IPDL_SOURCES += [
|
||||||
'PBrowser.ipdl',
|
'PBrowser.ipdl',
|
||||||
'PContent.ipdl',
|
'PContent.ipdl',
|
||||||
'PContentDialog.ipdl',
|
'PContentDialog.ipdl',
|
||||||
'PContentPermission.ipdlh',
|
|
||||||
'PContentPermissionRequest.ipdl',
|
'PContentPermissionRequest.ipdl',
|
||||||
'PCrashReporter.ipdl',
|
'PCrashReporter.ipdl',
|
||||||
'PDocumentRenderer.ipdl',
|
'PDocumentRenderer.ipdl',
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
#include "MediaEngineWebRTC.h"
|
#include "MediaEngineWebRTC.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MOZ_B2G
|
#ifdef MOZ_WIDGET_GONK
|
||||||
#include "MediaPermissionGonk.h"
|
#include "MediaPermissionGonk.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -756,7 +756,7 @@ public:
|
||||||
, mListener(aListener)
|
, mListener(aListener)
|
||||||
, mPrefs(aPrefs)
|
, mPrefs(aPrefs)
|
||||||
, mDeviceChosen(false)
|
, mDeviceChosen(false)
|
||||||
, mBackend(nullptr)
|
, mBackendChosen(false)
|
||||||
, mManager(MediaManager::GetInstance())
|
, mManager(MediaManager::GetInstance())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -778,11 +778,15 @@ public:
|
||||||
, mListener(aListener)
|
, mListener(aListener)
|
||||||
, mPrefs(aPrefs)
|
, mPrefs(aPrefs)
|
||||||
, mDeviceChosen(false)
|
, mDeviceChosen(false)
|
||||||
|
, mBackendChosen(true)
|
||||||
, mBackend(aBackend)
|
, mBackend(aBackend)
|
||||||
, mManager(MediaManager::GetInstance())
|
, mManager(MediaManager::GetInstance())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
~GetUserMediaRunnable() {
|
~GetUserMediaRunnable() {
|
||||||
|
if (mBackendChosen) {
|
||||||
|
delete mBackend;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHOD
|
NS_IMETHOD
|
||||||
|
@ -790,15 +794,14 @@ public:
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
|
NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
|
||||||
|
|
||||||
MediaEngine* backend = mBackend;
|
|
||||||
// Was a backend provided?
|
// Was a backend provided?
|
||||||
if (!backend) {
|
if (!mBackendChosen) {
|
||||||
backend = mManager->GetBackend(mWindowID);
|
mBackend = mManager->GetBackend(mWindowID);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Was a device provided?
|
// Was a device provided?
|
||||||
if (!mDeviceChosen) {
|
if (!mDeviceChosen) {
|
||||||
nsresult rv = SelectDevice(backend);
|
nsresult rv = SelectDevice();
|
||||||
if (rv != NS_OK) {
|
if (rv != NS_OK) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -870,10 +873,10 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
SelectDevice(MediaEngine* backend)
|
SelectDevice()
|
||||||
{
|
{
|
||||||
if (mConstraints.mPicture || mConstraints.mVideo) {
|
if (mConstraints.mPicture || mConstraints.mVideo) {
|
||||||
ScopedDeletePtr<SourceSet> sources (GetSources(backend,
|
ScopedDeletePtr<SourceSet> sources (GetSources(mBackend,
|
||||||
mConstraints.mVideom, &MediaEngine::EnumerateVideoDevices));
|
mConstraints.mVideom, &MediaEngine::EnumerateVideoDevices));
|
||||||
|
|
||||||
if (!sources->Length()) {
|
if (!sources->Length()) {
|
||||||
|
@ -887,7 +890,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mConstraints.mAudio) {
|
if (mConstraints.mAudio) {
|
||||||
ScopedDeletePtr<SourceSet> sources (GetSources(backend,
|
ScopedDeletePtr<SourceSet> sources (GetSources(mBackend,
|
||||||
mConstraints.mAudiom, &MediaEngine::EnumerateAudioDevices));
|
mConstraints.mAudiom, &MediaEngine::EnumerateAudioDevices));
|
||||||
|
|
||||||
if (!sources->Length()) {
|
if (!sources->Length()) {
|
||||||
|
@ -981,8 +984,9 @@ private:
|
||||||
MediaEnginePrefs mPrefs;
|
MediaEnginePrefs mPrefs;
|
||||||
|
|
||||||
bool mDeviceChosen;
|
bool mDeviceChosen;
|
||||||
|
bool mBackendChosen;
|
||||||
|
|
||||||
RefPtr<MediaEngine> mBackend;
|
MediaEngine* mBackend;
|
||||||
nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
|
nsRefPtr<MediaManager> mManager; // get ref to this when creating the runnable
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1262,10 +1266,10 @@ MediaManager::GetUserMedia(JSContext* aCx, bool aPrivileged,
|
||||||
// Force MediaManager to startup before we try to access it from other threads
|
// Force MediaManager to startup before we try to access it from other threads
|
||||||
// Hack: should init singleton earlier unless it's expensive (mem or CPU)
|
// Hack: should init singleton earlier unless it's expensive (mem or CPU)
|
||||||
(void) MediaManager::Get();
|
(void) MediaManager::Get();
|
||||||
#ifdef MOZ_B2G
|
#ifdef MOZ_WIDGET_GONK
|
||||||
// Initialize MediaPermissionManager before send out any permission request.
|
// Initialize MediaPermissionManager before send out any permission request.
|
||||||
(void) MediaPermissionManager::GetInstance();
|
(void) MediaPermissionManager::GetInstance();
|
||||||
#endif //MOZ_B2G
|
#endif //MOZ_WIDGET_GONK
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the WindowID in a hash table and mark as active. The entry is removed
|
// Store the WindowID in a hash table and mark as active. The entry is removed
|
||||||
|
@ -1411,11 +1415,11 @@ MediaManager::GetBackend(uint64_t aWindowId)
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
if (!mBackend) {
|
if (!mBackend) {
|
||||||
#if defined(MOZ_WEBRTC)
|
#if defined(MOZ_WEBRTC)
|
||||||
#ifndef MOZ_B2G_CAMERA
|
#ifndef MOZ_B2G_CAMERA
|
||||||
mBackend = new MediaEngineWebRTC(mPrefs);
|
mBackend = new MediaEngineWebRTC(mPrefs);
|
||||||
#else
|
#else
|
||||||
mBackend = new MediaEngineWebRTC(mCameraManager);
|
mBackend = new MediaEngineWebRTC(mCameraManager, aWindowId);
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
mBackend = new MediaEngineDefault();
|
mBackend = new MediaEngineDefault();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -513,7 +513,9 @@ private:
|
||||||
// Make private because we want only one instance of this class
|
// Make private because we want only one instance of this class
|
||||||
MediaManager();
|
MediaManager();
|
||||||
|
|
||||||
~MediaManager() {}
|
~MediaManager() {
|
||||||
|
delete mBackend;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult MediaCaptureWindowStateInternal(nsIDOMWindow* aWindow, bool* aVideo,
|
nsresult MediaCaptureWindowStateInternal(nsIDOMWindow* aWindow, bool* aVideo,
|
||||||
bool* aAudio);
|
bool* aAudio);
|
||||||
|
@ -528,11 +530,11 @@ private:
|
||||||
|
|
||||||
Mutex mMutex;
|
Mutex mMutex;
|
||||||
// protected with mMutex:
|
// protected with mMutex:
|
||||||
RefPtr<MediaEngine> mBackend;
|
MediaEngine* mBackend;
|
||||||
|
|
||||||
static StaticRefPtr<MediaManager> sSingleton;
|
static StaticRefPtr<MediaManager> sSingleton;
|
||||||
|
|
||||||
#ifdef MOZ_B2G_CAMERA
|
#ifdef MOZ_WIDGET_GONK
|
||||||
nsRefPtr<nsDOMCameraManager> mCameraManager;
|
nsRefPtr<nsDOMCameraManager> mCameraManager;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,36 +20,14 @@
|
||||||
#include "mozilla/dom/MediaStreamTrackBinding.h"
|
#include "mozilla/dom/MediaStreamTrackBinding.h"
|
||||||
#include "nsISupportsPrimitives.h"
|
#include "nsISupportsPrimitives.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsArrayUtils.h"
|
|
||||||
#include "nsContentPermissionHelper.h"
|
|
||||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||||
|
|
||||||
#define AUDIO_PERMISSION_NAME "audio-capture"
|
#define AUDIO_PERMISSION_NAME "audio-capture"
|
||||||
#define VIDEO_PERMISSION_NAME "video-capture"
|
|
||||||
|
|
||||||
using namespace mozilla::dom;
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
static MediaPermissionManager *gMediaPermMgr = nullptr;
|
static MediaPermissionManager *gMediaPermMgr = nullptr;
|
||||||
|
|
||||||
static uint32_t
|
|
||||||
ConvertArrayToPermissionRequest(nsIArray* aSrcArray,
|
|
||||||
nsTArray<PermissionRequest>& aDesArray)
|
|
||||||
{
|
|
||||||
uint32_t len = 0;
|
|
||||||
aSrcArray->GetLength(&len);
|
|
||||||
for (uint32_t i = 0; i < len; i++) {
|
|
||||||
nsCOMPtr<nsIContentPermissionType> cpt = do_QueryElementAt(aSrcArray, i);
|
|
||||||
nsAutoCString type;
|
|
||||||
nsAutoCString access;
|
|
||||||
cpt->GetType(type);
|
|
||||||
cpt->GetAccess(access);
|
|
||||||
aDesArray.AppendElement(PermissionRequest(type, access));
|
|
||||||
}
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function for notifying permission granted
|
// Helper function for notifying permission granted
|
||||||
static nsresult
|
static nsresult
|
||||||
NotifyPermissionAllow(const nsAString &aCallID, nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices)
|
NotifyPermissionAllow(const nsAString &aCallID, nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices)
|
||||||
|
@ -115,7 +93,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mAudio; // Request for audio permission
|
bool mAudio; // Request for audio permission
|
||||||
bool mVideo; // Request for video permission
|
|
||||||
nsRefPtr<dom::GetUserMediaRequest> mRequest;
|
nsRefPtr<dom::GetUserMediaRequest> mRequest;
|
||||||
nsTArray<nsCOMPtr<nsIMediaDevice> > mDevices; // candiate device list
|
nsTArray<nsCOMPtr<nsIMediaDevice> > mDevices; // candiate device list
|
||||||
};
|
};
|
||||||
|
@ -131,7 +108,6 @@ MediaPermissionRequest::MediaPermissionRequest(nsRefPtr<dom::GetUserMediaRequest
|
||||||
mRequest->GetConstraints(constraints);
|
mRequest->GetConstraints(constraints);
|
||||||
|
|
||||||
mAudio = constraints.mAudio;
|
mAudio = constraints.mAudio;
|
||||||
mVideo = constraints.mVideo;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < aDevices.Length(); ++i) {
|
for (uint32_t i = 0; i < aDevices.Length(); ++i) {
|
||||||
nsCOMPtr<nsIMediaDevice> device(aDevices[i]);
|
nsCOMPtr<nsIMediaDevice> device(aDevices[i]);
|
||||||
|
@ -140,34 +116,10 @@ MediaPermissionRequest::MediaPermissionRequest(nsRefPtr<dom::GetUserMediaRequest
|
||||||
if (mAudio && deviceType.EqualsLiteral("audio")) {
|
if (mAudio && deviceType.EqualsLiteral("audio")) {
|
||||||
mDevices.AppendElement(device);
|
mDevices.AppendElement(device);
|
||||||
}
|
}
|
||||||
if (mVideo && deviceType.EqualsLiteral("video")) {
|
|
||||||
mDevices.AppendElement(device);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsIContentPermissionRequest methods
|
// nsIContentPermissionRequest methods
|
||||||
NS_IMETHODIMP
|
|
||||||
MediaPermissionRequest::GetTypes(nsIArray** aTypes)
|
|
||||||
{
|
|
||||||
nsCOMPtr<nsIMutableArray> types = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
|
||||||
if (mAudio) {
|
|
||||||
nsCOMPtr<ContentPermissionType> AudioType =
|
|
||||||
new ContentPermissionType(NS_LITERAL_CSTRING(AUDIO_PERMISSION_NAME),
|
|
||||||
NS_LITERAL_CSTRING("unused"));
|
|
||||||
types->AppendElement(AudioType, false);
|
|
||||||
}
|
|
||||||
if (mVideo) {
|
|
||||||
nsCOMPtr<ContentPermissionType> VideoType =
|
|
||||||
new ContentPermissionType(NS_LITERAL_CSTRING(VIDEO_PERMISSION_NAME),
|
|
||||||
NS_LITERAL_CSTRING("unused"));
|
|
||||||
types->AppendElement(VideoType, false);
|
|
||||||
}
|
|
||||||
NS_IF_ADDREF(*aTypes = types);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
MediaPermissionRequest::GetPrincipal(nsIPrincipal **aRequestingPrincipal)
|
MediaPermissionRequest::GetPrincipal(nsIPrincipal **aRequestingPrincipal)
|
||||||
{
|
{
|
||||||
|
@ -183,6 +135,24 @@ MediaPermissionRequest::GetPrincipal(nsIPrincipal **aRequestingPrincipal)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
MediaPermissionRequest::GetType(nsACString &aType)
|
||||||
|
{
|
||||||
|
if (mAudio) {
|
||||||
|
aType = AUDIO_PERMISSION_NAME;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
MediaPermissionRequest::GetAccess(nsACString &aAccess)
|
||||||
|
{
|
||||||
|
aAccess = "unused";
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
MediaPermissionRequest::GetWindow(nsIDOMWindow** aRequestingWindow)
|
MediaPermissionRequest::GetWindow(nsIDOMWindow** aRequestingWindow)
|
||||||
{
|
{
|
||||||
|
@ -308,12 +278,13 @@ MediaDeviceSuccessCallback::DoPrompt(nsRefPtr<MediaPermissionRequest> &req)
|
||||||
dom::TabChild* child = dom::TabChild::GetFrom(window->GetDocShell());
|
dom::TabChild* child = dom::TabChild::GetFrom(window->GetDocShell());
|
||||||
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
nsCOMPtr<nsIArray> typeArray;
|
nsAutoCString type;
|
||||||
rv = req->GetTypes(getter_AddRefs(typeArray));
|
rv = req->GetType(type);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsTArray<PermissionRequest> permArray;
|
nsAutoCString access;
|
||||||
ConvertArrayToPermissionRequest(typeArray, permArray);
|
rv = req->GetAccess(access);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> principal;
|
nsCOMPtr<nsIPrincipal> principal;
|
||||||
rv = req->GetPrincipal(getter_AddRefs(principal));
|
rv = req->GetPrincipal(getter_AddRefs(principal));
|
||||||
|
@ -321,7 +292,8 @@ MediaDeviceSuccessCallback::DoPrompt(nsRefPtr<MediaPermissionRequest> &req)
|
||||||
|
|
||||||
req->AddRef();
|
req->AddRef();
|
||||||
child->SendPContentPermissionRequestConstructor(req,
|
child->SendPContentPermissionRequestConstructor(req,
|
||||||
permArray,
|
type,
|
||||||
|
access,
|
||||||
IPC::Principal(principal));
|
IPC::Principal(principal));
|
||||||
|
|
||||||
req->Sendprompt();
|
req->Sendprompt();
|
||||||
|
|
|
@ -169,7 +169,11 @@ function expandPermissions(aPerms) {
|
||||||
aPerms.forEach(function(el) {
|
aPerms.forEach(function(el) {
|
||||||
var access = permTable[el].access ? "readwrite" : null;
|
var access = permTable[el].access ? "readwrite" : null;
|
||||||
var expanded = SpecialPowers.unwrap(expand(el, access));
|
var expanded = SpecialPowers.unwrap(expand(el, access));
|
||||||
perms = perms.concat(expanded.slice(0));
|
// COW arrays don't behave array-like enough, to allow
|
||||||
|
// using expanded.slice(0) here.
|
||||||
|
for (let i = 0; i < expanded.length; i++) {
|
||||||
|
perms.push(expanded[i]);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return perms;
|
return perms;
|
||||||
|
|
|
@ -386,11 +386,17 @@ nsGeolocationRequest::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsGeolocationRequest::GetTypes(nsIArray** aTypes)
|
nsGeolocationRequest::GetType(nsACString & aType)
|
||||||
{
|
{
|
||||||
return CreatePermissionArray(NS_LITERAL_CSTRING("geolocation"),
|
aType = "geolocation";
|
||||||
NS_LITERAL_CSTRING("unused"),
|
return NS_OK;
|
||||||
aTypes);
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsGeolocationRequest::GetAccess(nsACString & aAccess)
|
||||||
|
{
|
||||||
|
aAccess = "unused";
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
@ -1447,15 +1453,12 @@ Geolocation::RegisterRequestWithPrompt(nsGeolocationRequest* request)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsTArray<PermissionRequest> permArray;
|
|
||||||
permArray.AppendElement(PermissionRequest(NS_LITERAL_CSTRING("geolocation"),
|
|
||||||
NS_LITERAL_CSTRING("unused")));
|
|
||||||
|
|
||||||
// Retain a reference so the object isn't deleted without IPDL's knowledge.
|
// Retain a reference so the object isn't deleted without IPDL's knowledge.
|
||||||
// Corresponding release occurs in DeallocPContentPermissionRequest.
|
// Corresponding release occurs in DeallocPContentPermissionRequest.
|
||||||
request->AddRef();
|
request->AddRef();
|
||||||
child->SendPContentPermissionRequestConstructor(request,
|
child->SendPContentPermissionRequestConstructor(request,
|
||||||
permArray,
|
NS_LITERAL_CSTRING("geolocation"),
|
||||||
|
NS_LITERAL_CSTRING("unused"),
|
||||||
IPC::Principal(mPrincipal));
|
IPC::Principal(mPrincipal));
|
||||||
|
|
||||||
request->Sendprompt();
|
request->Sendprompt();
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "PCOMContentPermissionRequestChild.h"
|
#include "PCOMContentPermissionRequestChild.h"
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "PermissionMessageUtils.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -180,12 +179,9 @@ DesktopNotification::Init()
|
||||||
// Corresponding release occurs in DeallocPContentPermissionRequest.
|
// Corresponding release occurs in DeallocPContentPermissionRequest.
|
||||||
nsRefPtr<DesktopNotificationRequest> copy = request;
|
nsRefPtr<DesktopNotificationRequest> copy = request;
|
||||||
|
|
||||||
nsTArray<PermissionRequest> permArray;
|
|
||||||
permArray.AppendElement(PermissionRequest(
|
|
||||||
NS_LITERAL_CSTRING("desktop-notification"),
|
|
||||||
NS_LITERAL_CSTRING("unused")));
|
|
||||||
child->SendPContentPermissionRequestConstructor(copy.forget().get(),
|
child->SendPContentPermissionRequestConstructor(copy.forget().get(),
|
||||||
permArray,
|
NS_LITERAL_CSTRING("desktop-notification"),
|
||||||
|
NS_LITERAL_CSTRING("unused"),
|
||||||
IPC::Principal(mPrincipal));
|
IPC::Principal(mPrincipal));
|
||||||
|
|
||||||
request->Sendprompt();
|
request->Sendprompt();
|
||||||
|
@ -357,11 +353,17 @@ DesktopNotificationRequest::Allow()
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
DesktopNotificationRequest::GetTypes(nsIArray** aTypes)
|
DesktopNotificationRequest::GetType(nsACString & aType)
|
||||||
{
|
{
|
||||||
return CreatePermissionArray(NS_LITERAL_CSTRING("desktop-notification"),
|
aType = "desktop-notification";
|
||||||
NS_LITERAL_CSTRING("unused"),
|
return NS_OK;
|
||||||
aTypes);
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
DesktopNotificationRequest::GetAccess(nsACString & aAccess)
|
||||||
|
{
|
||||||
|
aAccess = "unused";
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "nsDOMJSUtils.h"
|
#include "nsDOMJSUtils.h"
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||||
#include "nsContentPermissionHelper.h"
|
|
||||||
#ifdef MOZ_B2G
|
#ifdef MOZ_B2G
|
||||||
#include "nsIDOMDesktopNotification.h"
|
#include "nsIDOMDesktopNotification.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -268,11 +267,9 @@ NotificationPermissionRequest::Run()
|
||||||
// Corresponding release occurs in DeallocPContentPermissionRequest.
|
// Corresponding release occurs in DeallocPContentPermissionRequest.
|
||||||
AddRef();
|
AddRef();
|
||||||
|
|
||||||
nsTArray<PermissionRequest> permArray;
|
NS_NAMED_LITERAL_CSTRING(type, "desktop-notification");
|
||||||
permArray.AppendElement(PermissionRequest(
|
NS_NAMED_LITERAL_CSTRING(access, "unused");
|
||||||
NS_LITERAL_CSTRING("desktop-notification"),
|
child->SendPContentPermissionRequestConstructor(this, type, access,
|
||||||
NS_LITERAL_CSTRING("unused")));
|
|
||||||
child->SendPContentPermissionRequestConstructor(this, permArray,
|
|
||||||
IPC::Principal(mPrincipal));
|
IPC::Principal(mPrincipal));
|
||||||
|
|
||||||
Sendprompt();
|
Sendprompt();
|
||||||
|
@ -345,11 +342,17 @@ NotificationPermissionRequest::CallCallback()
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
NotificationPermissionRequest::GetTypes(nsIArray** aTypes)
|
NotificationPermissionRequest::GetAccess(nsACString& aAccess)
|
||||||
{
|
{
|
||||||
return CreatePermissionArray(NS_LITERAL_CSTRING("desktop-notification"),
|
aAccess.AssignLiteral("unused");
|
||||||
NS_LITERAL_CSTRING("unused"),
|
return NS_OK;
|
||||||
aTypes);
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
NotificationPermissionRequest::GetType(nsACString& aType)
|
||||||
|
{
|
||||||
|
aType.AssignLiteral("desktop-notification");
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "jsfriendapi.h"
|
#include "jsfriendapi.h"
|
||||||
#include "mozilla/ArrayUtils.h"
|
#include "mozilla/ArrayUtils.h"
|
||||||
#include "mozilla/CycleCollectedJSRuntime.h"
|
#include "mozilla/CycleCollectedJSRuntime.h"
|
||||||
|
#include "mozilla/dom/asmjscache/AsmJSCache.h"
|
||||||
#include "mozilla/dom/AtomList.h"
|
#include "mozilla/dom/AtomList.h"
|
||||||
#include "mozilla/dom/BindingUtils.h"
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
#include "mozilla/dom/ErrorEventBinding.h"
|
#include "mozilla/dom/ErrorEventBinding.h"
|
||||||
|
@ -766,6 +767,53 @@ CTypesActivityCallback(JSContext* aCx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static nsIPrincipal*
|
||||||
|
GetPrincipalForAsmJSCacheOp()
|
||||||
|
{
|
||||||
|
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||||
|
if (!workerPrivate) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// asmjscache::OpenEntryForX guarnatee to only access the given nsIPrincipal
|
||||||
|
// from the main thread.
|
||||||
|
return workerPrivate->GetPrincipalDontAssertMainThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
AsmJSCacheOpenEntryForRead(JS::Handle<JSObject*> aGlobal,
|
||||||
|
const jschar* aBegin,
|
||||||
|
const jschar* aLimit,
|
||||||
|
size_t* aSize,
|
||||||
|
const uint8_t** aMemory,
|
||||||
|
intptr_t *aHandle)
|
||||||
|
{
|
||||||
|
nsIPrincipal* principal = GetPrincipalForAsmJSCacheOp();
|
||||||
|
if (!principal) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return asmjscache::OpenEntryForRead(principal, aBegin, aLimit, aSize, aMemory,
|
||||||
|
aHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
AsmJSCacheOpenEntryForWrite(JS::Handle<JSObject*> aGlobal,
|
||||||
|
const jschar* aBegin,
|
||||||
|
const jschar* aEnd,
|
||||||
|
size_t aSize,
|
||||||
|
uint8_t** aMemory,
|
||||||
|
intptr_t* aHandle)
|
||||||
|
{
|
||||||
|
nsIPrincipal* principal = GetPrincipalForAsmJSCacheOp();
|
||||||
|
if (!principal) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return asmjscache::OpenEntryForWrite(principal, aBegin, aEnd, aSize, aMemory,
|
||||||
|
aHandle);
|
||||||
|
}
|
||||||
|
|
||||||
struct WorkerThreadRuntimePrivate : public PerThreadAtomCache
|
struct WorkerThreadRuntimePrivate : public PerThreadAtomCache
|
||||||
{
|
{
|
||||||
WorkerPrivate* mWorkerPrivate;
|
WorkerPrivate* mWorkerPrivate;
|
||||||
|
@ -808,6 +856,16 @@ CreateJSContextForWorker(WorkerPrivate* aWorkerPrivate, JSRuntime* aRuntime)
|
||||||
};
|
};
|
||||||
SetDOMCallbacks(aRuntime, &DOMCallbacks);
|
SetDOMCallbacks(aRuntime, &DOMCallbacks);
|
||||||
|
|
||||||
|
// Set up the asm.js cache callbacks
|
||||||
|
static JS::AsmJSCacheOps asmJSCacheOps = {
|
||||||
|
AsmJSCacheOpenEntryForRead,
|
||||||
|
asmjscache::CloseEntryForRead,
|
||||||
|
AsmJSCacheOpenEntryForWrite,
|
||||||
|
asmjscache::CloseEntryForWrite,
|
||||||
|
asmjscache::GetBuildId
|
||||||
|
};
|
||||||
|
JS::SetAsmJSCacheOps(aRuntime, &asmJSCacheOps);
|
||||||
|
|
||||||
JSContext* workerCx = JS_NewContext(aRuntime, 0);
|
JSContext* workerCx = JS_NewContext(aRuntime, 0);
|
||||||
if (!workerCx) {
|
if (!workerCx) {
|
||||||
NS_WARNING("Could not create new context!");
|
NS_WARNING("Could not create new context!");
|
||||||
|
|
|
@ -94,7 +94,7 @@ using mozilla::AutoSafeJSContext;
|
||||||
USING_WORKERS_NAMESPACE
|
USING_WORKERS_NAMESPACE
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(JsWorkerMallocSizeOf)
|
MOZ_DEFINE_MALLOC_SIZE_OF(JsWorkerMallocSizeOf)
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -2006,8 +2006,10 @@ struct WorkerPrivate::TimeoutInfo
|
||||||
bool mCanceled;
|
bool mCanceled;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WorkerPrivate::MemoryReporter MOZ_FINAL : public MemoryMultiReporter
|
class WorkerPrivate::MemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
|
|
||||||
friend class WorkerPrivate;
|
friend class WorkerPrivate;
|
||||||
|
|
||||||
SharedMutex mMutex;
|
SharedMutex mMutex;
|
||||||
|
@ -2119,6 +2121,8 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(WorkerPrivate::MemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
template <class Derived>
|
template <class Derived>
|
||||||
WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
||||||
JSContext* aCx,
|
JSContext* aCx,
|
||||||
|
|
|
@ -600,6 +600,15 @@ public:
|
||||||
return mLoadInfo.mPrincipal;
|
return mLoadInfo.mPrincipal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This method allows the principal to be retrieved off the main thread.
|
||||||
|
// Principals are main-thread objects so the caller must ensure that all
|
||||||
|
// access occurs on the main thread.
|
||||||
|
nsIPrincipal*
|
||||||
|
GetPrincipalDontAssertMainThread() const
|
||||||
|
{
|
||||||
|
return mLoadInfo.mPrincipal;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
SetPrincipal(nsIPrincipal* aPrincipal);
|
SetPrincipal(nsIPrincipal* aPrincipal);
|
||||||
|
|
||||||
|
|
|
@ -60,4 +60,6 @@ LOCAL_INCLUDES += [
|
||||||
'/xpcom/build',
|
'/xpcom/build',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|
||||||
FINAL_LIBRARY = 'gklayout'
|
FINAL_LIBRARY = 'gklayout'
|
||||||
|
|
|
@ -431,7 +431,6 @@ public:
|
||||||
// XXX I expect we will want to move mWidget into this class and implement
|
// XXX I expect we will want to move mWidget into this class and implement
|
||||||
// these methods properly.
|
// these methods properly.
|
||||||
virtual nsIWidget* GetWidget() const { return nullptr; }
|
virtual nsIWidget* GetWidget() const { return nullptr; }
|
||||||
virtual const nsIntSize& GetWidgetSize() = 0;
|
|
||||||
|
|
||||||
// Call before and after any rendering not done by this compositor but which
|
// Call before and after any rendering not done by this compositor but which
|
||||||
// might affect the compositor's internal state or the state of any APIs it
|
// might affect the compositor's internal state or the state of any APIs it
|
||||||
|
|
|
@ -133,15 +133,6 @@ LayerManager::CreateDrawTarget(const IntSize &aSize,
|
||||||
CreateOffscreenCanvasDrawTarget(aSize, aFormat);
|
CreateOffscreenCanvasDrawTarget(aSize, aFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureFactoryIdentifier
|
|
||||||
LayerManager::GetTextureFactoryIdentifier()
|
|
||||||
{
|
|
||||||
//TODO[nrc] make pure virtual when all layer managers use Compositor
|
|
||||||
NS_ERROR("Should have been overridden");
|
|
||||||
return TextureFactoryIdentifier();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void
|
void
|
||||||
LayerManager::Mutated(Layer* aLayer)
|
LayerManager::Mutated(Layer* aLayer)
|
||||||
|
|
|
@ -437,12 +437,6 @@ public:
|
||||||
|
|
||||||
virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) { return true; }
|
virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) { return true; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a TextureFactoryIdentifier which describes properties of the backend
|
|
||||||
* used to decide what kind of texture and buffer clients to create
|
|
||||||
*/
|
|
||||||
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns the maximum texture size on this layer backend, or INT32_MAX
|
* returns the maximum texture size on this layer backend, or INT32_MAX
|
||||||
* if there is no maximum
|
* if there is no maximum
|
||||||
|
|
|
@ -220,7 +220,6 @@ CreateBasicDeprecatedTextureHost(SurfaceDescriptorType aDescriptorType,
|
||||||
|
|
||||||
BasicCompositor::BasicCompositor(nsIWidget *aWidget)
|
BasicCompositor::BasicCompositor(nsIWidget *aWidget)
|
||||||
: mWidget(aWidget)
|
: mWidget(aWidget)
|
||||||
, mWidgetSize(-1, -1)
|
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(BasicCompositor);
|
MOZ_COUNT_CTOR(BasicCompositor);
|
||||||
sBackend = LAYERS_BASIC;
|
sBackend = LAYERS_BASIC;
|
||||||
|
@ -540,7 +539,6 @@ BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
|
||||||
nsIntRect intRect;
|
nsIntRect intRect;
|
||||||
mWidget->GetClientBounds(intRect);
|
mWidget->GetClientBounds(intRect);
|
||||||
Rect rect = Rect(0, 0, intRect.width, intRect.height);
|
Rect rect = Rect(0, 0, intRect.width, intRect.height);
|
||||||
mWidgetSize = intRect.Size();
|
|
||||||
|
|
||||||
nsIntRect invalidRect = aInvalidRegion.GetBounds();
|
nsIntRect invalidRect = aInvalidRegion.GetBounds();
|
||||||
mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);
|
mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);
|
||||||
|
|
|
@ -119,10 +119,6 @@ public:
|
||||||
virtual const char* Name() const { return "Basic"; }
|
virtual const char* Name() const { return "Basic"; }
|
||||||
|
|
||||||
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
||||||
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
|
|
||||||
{
|
|
||||||
return mWidgetSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
gfx::DrawTarget *GetDrawTarget() { return mDrawTarget; }
|
gfx::DrawTarget *GetDrawTarget() { return mDrawTarget; }
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ public:
|
||||||
virtual already_AddRefed<ColorLayer> CreateColorLayer();
|
virtual already_AddRefed<ColorLayer> CreateColorLayer();
|
||||||
virtual already_AddRefed<RefLayer> CreateRefLayer();
|
virtual already_AddRefed<RefLayer> CreateRefLayer();
|
||||||
|
|
||||||
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE
|
TextureFactoryIdentifier GetTextureFactoryIdentifier()
|
||||||
{
|
{
|
||||||
return mForwarder->GetTextureFactoryIdentifier();
|
return mForwarder->GetTextureFactoryIdentifier();
|
||||||
}
|
}
|
||||||
|
|
|
@ -203,6 +203,7 @@ LayerManagerComposite::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||||
EndTransactionFlags aFlags)
|
EndTransactionFlags aFlags)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mInTransaction, "Didn't call BeginTransaction?");
|
NS_ASSERTION(mInTransaction, "Didn't call BeginTransaction?");
|
||||||
|
NS_ASSERTION(!aCallback && !aCallbackData, "Not expecting callbacks here");
|
||||||
mInTransaction = false;
|
mInTransaction = false;
|
||||||
|
|
||||||
if (!mIsCompositorReady) {
|
if (!mIsCompositorReady) {
|
||||||
|
@ -240,13 +241,7 @@ LayerManagerComposite::EndTransaction(DrawThebesLayerCallback aCallback,
|
||||||
// so we don't need to pass any global transform here.
|
// so we don't need to pass any global transform here.
|
||||||
mRoot->ComputeEffectiveTransforms(gfx3DMatrix());
|
mRoot->ComputeEffectiveTransforms(gfx3DMatrix());
|
||||||
|
|
||||||
mThebesLayerCallback = aCallback;
|
|
||||||
mThebesLayerCallbackData = aCallbackData;
|
|
||||||
|
|
||||||
Render();
|
Render();
|
||||||
|
|
||||||
mThebesLayerCallback = nullptr;
|
|
||||||
mThebesLayerCallbackData = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mCompositor->SetTargetContext(nullptr);
|
mCompositor->SetTargetContext(nullptr);
|
||||||
|
@ -307,7 +302,7 @@ LayerManagerComposite::RootLayer() const
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<LayerComposite*>(mRoot->ImplData());
|
return ToLayerComposite(mRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t sFrameCount = 0;
|
static uint16_t sFrameCount = 0;
|
||||||
|
@ -723,7 +718,7 @@ LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mCompositable = static_cast<LayerComposite*>(aMaskLayer->ImplData())->GetCompositableHost();
|
mCompositable = ToLayerComposite(aMaskLayer)->GetCompositableHost();
|
||||||
if (!mCompositable) {
|
if (!mCompositable) {
|
||||||
NS_WARNING("Mask layer with no compositable host");
|
NS_WARNING("Mask layer with no compositable host");
|
||||||
return;
|
return;
|
||||||
|
@ -786,25 +781,6 @@ LayerComposite::Destroy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsIntSize&
|
|
||||||
LayerManagerComposite::GetWidgetSize()
|
|
||||||
{
|
|
||||||
return mCompositor->GetWidgetSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerComposite::SetCompositorID(uint32_t aID)
|
|
||||||
{
|
|
||||||
NS_ASSERTION(mCompositor, "No compositor");
|
|
||||||
mCompositor->SetCompositorID(aID);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LayerManagerComposite::NotifyShadowTreeTransaction()
|
|
||||||
{
|
|
||||||
mCompositor->NotifyLayersTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LayerManagerComposite::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
|
LayerManagerComposite::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
|
||||||
{
|
{
|
||||||
|
@ -812,18 +788,6 @@ LayerManagerComposite::CanUseCanvasLayerForSize(const gfxIntSize &aSize)
|
||||||
aSize.height));
|
aSize.height));
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureFactoryIdentifier
|
|
||||||
LayerManagerComposite::GetTextureFactoryIdentifier()
|
|
||||||
{
|
|
||||||
return mCompositor->GetTextureFactoryIdentifier();
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t
|
|
||||||
LayerManagerComposite::GetMaxTextureSize() const
|
|
||||||
{
|
|
||||||
return mCompositor->GetMaxTextureSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
|
#ifndef MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
|
||||||
|
|
||||||
/*static*/ bool
|
/*static*/ bool
|
||||||
|
|
|
@ -110,8 +110,6 @@ public:
|
||||||
}
|
}
|
||||||
void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget);
|
void BeginTransactionWithDrawTarget(gfx::DrawTarget* aTarget);
|
||||||
|
|
||||||
void NotifyShadowTreeTransaction();
|
|
||||||
|
|
||||||
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) MOZ_OVERRIDE;
|
virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT) MOZ_OVERRIDE;
|
||||||
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
|
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
|
||||||
void* aCallbackData,
|
void* aCallbackData,
|
||||||
|
@ -119,11 +117,14 @@ public:
|
||||||
|
|
||||||
virtual void SetRoot(Layer* aLayer) MOZ_OVERRIDE { mRoot = aLayer; }
|
virtual void SetRoot(Layer* aLayer) MOZ_OVERRIDE { mRoot = aLayer; }
|
||||||
|
|
||||||
|
// XXX[nrc]: never called, we should move this logic to ClientLayerManager
|
||||||
|
// (bug 946926).
|
||||||
virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) MOZ_OVERRIDE;
|
virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() MOZ_OVERRIDE;
|
virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE
|
||||||
|
{
|
||||||
virtual int32_t GetMaxTextureSize() const MOZ_OVERRIDE;
|
MOZ_CRASH("Call on compositor, not LayerManagerComposite");
|
||||||
|
}
|
||||||
|
|
||||||
virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE;
|
virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
@ -141,24 +142,16 @@ public:
|
||||||
|
|
||||||
virtual LayersBackend GetBackendType() MOZ_OVERRIDE
|
virtual LayersBackend GetBackendType() MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
return LAYERS_NONE;
|
MOZ_CRASH("Shouldn't be called for composited layer manager");
|
||||||
}
|
}
|
||||||
virtual void GetBackendName(nsAString& name) MOZ_OVERRIDE
|
virtual void GetBackendName(nsAString& name) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(false, "Shouldn't be called for composited layer manager");
|
MOZ_CRASH("Shouldn't be called for composited layer manager");
|
||||||
name.AssignLiteral("Composite");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual already_AddRefed<gfxASurface>
|
virtual already_AddRefed<gfxASurface>
|
||||||
CreateOptimalMaskSurface(const gfxIntSize &aSize) MOZ_OVERRIDE;
|
CreateOptimalMaskSurface(const gfxIntSize &aSize) MOZ_OVERRIDE;
|
||||||
|
|
||||||
|
|
||||||
DrawThebesLayerCallback GetThebesLayerCallback() const
|
|
||||||
{ return mThebesLayerCallback; }
|
|
||||||
|
|
||||||
void* GetThebesLayerCallbackData() const
|
|
||||||
{ return mThebesLayerCallbackData; }
|
|
||||||
|
|
||||||
virtual const char* Name() const MOZ_OVERRIDE { return ""; }
|
virtual const char* Name() const MOZ_OVERRIDE { return ""; }
|
||||||
|
|
||||||
enum WorldTransforPolicy {
|
enum WorldTransforPolicy {
|
||||||
|
@ -195,11 +188,9 @@ public:
|
||||||
* layermanager.
|
* layermanager.
|
||||||
*/
|
*/
|
||||||
virtual TemporaryRef<mozilla::gfx::DrawTarget>
|
virtual TemporaryRef<mozilla::gfx::DrawTarget>
|
||||||
CreateDrawTarget(const mozilla::gfx::IntSize &aSize,
|
CreateDrawTarget(const mozilla::gfx::IntSize& aSize,
|
||||||
mozilla::gfx::SurfaceFormat aFormat) MOZ_OVERRIDE;
|
mozilla::gfx::SurfaceFormat aFormat) MOZ_OVERRIDE;
|
||||||
|
|
||||||
const nsIntSize& GetWidgetSize();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the 'completeness' of the rendering that intersected with the
|
* Calculates the 'completeness' of the rendering that intersected with the
|
||||||
* screen on the last render. This is only useful when progressive tile
|
* screen on the last render. This is only useful when progressive tile
|
||||||
|
@ -217,8 +208,6 @@ public:
|
||||||
|
|
||||||
static void PlatformSyncBeforeReplyUpdate();
|
static void PlatformSyncBeforeReplyUpdate();
|
||||||
|
|
||||||
void SetCompositorID(uint32_t aID);
|
|
||||||
|
|
||||||
void AddInvalidRegion(const nsIntRegion& aRegion)
|
void AddInvalidRegion(const nsIntRegion& aRegion)
|
||||||
{
|
{
|
||||||
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
mInvalidRegion.Or(mInvalidRegion, aRegion);
|
||||||
|
@ -245,7 +234,7 @@ private:
|
||||||
nsIntRect mRenderBounds;
|
nsIntRect mRenderBounds;
|
||||||
|
|
||||||
/** Current root layer. */
|
/** Current root layer. */
|
||||||
LayerComposite *RootLayer() const;
|
LayerComposite* RootLayer() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursive helper method for use by ComputeRenderIntegrity. Subtracts
|
* Recursive helper method for use by ComputeRenderIntegrity. Subtracts
|
||||||
|
@ -275,10 +264,6 @@ private:
|
||||||
/** Our more efficient but less powerful alter ego, if one is available. */
|
/** Our more efficient but less powerful alter ego, if one is available. */
|
||||||
nsRefPtr<Composer2D> mComposer2D;
|
nsRefPtr<Composer2D> mComposer2D;
|
||||||
|
|
||||||
/* Thebes layer callbacks; valid at the end of a transaciton,
|
|
||||||
* while rendering */
|
|
||||||
DrawThebesLayerCallback mThebesLayerCallback;
|
|
||||||
void *mThebesLayerCallbackData;
|
|
||||||
gfxMatrix mWorldMatrix;
|
gfxMatrix mWorldMatrix;
|
||||||
|
|
||||||
bool mInTransaction;
|
bool mInTransaction;
|
||||||
|
|
|
@ -549,6 +549,8 @@ MemoryTextureHost::MemoryTextureHost(uint64_t aID,
|
||||||
MemoryTextureHost::~MemoryTextureHost()
|
MemoryTextureHost::~MemoryTextureHost()
|
||||||
{
|
{
|
||||||
DeallocateDeviceData();
|
DeallocateDeviceData();
|
||||||
|
NS_ASSERTION(!mBuffer || (mFlags & TEXTURE_DEALLOCATE_CLIENT),
|
||||||
|
"Leaking our buffer");
|
||||||
MOZ_COUNT_DTOR(MemoryTextureHost);
|
MOZ_COUNT_DTOR(MemoryTextureHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,14 +139,6 @@ public:
|
||||||
virtual void NotifyLayersTransaction() MOZ_OVERRIDE { }
|
virtual void NotifyLayersTransaction() MOZ_OVERRIDE { }
|
||||||
|
|
||||||
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
||||||
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
|
|
||||||
{
|
|
||||||
NS_ASSERTION(false, "Getting the widget size on windows causes some kind of resizing of buffers. "
|
|
||||||
"You should not do that outside of BeginFrame, so the best we can do is return "
|
|
||||||
"the last size we got, that might not be up to date. So you probably shouldn't "
|
|
||||||
"use this method.");
|
|
||||||
return mSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D11Device* GetDevice() { return mDevice; }
|
ID3D11Device* GetDevice() { return mDevice; }
|
||||||
|
|
||||||
|
|
|
@ -86,14 +86,6 @@ public:
|
||||||
virtual void NotifyLayersTransaction() MOZ_OVERRIDE {}
|
virtual void NotifyLayersTransaction() MOZ_OVERRIDE {}
|
||||||
|
|
||||||
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
||||||
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE
|
|
||||||
{
|
|
||||||
NS_ASSERTION(false, "Getting the widget size on windows causes some kind of resizing of buffers. "
|
|
||||||
"You should not do that outside of BeginFrame, so the best we can do is return "
|
|
||||||
"the last size we got, that might not be up to date. So you probably shouldn't "
|
|
||||||
"use this method.");
|
|
||||||
return mSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDirect3DDevice9* device() const
|
IDirect3DDevice9* device() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* vim: set sw=2 ts=2 et tw=80 : */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#include "CompositorParent.h"
|
|
||||||
#include "CompositorCocoaWidgetHelper.h"
|
|
||||||
#include "nsDebug.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
namespace compositor {
|
|
||||||
|
|
||||||
LayerManagerComposite*
|
|
||||||
GetLayerManager(CompositorParent* aParent)
|
|
||||||
{
|
|
||||||
return aParent->GetLayerManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
||||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
#ifndef mozilla_layers_CompositorCocoaWidgetHelper_h
|
|
||||||
#define mozilla_layers_CompositorCocoaWidgetHelper_h
|
|
||||||
|
|
||||||
// Note we can't include IPDL-generated headers here, since this file is being
|
|
||||||
// used as a workaround for Bug 719036.
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace layers {
|
|
||||||
|
|
||||||
class CompositorParent;
|
|
||||||
class LayerManagerComposite;
|
|
||||||
|
|
||||||
namespace compositor {
|
|
||||||
|
|
||||||
// Needed when we cannot directly include CompositorParent.h since it includes
|
|
||||||
// an IPDL-generated header (e.g. in widget/cocoa/nsChildView.mm; see Bug 719036).
|
|
||||||
LayerManagerComposite* GetLayerManager(CompositorParent* aParent);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif // mozilla_layers_CompositorCocoaWidgetHelper_h
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ namespace layers {
|
||||||
|
|
||||||
CompositorParent::LayerTreeState::LayerTreeState()
|
CompositorParent::LayerTreeState::LayerTreeState()
|
||||||
: mParent(nullptr)
|
: mParent(nullptr)
|
||||||
|
, mLayerManager(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,6 +238,7 @@ CompositorParent::Destroy()
|
||||||
|
|
||||||
// Ensure that the layer manager is destructed on the compositor thread.
|
// Ensure that the layer manager is destructed on the compositor thread.
|
||||||
mLayerManager = nullptr;
|
mLayerManager = nullptr;
|
||||||
|
mCompositor = nullptr;
|
||||||
mCompositionManager = nullptr;
|
mCompositionManager = nullptr;
|
||||||
mApzcTreeManager->ClearTree();
|
mApzcTreeManager->ClearTree();
|
||||||
mApzcTreeManager = nullptr;
|
mApzcTreeManager = nullptr;
|
||||||
|
@ -263,10 +265,12 @@ CompositorParent::RecvWillStop()
|
||||||
LayerTreeState* lts = &it->second;
|
LayerTreeState* lts = &it->second;
|
||||||
if (lts->mParent == this) {
|
if (lts->mParent == this) {
|
||||||
mLayerManager->ClearCachedResources(lts->mRoot);
|
mLayerManager->ClearCachedResources(lts->mRoot);
|
||||||
|
lts->mLayerManager = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mLayerManager->Destroy();
|
mLayerManager->Destroy();
|
||||||
mLayerManager = nullptr;
|
mLayerManager = nullptr;
|
||||||
|
mCompositor = nullptr;
|
||||||
mCompositionManager = nullptr;
|
mCompositionManager = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +375,9 @@ CompositorParent::ActorDestroy(ActorDestroyReason why)
|
||||||
if (mLayerManager) {
|
if (mLayerManager) {
|
||||||
mLayerManager->Destroy();
|
mLayerManager->Destroy();
|
||||||
mLayerManager = nullptr;
|
mLayerManager = nullptr;
|
||||||
|
sIndirectLayerTrees[mRootLayerTreeID].mLayerManager = nullptr;
|
||||||
mCompositionManager = nullptr;
|
mCompositionManager = nullptr;
|
||||||
|
mCompositor = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,7 +400,7 @@ CompositorParent::PauseComposition()
|
||||||
if (!mPaused) {
|
if (!mPaused) {
|
||||||
mPaused = true;
|
mPaused = true;
|
||||||
|
|
||||||
mLayerManager->GetCompositor()->Pause();
|
mCompositor->Pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if anyone's waiting to make sure that composition really got paused, tell them
|
// if anyone's waiting to make sure that composition really got paused, tell them
|
||||||
|
@ -409,7 +415,7 @@ CompositorParent::ResumeComposition()
|
||||||
|
|
||||||
MonitorAutoLock lock(mResumeCompositionMonitor);
|
MonitorAutoLock lock(mResumeCompositionMonitor);
|
||||||
|
|
||||||
if (!mLayerManager->GetCompositor()->Resume()) {
|
if (!mCompositor->Resume()) {
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
// We can't get a surface. This could be because the activity changed between
|
// We can't get a surface. This could be because the activity changed between
|
||||||
// the time resume was scheduled and now.
|
// the time resume was scheduled and now.
|
||||||
|
@ -440,8 +446,8 @@ CompositorParent::SetEGLSurfaceSize(int width, int height)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(mUseExternalSurfaceSize, "Compositor created without UseExternalSurfaceSize provided");
|
NS_ASSERTION(mUseExternalSurfaceSize, "Compositor created without UseExternalSurfaceSize provided");
|
||||||
mEGLSurfaceSize.SizeTo(width, height);
|
mEGLSurfaceSize.SizeTo(width, height);
|
||||||
if (mLayerManager) {
|
if (mCompositor) {
|
||||||
mLayerManager->GetCompositor()->SetDestinationSurfaceSize(gfx::IntSize(mEGLSurfaceSize.width, mEGLSurfaceSize.height));
|
mCompositor->SetDestinationSurfaceSize(gfx::IntSize(mEGLSurfaceSize.width, mEGLSurfaceSize.height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -503,7 +509,7 @@ CompositorParent::NotifyShadowTreeTransaction(uint64_t aId, bool aIsFirstPaint)
|
||||||
AutoResolveRefLayers resolve(mCompositionManager);
|
AutoResolveRefLayers resolve(mCompositionManager);
|
||||||
mApzcTreeManager->UpdatePanZoomControllerTree(this, mLayerManager->GetRoot(), aIsFirstPaint, aId);
|
mApzcTreeManager->UpdatePanZoomControllerTree(this, mLayerManager->GetRoot(), aIsFirstPaint, aId);
|
||||||
|
|
||||||
mLayerManager->AsLayerManagerComposite()->NotifyShadowTreeTransaction();
|
mCompositor->NotifyLayersTransaction();
|
||||||
}
|
}
|
||||||
ScheduleComposition();
|
ScheduleComposition();
|
||||||
}
|
}
|
||||||
|
@ -697,7 +703,7 @@ CompositorParent::ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ScheduleComposition();
|
ScheduleComposition();
|
||||||
mLayerManager->NotifyShadowTreeTransaction();
|
mCompositor->NotifyLayersTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -706,34 +712,32 @@ CompositorParent::InitializeLayerManager(const nsTArray<LayersBackend>& aBackend
|
||||||
NS_ASSERTION(!mLayerManager, "Already initialised mLayerManager");
|
NS_ASSERTION(!mLayerManager, "Already initialised mLayerManager");
|
||||||
|
|
||||||
for (size_t i = 0; i < aBackendHints.Length(); ++i) {
|
for (size_t i = 0; i < aBackendHints.Length(); ++i) {
|
||||||
RefPtr<LayerManagerComposite> layerManager;
|
RefPtr<Compositor> compositor;
|
||||||
if (aBackendHints[i] == LAYERS_OPENGL) {
|
if (aBackendHints[i] == LAYERS_OPENGL) {
|
||||||
layerManager =
|
compositor = new CompositorOGL(mWidget,
|
||||||
new LayerManagerComposite(new CompositorOGL(mWidget,
|
mEGLSurfaceSize.width,
|
||||||
mEGLSurfaceSize.width,
|
mEGLSurfaceSize.height,
|
||||||
mEGLSurfaceSize.height,
|
mUseExternalSurfaceSize);
|
||||||
mUseExternalSurfaceSize));
|
|
||||||
} else if (aBackendHints[i] == LAYERS_BASIC) {
|
} else if (aBackendHints[i] == LAYERS_BASIC) {
|
||||||
layerManager =
|
compositor = new BasicCompositor(mWidget);
|
||||||
new LayerManagerComposite(new BasicCompositor(mWidget));
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
} else if (aBackendHints[i] == LAYERS_D3D11) {
|
} else if (aBackendHints[i] == LAYERS_D3D11) {
|
||||||
layerManager =
|
compositor = new CompositorD3D11(mWidget);
|
||||||
new LayerManagerComposite(new CompositorD3D11(mWidget));
|
|
||||||
} else if (aBackendHints[i] == LAYERS_D3D9) {
|
} else if (aBackendHints[i] == LAYERS_D3D9) {
|
||||||
layerManager =
|
compositor = new CompositorD3D9(this, mWidget);
|
||||||
new LayerManagerComposite(new CompositorD3D9(this, mWidget));
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!layerManager) {
|
MOZ_ASSERT(compositor, "Passed invalid backend hint");
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
layerManager->SetCompositorID(mCompositorID);
|
compositor->SetCompositorID(mCompositorID);
|
||||||
|
RefPtr<LayerManagerComposite> layerManager = new LayerManagerComposite(compositor);
|
||||||
|
|
||||||
if (layerManager->Initialize()) {
|
if (layerManager->Initialize()) {
|
||||||
mLayerManager = layerManager;
|
mLayerManager = layerManager;
|
||||||
|
MOZ_ASSERT(compositor);
|
||||||
|
mCompositor = compositor;
|
||||||
|
sIndirectLayerTrees[mRootLayerTreeID].mLayerManager = layerManager;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -765,7 +769,7 @@ CompositorParent::AllocPLayerTransactionParent(const nsTArray<LayersBackend>& aB
|
||||||
mCompositionManager = new AsyncCompositionManager(mLayerManager);
|
mCompositionManager = new AsyncCompositionManager(mLayerManager);
|
||||||
*aSuccess = true;
|
*aSuccess = true;
|
||||||
|
|
||||||
*aTextureFactoryIdentifier = mLayerManager->GetTextureFactoryIdentifier();
|
*aTextureFactoryIdentifier = mCompositor->GetTextureFactoryIdentifier();
|
||||||
LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0);
|
LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0);
|
||||||
p->AddIPDLReference();
|
p->AddIPDLReference();
|
||||||
return p;
|
return p;
|
||||||
|
@ -851,6 +855,7 @@ void
|
||||||
CompositorParent::NotifyChildCreated(uint64_t aChild)
|
CompositorParent::NotifyChildCreated(uint64_t aChild)
|
||||||
{
|
{
|
||||||
sIndirectLayerTrees[aChild].mParent = this;
|
sIndirectLayerTrees[aChild].mParent = this;
|
||||||
|
sIndirectLayerTrees[aChild].mLayerManager = mLayerManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ uint64_t
|
/*static*/ uint64_t
|
||||||
|
@ -921,6 +926,17 @@ CompositorParent::GetAPZCTreeManager(uint64_t aLayersId)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
CompositorParent::ComputeRenderIntegrity()
|
||||||
|
{
|
||||||
|
if (mLayerManager) {
|
||||||
|
return mLayerManager->ComputeRenderIntegrity();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class handles layer updates pushed directly from child
|
* This class handles layer updates pushed directly from child
|
||||||
* processes to the compositor thread. It's associated with a
|
* processes to the compositor thread. It's associated with a
|
||||||
|
@ -1071,9 +1087,9 @@ CrossProcessCompositorParent::AllocPLayerTransactionParent(const nsTArray<Layers
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aId != 0);
|
MOZ_ASSERT(aId != 0);
|
||||||
|
|
||||||
if (sIndirectLayerTrees[aId].mParent) {
|
if (sIndirectLayerTrees[aId].mLayerManager) {
|
||||||
LayerManagerComposite* lm = sIndirectLayerTrees[aId].mParent->GetLayerManager();
|
LayerManagerComposite* lm = sIndirectLayerTrees[aId].mLayerManager;
|
||||||
*aTextureFactoryIdentifier = lm->GetTextureFactoryIdentifier();
|
*aTextureFactoryIdentifier = lm->GetCompositor()->GetTextureFactoryIdentifier();
|
||||||
*aSuccess = true;
|
*aSuccess = true;
|
||||||
LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId);
|
LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId);
|
||||||
p->AddIPDLReference();
|
p->AddIPDLReference();
|
||||||
|
|
|
@ -47,6 +47,7 @@ namespace layers {
|
||||||
|
|
||||||
class APZCTreeManager;
|
class APZCTreeManager;
|
||||||
class AsyncCompositionManager;
|
class AsyncCompositionManager;
|
||||||
|
class Compositor;
|
||||||
class LayerManagerComposite;
|
class LayerManagerComposite;
|
||||||
class LayerTransactionParent;
|
class LayerTransactionParent;
|
||||||
|
|
||||||
|
@ -107,8 +108,6 @@ public:
|
||||||
void ForceIsFirstPaint();
|
void ForceIsFirstPaint();
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
LayerManagerComposite* GetLayerManager() { return mLayerManager; }
|
|
||||||
|
|
||||||
void NotifyChildCreated(uint64_t aChild);
|
void NotifyChildCreated(uint64_t aChild);
|
||||||
|
|
||||||
void AsyncRender();
|
void AsyncRender();
|
||||||
|
@ -203,6 +202,7 @@ public:
|
||||||
nsRefPtr<Layer> mRoot;
|
nsRefPtr<Layer> mRoot;
|
||||||
nsRefPtr<GeckoContentController> mController;
|
nsRefPtr<GeckoContentController> mController;
|
||||||
CompositorParent* mParent;
|
CompositorParent* mParent;
|
||||||
|
LayerManagerComposite* mLayerManager;
|
||||||
TargetConfig mTargetConfig;
|
TargetConfig mTargetConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -213,6 +213,8 @@ public:
|
||||||
*/
|
*/
|
||||||
static const LayerTreeState* GetIndirectShadowTree(uint64_t aId);
|
static const LayerTreeState* GetIndirectShadowTree(uint64_t aId);
|
||||||
|
|
||||||
|
float ComputeRenderIntegrity();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell all CompositorParents to update their last refresh to aTime and sample
|
* Tell all CompositorParents to update their last refresh to aTime and sample
|
||||||
* animations at this time stamp. If aIsTesting is true, the
|
* animations at this time stamp. If aIsTesting is true, the
|
||||||
|
@ -295,6 +297,7 @@ private:
|
||||||
bool CanComposite();
|
bool CanComposite();
|
||||||
|
|
||||||
nsRefPtr<LayerManagerComposite> mLayerManager;
|
nsRefPtr<LayerManagerComposite> mLayerManager;
|
||||||
|
nsRefPtr<Compositor> mCompositor;
|
||||||
RefPtr<AsyncCompositionManager> mCompositionManager;
|
RefPtr<AsyncCompositionManager> mCompositionManager;
|
||||||
nsIWidget* mWidget;
|
nsIWidget* mWidget;
|
||||||
CancelableTask *mCurrentCompositeTask;
|
CancelableTask *mCurrentCompositeTask;
|
||||||
|
|
|
@ -128,7 +128,6 @@ EXPORTS.mozilla.layers += [
|
||||||
'ipc/CompositableForwarder.h',
|
'ipc/CompositableForwarder.h',
|
||||||
'ipc/CompositableTransactionParent.h',
|
'ipc/CompositableTransactionParent.h',
|
||||||
'ipc/CompositorChild.h',
|
'ipc/CompositorChild.h',
|
||||||
'ipc/CompositorCocoaWidgetHelper.h',
|
|
||||||
'ipc/CompositorParent.h',
|
'ipc/CompositorParent.h',
|
||||||
'ipc/GeckoContentController.h',
|
'ipc/GeckoContentController.h',
|
||||||
'ipc/GestureEventListener.h',
|
'ipc/GestureEventListener.h',
|
||||||
|
@ -240,7 +239,6 @@ UNIFIED_SOURCES += [
|
||||||
'ipc/Axis.cpp',
|
'ipc/Axis.cpp',
|
||||||
'ipc/CompositableTransactionParent.cpp',
|
'ipc/CompositableTransactionParent.cpp',
|
||||||
'ipc/CompositorChild.cpp',
|
'ipc/CompositorChild.cpp',
|
||||||
'ipc/CompositorCocoaWidgetHelper.cpp',
|
|
||||||
'ipc/CompositorParent.cpp',
|
'ipc/CompositorParent.cpp',
|
||||||
'ipc/GestureEventListener.cpp',
|
'ipc/GestureEventListener.cpp',
|
||||||
'ipc/ImageBridgeChild.cpp',
|
'ipc/ImageBridgeChild.cpp',
|
||||||
|
|
|
@ -158,9 +158,6 @@ public:
|
||||||
virtual bool Resume() MOZ_OVERRIDE;
|
virtual bool Resume() MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
|
||||||
virtual const nsIntSize& GetWidgetSize() MOZ_OVERRIDE {
|
|
||||||
return mWidgetSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLContext* gl() const { return mGLContext; }
|
GLContext* gl() const { return mGLContext; }
|
||||||
ShaderProgramType GetFBOLayerProgramType() const {
|
ShaderProgramType GetFBOLayerProgramType() const {
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
#include "GLManager.h"
|
#include "GLManager.h"
|
||||||
#include "CompositorOGL.h" // for CompositorOGL
|
#include "CompositorOGL.h" // for CompositorOGL
|
||||||
#include "GLContext.h" // for GLContext
|
#include "GLContext.h" // for GLContext
|
||||||
#include "Layers.h" // for LayerManager
|
|
||||||
#include "mozilla/Assertions.h" // for MOZ_CRASH
|
#include "mozilla/Assertions.h" // for MOZ_CRASH
|
||||||
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
|
#include "mozilla/Attributes.h" // for MOZ_OVERRIDE
|
||||||
#include "mozilla/RefPtr.h" // for RefPtr
|
#include "mozilla/RefPtr.h" // for RefPtr
|
||||||
|
@ -15,7 +14,6 @@
|
||||||
#include "mozilla/layers/LayersTypes.h"
|
#include "mozilla/layers/LayersTypes.h"
|
||||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||||
#include "nsAutoPtr.h" // for nsRefPtr
|
#include "nsAutoPtr.h" // for nsRefPtr
|
||||||
#include "nsISupportsImpl.h" // for LayerManager::AddRef, etc
|
|
||||||
|
|
||||||
using namespace mozilla::gl;
|
using namespace mozilla::gl;
|
||||||
|
|
||||||
|
@ -49,21 +47,14 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
/* static */ GLManager*
|
/* static */ GLManager*
|
||||||
GLManager::CreateGLManager(LayerManager* aManager)
|
GLManager::CreateGLManager(LayerManagerComposite* aManager)
|
||||||
{
|
{
|
||||||
if (!aManager) {
|
if (aManager &&
|
||||||
return nullptr;
|
Compositor::GetBackend() == LAYERS_OPENGL) {
|
||||||
|
return new GLManagerCompositor(static_cast<CompositorOGL*>(
|
||||||
|
aManager->GetCompositor()));
|
||||||
}
|
}
|
||||||
if (aManager->GetBackendType() == LAYERS_NONE) {
|
return nullptr;
|
||||||
if (Compositor::GetBackend() == LAYERS_OPENGL) {
|
|
||||||
return new GLManagerCompositor(static_cast<CompositorOGL*>(
|
|
||||||
static_cast<LayerManagerComposite*>(aManager)->GetCompositor()));
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_CRASH("Cannot create GLManager for non-GL layer manager");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ class GLContext;
|
||||||
|
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
|
||||||
class LayerManager;
|
class LayerManagerComposite;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minimal interface to allow widgets to draw using OpenGL. Abstracts
|
* Minimal interface to allow widgets to draw using OpenGL. Abstracts
|
||||||
|
@ -26,7 +26,7 @@ class LayerManager;
|
||||||
class GLManager
|
class GLManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static GLManager* CreateGLManager(LayerManager* aManager);
|
static GLManager* CreateGLManager(LayerManagerComposite* aManager);
|
||||||
|
|
||||||
virtual ~GLManager() {}
|
virtual ~GLManager() {}
|
||||||
|
|
||||||
|
|
|
@ -256,8 +256,17 @@ private:
|
||||||
|
|
||||||
nsRegion& Copy (const nsRect& aRect)
|
nsRegion& Copy (const nsRect& aRect)
|
||||||
{
|
{
|
||||||
pixman_box32_t box = RectToBox(aRect);
|
// pixman needs to distinguish between an empty region and a region
|
||||||
pixman_region32_reset(&mImpl, &box);
|
// with one rect so that it can return a different number of rectangles.
|
||||||
|
// Empty rect: data = empty_box
|
||||||
|
// 1 rect: data = NULL
|
||||||
|
// >1 rect: data = rects
|
||||||
|
if (aRect.IsEmpty()) {
|
||||||
|
pixman_region32_clear(&mImpl);
|
||||||
|
} else {
|
||||||
|
pixman_box32_t box = RectToBox(aRect);
|
||||||
|
pixman_region32_reset(&mImpl, &box);
|
||||||
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -631,10 +631,10 @@ PR_STATIC_ASSERT(uint32_t(CAIRO_SURFACE_TYPE_SKIA) ==
|
||||||
|
|
||||||
static int64_t gSurfaceMemoryUsed[gfxSurfaceTypeMax] = { 0 };
|
static int64_t gSurfaceMemoryUsed[gfxSurfaceTypeMax] = { 0 };
|
||||||
|
|
||||||
class SurfaceMemoryReporter MOZ_FINAL : public MemoryMultiReporter
|
class SurfaceMemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SurfaceMemoryReporter() { }
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
|
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
|
||||||
nsISupports *aClosure)
|
nsISupports *aClosure)
|
||||||
|
@ -651,8 +651,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult rv = aCb->Callback(EmptyCString(), nsCString(path),
|
nsresult rv = aCb->Callback(EmptyCString(), nsCString(path),
|
||||||
nsIMemoryReporter::KIND_OTHER,
|
KIND_OTHER, UNITS_BYTES,
|
||||||
nsIMemoryReporter::UNITS_BYTES,
|
|
||||||
gSurfaceMemoryUsed[i],
|
gSurfaceMemoryUsed[i],
|
||||||
nsCString(desc), aClosure);
|
nsCString(desc), aClosure);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
@ -663,6 +662,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(SurfaceMemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
void
|
void
|
||||||
gfxASurface::RecordMemoryUsedForSurfaceType(gfxSurfaceType aType,
|
gfxASurface::RecordMemoryUsedForSurfaceType(gfxSurfaceType aType,
|
||||||
int32_t aBytes)
|
int32_t aBytes)
|
||||||
|
|
|
@ -1360,7 +1360,9 @@ gfxFontFamily::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
|
||||||
* shaped-word caches to free up memory.
|
* shaped-word caches to free up memory.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontCacheMallocSizeOf)
|
MOZ_DEFINE_MALLOC_SIZE_OF(FontCacheMallocSizeOf)
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(gfxFontCache::MemoryReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
gfxFontCache::MemoryReporter::CollectReports
|
gfxFontCache::MemoryReporter::CollectReports
|
||||||
|
|
|
@ -951,13 +951,11 @@ public:
|
||||||
FontCacheSizes* aSizes) const;
|
FontCacheSizes* aSizes) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class MemoryReporter MOZ_FINAL : public mozilla::MemoryMultiReporter
|
class MemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemoryReporter() {}
|
NS_DECL_ISUPPORTS
|
||||||
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback* aCb,
|
|
||||||
nsISupports* aClosure);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Observer for notifications that the font cache cares about
|
// Observer for notifications that the font cache cares about
|
||||||
|
|
|
@ -71,10 +71,9 @@ gfxFontListPrefObserver::Observe(nsISupports *aSubject,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf)
|
MOZ_DEFINE_MALLOC_SIZE_OF(FontListMallocSizeOf)
|
||||||
|
|
||||||
gfxPlatformFontList::MemoryReporter::MemoryReporter()
|
NS_IMPL_ISUPPORTS1(gfxPlatformFontList::MemoryReporter, nsIMemoryReporter)
|
||||||
{}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
gfxPlatformFontList::MemoryReporter::CollectReports
|
gfxPlatformFontList::MemoryReporter::CollectReports
|
||||||
|
@ -91,23 +90,20 @@ gfxPlatformFontList::MemoryReporter::CollectReports
|
||||||
|
|
||||||
aCb->Callback(EmptyCString(),
|
aCb->Callback(EmptyCString(),
|
||||||
NS_LITERAL_CSTRING("explicit/gfx/font-list"),
|
NS_LITERAL_CSTRING("explicit/gfx/font-list"),
|
||||||
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
KIND_HEAP, UNITS_BYTES, sizes.mFontListSize,
|
||||||
sizes.mFontListSize,
|
|
||||||
NS_LITERAL_CSTRING("Memory used to manage the list of font families and faces."),
|
NS_LITERAL_CSTRING("Memory used to manage the list of font families and faces."),
|
||||||
aClosure);
|
aClosure);
|
||||||
|
|
||||||
aCb->Callback(EmptyCString(),
|
aCb->Callback(EmptyCString(),
|
||||||
NS_LITERAL_CSTRING("explicit/gfx/font-charmaps"),
|
NS_LITERAL_CSTRING("explicit/gfx/font-charmaps"),
|
||||||
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
KIND_HEAP, UNITS_BYTES, sizes.mCharMapsSize,
|
||||||
sizes.mCharMapsSize,
|
|
||||||
NS_LITERAL_CSTRING("Memory used to record the character coverage of individual fonts."),
|
NS_LITERAL_CSTRING("Memory used to record the character coverage of individual fonts."),
|
||||||
aClosure);
|
aClosure);
|
||||||
|
|
||||||
if (sizes.mFontTableCacheSize) {
|
if (sizes.mFontTableCacheSize) {
|
||||||
aCb->Callback(EmptyCString(),
|
aCb->Callback(EmptyCString(),
|
||||||
NS_LITERAL_CSTRING("explicit/gfx/font-tables"),
|
NS_LITERAL_CSTRING("explicit/gfx/font-tables"),
|
||||||
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
KIND_HEAP, UNITS_BYTES, sizes.mFontTableCacheSize,
|
||||||
sizes.mFontTableCacheSize,
|
|
||||||
NS_LITERAL_CSTRING("Memory used for cached font metrics and layout tables."),
|
NS_LITERAL_CSTRING("Memory used for cached font metrics and layout tables."),
|
||||||
aClosure);
|
aClosure);
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,12 +178,11 @@ public:
|
||||||
void RemoveCmap(const gfxCharacterMap *aCharMap);
|
void RemoveCmap(const gfxCharacterMap *aCharMap);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class MemoryReporter MOZ_FINAL : public mozilla::MemoryMultiReporter
|
class MemoryReporter MOZ_FINAL : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemoryReporter();
|
NS_DECL_ISUPPORTS
|
||||||
NS_IMETHOD CollectReports(nsIMemoryReporterCallback *aCb,
|
NS_DECL_NSIMEMORYREPORTER
|
||||||
nsISupports *aClosure);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);
|
gfxPlatformFontList(bool aNeedFullnamePostscriptNames = true);
|
||||||
|
|
|
@ -3,10 +3,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
#define PANGO_ENABLE_BACKEND
|
#define PANGO_ENABLE_BACKEND
|
||||||
#define PANGO_ENABLE_ENGINE
|
#define PANGO_ENABLE_ENGINE
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "gfxPlatformGtk.h"
|
#include "gfxPlatformGtk.h"
|
||||||
#include "prenv.h"
|
#include "prenv.h"
|
||||||
|
@ -14,16 +12,10 @@
|
||||||
#include "nsUnicharUtils.h"
|
#include "nsUnicharUtils.h"
|
||||||
#include "nsUnicodeProperties.h"
|
#include "nsUnicodeProperties.h"
|
||||||
#include "gfxFontconfigUtils.h"
|
#include "gfxFontconfigUtils.h"
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
#include "gfxPangoFonts.h"
|
#include "gfxPangoFonts.h"
|
||||||
#include "gfxContext.h"
|
#include "gfxContext.h"
|
||||||
#include "gfxUserFontSet.h"
|
#include "gfxUserFontSet.h"
|
||||||
#include "gfxFT2FontBase.h"
|
#include "gfxFT2FontBase.h"
|
||||||
#else
|
|
||||||
#include <ft2build.h>
|
|
||||||
#include FT_FREETYPE_H
|
|
||||||
#include "gfxFT2Fonts.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
|
|
||||||
|
@ -56,16 +48,6 @@ using namespace mozilla::unicode;
|
||||||
|
|
||||||
gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nullptr;
|
gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nullptr;
|
||||||
|
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
|
|
||||||
typedef nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<gfxFontEntry> > > PrefFontTable;
|
|
||||||
static FontTable *gPlatformFonts = nullptr;
|
|
||||||
static FontTable *gPlatformFontAliases = nullptr;
|
|
||||||
static PrefFontTable *gPrefFonts = nullptr;
|
|
||||||
static gfxSparseBitSet *gCodepointsWithNoFonts = nullptr;
|
|
||||||
static FT_Library gPlatformFTLibrary = nullptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static cairo_user_data_key_t cairo_gdk_drawable_key;
|
static cairo_user_data_key_t cairo_gdk_drawable_key;
|
||||||
|
|
||||||
#ifdef MOZ_X11
|
#ifdef MOZ_X11
|
||||||
|
@ -80,17 +62,6 @@ gfxPlatformGtk::gfxPlatformGtk()
|
||||||
sUseXRender = mozilla::Preferences::GetBool("gfx.xrender.enabled");
|
sUseXRender = mozilla::Preferences::GetBool("gfx.xrender.enabled");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
FT_Init_FreeType(&gPlatformFTLibrary);
|
|
||||||
gPlatformFonts = new FontTable();
|
|
||||||
gPlatformFonts->Init(100);
|
|
||||||
gPlatformFontAliases = new FontTable();
|
|
||||||
gPlatformFontAliases->Init(100);
|
|
||||||
gPrefFonts = new PrefFontTable();
|
|
||||||
gPrefFonts->Init(100);
|
|
||||||
gCodepointsWithNoFonts = new gfxSparseBitSet();
|
|
||||||
UpdateFontList();
|
|
||||||
#endif
|
|
||||||
uint32_t canvasMask = (1 << BACKEND_CAIRO) | (1 << BACKEND_SKIA);
|
uint32_t canvasMask = (1 << BACKEND_CAIRO) | (1 << BACKEND_SKIA);
|
||||||
uint32_t contentMask = (1 << BACKEND_CAIRO) | (1 << BACKEND_SKIA);
|
uint32_t contentMask = (1 << BACKEND_CAIRO) | (1 << BACKEND_SKIA);
|
||||||
InitBackendPrefs(canvasMask, BACKEND_CAIRO,
|
InitBackendPrefs(canvasMask, BACKEND_CAIRO,
|
||||||
|
@ -102,28 +73,7 @@ gfxPlatformGtk::~gfxPlatformGtk()
|
||||||
gfxFontconfigUtils::Shutdown();
|
gfxFontconfigUtils::Shutdown();
|
||||||
sFontconfigUtils = nullptr;
|
sFontconfigUtils = nullptr;
|
||||||
|
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
gfxPangoFontGroup::Shutdown();
|
gfxPangoFontGroup::Shutdown();
|
||||||
#else
|
|
||||||
delete gPlatformFonts;
|
|
||||||
gPlatformFonts = nullptr;
|
|
||||||
delete gPlatformFontAliases;
|
|
||||||
gPlatformFontAliases = nullptr;
|
|
||||||
delete gPrefFonts;
|
|
||||||
gPrefFonts = nullptr;
|
|
||||||
delete gCodepointsWithNoFonts;
|
|
||||||
gCodepointsWithNoFonts = nullptr;
|
|
||||||
|
|
||||||
#ifdef NS_FREE_PERMANENT_DATA
|
|
||||||
// do cairo cleanup *before* closing down the FTLibrary,
|
|
||||||
// otherwise we'll crash when the gfxPlatform destructor
|
|
||||||
// calls it (bug 605009)
|
|
||||||
cairo_debug_reset_static_data();
|
|
||||||
|
|
||||||
FT_Done_FreeType(gPlatformFTLibrary);
|
|
||||||
gPlatformFTLibrary = nullptr;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// It would be nice to do this (although it might need to be after
|
// It would be nice to do this (although it might need to be after
|
||||||
|
@ -187,8 +137,6 @@ gfxPlatformGtk::CreateOffscreenSurface(const gfxIntSize& size,
|
||||||
return newSurface.forget();
|
return newSurface.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup,
|
gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup,
|
||||||
const nsACString& aGenericFamily,
|
const nsACString& aGenericFamily,
|
||||||
|
@ -270,188 +218,6 @@ gfxPlatformGtk::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup,
|
|
||||||
const nsACString& aGenericFamily,
|
|
||||||
nsTArray<nsString>& aListOfFonts)
|
|
||||||
{
|
|
||||||
return sFontconfigUtils->GetFontList(aLangGroup, aGenericFamily,
|
|
||||||
aListOfFonts);
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
gfxPlatformGtk::UpdateFontList()
|
|
||||||
{
|
|
||||||
FcPattern *pat = nullptr;
|
|
||||||
FcObjectSet *os = nullptr;
|
|
||||||
FcFontSet *fs = nullptr;
|
|
||||||
int32_t result = -1;
|
|
||||||
|
|
||||||
pat = FcPatternCreate();
|
|
||||||
os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_WEIGHT, FC_SLANT, FC_WIDTH, nullptr);
|
|
||||||
|
|
||||||
fs = FcFontList(nullptr, pat, os);
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < fs->nfont; i++) {
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//printf("Family: %s\n", str);
|
|
||||||
|
|
||||||
nsAutoString name(NS_ConvertUTF8toUTF16(nsDependentCString(str)).get());
|
|
||||||
nsAutoString key(name);
|
|
||||||
ToLowerCase(key);
|
|
||||||
nsRefPtr<FontFamily> ff;
|
|
||||||
if (!gPlatformFonts->Get(key, &ff)) {
|
|
||||||
ff = new FontFamily(name);
|
|
||||||
gPlatformFonts->Put(key, ff);
|
|
||||||
}
|
|
||||||
|
|
||||||
FontEntry *fe = new FontEntry(ff->Name());
|
|
||||||
ff->AddFontEntry(fe);
|
|
||||||
|
|
||||||
if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, (FcChar8 **) &str) == FcResultMatch) {
|
|
||||||
fe->mFilename = nsDependentCString(str);
|
|
||||||
//printf(" - file: %s\n", str);
|
|
||||||
}
|
|
||||||
|
|
||||||
int x;
|
|
||||||
if (FcPatternGetInteger(fs->fonts[i], FC_INDEX, 0, &x) == FcResultMatch) {
|
|
||||||
//printf(" - index: %d\n", x);
|
|
||||||
fe->mFTFontIndex = x;
|
|
||||||
} else {
|
|
||||||
fe->mFTFontIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
fe->mWeight = gfxFontconfigUtils::GetThebesWeight(fs->fonts[i]);
|
|
||||||
//printf(" - weight: %d\n", fe->mWeight);
|
|
||||||
|
|
||||||
fe->mItalic = false;
|
|
||||||
if (FcPatternGetInteger(fs->fonts[i], FC_SLANT, 0, &x) == FcResultMatch) {
|
|
||||||
switch (x) {
|
|
||||||
case FC_SLANT_ITALIC:
|
|
||||||
case FC_SLANT_OBLIQUE:
|
|
||||||
fe->mItalic = true;
|
|
||||||
}
|
|
||||||
//printf(" - slant: %d\n", x);
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (FcPatternGetInteger(fs->fonts[i], FC_WIDTH, 0, &x) == FcResultMatch)
|
|
||||||
//printf(" - width: %d\n", x);
|
|
||||||
// XXX deal with font-stretch stuff later
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pat)
|
|
||||||
FcPatternDestroy(pat);
|
|
||||||
if (os)
|
|
||||||
FcObjectSetDestroy(os);
|
|
||||||
if (fs)
|
|
||||||
FcFontSetDestroy(fs);
|
|
||||||
|
|
||||||
return sFontconfigUtils->UpdateFontList();
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
gfxPlatformGtk::ResolveFontName(const nsAString& aFontName,
|
|
||||||
FontResolverCallback aCallback,
|
|
||||||
void *aClosure,
|
|
||||||
bool& aAborted)
|
|
||||||
{
|
|
||||||
|
|
||||||
nsAutoString name(aFontName);
|
|
||||||
ToLowerCase(name);
|
|
||||||
|
|
||||||
nsRefPtr<FontFamily> ff;
|
|
||||||
if (gPlatformFonts->Get(name, &ff) ||
|
|
||||||
gPlatformFontAliases->Get(name, &ff)) {
|
|
||||||
aAborted = !(*aCallback)(ff->Name(), aClosure);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoCString utf8Name = NS_ConvertUTF16toUTF8(aFontName);
|
|
||||||
|
|
||||||
FcPattern *npat = FcPatternCreate();
|
|
||||||
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
|
|
||||||
FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, nullptr);
|
|
||||||
FcFontSet *nfs = FcFontList(nullptr, npat, nos);
|
|
||||||
|
|
||||||
for (int k = 0; k < nfs->nfont; k++) {
|
|
||||||
FcChar8 *str;
|
|
||||||
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
|
|
||||||
continue;
|
|
||||||
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
|
|
||||||
ToLowerCase(altName);
|
|
||||||
if (gPlatformFonts->Get(altName, &ff)) {
|
|
||||||
//printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
|
|
||||||
gPlatformFontAliases->Put(name, ff);
|
|
||||||
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
|
|
||||||
goto DONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FcPatternDestroy(npat);
|
|
||||||
FcObjectSetDestroy(nos);
|
|
||||||
FcFontSetDestroy(nfs);
|
|
||||||
|
|
||||||
{
|
|
||||||
npat = FcPatternCreate();
|
|
||||||
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
|
|
||||||
FcPatternDel(npat, FC_LANG);
|
|
||||||
FcConfigSubstitute(nullptr, npat, FcMatchPattern);
|
|
||||||
FcDefaultSubstitute(npat);
|
|
||||||
|
|
||||||
nos = FcObjectSetBuild(FC_FAMILY, nullptr);
|
|
||||||
nfs = FcFontList(nullptr, npat, nos);
|
|
||||||
|
|
||||||
FcResult fresult;
|
|
||||||
|
|
||||||
FcPattern *match = FcFontMatch(nullptr, npat, &fresult);
|
|
||||||
if (match)
|
|
||||||
FcFontSetAdd(nfs, match);
|
|
||||||
|
|
||||||
for (int k = 0; k < nfs->nfont; k++) {
|
|
||||||
FcChar8 *str;
|
|
||||||
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
|
|
||||||
continue;
|
|
||||||
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
|
|
||||||
ToLowerCase(altName);
|
|
||||||
if (gPlatformFonts->Get(altName, &ff)) {
|
|
||||||
//printf("Adding alias: %s -> %s\n", utf8Name.get(), str);
|
|
||||||
gPlatformFontAliases->Put(name, ff);
|
|
||||||
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
|
|
||||||
goto DONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DONE:
|
|
||||||
FcPatternDestroy(npat);
|
|
||||||
FcObjectSetDestroy(nos);
|
|
||||||
FcFontSetDestroy(nfs);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
gfxPlatformGtk::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
|
|
||||||
{
|
|
||||||
return sFontconfigUtils->GetStandardFamilyName(aFontName, aFamilyName);
|
|
||||||
}
|
|
||||||
|
|
||||||
gfxFontGroup *
|
|
||||||
gfxPlatformGtk::CreateFontGroup(const nsAString &aFamilies,
|
|
||||||
const gfxFontStyle *aStyle,
|
|
||||||
gfxUserFontSet *aUserFontSet)
|
|
||||||
{
|
|
||||||
return new gfxFT2FontGroup(aFamilies, aStyle, aUserFontSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int32_t sDPI = 0;
|
static int32_t sDPI = 0;
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
|
@ -637,90 +403,6 @@ gfxPlatformGtk::GetPlatformCMSOutputProfile()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
FT_Library
|
|
||||||
gfxPlatformGtk::GetFTLibrary()
|
|
||||||
{
|
|
||||||
return gPlatformFTLibrary;
|
|
||||||
}
|
|
||||||
|
|
||||||
FontFamily *
|
|
||||||
gfxPlatformGtk::FindFontFamily(const nsAString& aName)
|
|
||||||
{
|
|
||||||
nsAutoString name(aName);
|
|
||||||
ToLowerCase(name);
|
|
||||||
|
|
||||||
nsRefPtr<FontFamily> ff;
|
|
||||||
if (!gPlatformFonts->Get(name, &ff)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return ff.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
FontEntry *
|
|
||||||
gfxPlatformGtk::FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle)
|
|
||||||
{
|
|
||||||
nsRefPtr<FontFamily> ff = FindFontFamily(aName);
|
|
||||||
if (!ff)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return ff->FindFontEntry(aFontStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PLDHashOperator
|
|
||||||
FindFontForCharProc(nsStringHashKey::KeyType aKey,
|
|
||||||
nsRefPtr<FontFamily>& aFontFamily,
|
|
||||||
void* aUserArg)
|
|
||||||
{
|
|
||||||
GlobalFontMatch *data = (GlobalFontMatch*)aUserArg;
|
|
||||||
aFontFamily->FindFontForChar(data);
|
|
||||||
return PL_DHASH_NEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<gfxFont>
|
|
||||||
gfxPlatformGtk::FindFontForChar(uint32_t aCh, gfxFont *aFont)
|
|
||||||
{
|
|
||||||
if (!gPlatformFonts || !gCodepointsWithNoFonts)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// is codepoint with no matching font? return null immediately
|
|
||||||
if (gCodepointsWithNoFonts->test(aCh)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalFontMatch data(aCh, GetScriptCode(aCh),
|
|
||||||
(aFont ? aFont->GetStyle() : nullptr));
|
|
||||||
|
|
||||||
// find fonts that support the character
|
|
||||||
gPlatformFonts->Enumerate(FindFontForCharProc, &data);
|
|
||||||
|
|
||||||
if (data.mBestMatch) {
|
|
||||||
nsRefPtr<gfxFT2Font> font =
|
|
||||||
gfxFT2Font::GetOrMakeFont(static_cast<FontEntry*>(data.mBestMatch.get()),
|
|
||||||
aFont->GetStyle());
|
|
||||||
gfxFont* ret = font.forget().get();
|
|
||||||
return already_AddRefed<gfxFont>(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
// no match? add to set of non-matching codepoints
|
|
||||||
gCodepointsWithNoFonts->set(aCh);
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
gfxPlatformGtk::GetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList)
|
|
||||||
{
|
|
||||||
return gPrefFonts->Get(aKey, aFontEntryList);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gfxPlatformGtk::SetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList)
|
|
||||||
{
|
|
||||||
gPrefFonts->Put(aKey, aFontEntryList);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (MOZ_WIDGET_GTK == 2)
|
#if (MOZ_WIDGET_GTK == 2)
|
||||||
void
|
void
|
||||||
gfxPlatformGtk::SetGdkDrawable(cairo_surface_t *target,
|
gfxPlatformGtk::SetGdkDrawable(cairo_surface_t *target,
|
||||||
|
|
|
@ -17,11 +17,6 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class gfxFontconfigUtils;
|
class gfxFontconfigUtils;
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
class FontFamily;
|
|
||||||
class FontEntry;
|
|
||||||
typedef struct FT_LibraryRec_ *FT_Library;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class gfxPlatformGtk : public gfxPlatform {
|
class gfxPlatformGtk : public gfxPlatform {
|
||||||
public:
|
public:
|
||||||
|
@ -54,7 +49,6 @@ public:
|
||||||
const gfxFontStyle *aStyle,
|
const gfxFontStyle *aStyle,
|
||||||
gfxUserFontSet *aUserFontSet);
|
gfxUserFontSet *aUserFontSet);
|
||||||
|
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
/**
|
/**
|
||||||
* Look up a local platform font using the full font face name (needed to
|
* Look up a local platform font using the full font face name (needed to
|
||||||
* support @font-face src local() )
|
* support @font-face src local() )
|
||||||
|
@ -76,19 +70,6 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool IsFontFormatSupported(nsIURI *aFontURI,
|
virtual bool IsFontFormatSupported(nsIURI *aFontURI,
|
||||||
uint32_t aFormatFlags);
|
uint32_t aFormatFlags);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
FontFamily *FindFontFamily(const nsAString& aName);
|
|
||||||
FontEntry *FindFontEntry(const nsAString& aFamilyName, const gfxFontStyle& aFontStyle);
|
|
||||||
already_AddRefed<gfxFont> FindFontForChar(uint32_t aCh, gfxFont *aFont);
|
|
||||||
bool GetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList);
|
|
||||||
void SetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
FT_Library GetFTLibrary();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (MOZ_WIDGET_GTK == 2)
|
#if (MOZ_WIDGET_GTK == 2)
|
||||||
static void SetGdkDrawable(cairo_surface_t *target,
|
static void SetGdkDrawable(cairo_surface_t *target,
|
||||||
|
|
|
@ -27,13 +27,9 @@
|
||||||
#include "gfxQPainterSurface.h"
|
#include "gfxQPainterSurface.h"
|
||||||
#include "nsUnicodeProperties.h"
|
#include "nsUnicodeProperties.h"
|
||||||
|
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
#include "gfxPangoFonts.h"
|
#include "gfxPangoFonts.h"
|
||||||
#include "gfxContext.h"
|
#include "gfxContext.h"
|
||||||
#include "gfxUserFontSet.h"
|
#include "gfxUserFontSet.h"
|
||||||
#else
|
|
||||||
#include "gfxFT2Fonts.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "nsUnicharUtils.h"
|
#include "nsUnicharUtils.h"
|
||||||
|
|
||||||
|
@ -47,11 +43,6 @@
|
||||||
|
|
||||||
#include "qcms.h"
|
#include "qcms.h"
|
||||||
|
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
#include <ft2build.h>
|
|
||||||
#include FT_FREETYPE_H
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
@ -75,16 +66,6 @@ static void do_qt_pixmap_unref (void *data)
|
||||||
|
|
||||||
static gfxImageFormat sOffscreenFormat = gfxImageFormatRGB24;
|
static gfxImageFormat sOffscreenFormat = gfxImageFormatRGB24;
|
||||||
|
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
|
|
||||||
typedef nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<FontEntry> > > PrefFontTable;
|
|
||||||
static FontTable *gPlatformFonts = nullptr;
|
|
||||||
static FontTable *gPlatformFontAliases = nullptr;
|
|
||||||
static PrefFontTable *gPrefFonts = nullptr;
|
|
||||||
static gfxSparseBitSet *gCodepointsWithNoFonts = nullptr;
|
|
||||||
static FT_Library gPlatformFTLibrary = nullptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gfxQtPlatform::gfxQtPlatform()
|
gfxQtPlatform::gfxQtPlatform()
|
||||||
{
|
{
|
||||||
mPrefFonts.Init(50);
|
mPrefFonts.Init(50);
|
||||||
|
@ -92,20 +73,7 @@ gfxQtPlatform::gfxQtPlatform()
|
||||||
if (!sFontconfigUtils)
|
if (!sFontconfigUtils)
|
||||||
sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
|
sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
|
||||||
|
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
g_type_init();
|
g_type_init();
|
||||||
#else
|
|
||||||
FT_Init_FreeType(&gPlatformFTLibrary);
|
|
||||||
|
|
||||||
gPlatformFonts = new FontTable();
|
|
||||||
gPlatformFonts->Init(100);
|
|
||||||
gPlatformFontAliases = new FontTable();
|
|
||||||
gPlatformFontAliases->Init(100);
|
|
||||||
gPrefFonts = new PrefFontTable();
|
|
||||||
gPrefFonts->Init(100);
|
|
||||||
gCodepointsWithNoFonts = new gfxSparseBitSet();
|
|
||||||
UpdateFontList();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
// 0 - default gfxQPainterSurface
|
// 0 - default gfxQPainterSurface
|
||||||
|
@ -148,23 +116,7 @@ gfxQtPlatform::~gfxQtPlatform()
|
||||||
gfxFontconfigUtils::Shutdown();
|
gfxFontconfigUtils::Shutdown();
|
||||||
sFontconfigUtils = nullptr;
|
sFontconfigUtils = nullptr;
|
||||||
|
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
gfxPangoFontGroup::Shutdown();
|
gfxPangoFontGroup::Shutdown();
|
||||||
#else
|
|
||||||
delete gPlatformFonts;
|
|
||||||
gPlatformFonts = nullptr;
|
|
||||||
delete gPlatformFontAliases;
|
|
||||||
gPlatformFontAliases = nullptr;
|
|
||||||
delete gPrefFonts;
|
|
||||||
gPrefFonts = nullptr;
|
|
||||||
delete gCodepointsWithNoFonts;
|
|
||||||
gCodepointsWithNoFonts = nullptr;
|
|
||||||
|
|
||||||
cairo_debug_reset_static_data();
|
|
||||||
|
|
||||||
FT_Done_FreeType(gPlatformFTLibrary);
|
|
||||||
gPlatformFTLibrary = nullptr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// It would be nice to do this (although it might need to be after
|
// It would be nice to do this (although it might need to be after
|
||||||
|
@ -259,103 +211,6 @@ gfxQtPlatform::GetFontList(nsIAtom *aLangGroup,
|
||||||
nsresult
|
nsresult
|
||||||
gfxQtPlatform::UpdateFontList()
|
gfxQtPlatform::UpdateFontList()
|
||||||
{
|
{
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
FcPattern *pat = nullptr;
|
|
||||||
FcObjectSet *os = nullptr;
|
|
||||||
FcFontSet *fs = nullptr;
|
|
||||||
|
|
||||||
pat = FcPatternCreate();
|
|
||||||
os = FcObjectSetBuild(FC_FAMILY, FC_FILE, FC_INDEX, FC_WEIGHT, FC_SLANT, FC_WIDTH, nullptr);
|
|
||||||
|
|
||||||
fs = FcFontList(nullptr, pat, os);
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < fs->nfont; i++) {
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
nsAutoString name(NS_ConvertUTF8toUTF16(nsDependentCString(str)).get());
|
|
||||||
nsAutoString key(name);
|
|
||||||
ToLowerCase(key);
|
|
||||||
nsRefPtr<FontFamily> ff;
|
|
||||||
if (!gPlatformFonts->Get(key, &ff)) {
|
|
||||||
ff = new FontFamily(name);
|
|
||||||
gPlatformFonts->Put(key, ff);
|
|
||||||
}
|
|
||||||
|
|
||||||
FontEntry *fe = new FontEntry(ff->Name());
|
|
||||||
ff->AddFontEntry(fe);
|
|
||||||
|
|
||||||
if (FcPatternGetString(fs->fonts[i], FC_FILE, 0, (FcChar8 **) &str) == FcResultMatch) {
|
|
||||||
fe->mFilename = nsDependentCString(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
int x;
|
|
||||||
if (FcPatternGetInteger(fs->fonts[i], FC_INDEX, 0, &x) == FcResultMatch) {
|
|
||||||
fe->mFTFontIndex = x;
|
|
||||||
} else {
|
|
||||||
fe->mFTFontIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FcPatternGetInteger(fs->fonts[i], FC_WEIGHT, 0, &x) == FcResultMatch) {
|
|
||||||
switch(x) {
|
|
||||||
case 0:
|
|
||||||
fe->mWeight = 100;
|
|
||||||
break;
|
|
||||||
case 40:
|
|
||||||
fe->mWeight = 200;
|
|
||||||
break;
|
|
||||||
case 50:
|
|
||||||
fe->mWeight = 300;
|
|
||||||
break;
|
|
||||||
case 75:
|
|
||||||
case 80:
|
|
||||||
fe->mWeight = 400;
|
|
||||||
break;
|
|
||||||
case 100:
|
|
||||||
fe->mWeight = 500;
|
|
||||||
break;
|
|
||||||
case 180:
|
|
||||||
fe->mWeight = 600;
|
|
||||||
break;
|
|
||||||
case 200:
|
|
||||||
fe->mWeight = 700;
|
|
||||||
break;
|
|
||||||
case 205:
|
|
||||||
fe->mWeight = 800;
|
|
||||||
break;
|
|
||||||
case 210:
|
|
||||||
fe->mWeight = 900;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// rough estimate
|
|
||||||
fe->mWeight = (((x * 4) + 100) / 100) * 100;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fe->mItalic = false;
|
|
||||||
if (FcPatternGetInteger(fs->fonts[i], FC_SLANT, 0, &x) == FcResultMatch) {
|
|
||||||
switch (x) {
|
|
||||||
case FC_SLANT_ITALIC:
|
|
||||||
case FC_SLANT_OBLIQUE:
|
|
||||||
fe->mItalic = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX deal with font-stretch (FC_WIDTH) stuff later
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pat)
|
|
||||||
FcPatternDestroy(pat);
|
|
||||||
if (os)
|
|
||||||
FcObjectSetDestroy(os);
|
|
||||||
if (fs)
|
|
||||||
FcFontSetDestroy(fs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return sFontconfigUtils->UpdateFontList();
|
return sFontconfigUtils->UpdateFontList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,80 +220,8 @@ gfxQtPlatform::ResolveFontName(const nsAString& aFontName,
|
||||||
void *aClosure,
|
void *aClosure,
|
||||||
bool& aAborted)
|
bool& aAborted)
|
||||||
{
|
{
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
return sFontconfigUtils->ResolveFontName(aFontName, aCallback,
|
return sFontconfigUtils->ResolveFontName(aFontName, aCallback,
|
||||||
aClosure, aAborted);
|
aClosure, aAborted);
|
||||||
#else
|
|
||||||
nsAutoString name(aFontName);
|
|
||||||
ToLowerCase(name);
|
|
||||||
|
|
||||||
nsRefPtr<FontFamily> ff;
|
|
||||||
if (gPlatformFonts->Get(name, &ff) ||
|
|
||||||
gPlatformFontAliases->Get(name, &ff)) {
|
|
||||||
aAborted = !(*aCallback)(ff->Name(), aClosure);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoCString utf8Name = NS_ConvertUTF16toUTF8(aFontName);
|
|
||||||
|
|
||||||
FcPattern *npat = FcPatternCreate();
|
|
||||||
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
|
|
||||||
FcObjectSet *nos = FcObjectSetBuild(FC_FAMILY, nullptr);
|
|
||||||
FcFontSet *nfs = FcFontList(nullptr, npat, nos);
|
|
||||||
|
|
||||||
for (int k = 0; k < nfs->nfont; k++) {
|
|
||||||
FcChar8 *str;
|
|
||||||
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
|
|
||||||
continue;
|
|
||||||
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
|
|
||||||
ToLowerCase(altName);
|
|
||||||
if (gPlatformFonts->Get(altName, &ff)) {
|
|
||||||
gPlatformFontAliases->Put(name, ff);
|
|
||||||
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
|
|
||||||
goto DONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FcPatternDestroy(npat);
|
|
||||||
FcObjectSetDestroy(nos);
|
|
||||||
FcFontSetDestroy(nfs);
|
|
||||||
|
|
||||||
{
|
|
||||||
npat = FcPatternCreate();
|
|
||||||
FcPatternAddString(npat, FC_FAMILY, (FcChar8*)utf8Name.get());
|
|
||||||
FcPatternDel(npat, FC_LANG);
|
|
||||||
FcConfigSubstitute(nullptr, npat, FcMatchPattern);
|
|
||||||
FcDefaultSubstitute(npat);
|
|
||||||
|
|
||||||
nos = FcObjectSetBuild(FC_FAMILY, nullptr);
|
|
||||||
nfs = FcFontList(nullptr, npat, nos);
|
|
||||||
|
|
||||||
FcResult fresult;
|
|
||||||
|
|
||||||
FcPattern *match = FcFontMatch(nullptr, npat, &fresult);
|
|
||||||
if (match)
|
|
||||||
FcFontSetAdd(nfs, match);
|
|
||||||
|
|
||||||
for (int k = 0; k < nfs->nfont; k++) {
|
|
||||||
FcChar8 *str;
|
|
||||||
if (FcPatternGetString(nfs->fonts[k], FC_FAMILY, 0, (FcChar8 **) &str) != FcResultMatch)
|
|
||||||
continue;
|
|
||||||
nsAutoString altName = NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str)));
|
|
||||||
ToLowerCase(altName);
|
|
||||||
if (gPlatformFonts->Get(altName, &ff)) {
|
|
||||||
gPlatformFontAliases->Put(name, ff);
|
|
||||||
aAborted = !(*aCallback)(NS_ConvertUTF8toUTF16(nsDependentCString(reinterpret_cast<char*>(str))), aClosure);
|
|
||||||
goto DONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DONE:
|
|
||||||
FcPatternDestroy(npat);
|
|
||||||
FcObjectSetDestroy(nos);
|
|
||||||
FcFontSetDestroy(nfs);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -452,14 +235,9 @@ gfxQtPlatform::CreateFontGroup(const nsAString &aFamilies,
|
||||||
const gfxFontStyle *aStyle,
|
const gfxFontStyle *aStyle,
|
||||||
gfxUserFontSet* aUserFontSet)
|
gfxUserFontSet* aUserFontSet)
|
||||||
{
|
{
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
return new gfxPangoFontGroup(aFamilies, aStyle, aUserFontSet);
|
return new gfxPangoFontGroup(aFamilies, aStyle, aUserFontSet);
|
||||||
#else
|
|
||||||
return new gfxFT2FontGroup(aFamilies, aStyle, aUserFontSet);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
gfxFontEntry*
|
gfxFontEntry*
|
||||||
gfxQtPlatform::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
gfxQtPlatform::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
|
||||||
const nsAString& aFontName)
|
const nsAString& aFontName)
|
||||||
|
@ -501,7 +279,6 @@ gfxQtPlatform::IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags)
|
||||||
// no format hint set, need to look at data
|
// no format hint set, need to look at data
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
qcms_profile*
|
qcms_profile*
|
||||||
gfxQtPlatform::GetPlatformCMSOutputProfile()
|
gfxQtPlatform::GetPlatformCMSOutputProfile()
|
||||||
|
@ -509,91 +286,6 @@ gfxQtPlatform::GetPlatformCMSOutputProfile()
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
FT_Library
|
|
||||||
gfxQtPlatform::GetFTLibrary()
|
|
||||||
{
|
|
||||||
return gPlatformFTLibrary;
|
|
||||||
}
|
|
||||||
|
|
||||||
FontFamily *
|
|
||||||
gfxQtPlatform::FindFontFamily(const nsAString& aName)
|
|
||||||
{
|
|
||||||
nsAutoString name(aName);
|
|
||||||
ToLowerCase(name);
|
|
||||||
|
|
||||||
nsRefPtr<FontFamily> ff;
|
|
||||||
if (!gPlatformFonts->Get(name, &ff)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return ff.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
FontEntry *
|
|
||||||
gfxQtPlatform::FindFontEntry(const nsAString& aName, const gfxFontStyle& aFontStyle)
|
|
||||||
{
|
|
||||||
nsRefPtr<FontFamily> ff = FindFontFamily(aName);
|
|
||||||
if (!ff)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
return ff->FindFontEntry(aFontStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PLDHashOperator
|
|
||||||
FindFontForCharProc(nsStringHashKey::KeyType aKey,
|
|
||||||
nsRefPtr<FontFamily>& aFontFamily,
|
|
||||||
void* aUserArg)
|
|
||||||
{
|
|
||||||
GlobalFontMatch *data = (GlobalFontMatch*)aUserArg;
|
|
||||||
aFontFamily->FindFontForChar(data);
|
|
||||||
return PL_DHASH_NEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
already_AddRefed<gfxFont>
|
|
||||||
gfxQtPlatform::FindFontForChar(uint32_t aCh, gfxFont *aFont)
|
|
||||||
{
|
|
||||||
if (!gPlatformFonts || !gCodepointsWithNoFonts)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
// is codepoint with no matching font? return null immediately
|
|
||||||
if (gCodepointsWithNoFonts->test(aCh)) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
GlobalFontMatch data(aCh, GetScriptCode(aCh),
|
|
||||||
(aFont ? aFont->GetStyle() : nullptr));
|
|
||||||
|
|
||||||
// find fonts that support the character
|
|
||||||
gPlatformFonts->Enumerate(FindFontForCharProc, &data);
|
|
||||||
|
|
||||||
if (data.mBestMatch) {
|
|
||||||
nsRefPtr<gfxFT2Font> font =
|
|
||||||
gfxFT2Font::GetOrMakeFont(static_cast<FontEntry*>(data.mBestMatch.get()),
|
|
||||||
aFont->GetStyle());
|
|
||||||
gfxFont* ret = font.forget().get();
|
|
||||||
return already_AddRefed<gfxFont>(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
// no match? add to set of non-matching codepoints
|
|
||||||
gCodepointsWithNoFonts->set(aCh);
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
gfxQtPlatform::GetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> > *array)
|
|
||||||
{
|
|
||||||
return mPrefFonts.Get(aKey, array);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gfxQtPlatform::SetPrefFontEntries(const nsCString& aKey, nsTArray<nsRefPtr<gfxFontEntry> >& array)
|
|
||||||
{
|
|
||||||
mPrefFonts.Put(aKey, array);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
gfxQtPlatform::GetDPI()
|
gfxQtPlatform::GetDPI()
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,12 +16,6 @@
|
||||||
|
|
||||||
class gfxFontconfigUtils;
|
class gfxFontconfigUtils;
|
||||||
class QWidget;
|
class QWidget;
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
typedef struct FT_LibraryRec_ *FT_Library;
|
|
||||||
|
|
||||||
class FontFamily;
|
|
||||||
class FontEntry;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class gfxQtPlatform : public gfxPlatform {
|
class gfxQtPlatform : public gfxPlatform {
|
||||||
public:
|
public:
|
||||||
|
@ -63,7 +57,6 @@ public:
|
||||||
const gfxFontStyle *aStyle,
|
const gfxFontStyle *aStyle,
|
||||||
gfxUserFontSet* aUserFontSet);
|
gfxUserFontSet* aUserFontSet);
|
||||||
|
|
||||||
#ifdef MOZ_PANGO
|
|
||||||
/**
|
/**
|
||||||
* Look up a local platform font using the full font face name (needed to
|
* Look up a local platform font using the full font face name (needed to
|
||||||
* support @font-face src local() )
|
* support @font-face src local() )
|
||||||
|
@ -85,22 +78,9 @@ public:
|
||||||
*/
|
*/
|
||||||
virtual bool IsFontFormatSupported(nsIURI *aFontURI,
|
virtual bool IsFontFormatSupported(nsIURI *aFontURI,
|
||||||
uint32_t aFormatFlags);
|
uint32_t aFormatFlags);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
FontFamily *FindFontFamily(const nsAString& aName);
|
|
||||||
FontEntry *FindFontEntry(const nsAString& aFamilyName, const gfxFontStyle& aFontStyle);
|
|
||||||
already_AddRefed<gfxFont> FindFontForChar(uint32_t aCh, gfxFont *aFont);
|
|
||||||
bool GetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> > *aFontEntryList);
|
|
||||||
void SetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<gfxFontEntry> >& aFontEntryList);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ClearPrefFonts() { mPrefFonts.Clear(); }
|
void ClearPrefFonts() { mPrefFonts.Clear(); }
|
||||||
|
|
||||||
#ifndef MOZ_PANGO
|
|
||||||
FT_Library GetFTLibrary();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
RenderMode GetRenderMode() { return mRenderMode; }
|
RenderMode GetRenderMode() { return mRenderMode; }
|
||||||
void SetRenderMode(RenderMode rmode) { mRenderMode = rmode; }
|
void SetRenderMode(RenderMode rmode) { mRenderMode = rmode; }
|
||||||
|
|
||||||
|
|
|
@ -209,7 +209,7 @@ typedef HRESULT (WINAPI*D3D11CreateDeviceFunc)(
|
||||||
ID3D11DeviceContext *ppImmediateContext
|
ID3D11DeviceContext *ppImmediateContext
|
||||||
);
|
);
|
||||||
|
|
||||||
class GPUAdapterReporter : public MemoryMultiReporter
|
class GPUAdapterReporter : public nsIMemoryReporter
|
||||||
{
|
{
|
||||||
// Callers must Release the DXGIAdapter after use or risk mem-leak
|
// Callers must Release the DXGIAdapter after use or risk mem-leak
|
||||||
static bool GetDXGIAdapter(IDXGIAdapter **DXGIAdapter)
|
static bool GetDXGIAdapter(IDXGIAdapter **DXGIAdapter)
|
||||||
|
@ -229,7 +229,7 @@ class GPUAdapterReporter : public MemoryMultiReporter
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GPUAdapterReporter() {}
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
NS_IMETHOD
|
NS_IMETHOD
|
||||||
CollectReports(nsIMemoryReporterCallback* aCb,
|
CollectReports(nsIMemoryReporterCallback* aCb,
|
||||||
|
@ -339,6 +339,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(GPUAdapterReporter, nsIMemoryReporter)
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
BuildKeyNameFromFontName(nsAString &aName)
|
BuildKeyNameFromFontName(nsAString &aName)
|
||||||
{
|
{
|
||||||
|
|
|
@ -103,6 +103,7 @@ elif CONFIG['MOZ_WIDGET_GTK']:
|
||||||
EXPORTS += [
|
EXPORTS += [
|
||||||
'gfxFT2FontBase.h',
|
'gfxFT2FontBase.h',
|
||||||
'gfxGdkNativeRenderer.h',
|
'gfxGdkNativeRenderer.h',
|
||||||
|
'gfxPangoFonts.h',
|
||||||
'gfxPDFSurface.h',
|
'gfxPDFSurface.h',
|
||||||
'gfxPlatformGtk.h',
|
'gfxPlatformGtk.h',
|
||||||
'gfxPSSurface.h',
|
'gfxPSSurface.h',
|
||||||
|
@ -113,6 +114,7 @@ elif CONFIG['MOZ_WIDGET_GTK']:
|
||||||
'gfxFT2FontBase.cpp',
|
'gfxFT2FontBase.cpp',
|
||||||
'gfxFT2Utils.cpp',
|
'gfxFT2Utils.cpp',
|
||||||
'gfxGdkNativeRenderer.cpp',
|
'gfxGdkNativeRenderer.cpp',
|
||||||
|
'gfxPangoFonts.cpp',
|
||||||
'gfxPDFSurface.cpp',
|
'gfxPDFSurface.cpp',
|
||||||
'gfxPlatformGtk.cpp',
|
'gfxPlatformGtk.cpp',
|
||||||
'gfxPSSurface.cpp',
|
'gfxPSSurface.cpp',
|
||||||
|
@ -129,16 +131,6 @@ elif CONFIG['MOZ_WIDGET_GTK']:
|
||||||
'gfxXlibSurface.cpp',
|
'gfxXlibSurface.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG['MOZ_PANGO']:
|
|
||||||
EXPORTS += ['gfxPangoFonts.h']
|
|
||||||
SOURCES += [
|
|
||||||
'gfxPangoFonts.cpp',
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
EXPORTS += ['gfxFT2Fonts.h']
|
|
||||||
SOURCES += [
|
|
||||||
'gfxPangoFonts.cpp',
|
|
||||||
]
|
|
||||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'os2':
|
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'os2':
|
||||||
EXPORTS += [
|
EXPORTS += [
|
||||||
'gfxOS2Fonts.h',
|
'gfxOS2Fonts.h',
|
||||||
|
@ -157,6 +149,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'os2':
|
||||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
|
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
|
||||||
EXPORTS += [
|
EXPORTS += [
|
||||||
'gfxFT2FontBase.h',
|
'gfxFT2FontBase.h',
|
||||||
|
'gfxPangoFonts.h',
|
||||||
'gfxPDFSurface.h',
|
'gfxPDFSurface.h',
|
||||||
'gfxQPainterSurface.h',
|
'gfxQPainterSurface.h',
|
||||||
'gfxQtNativeRenderer.h',
|
'gfxQtNativeRenderer.h',
|
||||||
|
@ -166,6 +159,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
|
||||||
'gfxFontconfigUtils.cpp',
|
'gfxFontconfigUtils.cpp',
|
||||||
'gfxFT2FontBase.cpp',
|
'gfxFT2FontBase.cpp',
|
||||||
'gfxFT2Utils.cpp',
|
'gfxFT2Utils.cpp',
|
||||||
|
'gfxPangoFonts.cpp',
|
||||||
'gfxPDFSurface.cpp',
|
'gfxPDFSurface.cpp',
|
||||||
'gfxQPainterSurface.cpp',
|
'gfxQPainterSurface.cpp',
|
||||||
'gfxQtPlatform.cpp',
|
'gfxQtPlatform.cpp',
|
||||||
|
@ -181,16 +175,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'qt':
|
||||||
'gfxXlibSurface.cpp',
|
'gfxXlibSurface.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG['MOZ_PANGO']:
|
|
||||||
EXPORTS += ['gfxPangoFonts.h']
|
|
||||||
SOURCES += [
|
|
||||||
'gfxPangoFonts.cpp',
|
|
||||||
]
|
|
||||||
else:
|
|
||||||
EXPORTS += ['gfxFT2Fonts.h']
|
|
||||||
SOURCES += [
|
|
||||||
'gfxFT2Fonts.cpp',
|
|
||||||
]
|
|
||||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||||
EXPORTS += [
|
EXPORTS += [
|
||||||
'gfxD2DSurface.h',
|
'gfxD2DSurface.h',
|
||||||
|
|
|
@ -349,7 +349,7 @@ Decoder::PostFrameStop(FrameBlender::FrameAlpha aFrameAlpha /* = FrameBlender::k
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentFrame->SetFrameDisposalMethod(aDisposalMethod);
|
mCurrentFrame->SetFrameDisposalMethod(aDisposalMethod);
|
||||||
mCurrentFrame->SetTimeout(aTimeout);
|
mCurrentFrame->SetRawTimeout(aTimeout);
|
||||||
mCurrentFrame->SetBlendMethod(aBlendMethod);
|
mCurrentFrame->SetBlendMethod(aBlendMethod);
|
||||||
mCurrentFrame->ImageUpdated(mCurrentFrame->GetRect());
|
mCurrentFrame->ImageUpdated(mCurrentFrame->GetRect());
|
||||||
|
|
||||||
|
|
|
@ -13,36 +13,36 @@ using namespace mozilla;
|
||||||
|
|
||||||
FrameAnimator::FrameAnimator(FrameBlender& aFrameBlender)
|
FrameAnimator::FrameAnimator(FrameBlender& aFrameBlender)
|
||||||
: mCurrentAnimationFrameIndex(0)
|
: mCurrentAnimationFrameIndex(0)
|
||||||
, mLoopCount(-1)
|
, mLoopCounter(-1)
|
||||||
, mFrameBlender(aFrameBlender)
|
, mFrameBlender(aFrameBlender)
|
||||||
, mAnimationMode(imgIContainer::kNormalAnimMode)
|
, mAnimationMode(imgIContainer::kNormalAnimMode)
|
||||||
, mDoneDecoding(false)
|
, mDoneDecoding(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
int32_t
|
||||||
FrameAnimator::GetSingleLoopTime() const
|
FrameAnimator::GetSingleLoopTime() const
|
||||||
{
|
{
|
||||||
// If we aren't done decoding, we don't know the image's full play time.
|
// If we aren't done decoding, we don't know the image's full play time.
|
||||||
if (!mDoneDecoding) {
|
if (!mDoneDecoding) {
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're not looping, a single loop time has no meaning
|
// If we're not looping, a single loop time has no meaning
|
||||||
if (mAnimationMode != imgIContainer::kNormalAnimMode) {
|
if (mAnimationMode != imgIContainer::kNormalAnimMode) {
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t looptime = 0;
|
uint32_t looptime = 0;
|
||||||
for (uint32_t i = 0; i < mFrameBlender.GetNumFrames(); ++i) {
|
for (uint32_t i = 0; i < mFrameBlender.GetNumFrames(); ++i) {
|
||||||
int32_t timeout = mFrameBlender.RawGetFrame(i)->GetTimeout();
|
int32_t timeout = mFrameBlender.GetTimeoutForFrame(i);
|
||||||
if (timeout > 0) {
|
if (timeout >= 0) {
|
||||||
looptime += static_cast<uint32_t>(timeout);
|
looptime += static_cast<uint32_t>(timeout);
|
||||||
} else {
|
} else {
|
||||||
// If we have a frame that never times out, we're probably in an error
|
// If we have a frame that never times out, we're probably in an error
|
||||||
// case, but let's handle it more gracefully.
|
// case, but let's handle it more gracefully.
|
||||||
NS_WARNING("Negative frame timeout - how did this happen?");
|
NS_WARNING("Negative frame timeout - how did this happen?");
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,9 +52,8 @@ FrameAnimator::GetSingleLoopTime() const
|
||||||
TimeStamp
|
TimeStamp
|
||||||
FrameAnimator::GetCurrentImgFrameEndTime() const
|
FrameAnimator::GetCurrentImgFrameEndTime() const
|
||||||
{
|
{
|
||||||
imgFrame* currentFrame = mFrameBlender.RawGetFrame(mCurrentAnimationFrameIndex);
|
|
||||||
TimeStamp currentFrameTime = mCurrentAnimationFrameTime;
|
TimeStamp currentFrameTime = mCurrentAnimationFrameTime;
|
||||||
int64_t timeout = currentFrame->GetTimeout();
|
int32_t timeout = mFrameBlender.GetTimeoutForFrame(mCurrentAnimationFrameIndex);
|
||||||
|
|
||||||
if (timeout < 0) {
|
if (timeout < 0) {
|
||||||
// We need to return a sentinel value in this case, because our logic
|
// We need to return a sentinel value in this case, because our logic
|
||||||
|
@ -82,7 +81,7 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
|
||||||
|
|
||||||
uint32_t currentFrameIndex = mCurrentAnimationFrameIndex;
|
uint32_t currentFrameIndex = mCurrentAnimationFrameIndex;
|
||||||
uint32_t nextFrameIndex = currentFrameIndex + 1;
|
uint32_t nextFrameIndex = currentFrameIndex + 1;
|
||||||
uint32_t timeout = 0;
|
int32_t timeout = 0;
|
||||||
|
|
||||||
RefreshResult ret;
|
RefreshResult ret;
|
||||||
|
|
||||||
|
@ -101,17 +100,22 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
|
||||||
// If we're done decoding the next frame, go ahead and display it now and
|
// If we're done decoding the next frame, go ahead and display it now and
|
||||||
// reinit with the next frame's delay time.
|
// reinit with the next frame's delay time.
|
||||||
if (mFrameBlender.GetNumFrames() == nextFrameIndex) {
|
if (mFrameBlender.GetNumFrames() == nextFrameIndex) {
|
||||||
// End of Animation, unless we are looping forever
|
// End of an animation loop...
|
||||||
|
|
||||||
// If animation mode is "loop once", it's time to stop animating
|
// If we are not looping forever, initialize the loop counter
|
||||||
if (mAnimationMode == imgIContainer::kLoopOnceAnimMode || mLoopCount == 0) {
|
if (mLoopCounter < 0 && mFrameBlender.GetLoopCount() >= 0) {
|
||||||
|
mLoopCounter = mFrameBlender.GetLoopCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If animation mode is "loop once", or we're at end of loop counter, it's time to stop animating
|
||||||
|
if (mAnimationMode == imgIContainer::kLoopOnceAnimMode || mLoopCounter == 0) {
|
||||||
ret.animationFinished = true;
|
ret.animationFinished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
nextFrameIndex = 0;
|
nextFrameIndex = 0;
|
||||||
|
|
||||||
if (mLoopCount > 0) {
|
if (mLoopCounter > 0) {
|
||||||
mLoopCount--;
|
mLoopCounter--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're done, exit early.
|
// If we're done, exit early.
|
||||||
|
@ -120,11 +124,11 @@ FrameAnimator::AdvanceFrame(TimeStamp aTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout = mFrameBlender.GetFrame(nextFrameIndex)->GetTimeout();
|
timeout = mFrameBlender.GetTimeoutForFrame(nextFrameIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bad data
|
// Bad data
|
||||||
if (!(timeout > 0)) {
|
if (timeout < 0) {
|
||||||
ret.animationFinished = true;
|
ret.animationFinished = true;
|
||||||
ret.error = true;
|
ret.error = true;
|
||||||
}
|
}
|
||||||
|
@ -246,12 +250,6 @@ FrameAnimator::UnionFirstFrameRefreshArea(const nsIntRect& aRect)
|
||||||
mFirstFrameRefreshArea.UnionRect(mFirstFrameRefreshArea, aRect);
|
mFirstFrameRefreshArea.UnionRect(mFirstFrameRefreshArea, aRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
FrameAnimator::SetLoopCount(int loopcount)
|
|
||||||
{
|
|
||||||
mLoopCount = loopcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
FrameAnimator::GetCurrentAnimationFrameIndex() const
|
FrameAnimator::GetCurrentAnimationFrameIndex() const
|
||||||
{
|
{
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче