mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 02:09:05 +02:00 
			
		
		
		
	Depends on D172133 Differential Revision: https://phabricator.services.mozilla.com/D172138
		
			
				
	
	
		
			185 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* vim: set ts=2 sw=2 sts=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/. */
 | 
						|
 | 
						|
import {
 | 
						|
  ContentPref,
 | 
						|
  _methodsCallableFromChild,
 | 
						|
  cbHandleCompletion,
 | 
						|
  cbHandleError,
 | 
						|
  cbHandleResult,
 | 
						|
  safeCallback,
 | 
						|
} from "resource://gre/modules/ContentPrefUtils.sys.mjs";
 | 
						|
 | 
						|
// We only need one bit of information out of the context.
 | 
						|
function contextArg(context) {
 | 
						|
  return context && context.usePrivateBrowsing
 | 
						|
    ? { usePrivateBrowsing: true }
 | 
						|
    : null;
 | 
						|
}
 | 
						|
 | 
						|
function NYI() {
 | 
						|
  throw new Error("Do not add any new users of these functions");
 | 
						|
}
 | 
						|
 | 
						|
function CallbackCaller(callback) {
 | 
						|
  this._callback = callback;
 | 
						|
}
 | 
						|
 | 
						|
CallbackCaller.prototype = {
 | 
						|
  handleResult(contentPref) {
 | 
						|
    cbHandleResult(
 | 
						|
      this._callback,
 | 
						|
      new ContentPref(contentPref.domain, contentPref.name, contentPref.value)
 | 
						|
    );
 | 
						|
  },
 | 
						|
 | 
						|
  handleError(result) {
 | 
						|
    cbHandleError(this._callback, result);
 | 
						|
  },
 | 
						|
 | 
						|
  handleCompletion(reason) {
 | 
						|
    cbHandleCompletion(this._callback, reason);
 | 
						|
  },
 | 
						|
};
 | 
						|
 | 
						|
export class ContentPrefsChild extends JSProcessActorChild {
 | 
						|
  constructor() {
 | 
						|
    super();
 | 
						|
 | 
						|
    // Map from pref name -> set of observers
 | 
						|
    this._observers = new Map();
 | 
						|
 | 
						|
    // Map from random ID string -> CallbackCaller, per request
 | 
						|
    this._requests = new Map();
 | 
						|
  }
 | 
						|
 | 
						|
  _getRandomId() {
 | 
						|
    return Services.uuid.generateUUID().toString();
 | 
						|
  }
 | 
						|
 | 
						|
  receiveMessage(msg) {
 | 
						|
    let data = msg.data;
 | 
						|
    let callback;
 | 
						|
    switch (msg.name) {
 | 
						|
      case "ContentPrefs:HandleResult":
 | 
						|
        callback = this._requests.get(data.requestId);
 | 
						|
        callback.handleResult(data.contentPref);
 | 
						|
        break;
 | 
						|
 | 
						|
      case "ContentPrefs:HandleError":
 | 
						|
        callback = this._requests.get(data.requestId);
 | 
						|
        callback.handleError(data.error);
 | 
						|
        break;
 | 
						|
 | 
						|
      case "ContentPrefs:HandleCompletion":
 | 
						|
        callback = this._requests.get(data.requestId);
 | 
						|
        this._requests.delete(data.requestId);
 | 
						|
        callback.handleCompletion(data.reason);
 | 
						|
        break;
 | 
						|
 | 
						|
      case "ContentPrefs:NotifyObservers": {
 | 
						|
        let observerList = this._observers.get(data.name);
 | 
						|
        if (!observerList) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
 | 
						|
        for (let observer of observerList) {
 | 
						|
          safeCallback(observer, data.callback, data.args);
 | 
						|
        }
 | 
						|
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  callFunction(call, args, callback) {
 | 
						|
    let requestId = this._getRandomId();
 | 
						|
    let data = { call, args, requestId };
 | 
						|
 | 
						|
    this._requests.set(requestId, new CallbackCaller(callback));
 | 
						|
    this.sendAsyncMessage("ContentPrefs:FunctionCall", data);
 | 
						|
  }
 | 
						|
 | 
						|
  addObserverForName(name, observer) {
 | 
						|
    let set = this._observers.get(name);
 | 
						|
    if (!set) {
 | 
						|
      set = new Set();
 | 
						|
 | 
						|
      // This is the first observer for this name. Start listening for changes
 | 
						|
      // to it.
 | 
						|
      this.sendAsyncMessage("ContentPrefs:AddObserverForName", {
 | 
						|
        name,
 | 
						|
      });
 | 
						|
      this._observers.set(name, set);
 | 
						|
    }
 | 
						|
 | 
						|
    set.add(observer);
 | 
						|
  }
 | 
						|
 | 
						|
  removeObserverForName(name, observer) {
 | 
						|
    let set = this._observers.get(name);
 | 
						|
    if (!set) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    set.delete(observer);
 | 
						|
    if (set.size === 0) {
 | 
						|
      // This was the last observer for this name. Stop listening for changes.
 | 
						|
      this.sendAsyncMessage("ContentPrefs:RemoveObserverForName", {
 | 
						|
        name,
 | 
						|
      });
 | 
						|
 | 
						|
      this._observers.delete(name);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
export var ContentPrefServiceChild = {
 | 
						|
  QueryInterface: ChromeUtils.generateQI(["nsIContentPrefService2"]),
 | 
						|
 | 
						|
  addObserverForName: (name, observer) => {
 | 
						|
    ChromeUtils.domProcessChild
 | 
						|
      .getActor("ContentPrefs")
 | 
						|
      .addObserverForName(name, observer);
 | 
						|
  },
 | 
						|
  removeObserverForName: (name, observer) => {
 | 
						|
    ChromeUtils.domProcessChild
 | 
						|
      .getActor("ContentPrefs")
 | 
						|
      .removeObserverForName(name, observer);
 | 
						|
  },
 | 
						|
 | 
						|
  getCachedByDomainAndName: NYI,
 | 
						|
  getCachedBySubdomainAndName: NYI,
 | 
						|
  getCachedGlobal: NYI,
 | 
						|
  extractDomain: NYI,
 | 
						|
};
 | 
						|
 | 
						|
function forwardMethodToParent(method, signature, ...args) {
 | 
						|
  // Ignore superfluous arguments
 | 
						|
  args = args.slice(0, signature.length);
 | 
						|
 | 
						|
  // Process context argument for forwarding
 | 
						|
  let contextIndex = signature.indexOf("context");
 | 
						|
  if (contextIndex > -1) {
 | 
						|
    args[contextIndex] = contextArg(args[contextIndex]);
 | 
						|
  }
 | 
						|
  // Take out the callback argument, if present.
 | 
						|
  let callbackIndex = signature.indexOf("callback");
 | 
						|
  let callback = null;
 | 
						|
  if (callbackIndex > -1 && args.length > callbackIndex) {
 | 
						|
    callback = args.splice(callbackIndex, 1)[0];
 | 
						|
  }
 | 
						|
 | 
						|
  let actor = ChromeUtils.domProcessChild.getActor("ContentPrefs");
 | 
						|
  actor.callFunction(method, args, callback);
 | 
						|
}
 | 
						|
 | 
						|
for (let [method, signature] of _methodsCallableFromChild) {
 | 
						|
  ContentPrefServiceChild[method] = forwardMethodToParent.bind(
 | 
						|
    ContentPrefServiceChild,
 | 
						|
    method,
 | 
						|
    signature
 | 
						|
  );
 | 
						|
}
 |