This file is indexed.

/usr/share/xul-ext/firegestures/components/xdGestureMapping.js is in xul-ext-firegestures 1.10.9-1~deb8u1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;

const TYPE_CATEGORY = Ci.xdIGestureMapping.TYPE_CATEGORY;
const TYPE_NORMAL   = Ci.xdIGestureMapping.TYPE_NORMAL;
const TYPE_SCRIPT   = Ci.xdIGestureMapping.TYPE_SCRIPT;

const RDF_NS   = "http://www.xuldev.org/firegestures-mapping#";
const RDF_ROOT = "urn:mapping:root";
const BROWSER_ID = "gesture_mappings";
const WINDOW_TYPE = "FireGestures:Options";

Cu.import("resource://gre/modules/XPCOMUtils.jsm");

function alert(aMsg) {
	Cu.reportError(aMsg);
	var fuelApp = Cc["@mozilla.org/fuel/application;1"].getService(Ci.fuelIApplication);
	fuelApp.console.open();
}



function xdGestureMapping() {}


xdGestureMapping.prototype = {

	classDescription: "Mouse Gesture Mapping",
	contractID: "@xuldev.org/firegestures/mapping;1",
	classID: Components.ID("{d7018e80-d6da-4cbc-b77f-8dca4d95bbbf}"),
	QueryInterface: XPCOMUtils.generateQI([
		Ci.nsISupports,
		Ci.xdIGestureMapping
	]),

	get rdfSvc() {
		var svc = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
		this.__defineGetter__("rdfSvc", function() svc);
		return this.rdfSvc;
	},

	id: null,

	name: null,

	_dataSource: null,

	_mapping: null,

	_getDBConnection: null,


	init: function FGM_init(aID, aURI, aName) {
		if (this._dataSource)
			throw Cr.NS_ERROR_ALREADY_INITIALIZED;
		if (!/^\w+$/.test(aID))
			throw Cr.NS_ERROR_ILLEGAL_VALUE;
		this.id = aID;
		this.name = aName;
		var gestureSvc = Cc["@xuldev.org/firegestures/service;1"].getService(Ci.xdIGestureService);
		this._getDBConnection = gestureSvc.getDBConnection;
		try {
			this._dataSource = this.rdfSvc.GetDataSourceBlocking(aURI);
		}
		catch(ex) {
			alert("FireGestures: An error occurred while parsing gesture mapping.\n\n" + ex);
			throw ex;
		}
		this._reloadMapping();
	},

	_ensureInit: function FGM__ensureInit() {
		if (!this._dataSource)
			throw Cr.NS_ERROR_NOT_INITIALIZED;
	},

	finalize: function FGM_finalize() {
		if (this._dataSource)
			this.rdfSvc.UnregisterDataSource(this._dataSource);
		this.id   = null;
		this.name = null;
		this._dataSource = null;
		this._mapping    = null;
	},

	_reloadMapping: function FGM__reloadMapping() {
		this._mapping = null;
		this._getUserMapping() || this._getDefaultMapping();
	},

	_getUserMapping: function FGM__getUserMapping() {
		this._ensureInit();
		var dbConn = this._getDBConnection(false);
		if (!dbConn || !dbConn.tableExists(this.id))
			return false;
		this._mapping = {};
		var stmt = dbConn.createStatement("SELECT * FROM " + this.id);
		try {
			while (stmt.executeStep()) {
				var type      = stmt.getInt32(0);
				var name      = stmt.getUTF8String(1);
				var command   = stmt.getUTF8String(2);
				var direction = stmt.getUTF8String(3);
				if (!command || !direction)
					continue;
				if (type != TYPE_SCRIPT)
					name = this._getLocalizedNameForCommand(command);
				this._mapping[direction] = new xdGestureCommand(type, name, command);
			}
		}
		catch(ex) { Cu.reportError(ex); }
		finally { stmt.reset(); stmt.finalize(); }
		var swipes = ["swipe-left", "swipe-right", "swipe-up", "swipe-down"];
		if (swipes.every(function(swipe) this._mapping[swipe] === undefined, this)) {
			swipes.forEach(function(swipe) {
				var prop    = this.rdfSvc.GetResource(RDF_NS + "extra");
				var target  = this.rdfSvc.GetLiteral(swipe);
				var res     = this._dataSource.GetSource(prop, target, true);
				var command = res.Value.substr(("urn:").length);
				var name    = this._getLocalizedNameForCommand(command);
				this._mapping[swipe] = new xdGestureCommand(TYPE_NORMAL, name, command);
			}, this);
		}
		return true;
	},

	_getDefaultMapping: function FGM__getDefaultMapping() {
		this._ensureInit();
		this._mapping = {};
		var rdfCont = Cc["@mozilla.org/rdf/container;1"].createInstance(Ci.nsIRDFContainer);
		rdfCont.Init(this._dataSource, this.rdfSvc.GetResource(RDF_ROOT));
		var resEnum = rdfCont.GetElements();
		while (resEnum.hasMoreElements()) {
			var res = resEnum.getNext().QueryInterface(Ci.nsIRDFResource);
			var type      = parseInt(this._getPropertyValue(res, "type"), 10);
			var name      = this._getPropertyValue(res, "name");
			var command   = res.Value.substr(("urn:").length);
			var direction = this._getPropertyValue(res, "direction");
			var extra     = this._getPropertyValue(res, "extra");
			if (type == TYPE_CATEGORY || (!direction && !extra))
				continue;
			this._mapping[direction] = new xdGestureCommand(type, name, command);
			if (extra)
				this._mapping[extra] = new xdGestureCommand(type, name, command);
		}
	},

	_getLocalizedNameForCommand: function FGM__getLocalizedNameForCommand(aCommand) {
		var res = this.rdfSvc.GetResource("urn:" + aCommand);
		return this._getPropertyValue(res, "name");
	},

	_getPropertyValue: function FGM__getPropertyValue(aRes, aProp) {
		aProp = this.rdfSvc.GetResource(RDF_NS + aProp);
		try {
			var target = this._dataSource.GetTarget(aRes, aProp, true);
			return target ? target.QueryInterface(Ci.nsIRDFLiteral).Value : null;
		}
		catch(ex) {
			return null;
		}
	},


	getCommandForDirection: function FGM_getCommandForDirection(aDirection) {
		return this._mapping[aDirection];
	},

	configure: function FGS_configure() {
		var browser = this.id == BROWSER_ID;
		var type = browser ? WINDOW_TYPE : WINDOW_TYPE + ":" + this.id;
		var winMed = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
		var win = winMed.getMostRecentWindow(type);
		if (win) {
			win.focus();
			win.document.documentElement.showPane(win.document.getElementById("mappingPane"));
			return;
		}
		var url = browser ? "chrome://firegestures/content/prefs.xul" : 
		                    "chrome://firegestures/content/prefs-generic.xul";
		var features = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
		win = winMed.getMostRecentWindow(null);
		if (browser)
			win.openDialog(url, type, features);
		else
			win.openDialog(url, type, features, this.id);
	},

	getMappingArray: function FGM_getMappingArray() {
		this._ensureInit();
		var items = [];
		var dbConn = this._getDBConnection(false);
		if (!dbConn || !dbConn.tableExists(this.id))
			dbConn = null;
		var rdfCont = Cc["@mozilla.org/rdf/container;1"].createInstance(Ci.nsIRDFContainer);
		rdfCont.Init(this._dataSource, this.rdfSvc.GetResource(RDF_ROOT));
		var resEnum = rdfCont.GetElements();
		while (resEnum.hasMoreElements()) {
			var res = resEnum.getNext().QueryInterface(Ci.nsIRDFResource);
			var type    = parseInt(this._getPropertyValue(res, "type"), 10);
			var name    = this._getPropertyValue(res, "name");
			var command = res.Value.substr("urn:".length);
			var flags   = this._getPropertyValue(res, "flags");
			if (dbConn && type == TYPE_NORMAL) {
				var directions = [];
				var stmt = dbConn.createStatement("SELECT direction FROM " + this.id + " WHERE command = ?");
				stmt.bindUTF8StringParameter(0, command);
				try {
					while (stmt.executeStep())
						directions.push(stmt.getUTF8String(0));
				}
				catch(ex) { Cu.reportError(ex); }
				finally { stmt.reset(); stmt.finalize(); }
				if (!directions.some(function(direction) { return /^[LRUD]*$/.test(direction); }))
					directions.unshift("");
				for (let direction of directions)
					items.push([type, name, command, direction, flags]);
			}
			else {
				var direction = this._getPropertyValue(res, "direction") || "";
				var extra     = this._getPropertyValue(res, "extra");
				items.push([type, name, command, direction, flags]);
				if (extra)
					items.push([type, name, command, extra, flags]);
			}
		}
		if (dbConn) {
			var sql = "SELECT name, command, direction FROM " + this.id + " WHERE type = " + TYPE_SCRIPT;
			var stmt = dbConn.createStatement(sql);
			try {
				while (stmt.executeStep()) {
					items.push([
						TYPE_SCRIPT, stmt.getUTF8String(0), stmt.getUTF8String(1), stmt.getUTF8String(2), null
					]);
				}
			}
			catch(ex) { Cu.reportError(ex); }
			finally { stmt.reset(); stmt.finalize(); }
		}
		return items;
	},

	saveUserMapping: function FGM_saveUserMapping(aItems) {
		this._ensureInit();
		var dbConn = this._getDBConnection(true);
		dbConn.executeSimpleSQL("DROP TABLE IF EXISTS " + this.id);
		dbConn.createTable(this.id, "type INTEGER, name TEXT, command TEXT, direction TEXT");
		dbConn.beginTransaction();
		for (let [type, name, command, direction] of aItems) {
			if (type == TYPE_CATEGORY || (type == TYPE_NORMAL && (!direction || !command)))
				continue;
			var stmt = dbConn.createStatement("INSERT INTO " + this.id + " VALUES(?,?,?,?)");
			stmt.bindInt32Parameter(0, type);
			stmt.bindUTF8StringParameter(1, type == TYPE_SCRIPT ? name : "");
			stmt.bindUTF8StringParameter(2, command);
			stmt.bindUTF8StringParameter(3, direction);
			try {
				stmt.execute();
			}
			catch(ex) { Cu.reportError(ex); }
			finally { stmt.reset(); stmt.finalize(); }
		}
		dbConn.commitTransaction();
		this._reloadMapping();
	},

	addScriptCommands: function FGM_addScriptCommands(aItems) {
		this._ensureInit();
		var added = false;
		var items = this.getMappingArray();
		outer: for (let aItem of aItems) {
			if (this.getCommandForDirection(aItem.direction))
				aItem.direction = "";
			inner: for (let [ type, , script, ] of items) {
				if (type != TYPE_SCRIPT)
					continue inner;
				if (script == aItem.script)
					continue outer;
			}
			items.push([TYPE_SCRIPT, aItem.name, aItem.script, aItem.direction, null]);
			added = true;
		}
		if (!added)
			return;
		this.saveUserMapping(items);
		this._reloadMapping();
	},

};



function xdGestureCommand(aType, aName, aCommand, aDirection) {
	this.type = aType;
	this.name = aName;
	this.value = aCommand;
	this.direction = aDirection;
}

xdGestureCommand.prototype = {
	QueryInterface: function(aIID) {
		if (!aIID.equals(Ci.nsISupports) && 
		    !aIID.equals(Ci.xdIGestureCommand)) {
			throw Cr.NS_ERROR_NO_INTERFACE;
		}
		return this;
	}
};



var NSGetFactory = XPCOMUtils.generateNSGetFactory([xdGestureMapping]);