Fix bug 490309 - Implement asynchronous ical parsing. r=philipp
This commit is contained in:
Родитель
bad689f77e
Коммит
003b13ff38
|
@ -1,4 +1,3 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -21,6 +20,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
|
||||
* Daniel Boelzle <mozilla@boelzle.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -37,9 +37,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIGenericFactory.h"
|
||||
|
||||
#include "nsIClassInfoImpl.h"
|
||||
|
||||
#include "calDateTime.h"
|
||||
#include "calDuration.h"
|
||||
#include "calPeriod.h"
|
||||
|
@ -69,7 +66,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(calDateTime)
|
|||
NS_DECL_CLASSINFO(calDateTime)
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(calICSService)
|
||||
NS_DECL_CLASSINFO(calICSService)
|
||||
|
||||
static const nsModuleComponentInfo components[] =
|
||||
{
|
||||
|
@ -109,13 +105,7 @@ static const nsModuleComponentInfo components[] =
|
|||
{ "ICS parser/serializer",
|
||||
CAL_ICSSERVICE_CID,
|
||||
CAL_ICSSERVICE_CONTRACTID,
|
||||
calICSServiceConstructor,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NS_CI_INTERFACE_GETTER_NAME(calICSService),
|
||||
NULL,
|
||||
&NS_CLASSINFO_NAME(calICSService)
|
||||
calICSServiceConstructor
|
||||
},
|
||||
{ "Calendar Recurrence Rule",
|
||||
CAL_RECURRENCERULE_CID,
|
||||
|
|
|
@ -176,7 +176,7 @@ function pasteFromClipboard() {
|
|||
let icsParser = Components.classes["@mozilla.org/calendar/ics-parser;1"]
|
||||
.createInstance(Components.interfaces.calIIcsParser);
|
||||
try {
|
||||
icsParser.parseString(data, null);
|
||||
icsParser.parseString(data);
|
||||
} catch(e) {}
|
||||
|
||||
let items = icsParser.getItems({});
|
||||
|
|
|
@ -292,7 +292,7 @@ calDNDBaseObserver.prototype = {
|
|||
#endif
|
||||
var parser = Components.classes["@mozilla.org/calendar/ics-parser;1"]
|
||||
.createInstance(Components.interfaces.calIIcsParser);
|
||||
parser.parseString(data, null);
|
||||
parser.parseString(data);
|
||||
this.onDropItems(parser.getItems({}).concat(parser.getParentlessItems({})));
|
||||
break;
|
||||
case "text/unicode":
|
||||
|
@ -357,7 +357,7 @@ calDNDBaseObserver.prototype = {
|
|||
}
|
||||
var parser = Components.classes["@mozilla.org/calendar/ics-parser;1"]
|
||||
.createInstance(Components.interfaces.calIIcsParser);
|
||||
parser.parseString(str, null);
|
||||
parser.parseString(str);
|
||||
self.onDropItems(parser.getItems({}).concat(parser.getParentlessItems({})));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,6 +99,77 @@ let cal = {
|
|||
thread.processNextEvent(false /* don't wait */);
|
||||
},
|
||||
|
||||
get threadingEnabled cal_threadingEnabled() {
|
||||
if (cal_threadingEnabled.val === undefined) {
|
||||
cal_threadingEnabled.val = !cal.getPrefSafe("calendar.threading.disabled", false);
|
||||
}
|
||||
return cal_threadingEnabled.val;
|
||||
},
|
||||
|
||||
getWorkerThread: function cal_getWorkerThread() {
|
||||
let threads = cal_getWorkerThread.mThreads;
|
||||
switch (threads) {
|
||||
case null:
|
||||
return null; // during shutdown
|
||||
case undefined: {
|
||||
cal_getWorkerThread.mThreads = threads = Components.classes["@mozilla.org/thread-pool;1"]
|
||||
.createInstance(Components.interfaces.nsIThreadPool);
|
||||
cal.addShutdownObserver(function() {
|
||||
cal.LOG("cal.getWorkerThread() shutdown.");
|
||||
let threads = cal_getWorkerThread.mThreads;
|
||||
cal_getWorkerThread.mThreads = null;
|
||||
threads.shutdown();
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
return threads;
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes the passed action function on a worker thread.
|
||||
* Once the action function has been executed, respFunc is called
|
||||
* on the same thread that execAsync() has been called on.
|
||||
*
|
||||
* xxx todo: think of leaks, ref cycles!
|
||||
*/
|
||||
execWorker: function cal_execWorker(actionFunc, respFunc) {
|
||||
// response executed on the calling thread:
|
||||
let callingThread = cal.getThreadManager().currentThread;
|
||||
|
||||
let worker = { // nsIRunnable:
|
||||
run: function worker_run() {
|
||||
let res = null;
|
||||
try {
|
||||
actionFunc(callingThread);
|
||||
} catch (exc) {
|
||||
res = exc;
|
||||
}
|
||||
|
||||
if (!respFunc) {
|
||||
return;
|
||||
}
|
||||
|
||||
let response = { // nsIRunnable:
|
||||
run: function response_run() {
|
||||
respFunc(res);
|
||||
}
|
||||
};
|
||||
callingThread.dispatch(response, Components.interfaces.nsIEventTarget.DISPATCH_NORMAL);
|
||||
}
|
||||
};
|
||||
|
||||
if (cal.threadingEnabled) {
|
||||
let thread = cal.getWorkerThread();
|
||||
if (thread) {
|
||||
thread.dispatch(worker, Components.interfaces.nsIEventTarget.DISPATCH_NORMAL);
|
||||
return;
|
||||
} // else shutdown ongoing
|
||||
}
|
||||
|
||||
runnable.run(); // exec on current thread
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks whether a timezone lacks a definition.
|
||||
*/
|
||||
|
@ -473,6 +544,40 @@ let cal = {
|
|||
wm.getMostRecentWindow("mail:3pane");
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds an observer listening for the topic.
|
||||
*
|
||||
* @param func function to execute on topic
|
||||
* @param topic topic to listen for
|
||||
* @param oneTime whether to listen only once
|
||||
*/
|
||||
addObserver: function cal_addObserver(func, topic, oneTime) {
|
||||
let observer = { // nsIObserver:
|
||||
observe: function cal_addObserver_observe(subject, topic_, data) {
|
||||
if (topic == topic_) {
|
||||
if (oneTime) {
|
||||
Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService)
|
||||
.removeObserver(this, topic);
|
||||
}
|
||||
func(subject, topic, data);
|
||||
}
|
||||
}
|
||||
};
|
||||
Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService)
|
||||
.addObserver(observer, topic, false /* don't hold weakly */);
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds an xpcom shutdown observer.
|
||||
*
|
||||
* @param func function to execute
|
||||
*/
|
||||
addShutdownObserver: function cal_addShutdownObserver(func) {
|
||||
cal.addObserver(func, "xpcom-shutdown", true /* one time */);
|
||||
},
|
||||
|
||||
/**
|
||||
* Due to wrapped js objects, some objects may have cyclic references.
|
||||
* You can register properties of objects to be cleaned up on xpcom-shutdown.
|
||||
|
@ -488,28 +593,18 @@ let cal = {
|
|||
// will be used to clean up global objects on shutdown
|
||||
// some objects have cyclic references due to wrappers
|
||||
function shutdownCleanup(obj, prop) {
|
||||
if (!shutdownCleanup.mObserver) {
|
||||
if (!shutdownCleanup.mEntries) {
|
||||
shutdownCleanup.mEntries = [];
|
||||
shutdownCleanup.mObserver = { // nsIObserver:
|
||||
observe: function shutdownCleanup_observe(subject, topic, data) {
|
||||
if (topic == "xpcom-shutdown") {
|
||||
Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService)
|
||||
.removeObserver(this, "xpcom-shutdown");
|
||||
for each (let entry in shutdownCleanup.mEntries) {
|
||||
if (entry.mProp) {
|
||||
delete entry.mObj[entry.mProp];
|
||||
} else {
|
||||
delete entry.mObj;
|
||||
}
|
||||
cal.addShutdownObserver(function() {
|
||||
for each (let entry in shutdownCleanup.mEntries) {
|
||||
if (entry.mProp) {
|
||||
delete entry.mObj[entry.mProp];
|
||||
} else {
|
||||
delete entry.mObj;
|
||||
}
|
||||
delete shutdownCleanup.mEntries;
|
||||
}
|
||||
}
|
||||
};
|
||||
Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService)
|
||||
.addObserver(shutdownCleanup.mObserver, "xpcom-shutdown", false /* don't hold weakly */);
|
||||
delete shutdownCleanup.mEntries;
|
||||
});
|
||||
}
|
||||
shutdownCleanup.mEntries.push({ mObj: obj, mProp: prop });
|
||||
}
|
||||
|
@ -518,7 +613,7 @@ function shutdownCleanup(obj, prop) {
|
|||
// will be used to generate service accessor functions, getIOService()
|
||||
function generateServiceAccessor(id, iface) {
|
||||
return function this_() {
|
||||
if (this_.mService === undefined) {
|
||||
if (!("mService" in this_)) {
|
||||
this_.mService = Components.classes[id].getService(iface);
|
||||
shutdownCleanup(this_, "mService");
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Boelzle <mozilla@boelzle.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -42,6 +43,16 @@ interface calIIcalComponent;
|
|||
interface calIItemBase;
|
||||
interface nsIInputStream;
|
||||
interface calITimezoneProvider;
|
||||
interface calIIcsParser;
|
||||
|
||||
/**
|
||||
* Listener being called once asynchronous parsing is done.
|
||||
*/
|
||||
[scriptable, uuid(d22527da-b0e2-41b7-b6f4-ee9c243cd285)]
|
||||
interface calIIcsParsingListener : nsISupports
|
||||
{
|
||||
void onParsingComplete(in nsresult rc, in calIIcsParser parser);
|
||||
};
|
||||
|
||||
/**
|
||||
* An interface for parsing an ics string or stream into its items.
|
||||
|
@ -57,12 +68,16 @@ interface calIIcsParser : nsISupports
|
|||
*
|
||||
* @param aICSString
|
||||
* The ICS string to parse
|
||||
* @param aTzProvider
|
||||
* @param optional aTzProvider
|
||||
* The timezone provider used to resolve timezones not contained in the
|
||||
* parent VCALENDAR or null (falls back to timezone service)
|
||||
* @param optional aAsyncParsing
|
||||
* If non-null, parsing will be performed on a worker thread,
|
||||
* and the passed listener is called when it's done
|
||||
*/
|
||||
void parseString(in AString aICSString,
|
||||
in calITimezoneProvider aTzProvider);
|
||||
[optional] in calITimezoneProvider aTzProvider,
|
||||
[optional] in calIIcsParsingListener aAsyncParsing);
|
||||
|
||||
/**
|
||||
* Parse an input stream.
|
||||
|
@ -70,12 +85,16 @@ interface calIIcsParser : nsISupports
|
|||
* @see parseString
|
||||
* @param aICSString
|
||||
* The stream to parse
|
||||
* @param aTzProvider
|
||||
* @param optional aTzProvider
|
||||
* The timezone provider used to resolve timezones not contained in the
|
||||
* parent VCALENDAR or null (falls back to timezone service)
|
||||
* @param optional aAsyncParsing
|
||||
* If non-null, parsing will be performed on a worker thread,
|
||||
* and the passed listener is called when it's done
|
||||
*/
|
||||
void parseFromStream(in nsIInputStream aStream,
|
||||
in calITimezoneProvider aTzProvider);
|
||||
[optional] in calITimezoneProvider aTzProvider,
|
||||
[optional] in calIIcsParsingListener aAsyncParsing);
|
||||
|
||||
/**
|
||||
* Get the items that were in the string or stream. In case an item represents a
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "nsStringStream.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
|
||||
#include "calICSService.h"
|
||||
#include "calTimezone.h"
|
||||
|
@ -815,7 +814,7 @@ calIcalComponent::Get##Attrname(calIDuration **dtp) \
|
|||
return NS_OK; \
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(calIcalComponent, calIIcalComponent)
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(calIcalComponent, calIIcalComponent)
|
||||
|
||||
NS_IMETHODIMP_(icalcomponent *)
|
||||
calIcalComponent::GetIcalComponent()
|
||||
|
@ -1197,7 +1196,9 @@ calIcalComponent::AddProperty(calIIcalProperty * prop)
|
|||
// return NS_OK;
|
||||
// }
|
||||
|
||||
NS_IMPL_ISUPPORTS1_CI(calICSService, calIICSService)
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(calICSService, calIICSService, nsIClassInfo)
|
||||
NS_IMPL_CI_INTERFACE_GETTER1(calICSService, calIICSService)
|
||||
NS_IMPL_THREADSAFE_CI(calICSService)
|
||||
|
||||
calICSService::calICSService()
|
||||
{
|
||||
|
|
|
@ -49,12 +49,14 @@ extern "C" {
|
|||
}
|
||||
|
||||
class calICSService : public calIICSService,
|
||||
public nsIClassInfo,
|
||||
public cal::XpcomBase
|
||||
{
|
||||
public:
|
||||
calICSService();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICLASSINFO
|
||||
NS_DECL_CALIICSSERVICE
|
||||
};
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Daniel Boelzle <mozilla@boelzle.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -45,19 +46,35 @@ function calIcsParser() {
|
|||
this.mProperties = new Array();
|
||||
}
|
||||
|
||||
calIcsParser.prototype.QueryInterface =
|
||||
function QueryInterface(aIID) {
|
||||
if (!aIID.equals(Components.interfaces.nsISupports) &&
|
||||
!aIID.equals(Components.interfaces.calIIcsParser)) {
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
var gIcsParserClassInfo = {
|
||||
getInterfaces: function (count) {
|
||||
const ifaces = [
|
||||
Components.interfaces.nsISupports,
|
||||
Components.interfaces.calIIcsParser,
|
||||
Components.interfaces.nsIClassInfo
|
||||
];
|
||||
count.value = ifaces.length;
|
||||
return ifaces;
|
||||
},
|
||||
|
||||
return this;
|
||||
getHelperForLanguage: function (language) {
|
||||
return null;
|
||||
},
|
||||
|
||||
contractID: "@mozilla.org/calendar/ics-parser;1",
|
||||
classDescription: "Calendar ICS Parser",
|
||||
classID: Components.ID("{6fe88047-75b6-4874-80e8-5f5800f14984}"),
|
||||
implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
|
||||
flags: Components.interfaces.nsIClassInfo.THREADSAFE
|
||||
};
|
||||
|
||||
calIcsParser.prototype.parseString =
|
||||
function ip_parseString(aICSString, aTzProvider) {
|
||||
let rootComp = getIcsService().parseICS(aICSString, aTzProvider);
|
||||
calIcsParser.prototype.QueryInterface =
|
||||
function ip_QueryInterface(aIID) {
|
||||
return doQueryInterface(this, calIcsParser.prototype, aIID, null, gIcsParserClassInfo);
|
||||
};
|
||||
|
||||
calIcsParser.prototype.processIcalComponent =
|
||||
function ip_processIcalComponent(rootComp) {
|
||||
let calComp;
|
||||
// libical returns the vcalendar component if there is just one vcalendar.
|
||||
// If there are multiple vcalendars, it returns an xroot component, with
|
||||
|
@ -125,6 +142,7 @@ function ip_parseString(aICSString, aTzProvider) {
|
|||
break;
|
||||
default:
|
||||
this.mComponents.push(subComp);
|
||||
break;
|
||||
}
|
||||
|
||||
if (item) {
|
||||
|
@ -190,42 +208,79 @@ function ip_parseString(aICSString, aTzProvider) {
|
|||
notifier.showAlertNotification("", title, text, false, null, null, title);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
calIcsParser.prototype.parseString =
|
||||
function ip_parseString(aICSString, aTzProvider, aAsyncParsing) {
|
||||
if (aAsyncParsing) {
|
||||
let this_ = this;
|
||||
let rootComp = null;
|
||||
// Do the actual ical parsing on a thread, but process the parsed ical
|
||||
// components on main/UI thread.
|
||||
cal.execWorker(
|
||||
function parseString_worker(responseThread) {
|
||||
rootComp = cal.getIcsService().parseICS(aICSString, aTzProvider);
|
||||
},
|
||||
function parseString_done(exc) {
|
||||
this_.processIcalComponent(rootComp);
|
||||
aAsyncParsing.onParsingComplete(exc ? exc.result : Components.results.NS_OK, this_);
|
||||
});
|
||||
} else {
|
||||
this.processIcalComponent(cal.getIcsService().parseICS(aICSString, aTzProvider));
|
||||
}
|
||||
};
|
||||
|
||||
calIcsParser.prototype.parseFromStream =
|
||||
function ip_parseFromStream(aStream, aTzProvider) {
|
||||
// Read in the string. Note that it isn't a real string at this point,
|
||||
// because likely, the file is utf8. The multibyte chars show up as multiple
|
||||
// 'chars' in this string. So call it an array of octets for now.
|
||||
|
||||
var octetArray = [];
|
||||
var binaryIS = Components.classes["@mozilla.org/binaryinputstream;1"]
|
||||
.createInstance(Components.interfaces.nsIBinaryInputStream);
|
||||
binaryIS.setInputStream(aStream);
|
||||
octetArray = binaryIS.readByteArray(binaryIS.available());
|
||||
|
||||
|
||||
// Some other apps (most notably, sunbird 0.2) happily splits an UTF8
|
||||
// character between the octets, and adds a newline and space between them,
|
||||
// for ICS folding. Unfold manually before parsing the file as utf8.This is
|
||||
// UTF8 safe, because octets with the first bit 0 are always one-octet
|
||||
// characters. So the space or the newline never can be part of a multi-byte
|
||||
// char.
|
||||
for (var i = octetArray.length - 2; i >= 0; i--) {
|
||||
if (octetArray[i] == "\n" && octetArray[i+1] == " ") {
|
||||
octetArray = octetArray.splice(i, 2);
|
||||
function ip_parseFromStream(aStream, aTzProvider, aAsyncParsing) {
|
||||
function readString(aStream_) {
|
||||
// Read in the string. Note that it isn't a real string at this point,
|
||||
// because likely, the file is utf8. The multibyte chars show up as multiple
|
||||
// 'chars' in this string. So call it an array of octets for now.
|
||||
|
||||
let octetArray = [];
|
||||
let binaryIS = Components.classes["@mozilla.org/binaryinputstream;1"]
|
||||
.createInstance(Components.interfaces.nsIBinaryInputStream);
|
||||
binaryIS.setInputStream(aStream);
|
||||
octetArray = binaryIS.readByteArray(binaryIS.available());
|
||||
|
||||
// Some other apps (most notably, sunbird 0.2) happily splits an UTF8
|
||||
// character between the octets, and adds a newline and space between them,
|
||||
// for ICS folding. Unfold manually before parsing the file as utf8.This is
|
||||
// UTF8 safe, because octets with the first bit 0 are always one-octet
|
||||
// characters. So the space or the newline never can be part of a multi-byte
|
||||
// char.
|
||||
for (var i = octetArray.length - 2; i >= 0; i--) {
|
||||
if (octetArray[i] == "\n" && octetArray[i+1] == " ") {
|
||||
octetArray = octetArray.splice(i, 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Interpret the byte-array as a UTF8-string, and convert into a
|
||||
// javascript string.
|
||||
let unicodeConverter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
|
||||
// ICS files are always UTF8
|
||||
unicodeConverter.charset = "UTF-8";
|
||||
return unicodeConverter.convertFromByteArray(octetArray, octetArray.length);
|
||||
}
|
||||
|
||||
// Interpret the byte-array as a UTF8-string, and convert into a
|
||||
// javascript string.
|
||||
var unicodeConverter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
|
||||
// ICS files are always UTF8
|
||||
unicodeConverter.charset = "UTF-8";
|
||||
var str = unicodeConverter.convertFromByteArray(octetArray, octetArray.length);
|
||||
return this.parseString(str, aTzProvider);
|
||||
if (aAsyncParsing) {
|
||||
let this_ = this;
|
||||
let rootComp = null;
|
||||
// Do the actual string reading and ical parsing on a athread, but process the parsed ical
|
||||
// components on main/UI thread.
|
||||
cal.execWorker(
|
||||
function parseString_worker(responseThread) {
|
||||
rootComp = cal.getIcsService().parseICS(readString(aStream), aTzProvider);
|
||||
},
|
||||
function parseString_done(exc) {
|
||||
this_.processIcalComponent(rootComp);
|
||||
aAsyncParsing.onParsingComplete(exc ? exc.result : Components.results.NS_OK, this_);
|
||||
});
|
||||
} else {
|
||||
this.processIcalComponent(cal.getIcsService().parseICS(readString(aStream), aTzProvider));
|
||||
}
|
||||
}
|
||||
|
||||
calIcsParser.prototype.getItems =
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -22,6 +21,7 @@
|
|||
* Contributor(s):
|
||||
* Vladimir Vukicevic <vladimir.vukicevic@oracle.com>
|
||||
* Philipp Kewisch <mozilla@kewis.ch>
|
||||
* Daniel Boelzle <mozilla@boelzle.org>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -52,8 +52,6 @@
|
|||
|
||||
#include "calBaseCID.h"
|
||||
|
||||
static NS_DEFINE_CID(kCalICSService, CAL_ICSSERVICE_CID);
|
||||
|
||||
extern "C" {
|
||||
#include "ical.h"
|
||||
}
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
#include "calIICSService.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsIProgrammingLanguage.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "calBaseCID.h"
|
||||
|
|
|
@ -208,7 +208,7 @@ ltnMimeConverter.prototype = {
|
|||
convertToHTML: function lmcCTH(contentType, data) {
|
||||
let parser = Components.classes["@mozilla.org/calendar/ics-parser;1"]
|
||||
.createInstance(Components.interfaces.calIIcsParser);
|
||||
parser.parseString(data, null);
|
||||
parser.parseString(data);
|
||||
let event = null;
|
||||
for each (var item in parser.getItems({})) {
|
||||
if (isEvent(item)) {
|
||||
|
|
|
@ -138,5 +138,8 @@ pref("calendar.categories.names", "");
|
|||
pref("mousewheel.withnokey.action", 0);
|
||||
pref("mousewheel.withshiftkey.action", 0);
|
||||
|
||||
// Disable use of worker threads. Restart needed.
|
||||
pref("calendar.threading.disabled", false);
|
||||
|
||||
// Set up user agent
|
||||
#expand pref("general.useragent.extra.lightning","Lightning/__LIGHTNING_VERSION__");
|
||||
|
|
|
@ -1133,7 +1133,7 @@ calDavCalendar.prototype = {
|
|||
var parser = Components.classes["@mozilla.org/calendar/ics-parser;1"]
|
||||
.createInstance(Components.interfaces.calIIcsParser);
|
||||
try {
|
||||
parser.parseString(calData, null);
|
||||
parser.parseString(calData);
|
||||
} catch (e) {
|
||||
// Warn and continue.
|
||||
// TODO As soon as we have activity manager integration,
|
||||
|
|
|
@ -234,32 +234,34 @@ calICSCalendar.prototype = {
|
|||
// Wrap parsing in a try block. Will ignore errors. That's a good thing
|
||||
// for non-existing or empty files, but not good for invalid files.
|
||||
// That's why we put them in readOnly mode
|
||||
try {
|
||||
var parser = Components.classes["@mozilla.org/calendar/ics-parser;1"].
|
||||
createInstance(Components.interfaces.calIIcsParser);
|
||||
parser.parseString(str, null);
|
||||
var items = parser.getItems({});
|
||||
|
||||
for each (var item in items) {
|
||||
this.mMemoryCalendar.adoptItem(item, null);
|
||||
let parser = Components.classes["@mozilla.org/calendar/ics-parser;1"]
|
||||
.createInstance(Components.interfaces.calIIcsParser);
|
||||
let this_ = this;
|
||||
let listener = { // calIIcsParsingListener
|
||||
onParsingComplete: function ics_onParsingComplete(rc, parser_) {
|
||||
try {
|
||||
for each (let item in parser_.getItems({})) {
|
||||
this_.mMemoryCalendar.adoptItem(item, null);
|
||||
}
|
||||
this_.unmappedComponents = parser_.getComponents({});
|
||||
this_.unmappedProperties = parser_.getProperties({});
|
||||
} catch (exc) {
|
||||
cal.LOG("Parsing the file failed: " + exc);
|
||||
this_.mObserver.onError(this_.superCalendar, exc.result, exc.toString());
|
||||
this_.mObserver.onError(this_.superCalendar, calIErrors.READ_FAILED, "");
|
||||
}
|
||||
this_.mObserver.onEndBatch();
|
||||
this_.mObserver.onLoad(this_);
|
||||
|
||||
// Now that all items have been stuffed into the memory calendar
|
||||
// we should add ourselves as observer. It is important that this
|
||||
// happens *after* the calls to adoptItem in the above loop to prevent
|
||||
// the views from being notified.
|
||||
this_.mMemoryCalendar.addObserver(this_.mObserver);
|
||||
this_.unlock();
|
||||
}
|
||||
this.unmappedComponents = parser.getComponents({});
|
||||
this.unmappedProperties = parser.getProperties({});
|
||||
} catch(e) {
|
||||
LOG("Parsing the file failed:"+e);
|
||||
this.mObserver.onError(this.superCalendar, e.result, e.toString());
|
||||
this.mObserver.onError(this.superCalendar, calIErrors.READ_FAILED, "");
|
||||
}
|
||||
this.mObserver.onEndBatch();
|
||||
this.mObserver.onLoad(this);
|
||||
|
||||
// Now that all items have been stuffed into the memory calendar
|
||||
// we should add ourselves as observer. It is important that this
|
||||
// happens *after* the calls to adoptItem in the above loop to prevent
|
||||
// the views from being notified.
|
||||
this.mMemoryCalendar.addObserver(this.mObserver);
|
||||
|
||||
this.unlock();
|
||||
};
|
||||
parser.parseString(str, null, listener);
|
||||
},
|
||||
|
||||
writeICS: function () {
|
||||
|
|
|
@ -71,6 +71,9 @@ pref("calendar.view.visiblehours", 9);
|
|||
pref("calendar.weeks.inview", 4);
|
||||
pref("calendar.previousweeks.inview", 0);
|
||||
|
||||
// Disable use of worker threads. Restart needed.
|
||||
pref("calendar.threading.disabled", false);
|
||||
|
||||
// default transparency of allday items; could be switched to e.g. "OPAQUE":
|
||||
pref("calendar.allday.defaultTransparency", "TRANSPARENT");
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ function createEventFromIcalString(icalString) {
|
|||
if (/^BEGIN:VCALENDAR/.test(icalString)) {
|
||||
var parser = Components.classes["@mozilla.org/calendar/ics-parser;1"]
|
||||
.createInstance(Components.interfaces.calIIcsParser);
|
||||
parser.parseString(icalString, null);
|
||||
parser.parseString(icalString);
|
||||
var items = parser.getItems({});
|
||||
ASSERT(items.length == 1);
|
||||
return items[0];
|
||||
|
|
Загрузка…
Ссылка в новой задаче