Bug 1410214: Part 3 - Support packed WebExtension dictionaries. r?aswan,masayuki
MozReview-Commit-ID: 6nrw0IIe4UG
--- a/extensions/spellcheck/hunspell/glue/mozHunspell.cpp
+++ b/extensions/spellcheck/hunspell/glue/mozHunspell.cpp
@@ -69,16 +69,17 @@
#include "mozISpellI18NManager.h"
#include "nsUnicharUtils.h"
#include "nsCRT.h"
#include "mozInlineSpellChecker.h"
#include "mozilla/Services.h"
#include <stdlib.h>
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
+#include "nsNetUtil.h"
#include "mozilla/dom/ContentParent.h"
using mozilla::dom::ContentParent;
using namespace mozilla;
NS_IMPL_CYCLE_COLLECTING_ADDREF(mozHunspell)
NS_IMPL_CYCLE_COLLECTING_RELEASE(mozHunspell)
@@ -153,41 +154,24 @@ NS_IMETHODIMP mozHunspell::SetDictionary
mAffixFileName.Truncate();
mLanguage.Truncate();
mDecoder = nullptr;
mEncoder = nullptr;
return NS_OK;
}
- nsIFile* affFile = mDictionaries.GetWeak(nsDependentString(aDictionary));
+ nsIURI* affFile = mDictionaries.GetWeak(nsDependentString(aDictionary));
if (!affFile)
return NS_ERROR_FILE_NOT_FOUND;
nsAutoCString dictFileName, affFileName;
-#ifdef XP_WIN
- nsAutoString affFileNameU;
- nsresult rv = affFile->GetPath(affFileNameU);
+ nsresult rv = affFile->GetSpec(affFileName);
NS_ENSURE_SUCCESS(rv, rv);
- // Hunspell 1.3.3+ supports UTF-8 file paths on Windows
- // by prefixing "\\\\?\\".
- if (StringBeginsWith(affFileNameU, NS_LITERAL_STRING("\\\\"))) {
- CopyUTF16toUTF8(affFileNameU, affFileName);
- if (affFileNameU.CharAt(2) != u'?') {
- affFileName.InsertLiteral("?\\UNC\\", 2);
- }
- } else {
- affFileName.AssignLiteral("\\\\?\\");
- AppendUTF16toUTF8(affFileNameU, affFileName);
- }
-#else
- nsresult rv = affFile->GetNativePath(affFileName);
- NS_ENSURE_SUCCESS(rv, rv);
-#endif
if (mAffixFileName.Equals(affFileName.get()))
return NS_OK;
dictFileName = affFileName;
int32_t dotPos = dictFileName.RFindChar('.');
if (dotPos == -1)
return NS_ERROR_FAILURE;
@@ -198,17 +182,17 @@ NS_IMETHODIMP mozHunspell::SetDictionary
// SetDictionary can be called multiple times, so we might have a
// valid mHunspell instance which needs cleaned up.
delete mHunspell;
mDictionary = aDictionary;
mAffixFileName = affFileName;
mHunspell = new Hunspell(affFileName.get(),
- dictFileName.get());
+ dictFileName.get());
if (!mHunspell)
return NS_ERROR_OUT_OF_MEMORY;
auto encoding =
Encoding::ForLabelNoReplacement(mHunspell->get_dict_encoding());
if (!encoding) {
return NS_ERROR_UCONV_NOCONV;
}
@@ -483,17 +467,21 @@ mozHunspell::LoadDictionariesFromDir(nsI
#ifdef DEBUG_bsmedberg
printf("Adding dictionary: %s\n", NS_ConvertUTF16toUTF8(dict).get());
#endif
// Replace '_' separator with '-'
dict.ReplaceChar("_", '-');
- mDictionaries.Put(dict, file);
+ nsCOMPtr<nsIURI> uri;
+ rv = NS_NewFileURI(getter_AddRefs(uri), file);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mDictionaries.Put(dict, uri);
}
return NS_OK;
}
nsresult
mozHunspell::ConvertCharset(const char16_t* aStr, std::string* aDst)
{
@@ -662,30 +650,30 @@ NS_IMETHODIMP mozHunspell::RemoveDirecto
obs->NotifyObservers(nullptr,
SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION,
nullptr);
}
#endif
return NS_OK;
}
-NS_IMETHODIMP mozHunspell::AddDictionary(const nsAString& aLang, nsIFile *aFile)
+NS_IMETHODIMP mozHunspell::AddDictionary(const nsAString& aLang, nsIURI *aFile)
{
NS_ENSURE_TRUE(aFile, NS_ERROR_INVALID_ARG);
mDynamicDictionaries.Put(aLang, aFile);
mDictionaries.Put(aLang, aFile);
DictionariesChanged(true);
return NS_OK;
}
-NS_IMETHODIMP mozHunspell::RemoveDictionary(const nsAString& aLang, nsIFile *aFile)
+NS_IMETHODIMP mozHunspell::RemoveDictionary(const nsAString& aLang, nsIURI *aFile)
{
NS_ENSURE_TRUE(aFile, NS_ERROR_INVALID_ARG);
- nsCOMPtr<nsIFile> file = mDynamicDictionaries.Get(aLang);
+ nsCOMPtr<nsIURI> file = mDynamicDictionaries.Get(aLang);
bool equal;
if (file && NS_SUCCEEDED(file->Equals(aFile, &equal)) && equal) {
mDynamicDictionaries.Remove(aLang);
LoadDictionaryList(true);
}
return NS_OK;
}
--- a/extensions/spellcheck/hunspell/glue/mozHunspell.h
+++ b/extensions/spellcheck/hunspell/glue/mozHunspell.h
@@ -63,16 +63,17 @@
#include <hunspell.hxx>
#include "mozISpellCheckingEngine.h"
#include "mozIPersonalDictionary.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "nsIMemoryReporter.h"
#include "nsIObserver.h"
+#include "nsIURI.h"
#include "mozilla/Encoding.h"
#include "nsInterfaceHashtable.h"
#include "nsWeakReference.h"
#include "nsCycleCollectionParticipant.h"
#include "mozHunspellAllocator.h"
#define MOZ_HUNSPELL_CONTRACTID "@mozilla.org/spellchecker/engine;1"
#define MOZ_HUNSPELL_CID \
@@ -107,21 +108,21 @@ protected:
void DictionariesChanged(bool aNotifyChildProcesses);
nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
mozilla::UniquePtr<mozilla::Encoder> mEncoder;
mozilla::UniquePtr<mozilla::Decoder> mDecoder;
// Hashtable matches dictionary name to .aff file
- nsInterfaceHashtable<nsStringHashKey, nsIFile> mDictionaries;
+ nsInterfaceHashtable<nsStringHashKey, nsIURI> mDictionaries;
nsString mDictionary;
nsString mLanguage;
nsCString mAffixFileName;
// dynamic dirs used to search for dictionaries
nsCOMArray<nsIFile> mDynamicDirectories;
- nsInterfaceHashtable<nsStringHashKey, nsIFile> mDynamicDictionaries;
+ nsInterfaceHashtable<nsStringHashKey, nsIURI> mDynamicDictionaries;
Hunspell *mHunspell;
};
#endif
--- a/extensions/spellcheck/idl/mozISpellCheckingEngine.idl
+++ b/extensions/spellcheck/idl/mozISpellCheckingEngine.idl
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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/. */
#include "nsISupports.idl"
interface nsIFile;
+interface nsIURI;
interface mozIPersonalDictionary;
[scriptable, uuid(8ba643a4-7ddc-4662-b976-7ec123843f10)]
/**
* This interface represents a SpellChecker.
*/
@@ -82,26 +83,26 @@ interface mozISpellCheckingEngine : nsIS
void addDirectory(in nsIFile dir);
/**
* Remove dictionaries from a directory from the spell checker
*/
void removeDirectory(in nsIFile dir);
/**
- * Add a dictionary with the given language code and file path.
+ * Add a dictionary with the given language code and file URI.
*/
- void addDictionary(in AString lang, in nsIFile dir);
+ void addDictionary(in AString lang, in nsIURI file);
/**
* Remove a dictionary with the given language code and path. If the path does
* not match that of the current entry with the given languate code, it is not
* removed.
*/
- void removeDictionary(in AString lang, in nsIFile dir);
+ void removeDictionary(in AString lang, in nsIURI file);
};
%{C++
#define DICTIONARY_SEARCH_DIRECTORY "DictD"
#define DICTIONARY_SEARCH_DIRECTORY_LIST "DictDL"
#define SPELLCHECK_DICTIONARY_REMOVE_NOTIFICATION \
"spellcheck-dictionary-remove"
--- a/toolkit/components/extensions/Extension.jsm
+++ b/toolkit/components/extensions/Extension.jsm
@@ -1867,20 +1867,20 @@ class Dictionary extends ExtensionData {
static getBootstrapScope(id, file) {
return new DictionaryBootstrapScope();
}
async startup(reason) {
this.dictionaries = {};
for (let [lang, path] of Object.entries(this.startupData.dictionaries)) {
- let {file} = Services.io.newURI(path, null, this.rootURI).QueryInterface(Ci.nsIFileURL);
- this.dictionaries[lang] = file;
+ let uri = Services.io.newURI(path, null, this.rootURI);
+ this.dictionaries[lang] = uri;
- spellCheck.addDictionary(lang, file);
+ spellCheck.addDictionary(lang, uri);
}
Management.emit("ready", this);
}
async shutdown(reason) {
if (reason !== "APP_SHUTDOWN") {
for (let [lang, file] of Object.entries(this.dictionaries)) {
--- a/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
@@ -320,17 +320,17 @@ class AddonInternal {
}
if (this.signedState === AddonManager.SIGNEDSTATE_NOT_REQUIRED)
return true;
return this.signedState > AddonManager.SIGNEDSTATE_MISSING;
}
get unpack() {
- return this.type === "dictionary" || this.type === "webextension-dictionary";
+ return this.type === "dictionary";
}
get isCompatible() {
return this.isCompatibleWith();
}
get disabled() {
return (this.userDisabled || this.appDisabled || this.softDisabled);
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell-unpack.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell-unpack.ini
@@ -7,10 +7,9 @@ dupe-manifest =
tags = addons
[test_webextension_paths.js]
tags = webextensions
[test_webextension_theme.js]
tags = webextensions
[test_dictionary.js]
-[test_dictionary_webextension.js]
[test_filepointer.js]
--- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
+++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.ini
@@ -86,16 +86,17 @@ run-if = addon_signing
[test_db_path.js]
head =
[test_default_providers_pref.js]
[test_delay_update.js]
[test_delay_update_webextension.js]
skip-if = appname == "thunderbird"
tags = webextensions
[test_dependencies.js]
+[test_dictionary_webextension.js]
[test_distribution.js]
[test_duplicateplugins.js]
# Bug 676992: test consistently hangs on Android
skip-if = os == "android"
[test_error.js]
[test_ext_management.js]
skip-if = appname == "thunderbird"
tags = webextensions