зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
Коммит
b77f0a036b
|
@ -8,6 +8,7 @@ ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
|
|||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
WindowsGPOParser: "resource:///modules/policies/WindowsGPOParser.jsm",
|
||||
macOSPoliciesParser: "resource:///modules/policies/macOSPoliciesParser.jsm",
|
||||
Policies: "resource:///modules/policies/Policies.jsm",
|
||||
JsonSchemaValidator: "resource://gre/modules/components-utils/JsonSchemaValidator.jsm",
|
||||
});
|
||||
|
@ -76,16 +77,19 @@ EnterprisePoliciesManager.prototype = {
|
|||
},
|
||||
|
||||
_chooseProvider() {
|
||||
let provider = null;
|
||||
if (AppConstants.platform == "win") {
|
||||
let gpoProvider = new GPOPoliciesProvider();
|
||||
if (gpoProvider.hasPolicies) {
|
||||
return gpoProvider;
|
||||
}
|
||||
provider = new WindowsGPOPoliciesProvider();
|
||||
} else if (AppConstants.platform == "macosx") {
|
||||
provider = new macOSPoliciesProvider();
|
||||
}
|
||||
if (provider && provider.hasPolicies) {
|
||||
return provider;
|
||||
}
|
||||
|
||||
let jsonProvider = new JSONPoliciesProvider();
|
||||
if (jsonProvider.hasPolicies) {
|
||||
return jsonProvider;
|
||||
provider = new JSONPoliciesProvider();
|
||||
if (provider.hasPolicies) {
|
||||
return provider;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -395,7 +399,7 @@ class JSONPoliciesProvider {
|
|||
}
|
||||
}
|
||||
|
||||
class GPOPoliciesProvider {
|
||||
class WindowsGPOPoliciesProvider {
|
||||
constructor() {
|
||||
this._policies = null;
|
||||
|
||||
|
@ -429,5 +433,41 @@ class GPOPoliciesProvider {
|
|||
}
|
||||
}
|
||||
|
||||
class macOSPoliciesProvider {
|
||||
constructor() {
|
||||
this._policies = null;
|
||||
let prefReader = Cc["@mozilla.org/mac-preferences-reader;1"]
|
||||
.createInstance(Ci.nsIMacPreferencesReader);
|
||||
if (!prefReader.policiesEnabled()) {
|
||||
return;
|
||||
}
|
||||
this._policies = macOSPoliciesParser.readPolicies(prefReader);
|
||||
this._removeUnknownPolicies();
|
||||
}
|
||||
|
||||
_removeUnknownPolicies() {
|
||||
let { schema } = ChromeUtils.import("resource:///modules/policies/schema.jsm", {});
|
||||
|
||||
for (let policyName of Object.keys(this._policies)) {
|
||||
if (!schema.properties.hasOwnProperty(policyName)) {
|
||||
log.debug(`Removing unknown policy: ${policyName}`);
|
||||
delete this._policies[policyName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get hasPolicies() {
|
||||
return this._policies !== null;
|
||||
}
|
||||
|
||||
get policies() {
|
||||
return this._policies;
|
||||
}
|
||||
|
||||
get failed() {
|
||||
return this._failed;
|
||||
}
|
||||
}
|
||||
|
||||
var components = [EnterprisePoliciesManager];
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
|
||||
|
|
|
@ -204,7 +204,8 @@ function generateErrors() {
|
|||
"Enterprise Policies Child",
|
||||
"BookmarksPolicies.jsm",
|
||||
"ProxyPolicies.jsm",
|
||||
"WebsiteFilter Policy"];
|
||||
"WebsiteFilter Policy",
|
||||
"macOSPoliciesParser.jsm"];
|
||||
|
||||
let new_cont = document.getElementById("errorsContent");
|
||||
new_cont.classList.add("errors");
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/* 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/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
const PREF_LOGLEVEL = "browser.policies.loglevel";
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "log", () => {
|
||||
let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm", {});
|
||||
return new ConsoleAPI({
|
||||
prefix: "macOSPoliciesParser.jsm",
|
||||
// tip: set maxLogLevel to "debug" and use log.debug() to create detailed
|
||||
// messages during development. See LOG_LEVELS in Console.jsm for details.
|
||||
maxLogLevel: "error",
|
||||
maxLogLevelPref: PREF_LOGLEVEL,
|
||||
});
|
||||
});
|
||||
|
||||
var EXPORTED_SYMBOLS = ["macOSPoliciesParser"];
|
||||
|
||||
var macOSPoliciesParser = {
|
||||
readPolicies(reader) {
|
||||
let nativePolicies = reader.readPreferences();
|
||||
if (!nativePolicies) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Need an extra check here so we don't
|
||||
// JSON.stringify if we aren't in debug mode
|
||||
if (log.maxLogLevel == "debug") {
|
||||
log.debug(JSON.stringify(nativePolicies, null, 2));
|
||||
}
|
||||
|
||||
return nativePolicies;
|
||||
},
|
||||
};
|
|
@ -31,6 +31,11 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'WindowsGPOParser.jsm',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
EXTRA_JS_MODULES.policies += [
|
||||
'macOSPoliciesParser.jsm',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'browsercomps'
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
|
|
@ -29,7 +29,11 @@ support-files =
|
|||
tags = fullscreen
|
||||
[browser_fullscreen-contextmenu-esc.js]
|
||||
tags = fullscreen
|
||||
[browser_fullscreen-newtab.js]
|
||||
tags = fullscreen
|
||||
support-files = file_fullscreen-newtab.html
|
||||
skip-if = os == 'mac' # bug 1494843
|
||||
[browser_submission_flush.js]
|
||||
[browser_refresh_wyciwyg_url.js]
|
||||
support-files =
|
||||
file_refresh_wyciwyg_url.html
|
||||
file_refresh_wyciwyg_url.html
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
"use strict";
|
||||
|
||||
const kPage = "http://example.org/browser/" +
|
||||
"dom/html/test/file_fullscreen-newtab.html";
|
||||
|
||||
function getSizeMode() {
|
||||
return document.documentElement.getAttribute("sizemode");
|
||||
}
|
||||
|
||||
async function runTest() {
|
||||
await BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: kPage
|
||||
}, async function (browser) {
|
||||
await ContentTask.spawn(browser, null, function() {
|
||||
content.document.addEventListener("fullscreenchange", () => {
|
||||
sendAsyncMessage("Test:FullscreenChange");
|
||||
});
|
||||
content.document.addEventListener("fullscreenerror", () => {
|
||||
sendAsyncMessage("Test:FullscreenError");
|
||||
});
|
||||
});
|
||||
let promiseFsEvents = new Promise(resolve => {
|
||||
let countFsChange = 0;
|
||||
let countFsError = 0;
|
||||
function checkAndResolve() {
|
||||
if (countFsChange > 0 && countFsError > 0) {
|
||||
ok(false, "Got both fullscreenchange and fullscreenerror events");
|
||||
} else if (countFsChange > 2) {
|
||||
ok(false, "Got too many fullscreenchange events");
|
||||
} else if (countFsError > 1) {
|
||||
ok(false, "Got too many fullscreenerror events");
|
||||
} else if (countFsChange == 2 || countFsError == 1) {
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
let mm = browser.messageManager;
|
||||
mm.addMessageListener("Test:FullscreenChange", () => {
|
||||
info("Got fullscreenchange event");
|
||||
++countFsChange;
|
||||
checkAndResolve();
|
||||
});
|
||||
mm.addMessageListener("Test:FullscreenError", () => {
|
||||
info("Got fullscreenerror event");
|
||||
++countFsError;
|
||||
checkAndResolve();
|
||||
});
|
||||
});
|
||||
let promiseNewTab =
|
||||
BrowserTestUtils.waitForNewTab(gBrowser, "about:blank");
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter("#link", {}, browser);
|
||||
let [newtab] = await Promise.all([promiseNewTab, promiseFsEvents]);
|
||||
await BrowserTestUtils.removeTab(newtab);
|
||||
|
||||
// Ensure the browser exits fullscreen state in reasonable time.
|
||||
await Promise.race([
|
||||
BrowserTestUtils.waitForCondition(() => getSizeMode() == "normal"),
|
||||
new Promise(resolve => setTimeout(resolve, 2000))
|
||||
]);
|
||||
|
||||
ok(!window.fullScreen, "The chrome window should not be in fullscreen");
|
||||
ok(!document.fullscreen, "The chrome document should not be in fullscreen");
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function () {
|
||||
await pushPrefs(
|
||||
["full-screen-api.unprefix.enabled", true],
|
||||
["full-screen-api.transition-duration.enter", "0 0"],
|
||||
["full-screen-api.transition-duration.leave", "0 0"]);
|
||||
await runTest();
|
||||
});
|
||||
|
||||
add_task(async function () {
|
||||
await pushPrefs(
|
||||
["full-screen-api.unprefix.enabled", true],
|
||||
["full-screen-api.transition-duration.enter", "200 200"],
|
||||
["full-screen-api.transition-duration.leave", "200 200"]);
|
||||
await runTest();
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="UTF-8">
|
||||
<a id="link" href="about:blank" target="_blank"
|
||||
onclick="document.body.requestFullscreen()">Click here</a>
|
|
@ -8,7 +8,8 @@ varying vec3 vUv;
|
|||
flat varying vec4 vUvRect;
|
||||
flat varying vec2 vOffsetScale;
|
||||
flat varying float vSigma;
|
||||
flat varying int vBlurRadius;
|
||||
// The number of pixels on each end that we apply the blur filter over.
|
||||
flat varying int vSupport;
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
// Applies a separable gaussian blur in one direction, as specified
|
||||
|
@ -50,9 +51,15 @@ void main(void) {
|
|||
vec2 texture_size = vec2(textureSize(sCacheA8, 0).xy);
|
||||
#endif
|
||||
vUv.z = src_task.texture_layer_index;
|
||||
vBlurRadius = int(3.0 * blur_task.blur_radius);
|
||||
vSigma = blur_task.blur_radius;
|
||||
|
||||
// Ensure that the support is an even number of pixels to simplify the
|
||||
// fragment shader logic.
|
||||
//
|
||||
// TODO(pcwalton): Actually make use of this fact and use the texture
|
||||
// hardware for linear filtering.
|
||||
vSupport = int(ceil(1.5 * blur_task.blur_radius)) * 2;
|
||||
|
||||
switch (aBlurDirection) {
|
||||
case DIR_HORIZONTAL:
|
||||
vOffsetScale = vec2(1.0 / texture_size.x, 0.0);
|
||||
|
@ -101,7 +108,7 @@ void main(void) {
|
|||
// TODO(gw): The gauss function gets NaNs when blur radius
|
||||
// is zero. In the future, detect this earlier
|
||||
// and skip the blur passes completely.
|
||||
if (vBlurRadius == 0) {
|
||||
if (vSupport == 0) {
|
||||
oFragColor = vec4(original_color);
|
||||
return;
|
||||
}
|
||||
|
@ -117,7 +124,7 @@ void main(void) {
|
|||
gauss_coefficient_sum += gauss_coefficient.x;
|
||||
gauss_coefficient.xy *= gauss_coefficient.yz;
|
||||
|
||||
for (int i=1 ; i <= vBlurRadius ; ++i) {
|
||||
for (int i = 1; i <= vSupport; i++) {
|
||||
vec2 offset = vOffsetScale * float(i);
|
||||
|
||||
vec2 st0 = clamp(vUv.xy - offset, vUvRect.xy, vUvRect.zw);
|
||||
|
|
|
@ -214,9 +214,11 @@ impl BorderSideHelpers for BorderSide {
|
|||
// modulate the colors in order to generate colors for the inset/outset
|
||||
// and groove/ridge border styles.
|
||||
//
|
||||
// NOTE(emilio): Gecko at least takes the background color into
|
||||
// account, should we do the same? Looks a bit annoying for this.
|
||||
//
|
||||
// NOTE(emilio): If you change this algorithm, do the same change on
|
||||
// get_colors_for_side in cs_border_segment.glsl, and
|
||||
// NS_GetSpecial3DColors in Gecko.
|
||||
// get_colors_for_side in cs_border_segment.glsl.
|
||||
if self.color.r != 0.0 || self.color.g != 0.0 || self.color.b != 0.0 {
|
||||
let scale = if lighter { 1.0 } else { 2.0 / 3.0 };
|
||||
return self.color.scale_rgb(scale)
|
||||
|
|
|
@ -253,10 +253,14 @@ impl ClipScrollTree {
|
|||
&mut self,
|
||||
pan: WorldPoint,
|
||||
scene_properties: &SceneProperties,
|
||||
) -> TransformPalette {
|
||||
let mut transform_palette = TransformPalette::new(self.spatial_nodes.len());
|
||||
mut transform_palette: Option<&mut TransformPalette>,
|
||||
) {
|
||||
if self.spatial_nodes.is_empty() {
|
||||
return transform_palette;
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(ref mut palette) = transform_palette {
|
||||
palette.allocate(self.spatial_nodes.len());
|
||||
}
|
||||
|
||||
self.coord_systems.clear();
|
||||
|
@ -282,7 +286,9 @@ impl ClipScrollTree {
|
|||
};
|
||||
|
||||
node.update(&mut state, &mut self.coord_systems, scene_properties);
|
||||
node.push_gpu_data(&mut transform_palette, node_index);
|
||||
if let Some(ref mut palette) = transform_palette {
|
||||
node.push_gpu_data(palette, node_index);
|
||||
}
|
||||
|
||||
if !node.children.is_empty() {
|
||||
node.prepare_state_for_children(&mut state);
|
||||
|
@ -293,8 +299,6 @@ impl ClipScrollTree {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
transform_palette
|
||||
}
|
||||
|
||||
pub fn finalize_and_apply_pending_scroll_offsets(&mut self, old_states: ScrollStates) {
|
||||
|
@ -506,7 +510,7 @@ fn test_cst_simple_translation() {
|
|||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new());
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new(), None);
|
||||
|
||||
test_pt(100.0, 100.0, &cst, child1, root, 200.0, 100.0);
|
||||
test_pt(100.0, 100.0, &cst, root, child1, 0.0, 100.0);
|
||||
|
@ -551,7 +555,7 @@ fn test_cst_simple_scale() {
|
|||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new());
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new(), None);
|
||||
|
||||
test_pt(100.0, 100.0, &cst, child1, root, 400.0, 100.0);
|
||||
test_pt(100.0, 100.0, &cst, root, child1, 25.0, 100.0);
|
||||
|
@ -605,7 +609,7 @@ fn test_cst_scale_translation() {
|
|||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new());
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new(), None);
|
||||
|
||||
test_pt(100.0, 100.0, &cst, child1, root, 200.0, 150.0);
|
||||
test_pt(100.0, 100.0, &cst, child2, root, 300.0, 450.0);
|
||||
|
@ -644,7 +648,7 @@ fn test_cst_translation_rotate() {
|
|||
LayoutVector2D::zero(),
|
||||
);
|
||||
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new());
|
||||
cst.update_tree(WorldPoint::zero(), &SceneProperties::new(), None);
|
||||
|
||||
test_pt(100.0, 0.0, &cst, child1, root, 0.0, -100.0);
|
||||
}
|
||||
|
|
|
@ -2235,7 +2235,7 @@ impl Device {
|
|||
fn gl_describe_format(&self, format: ImageFormat) -> FormatDesc {
|
||||
match format {
|
||||
ImageFormat::R8 => FormatDesc {
|
||||
internal: gl::RED as _,
|
||||
internal: gl::R8 as _,
|
||||
external: gl::RED,
|
||||
pixel_type: gl::UNSIGNED_BYTE,
|
||||
},
|
||||
|
|
|
@ -348,9 +348,11 @@ impl FrameBuilder {
|
|||
resource_cache.begin_frame(frame_id);
|
||||
gpu_cache.begin_frame();
|
||||
|
||||
let mut transform_palette = clip_scroll_tree.update_tree(
|
||||
let mut transform_palette = TransformPalette::new();
|
||||
clip_scroll_tree.update_tree(
|
||||
pan,
|
||||
scene_properties,
|
||||
Some(&mut transform_palette),
|
||||
);
|
||||
|
||||
self.update_scroll_bars(clip_scroll_tree, gpu_cache);
|
||||
|
|
|
@ -427,14 +427,19 @@ pub struct TransformPalette {
|
|||
}
|
||||
|
||||
impl TransformPalette {
|
||||
pub fn new(spatial_node_count: usize) -> Self {
|
||||
pub fn new() -> Self {
|
||||
TransformPalette {
|
||||
transforms: vec![TransformData::invalid(); spatial_node_count],
|
||||
metadata: vec![TransformMetadata::invalid(); spatial_node_count],
|
||||
transforms: Vec::new(),
|
||||
metadata: Vec::new(),
|
||||
map: FastHashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn allocate(&mut self, count: usize) {
|
||||
self.transforms = vec![TransformData::invalid(); count];
|
||||
self.metadata = vec![TransformMetadata::invalid(); count];
|
||||
}
|
||||
|
||||
pub fn set_world_transform(
|
||||
&mut self,
|
||||
index: SpatialNodeIndex,
|
||||
|
|
|
@ -42,7 +42,7 @@ use serde::{Serialize, Deserialize};
|
|||
use serde_json;
|
||||
#[cfg(any(feature = "capture", feature = "replay"))]
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::mem::replace;
|
||||
use std::os::raw::c_void;
|
||||
use std::sync::mpsc::{channel, Sender, Receiver};
|
||||
|
@ -206,6 +206,9 @@ impl Document {
|
|||
};
|
||||
}
|
||||
FrameMsg::HitTest(pipeline_id, point, flags, tx) => {
|
||||
if !self.hit_tester_is_valid {
|
||||
self.rebuild_hit_tester();
|
||||
}
|
||||
|
||||
let result = match self.hit_tester {
|
||||
Some(ref hit_tester) => {
|
||||
|
@ -293,6 +296,24 @@ impl Document {
|
|||
}
|
||||
}
|
||||
|
||||
fn rebuild_hit_tester(&mut self) {
|
||||
if let Some(ref mut frame_builder) = self.frame_builder {
|
||||
let accumulated_scale_factor = self.view.accumulated_scale_factor();
|
||||
let pan = self.view.pan.to_f32() / accumulated_scale_factor;
|
||||
|
||||
self.clip_scroll_tree.update_tree(
|
||||
pan,
|
||||
&self.dynamic_properties,
|
||||
None,
|
||||
);
|
||||
|
||||
self.hit_tester = Some(frame_builder.create_hit_tester(
|
||||
&self.clip_scroll_tree,
|
||||
&self.clip_data_store,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn updated_pipeline_info(&mut self) -> PipelineInfo {
|
||||
let removed_pipelines = replace(&mut self.removed_pipelines, Vec::new());
|
||||
PipelineInfo {
|
||||
|
@ -347,20 +368,19 @@ impl Document {
|
|||
|
||||
struct DocumentOps {
|
||||
scroll: bool,
|
||||
build_frame: bool,
|
||||
}
|
||||
|
||||
impl DocumentOps {
|
||||
fn nop() -> Self {
|
||||
DocumentOps {
|
||||
scroll: false,
|
||||
build_frame: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The unique id for WR resource identification.
|
||||
static NEXT_NAMESPACE_ID: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||
/// The namespace_id should start from 1.
|
||||
static NEXT_NAMESPACE_ID: AtomicUsize = AtomicUsize::new(1);
|
||||
|
||||
#[cfg(any(feature = "capture", feature = "replay"))]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
|
@ -419,9 +439,6 @@ impl RenderBackend {
|
|||
sampler: Option<Box<AsyncPropertySampler + Send>>,
|
||||
size_of_op: Option<VoidPtrToSizeFn>,
|
||||
) -> RenderBackend {
|
||||
// The namespace_id should start from 1.
|
||||
NEXT_NAMESPACE_ID.fetch_add(1, Ordering::Relaxed);
|
||||
|
||||
RenderBackend {
|
||||
api_rx,
|
||||
payload_rx,
|
||||
|
@ -615,7 +632,6 @@ impl RenderBackend {
|
|||
txn.clip_updates.take(),
|
||||
replace(&mut txn.frame_ops, Vec::new()),
|
||||
replace(&mut txn.notifications, Vec::new()),
|
||||
txn.build_frame,
|
||||
txn.render_frame,
|
||||
&mut frame_counter,
|
||||
&mut profile_counters,
|
||||
|
@ -625,6 +641,9 @@ impl RenderBackend {
|
|||
SceneBuilderResult::FlushComplete(tx) => {
|
||||
tx.send(()).ok();
|
||||
}
|
||||
SceneBuilderResult::ExternalEvent(evt) => {
|
||||
self.notifier.external_event(evt);
|
||||
}
|
||||
SceneBuilderResult::Stopped => {
|
||||
panic!("We haven't sent a Stop yet, how did we get a Stopped back?");
|
||||
}
|
||||
|
@ -727,7 +746,7 @@ impl RenderBackend {
|
|||
).unwrap();
|
||||
}
|
||||
ApiMsg::ExternalEvent(evt) => {
|
||||
self.notifier.external_event(evt);
|
||||
self.low_priority_scene_tx.send(SceneBuilderRequest::ExternalEvent(evt)).unwrap();
|
||||
}
|
||||
ApiMsg::ClearNamespace(namespace_id) => {
|
||||
self.resource_cache.clear_namespace(namespace_id);
|
||||
|
@ -885,7 +904,6 @@ impl RenderBackend {
|
|||
rasterized_blobs: Vec::new(),
|
||||
notifications: transaction_msg.notifications,
|
||||
set_root_pipeline: None,
|
||||
build_frame: transaction_msg.generate_frame,
|
||||
render_frame: transaction_msg.generate_frame,
|
||||
});
|
||||
|
||||
|
@ -921,7 +939,6 @@ impl RenderBackend {
|
|||
None,
|
||||
replace(&mut txn.frame_ops, Vec::new()),
|
||||
replace(&mut txn.notifications, Vec::new()),
|
||||
txn.build_frame,
|
||||
txn.render_frame,
|
||||
frame_counter,
|
||||
profile_counters,
|
||||
|
@ -959,7 +976,6 @@ impl RenderBackend {
|
|||
clip_updates: Option<ClipDataUpdateList>,
|
||||
mut frame_ops: Vec<FrameMsg>,
|
||||
mut notifications: Vec<NotificationRequest>,
|
||||
mut build_frame: bool,
|
||||
mut render_frame: bool,
|
||||
frame_counter: &mut u32,
|
||||
profile_counters: &mut BackendProfileCounters,
|
||||
|
@ -972,7 +988,7 @@ impl RenderBackend {
|
|||
// fiddle with things after a potentially long scene build, but just
|
||||
// before rendering. This is useful for rendering with the latest
|
||||
// async transforms.
|
||||
if build_frame {
|
||||
if requested_frame || has_built_scene {
|
||||
if let Some(ref sampler) = self.sampler {
|
||||
frame_ops.append(&mut sampler.sample());
|
||||
}
|
||||
|
@ -992,7 +1008,6 @@ impl RenderBackend {
|
|||
for frame_msg in frame_ops {
|
||||
let _timer = profile_counters.total_time.timer();
|
||||
let op = doc.process_frame_msg(frame_msg);
|
||||
build_frame |= op.build_frame;
|
||||
scroll |= op.scroll;
|
||||
}
|
||||
|
||||
|
@ -1007,31 +1022,20 @@ impl RenderBackend {
|
|||
&mut profile_counters.resources,
|
||||
);
|
||||
|
||||
// After applying the new scene we need to
|
||||
// rebuild the hit-tester, so we trigger a frame generation
|
||||
// step.
|
||||
//
|
||||
// TODO: We could avoid some the cost of building the frame by only
|
||||
// building the information required for hit-testing (See #2807).
|
||||
build_frame |= has_built_scene;
|
||||
|
||||
if doc.dynamic_properties.flush_pending_updates() {
|
||||
doc.frame_is_valid = false;
|
||||
doc.hit_tester_is_valid = false;
|
||||
build_frame = true;
|
||||
}
|
||||
|
||||
if !doc.can_render() {
|
||||
// TODO: this happens if we are building the first scene asynchronously and
|
||||
// scroll at the same time. we should keep track of the fact that we skipped
|
||||
// composition here and do it as soon as we receive the scene.
|
||||
build_frame = false;
|
||||
render_frame = false;
|
||||
}
|
||||
|
||||
if doc.frame_is_valid {
|
||||
build_frame = false;
|
||||
}
|
||||
// Avoid re-building the frame if the current built frame is still valid.
|
||||
let build_frame = render_frame && !doc.frame_is_valid;
|
||||
|
||||
let mut frame_build_time = None;
|
||||
if build_frame && doc.has_pixels() {
|
||||
|
@ -1100,6 +1104,10 @@ impl RenderBackend {
|
|||
if requested_frame {
|
||||
self.notifier.new_frame_ready(document_id, scroll, render_frame, frame_build_time);
|
||||
}
|
||||
|
||||
if !doc.hit_tester_is_valid {
|
||||
doc.rebuild_hit_tester();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "debugger"))]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{AsyncBlobImageRasterizer, BlobImageRequest, BlobImageParams, BlobImageResult};
|
||||
use api::{DocumentId, PipelineId, ApiMsg, FrameMsg, ResourceUpdate, Epoch};
|
||||
use api::{DocumentId, PipelineId, ApiMsg, FrameMsg, ResourceUpdate, ExternalEvent, Epoch};
|
||||
use api::{BuiltDisplayList, ColorF, LayoutSize, NotificationRequest, Checkpoint};
|
||||
use api::channel::MsgSender;
|
||||
#[cfg(feature = "capture")]
|
||||
|
@ -39,7 +39,6 @@ pub struct Transaction {
|
|||
pub frame_ops: Vec<FrameMsg>,
|
||||
pub notifications: Vec<NotificationRequest>,
|
||||
pub set_root_pipeline: Option<PipelineId>,
|
||||
pub build_frame: bool,
|
||||
pub render_frame: bool,
|
||||
}
|
||||
|
||||
|
@ -73,7 +72,6 @@ pub struct BuiltTransaction {
|
|||
pub clip_updates: Option<ClipDataUpdateList>,
|
||||
pub scene_build_start_time: u64,
|
||||
pub scene_build_end_time: u64,
|
||||
pub build_frame: bool,
|
||||
pub render_frame: bool,
|
||||
}
|
||||
|
||||
|
@ -116,6 +114,7 @@ pub struct BuiltScene {
|
|||
// Message from render backend to scene builder.
|
||||
pub enum SceneBuilderRequest {
|
||||
Transaction(Box<Transaction>),
|
||||
ExternalEvent(ExternalEvent),
|
||||
DeleteDocument(DocumentId),
|
||||
WakeUp,
|
||||
Flush(MsgSender<()>),
|
||||
|
@ -132,6 +131,7 @@ pub enum SceneBuilderRequest {
|
|||
// Message from scene builder to render backend.
|
||||
pub enum SceneBuilderResult {
|
||||
Transaction(Box<BuiltTransaction>, Option<Sender<SceneSwapResult>>),
|
||||
ExternalEvent(ExternalEvent),
|
||||
FlushComplete(MsgSender<()>),
|
||||
Stopped,
|
||||
}
|
||||
|
@ -228,6 +228,10 @@ impl SceneBuilder {
|
|||
Ok(SceneBuilderRequest::SaveScene(config)) => {
|
||||
self.save_scene(config);
|
||||
}
|
||||
Ok(SceneBuilderRequest::ExternalEvent(evt)) => {
|
||||
self.tx.send(SceneBuilderResult::ExternalEvent(evt)).unwrap();
|
||||
self.api_tx.send(ApiMsg::WakeUp).unwrap();
|
||||
}
|
||||
Ok(SceneBuilderRequest::Stop) => {
|
||||
self.tx.send(SceneBuilderResult::Stopped).unwrap();
|
||||
// We don't need to send a WakeUp to api_tx because we only
|
||||
|
@ -307,7 +311,6 @@ impl SceneBuilder {
|
|||
|
||||
let txn = Box::new(BuiltTransaction {
|
||||
document_id: item.document_id,
|
||||
build_frame: true,
|
||||
render_frame: item.build_frame,
|
||||
built_scene,
|
||||
resource_updates: Vec::new(),
|
||||
|
@ -408,7 +411,6 @@ impl SceneBuilder {
|
|||
|
||||
Box::new(BuiltTransaction {
|
||||
document_id: txn.document_id,
|
||||
build_frame: txn.build_frame || built_scene.is_some(),
|
||||
render_frame: txn.render_frame,
|
||||
built_scene,
|
||||
rasterized_blobs,
|
||||
|
|
|
@ -379,7 +379,7 @@ pub struct BlobImageDescriptor {
|
|||
/// Representation of a rasterized blob image. This is obtained by passing
|
||||
/// `BlobImageData` to the embedding via the rasterization callback.
|
||||
pub struct RasterizedBlobImage {
|
||||
/// The bounding rectangle for this bob image.
|
||||
/// The bounding rectangle for this blob image.
|
||||
pub rasterized_rect: DeviceUintRect,
|
||||
/// Backing store. The format is stored out of band in `BlobImageDescriptor`.
|
||||
pub data: Arc<Vec<u8>>,
|
||||
|
|
|
@ -1 +1 @@
|
|||
43e8d85789efb95099affe3257a9c254ef3d2f4c
|
||||
0d2e9611c07e04ac830277f16a3b46bf125b9e7c
|
||||
|
|
|
@ -150,7 +150,7 @@ Atomic64 Release_Load(volatile const Atomic64* ptr);
|
|||
// Include our platform specific implementation.
|
||||
#if defined(OS_WIN) && defined(ARCH_CPU_X86_FAMILY)
|
||||
#include "base/atomicops_internals_x86_msvc.h"
|
||||
#elif defined(OS_WIN) && defined(ARCH_CPU_AARCH64_FAMILY)
|
||||
#elif defined(OS_WIN) && defined(ARCH_CPU_ARM64)
|
||||
// Works just fine, separate case in case we need to change things.
|
||||
#include "base/atomicops_internals_x86_msvc.h"
|
||||
#elif defined(OS_MACOSX) && defined(ARCH_CPU_X86_FAMILY)
|
||||
|
|
|
@ -1018,9 +1018,23 @@ EnqueuePromiseReactionJob(JSContext* cx, HandleObject reactionObj,
|
|||
// handler's compartment above, because we should pass objects from a
|
||||
// single compartment to the enqueuePromiseJob callback.
|
||||
RootedObject promise(cx, reaction->promise());
|
||||
if (promise && promise->is<PromiseObject>()) {
|
||||
if (!cx->compartment()->wrap(cx, &promise)) {
|
||||
return false;
|
||||
if (promise) {
|
||||
if (promise->is<PromiseObject>()) {
|
||||
if (!cx->compartment()->wrap(cx, &promise)) {
|
||||
return false;
|
||||
}
|
||||
} else if (IsWrapper(promise)) {
|
||||
// `promise` can be already-wrapped promise object at this point.
|
||||
JSObject* unwrappedPromise = UncheckedUnwrap(promise);
|
||||
if (unwrappedPromise->is<PromiseObject>()) {
|
||||
if (!cx->compartment()->wrap(cx, &promise)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
promise = nullptr;
|
||||
}
|
||||
} else {
|
||||
promise = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -648,6 +648,10 @@ JSRuntime::enqueuePromiseJob(JSContext* cx, HandleFunction job, HandleObject pro
|
|||
void* data = cx->enqueuePromiseJobCallbackData;
|
||||
RootedObject allocationSite(cx);
|
||||
if (promise) {
|
||||
#ifdef DEBUG
|
||||
AssertSameCompartment(job, promise);
|
||||
#endif
|
||||
|
||||
RootedObject unwrappedPromise(cx, promise);
|
||||
// While the job object is guaranteed to be unwrapped, the promise
|
||||
// might be wrapped. See the comments in EnqueuePromiseReactionJob in
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
# e.g. filter: blur(3px) grayscale(0.5) invert(0.2);
|
||||
|
||||
# Some platforms render this complex filter chain a little differently, and that's ok.
|
||||
fuzzy(0-5,0-13638) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&layersGPUAccelerated,0-35,0-13638) fuzzy-if(webrender,5-6,17922-18643) == long-chain.html long-chain-ref.html # Win10: Bug 1258241
|
||||
fuzzy(0-5,0-13638) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)&&layersGPUAccelerated,0-35,0-13638) fuzzy-if(webrender,5-6,17922-18853) == long-chain.html long-chain-ref.html # Win10: Bug 1258241
|
||||
== moz-element.html moz-element-ref.html
|
||||
fuzzy-if(webrender,15-15,7958-8262) == same-filter.html same-filter-ref.html
|
||||
fuzzy-if(webrender,15-15,7678-8262) == same-filter.html same-filter-ref.html
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
# These tests verify that CSS filters behave properly.
|
||||
# e.g. filter: blur(3px)
|
||||
|
||||
fuzzy-if(webrender,9-9,4780-4784) == blur.html blur-ref.html
|
||||
fuzzy-if(webrender,9-9,4780-5120) == blur.html blur-ref.html
|
||||
== blur.svg blur-ref.svg
|
||||
== blur-calc.html blur-calc-ref.html
|
||||
== blur-calc-negative.html blur-calc-negative-ref.html
|
||||
fuzzy-if(cocoaWidget&&webrender,1-1,1-1) skip-if(d2d) == blur-cap-large-radius-on-software.html blur-cap-large-radius-on-software-ref.html
|
||||
fuzzy-if(webrender,9-9,4780-4784) == blur-em-radius.html blur-em-radius-ref.html
|
||||
fuzzy-if(webrender,9-9,4780-5120) == blur-em-radius.html blur-em-radius-ref.html
|
||||
== blur-invalid-radius.html blur-invalid-radius-ref.html
|
||||
fuzzy-if(webrender,9-9,4780-4784) == blur-rem-radius.html blur-rem-radius-ref.html
|
||||
fuzzy-if(webrender,9-9,4780-5120) == blur-rem-radius.html blur-rem-radius-ref.html
|
||||
== blur-zero-radius.html blur-zero-radius-ref.html
|
||||
fuzzy-if(webrender,5-7,19040-21308) == blur-zoomed-page.html blur-zoomed-page-ref.html
|
||||
fuzzy-if(webrender,5-7,19040-22652) == blur-zoomed-page.html blur-zoomed-page-ref.html
|
||||
== brightness.html brightness-ref.html
|
||||
== brightness-darken.html brightness-darken-ref.html
|
||||
== brightness-extreme.html brightness-extreme-ref.html
|
||||
|
@ -24,9 +24,9 @@ fuzzy-if(webrender,5-7,19040-21308) == blur-zoomed-page.html blur-zoomed-page-re
|
|||
== contrast-percent.html contrast-percent-ref.html
|
||||
== contrast-reduce.html contrast-reduce-ref.html
|
||||
== contrast-zero.html contrast-zero-ref.html
|
||||
fuzzy-if(webrender,9-9,2625-2628) == drop-shadow.html drop-shadow-ref.html
|
||||
fuzzy-if(webrender,9-9,2625-2628) fails-if(webrender&&winWidget) == drop-shadow-default-color.html drop-shadow-default-color-ref.html
|
||||
fuzzy-if(webrender,9-9,2625-2628) fails-if(webrender&&winWidget) == drop-shadow-negative-offset.html drop-shadow-negative-offset-ref.html
|
||||
fuzzy-if(webrender,9-9,2625-3002) == drop-shadow.html drop-shadow-ref.html
|
||||
fuzzy-if(webrender,9-9,2625-3002) fails-if(webrender&&winWidget) == drop-shadow-default-color.html drop-shadow-default-color-ref.html
|
||||
fuzzy-if(webrender,9-9,2625-3002) fails-if(webrender&&winWidget) == drop-shadow-negative-offset.html drop-shadow-negative-offset-ref.html
|
||||
== filter-on-huge-bbox.html pass.svg
|
||||
== filter-on-outer-svg.html pass.svg
|
||||
fuzzy-if(webrender,0-1,0-10000) fuzzy-if(d2d,0-1,0-10000) == grayscale.html grayscale-ref.html
|
||||
|
|
|
@ -66,7 +66,7 @@ user_pref("identity.fxaccounts.auth.uri", "https://127.0.0.1/fxa-dummy/");
|
|||
user_pref("identity.fxaccounts.migrateToDevEdition", false);
|
||||
// Make tests run consistently on DevEdition (which has a lightweight theme
|
||||
// selected by default).
|
||||
user_pref("lightweightThemes.selectedThemeID", "");
|
||||
user_pref("lightweightThemes.selectedThemeID", "default-theme@mozilla.org");
|
||||
user_pref("media.capturestream_hints.enabled", true);
|
||||
user_pref("media.gmp-manager.url", "http://127.0.0.1/gmpmanager-dummy/update.xml");
|
||||
// Don't block old libavcodec libraries when testing, because our test systems
|
||||
|
|
|
@ -189,7 +189,7 @@ user_pref("layout.css.shape-outside.enabled", true);
|
|||
user_pref("layout.spammy_warnings.enabled", false);
|
||||
// Make tests run consistently on DevEdition (which has a lightweight theme
|
||||
// selected by default).
|
||||
user_pref("lightweightThemes.selectedThemeID", "");
|
||||
user_pref("lightweightThemes.selectedThemeID", "default-theme@mozilla.org");
|
||||
// Disable all recommended Marionette preferences for Gecko tests.
|
||||
// The prefs recommended by Marionette are typically geared towards
|
||||
// consumer automation; not vendor testing.
|
||||
|
|
|
@ -125,6 +125,7 @@ add_task(async function test_management_themes() {
|
|||
};
|
||||
is(await extension.awaitMessage("onInstalled"), "Bling", "LWT installed");
|
||||
is(await extension.awaitMessage("onEnabled"), "Bling", "LWT enabled");
|
||||
is(await extension.awaitMessage("onDisabled"), "Default", "default disabled");
|
||||
|
||||
await theme.startup();
|
||||
is(await extension.awaitMessage("onInstalled"), "Simple theme test", "webextension theme installed");
|
||||
|
|
|
@ -1313,6 +1313,12 @@ nsBaseWidget::CreateCompositorSession(int aWidth,
|
|||
do {
|
||||
CreateCompositorVsyncDispatcher();
|
||||
|
||||
gfx::GPUProcessManager* gpu = gfx::GPUProcessManager::Get();
|
||||
// Make sure GPU process is ready for use.
|
||||
// If it failed to connect to GPU process, GPU process usage is disabled in EnsureGPUReady().
|
||||
// It could update gfxVars and gfxConfigs.
|
||||
gpu->EnsureGPUReady();
|
||||
|
||||
// If widget type does not supports acceleration, we use ClientLayerManager
|
||||
// even when gfxVars::UseWebRender() is true. WebRender could coexist only
|
||||
// with BasicCompositor.
|
||||
|
@ -1338,7 +1344,6 @@ nsBaseWidget::CreateCompositorSession(int aWidth,
|
|||
}
|
||||
|
||||
bool retry = false;
|
||||
gfx::GPUProcessManager* gpu = gfx::GPUProcessManager::Get();
|
||||
mCompositorSession = gpu->CreateTopLevelCompositor(
|
||||
this,
|
||||
lm,
|
||||
|
|
|
@ -30,15 +30,18 @@ XPIDL_SOURCES += [
|
|||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
XPIDL_SOURCES += [
|
||||
'nsIMacPreferencesReader.idl',
|
||||
'nsIMacUtils.idl',
|
||||
]
|
||||
EXPORTS.mozilla += [
|
||||
'MacHelpers.h',
|
||||
'MacStringHelpers.h',
|
||||
'nsMacPreferencesReader.h',
|
||||
]
|
||||
UNIFIED_SOURCES += [
|
||||
'MacHelpers.mm',
|
||||
'MacStringHelpers.mm',
|
||||
'nsMacPreferencesReader.mm',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'xpcom_base'
|
||||
|
@ -213,6 +216,7 @@ FINAL_LIBRARY = 'xul'
|
|||
LOCAL_INCLUDES += [
|
||||
'../build',
|
||||
'/dom/base',
|
||||
'/mfbt',
|
||||
'/xpcom/ds',
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* 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 "nsISupportsPrimitives.idl"
|
||||
|
||||
%{C++
|
||||
#define ENTERPRISE_POLICIES_ENABLED_KEY "EnterprisePoliciesEnabled"
|
||||
%}
|
||||
|
||||
/**
|
||||
* This interface is designed to provide scriptable access to the macOS
|
||||
* preferences system.
|
||||
*
|
||||
* This interface is highly macOS specific.
|
||||
*/
|
||||
[scriptable, uuid(06da64da-647f-4286-ac20-50ab4190cfe3)]
|
||||
interface nsIMacPreferencesReader : nsISupports
|
||||
{
|
||||
/**
|
||||
* This method checks whether macOS policies are enabled.
|
||||
*
|
||||
* @return true if macOS policies are enabled, false otherwise.
|
||||
*/
|
||||
bool policiesEnabled();
|
||||
|
||||
/**
|
||||
* This method reads and returns the macOS preferences.
|
||||
*
|
||||
* @return A JSON object containing all macOS preferences.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
jsval readPreferences();
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
/* 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 MacPreferencesReader_h__
|
||||
#define MacPreferencesReader_h__
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "nsIMacPreferencesReader.h"
|
||||
|
||||
#define NS_MACPREFERENCESREADER_CID \
|
||||
{ 0x95790842, 0x75a0, 0x430d, \
|
||||
{ 0x98, 0xbf, 0xf5, 0xce, 0x37, 0x88, 0xea, 0x6d } }
|
||||
#define NS_MACPREFERENCESREADER_CONTRACTID \
|
||||
"@mozilla.org/mac-preferences-reader;1"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class nsMacPreferencesReader : public nsIMacPreferencesReader
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMACPREFERENCESREADER
|
||||
|
||||
nsMacPreferencesReader() {};
|
||||
|
||||
protected:
|
||||
virtual ~nsMacPreferencesReader() = default;
|
||||
};
|
||||
|
||||
#endif // MacPreferencesReader_h__
|
|
@ -0,0 +1,97 @@
|
|||
/* 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 "nsMacPreferencesReader.h"
|
||||
|
||||
#include "js/JSON.h"
|
||||
#include "JSONWriter.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsMacPreferencesReader, nsIMacPreferencesReader)
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
struct StringWriteFunc : public JSONWriteFunc
|
||||
{
|
||||
nsCString& mCString;
|
||||
explicit StringWriteFunc(nsCString& aCString) : mCString(aCString)
|
||||
{
|
||||
}
|
||||
void Write(const char* aStr) override { mCString.Append(aStr); }
|
||||
};
|
||||
|
||||
static void
|
||||
EvaluateDict(JSONWriter* aWriter, NSDictionary<NSString*, id>* aDict);
|
||||
|
||||
static void
|
||||
EvaluateArray(JSONWriter* aWriter, NSArray* aArray)
|
||||
{
|
||||
for (id elem in aArray) {
|
||||
if ([elem isKindOfClass:[NSString class]]) {
|
||||
aWriter->StringElement([elem UTF8String]);
|
||||
} else if ([elem isKindOfClass:[NSNumber class]]) {
|
||||
aWriter->IntElement([elem longLongValue]);
|
||||
} else if ([elem isKindOfClass:[NSArray class]]) {
|
||||
aWriter->StartArrayElement();
|
||||
EvaluateArray(aWriter, elem);
|
||||
aWriter->EndArray();
|
||||
} else if ([elem isKindOfClass:[NSDictionary class]]) {
|
||||
aWriter->StartObjectElement();
|
||||
EvaluateDict(aWriter, elem);
|
||||
aWriter->EndObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
EvaluateDict(JSONWriter* aWriter, NSDictionary<NSString*, id>* aDict)
|
||||
{
|
||||
for (NSString* key in aDict) {
|
||||
id value = aDict[key];
|
||||
if ([value isKindOfClass:[NSString class]]) {
|
||||
aWriter->StringProperty([key UTF8String], [value UTF8String]);
|
||||
} else if ([value isKindOfClass:[NSNumber class]]) {
|
||||
aWriter->IntProperty([key UTF8String], [value longLongValue]);
|
||||
} else if ([value isKindOfClass:[NSArray class]]) {
|
||||
aWriter->StartArrayProperty([key UTF8String]);
|
||||
EvaluateArray(aWriter, value);
|
||||
aWriter->EndArray();
|
||||
} else if ([value isKindOfClass:[NSDictionary class]]) {
|
||||
aWriter->StartObjectProperty([key UTF8String]);
|
||||
EvaluateDict(aWriter, value);
|
||||
aWriter->EndObject();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacPreferencesReader::PoliciesEnabled(bool* aPoliciesEnabled)
|
||||
{
|
||||
NSString* policiesEnabledStr =
|
||||
[NSString stringWithUTF8String:ENTERPRISE_POLICIES_ENABLED_KEY];
|
||||
*aPoliciesEnabled = [[NSUserDefaults standardUserDefaults]
|
||||
boolForKey:policiesEnabledStr] == YES;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacPreferencesReader::ReadPreferences(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aResult)
|
||||
{
|
||||
nsAutoCString jsonStr;
|
||||
JSONWriter w(MakeUnique<StringWriteFunc>(jsonStr));
|
||||
w.Start();
|
||||
EvaluateDict(&w, [[NSUserDefaults standardUserDefaults]
|
||||
dictionaryRepresentation]);
|
||||
w.End();
|
||||
|
||||
NS_ConvertUTF8toUTF16 jsString(nsDependentCString(jsonStr.get()));
|
||||
auto json = static_cast<const char16_t*>(jsString.get());
|
||||
|
||||
JS::RootedValue val(aCx);
|
||||
MOZ_ALWAYS_TRUE(JS_ParseJSON(aCx, json, jsonStr.Length(), &val));
|
||||
|
||||
aResult.set(val);
|
||||
return NS_OK;
|
||||
}
|
|
@ -93,6 +93,7 @@ extern nsresult nsStringInputStreamConstructor(nsISupports*, REFNSIID, void**);
|
|||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
#include "nsMacUtilsImpl.h"
|
||||
#include "nsMacPreferencesReader.h"
|
||||
#endif
|
||||
|
||||
#include "nsSystemInfo.h"
|
||||
|
@ -213,6 +214,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
|
|||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacUtilsImpl)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacPreferencesReader)
|
||||
#endif
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemInfo, Init)
|
||||
|
@ -251,6 +253,10 @@ NS_DEFINE_NAMED_CID(NS_CHROMEPROTOCOLHANDLER_CID);
|
|||
|
||||
NS_DEFINE_NAMED_CID(NS_SECURITY_CONSOLE_MESSAGE_CID);
|
||||
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
NS_DEFINE_NAMED_CID(NS_MACPREFERENCESREADER_CID);
|
||||
#endif
|
||||
|
||||
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsChromeRegistry,
|
||||
nsChromeRegistry::GetSingleton)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsChromeProtocolHandler)
|
||||
|
@ -278,6 +284,9 @@ const mozilla::Module::CIDEntry kXPCOMCIDEntries[] = {
|
|||
{ &kNS_CHROMEREGISTRY_CID, false, nullptr, nsChromeRegistryConstructor },
|
||||
{ &kNS_CHROMEPROTOCOLHANDLER_CID, false, nullptr, nsChromeProtocolHandlerConstructor },
|
||||
{ &kNS_SECURITY_CONSOLE_MESSAGE_CID, false, nullptr, nsSecurityConsoleMessageConstructor },
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
{ &kNS_MACPREFERENCESREADER_CID, false, nullptr, nsMacPreferencesReaderConstructor },
|
||||
#endif
|
||||
{ nullptr }
|
||||
};
|
||||
#undef COMPONENT
|
||||
|
@ -291,6 +300,9 @@ const mozilla::Module::ContractIDEntry kXPCOMContracts[] = {
|
|||
{ NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "chrome", &kNS_CHROMEPROTOCOLHANDLER_CID },
|
||||
{ NS_INIPARSERFACTORY_CONTRACTID, &kINIParserFactoryCID },
|
||||
{ NS_SECURITY_CONSOLE_MESSAGE_CONTRACTID, &kNS_SECURITY_CONSOLE_MESSAGE_CID },
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
{ NS_MACPREFERENCESREADER_CONTRACTID, &kNS_MACPREFERENCESREADER_CID },
|
||||
#endif
|
||||
{ nullptr }
|
||||
};
|
||||
#undef COMPONENT
|
||||
|
|
Загрузка…
Ссылка в новой задаче