Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 // Helper file for shared image functionality
3 //
4 // Note that this is use by tests elsewhere in the source tree. When in doubt,
5 // check mxr before removing or changing functionality.
7 // Helper function to clear the image cache of content images
8 function clearImageCache()
9 {
10 var tools = SpecialPowers.Cc["@mozilla.org/image/tools;1"]
11 .getService(SpecialPowers.Ci.imgITools);
12 var imageCache = tools.getImgCacheForDocument(window.document);
13 imageCache.clearCache(false); // true=chrome, false=content
14 }
16 // Helper function to determine if the frame is decoded for a given image id
17 function isFrameDecoded(id)
18 {
19 return (getImageStatus(id) &
20 SpecialPowers.Ci.imgIRequest.STATUS_FRAME_COMPLETE)
21 ? true : false;
22 }
24 // Helper function to determine if the image is loaded for a given image id
25 function isImageLoaded(id)
26 {
27 return (getImageStatus(id) &
28 SpecialPowers.Ci.imgIRequest.STATUS_LOAD_COMPLETE)
29 ? true : false;
30 }
32 // Helper function to get the status flags of an image
33 function getImageStatus(id)
34 {
35 // Get the image
36 var img = SpecialPowers.wrap(document.getElementById(id));
38 // QI the image to nsImageLoadingContent
39 img.QueryInterface(SpecialPowers.Ci.nsIImageLoadingContent);
41 // Get the request
42 var request = img.getRequest(SpecialPowers.Ci
43 .nsIImageLoadingContent
44 .CURRENT_REQUEST);
46 // Return the status
47 return request.imageStatus;
48 }
50 // Forces a synchronous decode of an image by drawing it to a canvas. Only
51 // really meaningful if the image is fully loaded first
52 function forceDecode(id)
53 {
54 // Get the image
55 var img = document.getElementById(id);
57 // Make a new canvas
58 var canvas = document.createElement("canvas");
60 // Draw the image to the canvas. This forces a synchronous decode
61 var ctx = canvas.getContext("2d");
62 ctx.drawImage(img, 0, 0);
63 }
66 // Functions to facilitate getting/setting various image-related prefs
67 //
68 // If you change a pref in a mochitest, Don't forget to reset it to its
69 // original value!
70 //
71 // Null indicates no pref set
73 const DISCARD_ENABLED_PREF = {name: "discardable", branch: "image.mem.", type: "bool"};
74 const DECODEONDRAW_ENABLED_PREF = {name: "decodeondraw", branch: "image.mem.", type: "bool"};
75 const DISCARD_TIMEOUT_PREF = {name: "min_discard_timeout_ms", branch: "image.mem.", type: "int"};
77 function setImagePref(pref, val)
78 {
79 var prefService = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]
80 .getService(SpecialPowers.Ci.nsIPrefService);
81 var branch = prefService.getBranch(pref.branch);
82 if (val != null) {
83 switch(pref.type) {
84 case "bool":
85 branch.setBoolPref(pref.name, val);
86 break;
87 case "int":
88 branch.setIntPref(pref.name, val);
89 break;
90 default:
91 throw new Error("Unknown pref type");
92 }
93 }
94 else if (branch.prefHasUserValue(pref.name))
95 branch.clearUserPref(pref.name);
96 }
98 function getImagePref(pref)
99 {
100 var prefService = SpecialPowers.Cc["@mozilla.org/preferences-service;1"]
101 .getService(SpecialPowers.Ci.nsIPrefService);
102 var branch = prefService.getBranch(pref.branch);
103 if (branch.prefHasUserValue(pref.name)) {
104 switch (pref.type) {
105 case "bool":
106 return branch.getBoolPref(pref.name);
107 case "int":
108 return branch.getIntPref(pref.name);
109 default:
110 throw new Error("Unknown pref type");
111 }
112 }
113 else
114 return null;
115 }
117 // JS implementation of imgIScriptedNotificationObserver with stubs for all of its methods.
118 function ImageDecoderObserverStub()
119 {
120 this.sizeAvailable = function sizeAvailable(aRequest) {}
121 this.frameComplete = function frameComplete(aRequest) {}
122 this.decodeComplete = function decodeComplete(aRequest) {}
123 this.loadComplete = function loadComplete(aRequest) {}
124 this.frameUpdate = function frameUpdate(aRequest) {}
125 this.discard = function discard(aRequest) {}
126 this.isAnimated = function isAnimated(aRequest) {}
127 }