1
# -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
4
# The contents of this file are subject to the Mozilla Public License Version
5
# 1.1 (the "License"); you may not use this file except in compliance with
6
# the License. You may obtain a copy of the License at
7
# http://www.mozilla.org/MPL/
9
# Software distributed under the License is distributed on an "AS IS" basis,
10
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
# for the specific language governing rights and limitations under the
14
# The Original Code is Mozilla.org Code.
16
# The Initial Developer of the Original Code is
18
# Portions created by the Initial Developer are Copyright (C) 2001
19
# the Initial Developer. All Rights Reserved.
22
# Ben Goodger <ben@bengoodger.com>
24
# Alternatively, the contents of this file may be used under the terms of
25
# either the GNU General Public License Version 2 or later (the "GPL"), or
26
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27
# in which case the provisions of the GPL or the LGPL are applicable instead
28
# of those above. If you wish to allow use of your version of this file only
29
# under the terms of either the GPL or the LGPL, and not to allow others to
30
# use your version of this file under the terms of the MPL, indicate your
31
# decision by deleting the provisions above and replace them with the notice
32
# and other provisions required by the GPL or the LGPL. If you do not delete
33
# the provisions above, a recipient may use your version of this file under
34
# the terms of any one of the MPL, the GPL or the LGPL.
36
# ***** END LICENSE BLOCK *****
40
///////////////////////////////////////////////////////////////////////////////
41
// MIME Types DataSource Wrapper
43
function NC_URI(aProperty)
45
return "http://home.netscape.com/NC-rdf#" + aProperty;
48
function MIME_URI(aType)
50
return "urn:mimetype:" + aType;
53
function HANDLER_URI(aHandler)
55
return "urn:mimetype:handler:" + aHandler;
58
function APP_URI(aType)
60
return "urn:mimetype:externalApplication:" + aType;
63
function ArrayEnumerator(aItems)
68
for (var i = 0; i < aItems.length; ++i) {
74
this._contents = aItems || [];
76
this.push = function (aElement)
79
this._contents.push(aElement);
82
this.hasMoreElements = function ()
84
return this._index < this._contents.length;
87
this.getNext = function ()
89
return this._contents[this._index++];
96
gRDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
98
const mimeTypes = "UMimTyp";
99
var fileLocator = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
101
var file = fileLocator.get(mimeTypes, Components.interfaces.nsIFile);
103
var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
104
var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Components.interfaces.nsIFileProtocolHandler);
105
this._inner = gRDF.GetDataSourceBlocking(fileHandler.getURLSpecFromFile(file));
106
this._inner.AddObserver(this);
108
this._fileTypeArc = gRDF.GetResource(NC_URI("FileType"));
109
this._fileHandlerArc = gRDF.GetResource(NC_URI("FileHandler"));
110
this._fileIconArc = gRDF.GetResource(NC_URI("FileIcon"));
111
this._fileExtensionArc = gRDF.GetResource(NC_URI("FileExtension"));
112
this._fileExtensionsArc = gRDF.GetResource(NC_URI("FileExtensions"));
113
this._handleAutoArc = gRDF.GetResource(NC_URI("FileHandleAuto"));
114
this._valueArc = gRDF.GetResource(NC_URI("value"));
115
this._handlerPropArc = gRDF.GetResource(NC_URI("handlerProp"));
116
this._externalAppArc = gRDF.GetResource(NC_URI("externalApplication"));
119
HelperApps.prototype = {
120
mimeHandlerExists: function (aMIMEType)
122
var valueProperty = gRDF.GetUnicodeResource(NC_URI("value"));
123
var mimeSource = gRDF.GetUnicodeResource(MIME_URI(aMIMEType));
124
var mimeLiteral = gRDF.GetLiteral(aMIMEType);
125
return this._inner.HasAssertion(mimeSource, valueProperty, mimeLiteral, true);
128
updateTypeInfo: function (aMIMEInfo)
130
var mimeType = aMIMEInfo.MIMEType;
131
var isNewMIMEType = this.mimeHandlerExists(mimeType);
132
var entry = new HandlerOverride(MIME_URI(mimeType), this._inner);
133
entry.mimeType = mimeType;
134
entry.isEditable = true;
135
entry.alwaysAsk = aMIMEInfo.alwaysAskBeforeHandling;
137
// If not updating (i.e., a newly encountered mime type),
138
// then update extension list and description.
139
if (!isNewMIMEType) {
140
var extEnumerator = aMIMEInfo.getFileExtensions();
141
while (extEnumerator.hasMore()) {
142
entry.addExtension(extEnumerator.getNext());
144
entry.description = aMIMEInfo.Description;
145
entry.appDisplayName = "";
148
const nsIMIMEInfo = Components.interfaces.nsIMIMEInfo;
149
if (aMIMEInfo.preferredAction == nsIMIMEInfo.saveToDisk) {
150
entry.saveToDisk = true;
151
if (!isNewMIMEType) {
152
// Creating a new entry, set path.
156
else if (aMIMEInfo.preferredAction == nsIMIMEInfo.useSystemDefault ||
157
aMIMEInfo.preferredApplicationHandler == null) {
158
entry.useSystemDefault = true;
159
if (!isNewMIMEType) {
160
// Creating a new entry, set path.
165
entry.saveToDisk = false;
166
entry.useSystemDefault = false;
167
entry.handleInternal = false;
168
entry.appPath = aMIMEInfo.preferredApplicationHandler.path;
169
entry.appDisplayName = aMIMEInfo.applicationDescription;
177
getLiteralValue: function (aResource, aProperty)
179
var res = gRDF.GetResource(aResource);
180
var prop = gRDF.GetResource(NC_URI(aProperty));
181
var val = this.GetTarget(res, prop, true);
183
val = val.QueryInterface(Components.interfaces.nsIRDFLiteral);
189
/* nsIRDFDataSource */
191
return this._inner.URI;
194
GetSource: function (aProperty, aTarget, aTruthValue) {
195
return this._inner.GetSource(aProperty, aTarget, aTruthValue);
197
GetSources: function (aProperty, aTarget, aTruthValue) {
198
return this._inner.GetSources(aProperty, aTarget, aTruthValue);
201
_isRootTypeResource: function (aResource) {
202
aResource = aResource.QueryInterface(Components.interfaces.nsIRDFResource);
203
const kRootTypePrefix = "urn:mimetype:";
204
return (aResource.Value.substr(0, kRootTypePrefix.length) == kRootTypePrefix);
207
getMIMEInfo: function (aResource) {
208
var types = this._inner.GetTarget(aResource, this._valueArc, true);
210
types = types.QueryInterface(Components.interfaces.nsIRDFLiteral);
211
types = types.Value.split(", ");
213
// We're using helper app service as our MIME Service here because the helper app service
214
// talks to OS Specific hooks that on some platforms (MacOS X) are required to get a
215
// fully populated MIME Info object. Thus it is this object that we return.
216
mimeSvc = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"].getService(Components.interfaces.nsIMIMEService);
217
return mimeSvc.getFromTypeAndExtension(types[0], null);
223
GetTarget: function (aSource, aProperty, aTruthValue) {
224
if (this._isRootTypeResource(aSource)) {
225
var typeInfo = this.getMIMEInfo(aSource);
227
var bundle = document.getElementById("strings");
228
if (aProperty.EqualsNode(this._handleAutoArc)) {
229
var handler = this.GetTarget(aSource, this._handlerPropArc, true);
231
handler = handler.QueryInterface(Components.interfaces.nsIRDFResource);
232
return gRDF.GetLiteral(!(this.getLiteralValue(handler.Value, "alwaysAsk") == "true"));
235
else if (aProperty.EqualsNode(this._fileTypeArc)) {
236
if (typeInfo.Description == "") {
238
var literal = bundle.getFormattedString("fileEnding", [typeInfo.primaryExtension.toUpperCase()]);
239
return gRDF.GetLiteral(literal);
242
// Wow, this sucks, just show the MIME type as a last ditch effort to display
243
// the type of file that this is.
244
return gRDF.GetLiteral(typeInfo.MIMEType);
247
return gRDF.GetLiteral(typeInfo.Description);
249
else if (aProperty.EqualsNode(this._fileHandlerArc)) {
250
var handler = this.GetTarget(aSource, this._handlerPropArc, true);
252
handler = handler.QueryInterface(Components.interfaces.nsIRDFResource);
253
if (this.getLiteralValue(handler.Value, "saveToDisk") == "true") {
254
var saveToDisk = bundle.getString("saveToDisk");
255
return gRDF.GetLiteral(saveToDisk);
257
else if (this.getLiteralValue(handler.Value, "useSystemDefault") == "false") {
258
var extApp = this.GetTarget(handler, this._externalAppArc, true);
260
extApp = extApp.QueryInterface(Components.interfaces.nsIRDFResource);
261
var openWith = bundle.getFormattedString("openWith", [this.getLiteralValue(extApp.Value, "prettyName")]);
262
return gRDF.GetLiteral(openWith);
267
var openWith2 = bundle.getFormattedString("openWith", [typeInfo.defaultDescription]);
268
return gRDF.GetLiteral(openWith2);
270
else if (aProperty.EqualsNode(this._fileIconArc)) {
272
return gRDF.GetLiteral("moz-icon://goat." + typeInfo.primaryExtension + "?size=16");
275
return gRDF.GetLiteral("moz-icon://goat?size=16&contentType=" + typeInfo.MIMEType);
278
else if (aProperty.EqualsNode(this._fileExtensionArc)) {
280
return gRDF.GetLiteral(typeInfo.primaryExtension.toUpperCase());
283
return gRDF.GetLiteral("");
285
else if (aProperty.EqualsNode(this._fileExtensionsArc)) {
286
var extns = typeInfo.getFileExtensions();
288
// Prevent duplicates.
290
while (extns.hasMore())
291
hash[extns.getNext().toUpperCase()] = 0;
294
for (var extn in hash)
296
str = str.substring(0, str.length - 1);
298
return gRDF.GetLiteral(str);
303
return this._inner.GetTarget(aSource, aProperty, aTruthValue);
306
GetTargets: function (aSource, aProperty, aTruthValue) {
307
if (this._isRootTypeResource(aSource)) {
308
return new ArrayEnumerator([this.GetTarget(aSource, aProperty, aTruthValue)]);
311
return this._inner.GetTargets(aSource, aProperty, aTruthValue);
313
Assert: function (aSource, aProperty, aTarget, aTruthValue) {
314
return this._inner.Assert(aSource, aProperty, aTarget, aTruthValue);
316
Unassert: function (aSource, aProperty, aTarget) {
317
return this._inner.Unassert(aSource, aProperty, aTarget);
319
Change: function (aSource, aProperty, aOldTarget, aNewTarget) {
321
var ot = aOldTarget.QueryInterface(Components.interfaces.nsIRDFLiteral);
323
var nt = aNewTarget.QueryInterface(Components.interfaces.nsIRDFLiteral);
325
return this._inner.Change(aSource, aProperty, aOldTarget, aNewTarget);
327
Move: function (aOldSource, aNewSource, aProperty, aTarget) {
328
return this._inner.Assert(aOldSource, aNewSource, aProperty, aTarget);
330
HasAssertion: function (aSource, aProperty, aTarget, aTruthValue) {
331
if (this._isRootTypeResource(aSource)) {
332
// Don't show entries in the list for types that we DO NOT handle
333
// automatically. i.e. this list is a means of editing and removing
334
// automatic overrides only.
335
if (aProperty.EqualsNode(this._handleAutoArc)) {
336
var handler = this.GetTarget(aSource, this._handlerPropArc, true);
338
handler = handler.QueryInterface(Components.interfaces.nsIRDFResource);
339
return !(this.getLiteralValue(handler.Value, "alwaysAsk") == "true");
343
return this._inner.HasAssertion(aSource, aProperty, aTarget, aTruthValue);
345
AddObserver: function (aObserver) {
346
this._inner.AddObserver(aObserver);
348
RemoveObserver: function (aObserver) {
349
this._inner.RemoveObserver(aObserver);
351
ArcLabelsIn: function (aNode) {
352
return this._inner.ArcLabelsIn(aNode);
354
ArcLabelsOut: function (aNode) {
355
return this._inner.ArcLabelsOut(aNode);
357
GetAllResources: function () {
358
return this._inner.GetAllResources();
360
hasArcIn: function (aNode, aArc) {
361
return this._inner.hasArcIn(aNode, aArc);
363
hasArcOut: function (aNode, aArc) {
364
return this._inner.hasArcOut(aNode, aArc);
368
AddObserver: function (aObserver) {
369
this._observers.push(aObserver);
372
RemoveObserver: function (aObserver) {
373
for (var i = 0; i < this._observers.length; ++i) {
374
if (this._observers[i] == aObserver) {
375
this._observers.splice(i, 1);
381
onAssert: function (aDataSource, aSource, aProperty, aTarget) {
382
for (var i = 0; i < this._observers.length; ++i) {
383
this._observers[i].onAssert(aDataSource, aSource, aProperty, aTarget);
387
onUnassert: function (aDataSource, aSource, aProperty, aTarget) {
388
for (var i = 0; i < this._observers.length; ++i) {
389
this._observers[i].onUnassert(aDataSource, aSource, aProperty, aTarget);
393
onChange: function (aDataSource, aSource, aProperty, aOldTarget, aNewTarget) {
394
for (var i = 0; i < this._observers.length; ++i) {
395
this._observers[i].onChange(aDataSource, aSource, aProperty, aOldTarget, aNewTarget);
399
onMove: function (aDataSource, aOldSource, aNewSource, aProperty, aTarget) {
400
for (var i = 0; i < this._observers.length; ++i) {
401
this._observers[i].onMove(aDataSource, aOldSource, aNewSource, aProperty, aTarget);
405
beginUpdateBatch: function (aDataSource) {
406
for (var i = 0; i < this._observers.length; ++i) {
407
this._observers[i].beginUpdateBatch(aDataSource);
411
endUpdateBatch: function (aDataSource) {
412
for (var i = 0; i < this._observers.length; ++i) {
413
this._observers[i].endUpdateBatch(aDataSource);
418
var rds = this._inner.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
423
destroy: function () {
424
this._inner.RemoveObserver(this);
429
* Handler Override class
431
function HandlerOverride(aURI, aDatasource)
434
this._DS = aDatasource;
437
HandlerOverride.prototype = {
438
// general information
441
return this.getLiteralForContentType(this.URI, "value");
444
set mimeType(aMIMETypeString)
446
this.changeMIMEStuff(MIME_URI(aMIMETypeString), "value", aMIMETypeString.toLowerCase());
447
return aMIMETypeString;
452
return this.getLiteralForContentType(this.URI, "description");
455
set description(aDescriptionString)
457
this.changeMIMEStuff(MIME_URI(this.mimeType), "description", aDescriptionString);
458
return aDescriptionString;
463
return this.getLiteralForContentType(this.URI, "editable");
466
set isEditable(aIsEditableString)
468
this.changeMIMEStuff(MIME_URI(this.mimeType), "editable", aIsEditableString);
469
return aIsEditableString;
474
var extensionResource = gRDF.GetUnicodeResource(NC_URI("fileExtensions"));
475
var contentTypeResource = gRDF.GetUnicodeResource(MIME_URI(this.mimeType));
476
var extensionTargets = this._DS.GetTargets(contentTypeResource, extensionResource, true);
478
if (extensionTargets) {
479
while (extensionTargets.hasMoreElements()) {
480
var currentExtension = extensionTargets.getNext();
481
if (currentExtension) {
482
currentExtension = currentExtension.QueryInterface(Components.interfaces.nsIRDFLiteral);
483
if (extString != "") {
486
extString += currentExtension.Value.toLowerCase();
493
addExtension: function (aExtensionString)
495
this.assertMIMEStuff(MIME_URI(this.mimeType), "fileExtensions", aExtensionString.toLowerCase());
498
removeExtension: function (aExtensionString)
500
this.unassertMIMEStuff(MIME_URI(this.mimeType), "fileExtensions", aExtensionString.toLowerCase());
503
clearExtensions: function ()
505
var extArray = this.extensions.split(" ");
506
for (i = extArray.length - 1; i >= 0; --i) {
507
this.removeExtension(extArray[i]);
514
return this.getHandlerInfoForType(this.URI, "saveToDisk");
517
set saveToDisk(aSavedToDisk)
519
this.changeMIMEStuff(HANDLER_URI(this.mimeType), "saveToDisk", aSavedToDisk);
520
this.setHandlerProcedure("handleInternal", "false");
521
this.setHandlerProcedure("useSystemDefault", "false");
525
get useSystemDefault()
527
return this.getHandlerInfoForType(this.URI, "useSystemDefault");
530
set useSystemDefault(aUseSystemDefault)
532
this.changeMIMEStuff(HANDLER_URI(this.mimeType), "useSystemDefault", aUseSystemDefault);
533
this.setHandlerProcedure("handleInternal", "false");
534
this.setHandlerProcedure("saveToDisk", "false");
535
return aUseSystemDefault;
540
return this.getHandlerInfoForType(this.URI, "handleInternal");
543
set handleInternal(aHandledInternally)
545
this.changeMIMEStuff(HANDLER_URI(this.mimeType), "handleInternal", aHandledInternally);
546
this.setHandlerProcedure("saveToDisk", "false");
547
this.setHandlerProcedure("useSystemDefault", "false");
548
return aHandledInternally;
551
setHandlerProcedure: function (aHandlerProcedure, aValue)
553
var handlerSource = gRDF.GetUnicodeResource(HANDLER_URI(this.mimeType));
554
var handlerProperty = gRDF.GetUnicodeResource(NC_URI(aHandlerProcedure));
555
var oppositeValue = aValue == "false" ? "true" : "false";
556
var trueLiteral = gRDF.GetLiteral(oppositeValue);
557
var hasCounterpart = this._DS.HasAssertion(handlerSource, handlerProperty, trueLiteral, true);
558
if (hasCounterpart) {
559
var falseLiteral = gRDF.GetLiteral(aValue);
560
this._DS.Change(handlerSource, handlerProperty, trueLiteral, falseLiteral);
566
return this.getHandlerInfoForType(this.URI, "alwaysAsk");
569
set alwaysAsk(aAlwaysAsk)
571
this.changeMIMEStuff(HANDLER_URI(this.mimeType), "alwaysAsk", aAlwaysAsk);
575
// helper application
578
return getHelperAppInfoForType(this.URI, "prettyName");
581
set appDisplayName(aDisplayName)
583
this.changeMIMEStuff(APP_URI(this.mimeType), "prettyName", aDisplayName);
589
return this.getHelperAppInfoForType(this.URI, "path");
592
set appPath(aAppPath)
594
this.changeMIMEStuff(APP_URI(this.mimeType), "path", aAppPath);
599
* After setting the various properties on this override, we need to
600
* build the links between the mime type resource, the handler for that
601
* resource, and the helper app (if any) associated with the resource.
602
* We also need to add this mime type to the RDF seq (list) of types.
604
buildLinks: function()
606
// assert the handler resource
607
var mimeSource = gRDF.GetUnicodeResource(MIME_URI(this.mimeType));
608
var handlerProperty = gRDF.GetUnicodeResource(NC_URI("handlerProp"));
609
var handlerResource = gRDF.GetUnicodeResource(HANDLER_URI(this.mimeType));
610
this._DS.Assert(mimeSource, handlerProperty, handlerResource, true);
611
// assert the helper app resource
612
var helperAppProperty = gRDF.GetUnicodeResource(NC_URI("externalApplication"));
613
var helperAppResource = gRDF.GetUnicodeResource(APP_URI(this.mimeType));
614
this._DS.Assert(handlerResource, helperAppProperty, helperAppResource, true);
615
// add the mime type to the MIME types seq
616
var container = Components.classes["@mozilla.org/rdf/container;1"].createInstance();
618
container = container.QueryInterface(Components.interfaces.nsIRDFContainer);
620
var containerRes = gRDF.GetUnicodeResource("urn:mimetypes:root");
621
container.Init(this._DS, containerRes);
622
var element = gRDF.GetUnicodeResource(MIME_URI(this.mimeType));
623
if (container.IndexOf(element) == -1)
624
container.AppendElement(element);
629
// Implementation helper methods
631
getLiteralForContentType: function (aURI, aProperty)
633
var contentTypeResource = gRDF.GetUnicodeResource(aURI);
634
var propertyResource = gRDF.GetUnicodeResource(NC_URI(aProperty));
635
return this.getLiteral(contentTypeResource, propertyResource);
638
getLiteral: function (aSource, aProperty)
640
var node = this._DS.GetTarget(aSource, aProperty, true);
642
node = node.QueryInterface(Components.interfaces.nsIRDFLiteral);
648
getHandlerInfoForType: function (aURI, aPropertyString)
650
// get current selected type
651
var handler = HANDLER_URI(this.getLiteralForContentType(aURI, "value"));
652
var source = gRDF.GetUnicodeResource(handler);
653
var property = gRDF.GetUnicodeResource(NC_URI(aPropertyString));
654
var target = this._DS.GetTarget(source, property, true);
656
target = target.QueryInterface(Components.interfaces.nsIRDFLiteral);
662
getHelperAppInfoForType: function (aURI, aPropertyString)
664
var appURI = APP_URI(this.getLiteralForContentType(aURI, "value"));
665
var appRes = gRDF.GetUnicodeResource(appURI);
666
var appProperty = gRDF.GetUnicodeResource(NC_URI(aPropertyString));
667
return getLiteral(appRes, appProperty);
671
assertMIMEStuff: function (aMIMEString, aPropertyString, aValueString)
673
var mimeSource = gRDF.GetUnicodeResource(aMIMEString);
674
var valueProperty = gRDF.GetUnicodeResource(NC_URI(aPropertyString));
675
var mimeLiteral = gRDF.GetLiteral(aValueString);
676
this._DS.Assert(mimeSource, valueProperty, mimeLiteral, true);
679
changeMIMEStuff: function(aMIMEString, aPropertyString, aValueString)
681
var mimeSource = gRDF.GetUnicodeResource(aMIMEString);
682
var valueProperty = gRDF.GetUnicodeResource(NC_URI(aPropertyString));
683
var mimeLiteral = gRDF.GetLiteral(aValueString);
684
var currentValue = this._DS.GetTarget(mimeSource, valueProperty, true);
686
this._DS.Change(mimeSource, valueProperty, currentValue, mimeLiteral);
688
this._DS.Assert(mimeSource, valueProperty, mimeLiteral, true);
692
unassertMIMEStuff: function(aMIMEString, aPropertyString, aValueString)
694
var mimeSource = gRDF.GetUnicodeResource(aMIMEString);
695
var valueProperty = gRDF.GetUnicodeResource(NC_URI(aPropertyString));
696
var mimeLiteral = gRDF.GetLiteral(aValueString);
697
this._DS.Unassert(mimeSource, valueProperty, mimeLiteral, true);