mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
merge m-c into fx-team
This commit is contained in:
commit
66c17330d4
@ -308,7 +308,7 @@ pref("browser.urlbar.trimURLs", true);
|
||||
// the Content-Disposition filename) before giving up and falling back to
|
||||
// picking a filename without that info in hand so that the user sees some
|
||||
// feedback from their action.
|
||||
pref("browser.download.saveLinkAsFilenameTimeout", 1000);
|
||||
pref("browser.download.saveLinkAsFilenameTimeout", 4000);
|
||||
|
||||
pref("browser.download.useDownloadDir", true);
|
||||
|
||||
|
@ -321,10 +321,8 @@ nsContextMenu.prototype = {
|
||||
var onMisspelling = InlineSpellCheckerUI.overMisspelling;
|
||||
this.showItem("spell-check-enabled", canSpell);
|
||||
this.showItem("spell-separator", canSpell || this.onEditableArea);
|
||||
if (canSpell) {
|
||||
document.getElementById("spell-check-enabled")
|
||||
.setAttribute("checked", InlineSpellCheckerUI.enabled);
|
||||
}
|
||||
document.getElementById("spell-check-enabled")
|
||||
.setAttribute("checked", canSpell && InlineSpellCheckerUI.enabled);
|
||||
|
||||
this.showItem("spell-add-to-dictionary", onMisspelling);
|
||||
|
||||
|
22
configure.in
22
configure.in
@ -295,6 +295,28 @@ case "$target" in
|
||||
|
||||
if test -z "$android_sdk" ; then
|
||||
AC_MSG_ERROR([You must specify --with-android-sdk=/path/to/sdk when targeting Android.])
|
||||
else
|
||||
if ! test -e "$android_sdk"/source.properties ; then
|
||||
AC_MSG_ERROR([The path in --with-android-sdk isn't valid (source.properties hasn't been found).])
|
||||
fi
|
||||
|
||||
# Minimum Android SDK API Level we require.
|
||||
android_min_api_level=13
|
||||
|
||||
# Get the api level from "$android_sdk"/source.properties.
|
||||
android_api_level=`$AWK -F = '$1 == "AndroidVersion.ApiLevel" {print $2}' "$android_sdk"/source.properties`
|
||||
|
||||
if test -z "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: no AndroidVersion.ApiLevel field has been found in source.properties.])
|
||||
fi
|
||||
|
||||
if ! test "$android_api_level" -eq "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: the found android api value isn't a number! (found $android_api_level)])
|
||||
fi
|
||||
|
||||
if test $android_api_level -lt $android_min_api_level ; then
|
||||
AC_MSG_ERROR([The given Android SDK provides API level $android_api_level ($android_min_api_level or higher required).])
|
||||
fi
|
||||
fi
|
||||
|
||||
android_platform_tools="$android_sdk"/../../platform-tools
|
||||
|
@ -916,6 +916,8 @@ static const char js_profiling_content_str[] = JS_OPTIONS_DOT_STR "jitprofiling
|
||||
static const char js_profiling_chrome_str[] = JS_OPTIONS_DOT_STR "jitprofiling.chrome";
|
||||
static const char js_methodjit_always_str[] = JS_OPTIONS_DOT_STR "methodjit_always";
|
||||
static const char js_typeinfer_str[] = JS_OPTIONS_DOT_STR "typeinference";
|
||||
static const char js_pccounts_content_str[] = JS_OPTIONS_DOT_STR "pccounts.content";
|
||||
static const char js_pccounts_chrome_str[] = JS_OPTIONS_DOT_STR "pccounts.chrome";
|
||||
static const char js_memlog_option_str[] = JS_OPTIONS_DOT_STR "mem.log";
|
||||
|
||||
int
|
||||
@ -947,6 +949,9 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||
PRBool useProfiling = Preferences::GetBool(chromeWindow ?
|
||||
js_profiling_chrome_str :
|
||||
js_profiling_content_str);
|
||||
PRBool usePCCounts = Preferences::GetBool(chromeWindow ?
|
||||
js_pccounts_chrome_str :
|
||||
js_pccounts_content_str);
|
||||
PRBool useMethodJITAlways = Preferences::GetBool(js_methodjit_always_str);
|
||||
PRBool useTypeInference = !chromeWindow && Preferences::GetBool(js_typeinfer_str);
|
||||
nsCOMPtr<nsIXULRuntime> xr = do_GetService(XULRUNTIME_SERVICE_CONTRACTID);
|
||||
@ -957,6 +962,7 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||
useTraceJIT = PR_FALSE;
|
||||
useMethodJIT = PR_FALSE;
|
||||
useProfiling = PR_FALSE;
|
||||
usePCCounts = PR_FALSE;
|
||||
useTypeInference = PR_FALSE;
|
||||
useMethodJITAlways = PR_TRUE;
|
||||
}
|
||||
@ -977,6 +983,11 @@ nsJSContext::JSOptionChangedCallback(const char *pref, void *data)
|
||||
else
|
||||
newDefaultJSOptions &= ~JSOPTION_PROFILING;
|
||||
|
||||
if (usePCCounts)
|
||||
newDefaultJSOptions |= JSOPTION_PCCOUNT;
|
||||
else
|
||||
newDefaultJSOptions &= ~JSOPTION_PCCOUNT;
|
||||
|
||||
if (useMethodJITAlways)
|
||||
newDefaultJSOptions |= JSOPTION_METHODJIT_ALWAYS;
|
||||
else
|
||||
|
@ -73,6 +73,7 @@
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsJSEnvironment.h"
|
||||
|
||||
#include "History.h"
|
||||
#include "nsDocShellCID.h"
|
||||
@ -763,5 +764,20 @@ ContentChild::GetIndexedDBPath()
|
||||
return *gIndexedDBPath;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvGarbageCollect()
|
||||
{
|
||||
nsJSContext::GarbageCollectNow();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvCycleCollect()
|
||||
{
|
||||
nsJSContext::GarbageCollectNow();
|
||||
nsJSContext::CycleCollectNow();
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -148,6 +148,9 @@ public:
|
||||
|
||||
virtual bool RecvActivateA11y();
|
||||
|
||||
virtual bool RecvGarbageCollect();
|
||||
virtual bool RecvCycleCollect();
|
||||
|
||||
#ifdef ANDROID
|
||||
gfxIntSize GetScreenSize() { return mScreenSize; }
|
||||
#endif
|
||||
|
@ -200,6 +200,8 @@ ContentParent::Init()
|
||||
obs->AddObserver(this, NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC, PR_FALSE);
|
||||
obs->AddObserver(this, "child-memory-reporter-request", PR_FALSE);
|
||||
obs->AddObserver(this, "memory-pressure", PR_FALSE);
|
||||
obs->AddObserver(this, "child-gc-request", PR_FALSE);
|
||||
obs->AddObserver(this, "child-cc-request", PR_FALSE);
|
||||
#ifdef ACCESSIBILITY
|
||||
obs->AddObserver(this, "a11y-init-or-shutdown", PR_FALSE);
|
||||
#endif
|
||||
@ -304,6 +306,8 @@ ContentParent::ActorDestroy(ActorDestroyReason why)
|
||||
obs->RemoveObserver(static_cast<nsIObserver*>(this), "memory-pressure");
|
||||
obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-memory-reporter-request");
|
||||
obs->RemoveObserver(static_cast<nsIObserver*>(this), NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC);
|
||||
obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-gc-request");
|
||||
obs->RemoveObserver(static_cast<nsIObserver*>(this), "child-cc-request");
|
||||
#ifdef ACCESSIBILITY
|
||||
obs->RemoveObserver(static_cast<nsIObserver*>(this), "a11y-init-or-shutdown");
|
||||
#endif
|
||||
@ -749,6 +753,12 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
else if (!strcmp(aTopic, "child-memory-reporter-request")) {
|
||||
SendPMemoryReportRequestConstructor();
|
||||
}
|
||||
else if (!strcmp(aTopic, "child-gc-request")){
|
||||
SendGarbageCollect();
|
||||
}
|
||||
else if (!strcmp(aTopic, "child-cc-request")){
|
||||
SendCycleCollect();
|
||||
}
|
||||
#ifdef ACCESSIBILITY
|
||||
// Make sure accessibility is running in content process when accessibility
|
||||
// gets initiated in chrome process.
|
||||
|
@ -105,6 +105,7 @@ LOCAL_INCLUDES += \
|
||||
-I$(srcdir)/../../xpcom/base \
|
||||
-I$(srcdir)/../indexedDB \
|
||||
-I$(topsrcdir)/extensions/cookie \
|
||||
-I$(topsrcdir)/dom/base \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += -DBIN_SUFFIX='"$(BIN_SUFFIX)"'
|
||||
|
@ -129,6 +129,9 @@ child:
|
||||
|
||||
FlushMemory(nsString reason);
|
||||
|
||||
GarbageCollect();
|
||||
CycleCollect();
|
||||
|
||||
/**
|
||||
* Start accessibility engine in content process.
|
||||
*/
|
||||
|
@ -411,7 +411,9 @@ typedef enum {
|
||||
|
||||
NPNVprivateModeBool = 18,
|
||||
|
||||
NPNVsupportsAdvancedKeyHandling = 21
|
||||
NPNVsupportsAdvancedKeyHandling = 21,
|
||||
|
||||
NPNVdocumentOrigin = 22
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
/* Used for negotiating drawing models */
|
||||
|
@ -55,7 +55,7 @@
|
||||
typedef unsigned int uint32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(HPUX)
|
||||
#elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(IRIX) || defined(HPUX)
|
||||
/*
|
||||
* AIX and SunOS ship a inttypes.h header that defines [u]int32_t,
|
||||
* but not bool for C.
|
||||
|
@ -70,11 +70,14 @@
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIUnicodeNormalizer.h"
|
||||
#include "nsDOMJSUtils.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsWildCard.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
#include "nsIXPConnect.h"
|
||||
|
||||
@ -2159,6 +2162,46 @@ _getvalue(NPP npp, NPNVariable variable, void *result)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
case NPNVdocumentOrigin: {
|
||||
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)npp->ndata;
|
||||
if (!inst) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element;
|
||||
inst->GetDOMElement(getter_AddRefs(element));
|
||||
if (!element) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(element));
|
||||
if (!content) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
nsIPrincipal* principal = content->NodePrincipal();
|
||||
|
||||
nsAutoString utf16Origin;
|
||||
res = nsContentUtils::GetUTFOrigin(principal, utf16Origin);
|
||||
if (NS_FAILED(res)) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIUnicodeNormalizer> normalizer = do_GetService(NS_UNICODE_NORMALIZER_CONTRACTID);
|
||||
if (!normalizer) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
nsAutoString normalizedUTF16Origin;
|
||||
res = normalizer->NormalizeUnicodeNFKC(utf16Origin, normalizedUTF16Origin);
|
||||
if (NS_FAILED(res)) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
*(char**)result = ToNewUTF8String(normalizedUTF16Origin);
|
||||
return *(char**)result ? NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
case NPNVpluginDrawingModel: {
|
||||
if (npp) {
|
||||
|
@ -171,6 +171,8 @@ parent:
|
||||
returns (bool value, NPError result);
|
||||
rpc NPN_GetValue_NPNVnetscapeWindow()
|
||||
returns (NativeWindowHandle value, NPError result);
|
||||
rpc NPN_GetValue_NPNVdocumentOrigin()
|
||||
returns (nsCString value, NPError result);
|
||||
|
||||
rpc NPN_SetValue_NPPVpluginWindow(bool windowed)
|
||||
returns (NPError result);
|
||||
|
@ -359,6 +359,18 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
|
||||
return result;
|
||||
}
|
||||
|
||||
case NPNVdocumentOrigin: {
|
||||
nsCString v;
|
||||
NPError result;
|
||||
if (!CallNPN_GetValue_NPNVdocumentOrigin(&v, &result)) {
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
if (result == NPERR_NO_ERROR) {
|
||||
*static_cast<char**>(aValue) = ToNewCString(v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
case NPNVWindowNPObject: // Intentional fall-through
|
||||
case NPNVPluginElementNPObject: {
|
||||
NPObject* object;
|
||||
@ -2849,6 +2861,7 @@ PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
|
||||
exposeEvent.major_code = 0;
|
||||
exposeEvent.minor_code = 0;
|
||||
mPluginIface->event(&mData, reinterpret_cast<void*>(&exposeEvent));
|
||||
aSurface->MarkDirty(gfxRect(aRect.x, aRect.y, aRect.width, aRect.height));
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@ -2926,7 +2939,7 @@ PluginInstanceChild::PaintRectToSurface(const nsIntRect& aRect,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (aColor.a > 0.0) {
|
||||
if (mIsTransparent && !CanPaintOnBackground()) {
|
||||
// Clear surface content for transparent rendering
|
||||
nsRefPtr<gfxContext> ctx = new gfxContext(renderSurface);
|
||||
ctx->SetColor(aColor);
|
||||
|
@ -341,6 +341,18 @@ PluginInstanceParent::AnswerNPN_GetValue_NPNVprivateModeBool(bool* value,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceParent::AnswerNPN_GetValue_NPNVdocumentOrigin(nsCString* value,
|
||||
NPError* result)
|
||||
{
|
||||
void *v = nsnull;
|
||||
*result = mNPNIface->getvalue(mNPP, NPNVdocumentOrigin, &v);
|
||||
if (*result == NPERR_NO_ERROR && v) {
|
||||
value->Adopt(static_cast<char*>(v));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginWindow(
|
||||
const bool& windowed, NPError* result)
|
||||
|
@ -131,6 +131,9 @@ public:
|
||||
virtual bool
|
||||
AnswerNPN_GetValue_NPNVprivateModeBool(bool* value, NPError* result);
|
||||
|
||||
virtual bool
|
||||
AnswerNPN_GetValue_NPNVdocumentOrigin(nsCString* value, NPError* result);
|
||||
|
||||
virtual bool
|
||||
AnswerNPN_SetValue_NPPVpluginWindow(const bool& windowed, NPError* result);
|
||||
virtual bool
|
||||
|
@ -213,6 +213,7 @@ NPNVariableToString(NPNVariable aVar)
|
||||
VARSTR(NPNVSupportsWindowless);
|
||||
|
||||
VARSTR(NPNVprivateModeBool);
|
||||
VARSTR(NPNVdocumentOrigin);
|
||||
|
||||
default: return "???";
|
||||
}
|
||||
|
@ -102,6 +102,7 @@ _MOCHITEST_FILES = \
|
||||
test_zero_opacity.html \
|
||||
test_NPPVpluginWantsAllNetworkStreams.html \
|
||||
test_npruntime_npnsetexception.html \
|
||||
test_NPNVdocumentOrigin.html \
|
||||
$(NULL)
|
||||
|
||||
# test_plugin_scroll_painting.html \ bug 596491
|
||||
|
34
dom/plugins/test/mochitest/test_NPNVdocumentOrigin.html
Normal file
34
dom/plugins/test/mochitest/test_NPNVdocumentOrigin.html
Normal file
@ -0,0 +1,34 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Test NPNVdocumentOrigin</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
</head>
|
||||
<body onload="runTest()">
|
||||
<embed id="plugin1" type="application/x-test" width="200" height="200"></embed>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function runTest() {
|
||||
var p1 = document.getElementById("plugin1");
|
||||
var realOrigin = "http://mochi.test:8888";
|
||||
|
||||
// Test with no modifications
|
||||
is(p1.getNPNVdocumentOrigin(), realOrigin, "Checking for expected origin.");
|
||||
|
||||
// Mess with window.location.toString
|
||||
window.location.toString = function() { return 'http://victim.rckc.at/'; }
|
||||
is(p1.getNPNVdocumentOrigin(), realOrigin, "Checking for expected origin afer modifying window.location.toString.");
|
||||
|
||||
// Create a plugin in a new window with about:blank
|
||||
var newWindow = window.open("about:blank");
|
||||
newWindow.document.writeln('<embed id="plugin2" type="application/x-test" width="200" height="200"></embed>');
|
||||
var p2 = newWindow.document.getElementById("plugin2");
|
||||
is(p2.getNPNVdocumentOrigin(), realOrigin, "Checking for expected origin of plugin in new about:blank window.");
|
||||
newWindow.close();
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -37,6 +37,10 @@ Hands back an object which reflects properties as values, e.g.
|
||||
.getReflector()['foo'] = 'foo'
|
||||
.getReflector()[1] = 1
|
||||
|
||||
* .getNPNVdocumentOrigin()
|
||||
Returns the origin string retrieved from the browser by a NPNVdocumentOrigin
|
||||
variable request. Does not cache the value, gets it from the browser every time.
|
||||
|
||||
== NPN_ConvertPoint testing ==
|
||||
|
||||
* convertPointX(sourceSpace, sourceX, sourceY, destSpace)
|
||||
|
@ -167,6 +167,7 @@ static bool constructObject(NPObject* npobj, const NPVariant* args, uint32_t arg
|
||||
static bool setSitesWithData(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool setSitesWithDataCapabilities(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool getLastKeyText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
static bool getNPNVdocumentOrigin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
|
||||
|
||||
static const NPUTF8* sPluginMethodIdentifierNames[] = {
|
||||
"npnEvaluateTest",
|
||||
@ -225,7 +226,8 @@ static const NPUTF8* sPluginMethodIdentifierNames[] = {
|
||||
"constructObject",
|
||||
"setSitesWithData",
|
||||
"setSitesWithDataCapabilities",
|
||||
"getLastKeyText"
|
||||
"getLastKeyText",
|
||||
"getNPNVdocumentOrigin"
|
||||
};
|
||||
static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
|
||||
static const ScriptableFunction sPluginMethodFunctions[] = {
|
||||
@ -285,7 +287,8 @@ static const ScriptableFunction sPluginMethodFunctions[] = {
|
||||
constructObject,
|
||||
setSitesWithData,
|
||||
setSitesWithDataCapabilities,
|
||||
getLastKeyText
|
||||
getLastKeyText,
|
||||
getNPNVdocumentOrigin
|
||||
};
|
||||
|
||||
STATIC_ASSERT(ARRAY_LENGTH(sPluginMethodIdentifierNames) ==
|
||||
@ -3474,3 +3477,22 @@ bool getLastKeyText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||
STRINGZ_TO_NPVARIANT(NPN_StrDup(id->lastKeyText.c_str()), *result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getNPNVdocumentOrigin(NPObject* npobj, const NPVariant* args, uint32_t argCount,
|
||||
NPVariant* result)
|
||||
{
|
||||
if (argCount != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
NPP npp = static_cast<TestNPObject*>(npobj)->npp;
|
||||
|
||||
char *origin = NULL;
|
||||
NPError err = NPN_GetValue(npp, NPNVdocumentOrigin, &origin);
|
||||
if (err != NPERR_NO_ERROR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
STRINGZ_TO_NPVARIANT(origin, *result);
|
||||
return true;
|
||||
}
|
||||
|
@ -558,6 +558,31 @@ nsEditorSpellCheck::SetCurrentDictionary(const nsAString& aDictionary)
|
||||
return mSpellChecker->SetCurrentDictionary(aDictionary);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditorSpellCheck::CheckCurrentDictionary()
|
||||
{
|
||||
mSpellChecker->CheckCurrentDictionary();
|
||||
|
||||
// Check if our current dictionary is still available.
|
||||
nsAutoString currentDictionary;
|
||||
nsresult rv = GetCurrentDictionary(currentDictionary);
|
||||
if (NS_SUCCEEDED(rv) && !currentDictionary.IsEmpty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If our preferred current dictionary has gone, pick another one.
|
||||
nsTArray<nsString> dictList;
|
||||
rv = mSpellChecker->GetDictionaryList(&dictList);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (dictList.Length() > 0) {
|
||||
rv = SetCurrentDictionary(dictList[0]);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditorSpellCheck::UninitSpellChecker()
|
||||
{
|
||||
@ -658,8 +683,6 @@ nsEditorSpellCheck::UpdateCurrentDictionary()
|
||||
}
|
||||
}
|
||||
|
||||
SetCurrentDictionary(EmptyString());
|
||||
|
||||
if (NS_SUCCEEDED(rv) && !dictName.IsEmpty()) {
|
||||
rv = SetCurrentDictionary(dictName);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -41,10 +41,17 @@
|
||||
interface nsIEditor;
|
||||
interface nsITextServicesFilter;
|
||||
|
||||
[scriptable, uuid(af84da62-588f-409f-847d-feecc991bd93)]
|
||||
[scriptable, uuid(334946c3-0e93-4aac-b662-e1b56f95d68b)]
|
||||
interface nsIEditorSpellCheck : nsISupports
|
||||
{
|
||||
|
||||
/**
|
||||
* Call this on any change in installed dictionaries to ensure that the spell
|
||||
* checker is not using a current dictionary which is no longer available.
|
||||
* If the current dictionary is no longer available, then pick another one.
|
||||
*/
|
||||
void checkCurrentDictionary();
|
||||
|
||||
/**
|
||||
* Returns true if we can enable spellchecking. If there are no available
|
||||
* dictionaries, this will return false.
|
||||
|
@ -94,4 +94,5 @@ INCLUDES += \
|
||||
-I$(topsrcdir)/content/base/src \
|
||||
-I$(topsrcdir)/content/events/src \
|
||||
-I$(topsrcdir)/layout/style \
|
||||
-I$(topsrcdir)/extensions/spellcheck/src \
|
||||
$(NULL)
|
||||
|
@ -24,6 +24,7 @@
|
||||
* Daniel Glazman <glazman@netscape.com>
|
||||
* Masayuki Nakano <masayuki@d-toybox.com>
|
||||
* Mats Palmgren <matspal@gmail.com>
|
||||
* Jesper Kristensen <mail@jesperkristensen.dk>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -48,6 +49,11 @@
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozISpellCheckingEngine.h"
|
||||
#include "nsIEditorSpellCheck.h"
|
||||
#include "mozInlineSpellChecker.h"
|
||||
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsIDOMElement.h"
|
||||
@ -207,6 +213,7 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsEditor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIEditorIMESupport)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIEditor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIEditor)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
@ -300,6 +307,13 @@ nsEditor::PostCreate()
|
||||
// update the UI with our state
|
||||
NotifyDocumentListeners(eDocumentCreated);
|
||||
NotifyDocumentListeners(eDocumentStateChanged);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(this,
|
||||
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
|
||||
PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
// update nsTextStateManager and caret if we have focus
|
||||
@ -412,6 +426,12 @@ nsEditor::PreDestroy(PRBool aDestroyingFrames)
|
||||
if (mDidPreDestroy)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->RemoveObserver(this,
|
||||
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION);
|
||||
}
|
||||
|
||||
// Let spellchecker clean up its observers etc. It is important not to
|
||||
// actually free the spellchecker here, since the spellchecker could have
|
||||
// caused flush notifications, which could have gotten here if a textbox
|
||||
@ -1283,6 +1303,13 @@ NS_IMETHODIMP nsEditor::GetInlineSpellChecker(PRBool autoCreate,
|
||||
return autoCreate ? NS_ERROR_NOT_AVAILABLE : NS_OK;
|
||||
}
|
||||
|
||||
// We don't want to show the spell checking UI if there are no spell check dictionaries available.
|
||||
PRBool canSpell = mozInlineSpellChecker::CanEnableInlineSpellChecking();
|
||||
if (!canSpell) {
|
||||
*aInlineSpellChecker = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
if (!mInlineSpellChecker && autoCreate) {
|
||||
mInlineSpellChecker = do_CreateInstance(MOZ_INLINESPELLCHECKER_CONTRACTID, &rv);
|
||||
@ -1301,17 +1328,49 @@ NS_IMETHODIMP nsEditor::GetInlineSpellChecker(PRBool autoCreate,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsEditor::Observe(nsISupports* aSubj, const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
NS_ASSERTION(!strcmp(aTopic,
|
||||
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION),
|
||||
"Unexpected observer topic");
|
||||
|
||||
// When mozInlineSpellChecker::CanEnableInlineSpellChecking changes
|
||||
SyncRealTimeSpell();
|
||||
|
||||
// When nsIEditorSpellCheck::GetCurrentDictionary changes
|
||||
if (mInlineSpellChecker) {
|
||||
// if the current dictionary is no longer available, find another one
|
||||
nsCOMPtr<nsIEditorSpellCheck> editorSpellCheck;
|
||||
mInlineSpellChecker->GetSpellChecker(getter_AddRefs(editorSpellCheck));
|
||||
if (editorSpellCheck) {
|
||||
// Note: This might change the current dictionary, which may call
|
||||
// this observer recursively.
|
||||
editorSpellCheck->CheckCurrentDictionary();
|
||||
}
|
||||
|
||||
// update the inline spell checker to reflect the new current dictionary
|
||||
mInlineSpellChecker->SpellCheckRange(nsnull); // causes recheck
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsEditor::SyncRealTimeSpell()
|
||||
{
|
||||
NS_TIME_FUNCTION;
|
||||
|
||||
PRBool enable = GetDesiredSpellCheckState();
|
||||
|
||||
// Initializes mInlineSpellChecker
|
||||
nsCOMPtr<nsIInlineSpellChecker> spellChecker;
|
||||
GetInlineSpellChecker(enable, getter_AddRefs(spellChecker));
|
||||
|
||||
if (spellChecker) {
|
||||
spellChecker->SetEnableRealTimeSpell(enable);
|
||||
if (mInlineSpellChecker) {
|
||||
// We might have a mInlineSpellChecker even if there are no dictionaries
|
||||
// available since we don't destroy the mInlineSpellChecker when the last
|
||||
// dictionariy is removed, but in that case spellChecker is null
|
||||
mInlineSpellChecker->SetEnableRealTimeSpell(enable && spellChecker);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include "nsStubMutationObserver.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
class nsIDOMCharacterData;
|
||||
class nsIDOMRange;
|
||||
@ -100,6 +101,7 @@ class nsIDOMNSEvent;
|
||||
class nsEditor : public nsIEditor,
|
||||
public nsIEditorIMESupport,
|
||||
public nsSupportsWeakReference,
|
||||
public nsIObserver,
|
||||
public nsIPhonetic
|
||||
{
|
||||
public:
|
||||
@ -153,6 +155,9 @@ public:
|
||||
/* ------------ nsIEditorIMESupport methods -------------- */
|
||||
NS_DECL_NSIEDITORIMESUPPORT
|
||||
|
||||
/* ------------ nsIObserver methods -------------- */
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
// nsIPhonetic
|
||||
NS_DECL_NSIPHONETIC
|
||||
|
||||
|
@ -44,9 +44,9 @@
|
||||
#define NS_SPELLCHECKER_CONTRACTID "@mozilla.org/spellchecker;1"
|
||||
|
||||
#define NS_ISPELLCHECKER_IID \
|
||||
{ /* E75AC48C-E948-452E-8DB3-30FEE29FE3D2 */ \
|
||||
0xe75ac48c, 0xe948, 0x452e, \
|
||||
{ 0x8d, 0xb3, 0x30, 0xfe, 0xe2, 0x9f, 0xe3, 0xd2 } }
|
||||
{ /* 27bff957-b486-40ae-9f5d-af0cdd211868 */ \
|
||||
0x27bff957, 0xb486, 0x40ae, \
|
||||
{ 0x9f, 0x5d, 0xaf, 0x0c, 0xdd, 0x21, 0x18, 0x68 } }
|
||||
|
||||
class nsITextServicesDocument;
|
||||
class nsString;
|
||||
@ -146,6 +146,12 @@ public:
|
||||
* empty string, spellchecker will be disabled.
|
||||
*/
|
||||
NS_IMETHOD SetCurrentDictionary(const nsAString &aDictionary) = 0;
|
||||
|
||||
/**
|
||||
* Call this on any change in installed dictionaries to ensure that the spell
|
||||
* checker is not using a current dictionary which is no longer available.
|
||||
*/
|
||||
NS_IMETHOD CheckCurrentDictionary() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsISpellChecker, NS_ISPELLCHECKER_IID)
|
||||
|
@ -44,4 +44,8 @@ include $(DEPTH)/config/autoconf.mk
|
||||
MODULE = spellchecker
|
||||
DIRS = idl locales hunspell src
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
DIRS += tests
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -71,6 +71,8 @@ endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += -I$(topsrcdir)/extensions/spellcheck/src
|
||||
|
||||
ifdef MOZ_NATIVE_HUNSPELL
|
||||
CXXFLAGS += $(MOZ_HUNSPELL_CFLAGS)
|
||||
endif
|
||||
|
@ -41,6 +41,7 @@
|
||||
* Harri Pitkanen
|
||||
* Andras Timar
|
||||
* Tor Lillqvist
|
||||
* Jesper Kristensen (mail@jesperkristensen.dk)
|
||||
*
|
||||
* 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
|
||||
@ -70,6 +71,8 @@
|
||||
#include "nsUnicharUtilCIID.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsCRT.h"
|
||||
#include "mozInlineSpellChecker.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include <stdlib.h>
|
||||
#include "nsIMemoryReporter.h"
|
||||
|
||||
@ -122,8 +125,7 @@ mozHunspell::Init()
|
||||
|
||||
LoadDictionaryList();
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs =
|
||||
do_GetService("@mozilla.org/observer-service;1");
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->AddObserver(this, "profile-do-change", PR_TRUE);
|
||||
}
|
||||
@ -147,9 +149,6 @@ NS_IMETHODIMP mozHunspell::GetDictionary(PRUnichar **aDictionary)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDictionary);
|
||||
|
||||
if (mDictionary.IsEmpty())
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
*aDictionary = ToNewUnicode(mDictionary);
|
||||
return *aDictionary ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -161,8 +160,23 @@ NS_IMETHODIMP mozHunspell::SetDictionary(const PRUnichar *aDictionary)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDictionary);
|
||||
|
||||
if (mDictionary.Equals(aDictionary))
|
||||
if (nsDependentString(aDictionary).IsEmpty()) {
|
||||
delete mHunspell;
|
||||
mHunspell = nsnull;
|
||||
mDictionary.AssignLiteral("");
|
||||
mAffixFileName.AssignLiteral("");
|
||||
mLanguage.AssignLiteral("");
|
||||
mDecoder = nsnull;
|
||||
mEncoder = nsnull;
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->NotifyObservers(nsnull,
|
||||
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
|
||||
nsnull);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIFile* affFile = mDictionaries.GetWeak(nsDependentString(aDictionary));
|
||||
if (!affFile)
|
||||
@ -178,6 +192,9 @@ NS_IMETHODIMP mozHunspell::SetDictionary(const PRUnichar *aDictionary)
|
||||
nsresult rv = affFile->GetNativePath(affFileName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mAffixFileName.Equals(affFileName.get()))
|
||||
return NS_OK;
|
||||
|
||||
dictFileName = affFileName;
|
||||
PRInt32 dotPos = dictFileName.RFindChar('.');
|
||||
if (dotPos == -1)
|
||||
@ -191,6 +208,7 @@ NS_IMETHODIMP mozHunspell::SetDictionary(const PRUnichar *aDictionary)
|
||||
delete mHunspell;
|
||||
|
||||
mDictionary = aDictionary;
|
||||
mAffixFileName = affFileName;
|
||||
|
||||
mHunspell = new Hunspell(affFileName.get(),
|
||||
dictFileName.get());
|
||||
@ -222,6 +240,13 @@ NS_IMETHODIMP mozHunspell::SetDictionary(const PRUnichar *aDictionary)
|
||||
else
|
||||
mLanguage = Substring(mDictionary, 0, pos);
|
||||
|
||||
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
|
||||
if (obs) {
|
||||
obs->NotifyObservers(nsnull,
|
||||
SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION,
|
||||
nsnull);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -333,6 +358,14 @@ NS_IMETHODIMP mozHunspell::GetDictionaryList(PRUnichar ***aDictionaries,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
FindFirstString(const nsAString& aString, nsIFile* aFile, void* aClosure)
|
||||
{
|
||||
nsAString *dic = (nsAString*) aClosure;
|
||||
dic->Assign(aString);
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
|
||||
void
|
||||
mozHunspell::LoadDictionaryList()
|
||||
{
|
||||
@ -345,6 +378,7 @@ mozHunspell::LoadDictionaryList()
|
||||
if (!dirSvc)
|
||||
return;
|
||||
|
||||
// find built in dictionaries
|
||||
nsCOMPtr<nsIFile> dictDir;
|
||||
rv = dirSvc->Get(DICTIONARY_SEARCH_DIRECTORY,
|
||||
NS_GET_IID(nsIFile), getter_AddRefs(dictDir));
|
||||
@ -372,6 +406,7 @@ mozHunspell::LoadDictionaryList()
|
||||
}
|
||||
}
|
||||
|
||||
// find dictionaries from extensions requiring restart
|
||||
nsCOMPtr<nsISimpleEnumerator> dictDirs;
|
||||
rv = dirSvc->Get(DICTIONARY_SEARCH_DIRECTORY_LIST,
|
||||
NS_GET_IID(nsISimpleEnumerator), getter_AddRefs(dictDirs));
|
||||
@ -387,6 +422,29 @@ mozHunspell::LoadDictionaryList()
|
||||
if (dictDir)
|
||||
LoadDictionariesFromDir(dictDir);
|
||||
}
|
||||
|
||||
// find dictionaries from restartless extensions
|
||||
for (PRUint32 i = 0; i < mDynamicDirectories.Count(); i++) {
|
||||
LoadDictionariesFromDir(mDynamicDirectories[i]);
|
||||
}
|
||||
|
||||
// Now we have finished updating the list of dictionaries, update the current
|
||||
// dictionary and any editors which may use it.
|
||||
mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking();
|
||||
|
||||
// Check if the current dictionary is still available.
|
||||
// If not, try to replace it with another dictionary of the same language.
|
||||
if (!mDictionary.IsEmpty()) {
|
||||
rv = SetDictionary(mDictionary.get());
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return;
|
||||
}
|
||||
|
||||
// If the current dictionary has gone, and we don't have a good replacement,
|
||||
// set no current dictionary.
|
||||
if (!mDictionary.IsEmpty()) {
|
||||
SetDictionary(EmptyString().get());
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -542,3 +600,19 @@ mozHunspell::Observe(nsISupports* aSubj, const char *aTopic,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void addDirectory(in nsIFile dir); */
|
||||
NS_IMETHODIMP mozHunspell::AddDirectory(nsIFile *aDir)
|
||||
{
|
||||
mDynamicDirectories.AppendObject(aDir);
|
||||
LoadDictionaryList();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void removeDirectory(in nsIFile dir); */
|
||||
NS_IMETHODIMP mozHunspell::RemoveDirectory(nsIFile *aDir)
|
||||
{
|
||||
mDynamicDirectories.RemoveObject(aDir);
|
||||
LoadDictionaryList();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
* Harri Pitkanen
|
||||
* Andras Timar
|
||||
* Tor Lillqvist
|
||||
* Jesper Kristensen (mail@jesperkristensen.dk)
|
||||
*
|
||||
* 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
|
||||
@ -64,6 +65,7 @@
|
||||
#include "mozIPersonalDictionary.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIUnicodeEncoder.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
@ -109,6 +111,10 @@ protected:
|
||||
nsInterfaceHashtable<nsStringHashKey, nsIFile> mDictionaries;
|
||||
nsString mDictionary;
|
||||
nsString mLanguage;
|
||||
nsCString mAffixFileName;
|
||||
|
||||
// dynamic dirs used to search for dictionaries
|
||||
nsCOMArray<nsIFile> mDynamicDirectories;
|
||||
|
||||
Hunspell *mHunspell;
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jesper Kristensen <mail@jesperkristensen.dk>
|
||||
*
|
||||
* 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
|
||||
@ -40,7 +41,7 @@
|
||||
interface nsIFile;
|
||||
interface mozIPersonalDictionary;
|
||||
|
||||
[scriptable, uuid(6eb307d6-3567-481a-971a-feb666b8ae72)]
|
||||
[scriptable, uuid(8ba643a4-7ddc-4662-b976-7ec123843f10)]
|
||||
|
||||
/**
|
||||
* This interface represents a SpellChecker.
|
||||
@ -48,12 +49,23 @@ interface mozIPersonalDictionary;
|
||||
|
||||
interface mozISpellCheckingEngine : nsISupports {
|
||||
/**
|
||||
* The name of the current dictionary
|
||||
* The name of the current dictionary. Is either a value from
|
||||
* getDictionaryList or the empty string if no dictionary is selected.
|
||||
* Setting this attribute to a value not in getDictionaryList will throw
|
||||
* NS_ERROR_FILE_NOT_FOUND.
|
||||
*
|
||||
* The spellcheck engine will send a notification with
|
||||
* "spellcheck-dictionary-update" as topic when this changes.
|
||||
* If the dictionary is changed to no dictionary (the empty string), an
|
||||
* observer is allowed to set another dictionary before it returns.
|
||||
*/
|
||||
attribute wstring dictionary;
|
||||
|
||||
/**
|
||||
* The language this spellchecker is using when checking
|
||||
*
|
||||
* The spellcheck engine will send a notification with
|
||||
* "spellcheck-dictionary-update" as topic when this changes.
|
||||
*/
|
||||
readonly attribute wstring language;
|
||||
|
||||
@ -89,11 +101,17 @@ interface mozISpellCheckingEngine : nsISupports {
|
||||
|
||||
/**
|
||||
* check a word
|
||||
*
|
||||
* The spellcheck engine will send a notification with
|
||||
* "spellcheck-dictionary-update" as topic when this changes.
|
||||
*/
|
||||
boolean check(in wstring word);
|
||||
|
||||
/**
|
||||
* get a list of suggestions for a misspelled word
|
||||
*
|
||||
* The spellcheck engine will send a notification with
|
||||
* "spellcheck-dictionary-update" as topic when this changes.
|
||||
*/
|
||||
void suggest(in wstring word,[array, size_is(count)] out wstring suggestions, out PRUint32 count);
|
||||
|
||||
@ -101,9 +119,22 @@ interface mozISpellCheckingEngine : nsISupports {
|
||||
* Load dictionaries from the specified dir
|
||||
*/
|
||||
void loadDictionariesFromDir(in nsIFile dir);
|
||||
|
||||
/**
|
||||
* Add dictionaries from a directory to the spell checker
|
||||
*/
|
||||
void addDirectory(in nsIFile dir);
|
||||
|
||||
/**
|
||||
* Remove dictionaries from a directory from the spell checker
|
||||
*/
|
||||
void removeDirectory(in nsIFile dir);
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define DICTIONARY_SEARCH_DIRECTORY "DictD"
|
||||
#define DICTIONARY_SEARCH_DIRECTORY_LIST "DictDL"
|
||||
|
||||
#define SPELLCHECK_DICTIONARY_UPDATE_NOTIFICATION \
|
||||
"spellcheck-dictionary-update"
|
||||
%}
|
||||
|
@ -600,9 +600,9 @@ nsresult mozInlineSpellChecker::Cleanup(PRBool aDestroyingFrames)
|
||||
// do that and caches the result so we don't have to keep allocating those
|
||||
// objects if there are no dictionaries or spellchecking.
|
||||
//
|
||||
// This caching will prevent adding dictionaries at runtime if we start out
|
||||
// with no dictionaries! Installing dictionaries as extensions will require
|
||||
// a restart anyway, so it shouldn't be a problem.
|
||||
// Whenever dictionaries are added or removed at runtime, this value must be
|
||||
// updated before an observer notification is sent out about the change, to
|
||||
// avoid editors getting a wrong cached result.
|
||||
|
||||
PRBool // static
|
||||
mozInlineSpellChecker::CanEnableInlineSpellChecking()
|
||||
@ -625,6 +625,12 @@ mozInlineSpellChecker::CanEnableInlineSpellChecking()
|
||||
return (gCanEnableSpellChecking == SpellCheck_Available);
|
||||
}
|
||||
|
||||
void // static
|
||||
mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking()
|
||||
{
|
||||
gCanEnableSpellChecking = SpellCheck_Uninitialized;
|
||||
}
|
||||
|
||||
// mozInlineSpellChecker::RegisterEventListeners
|
||||
//
|
||||
// The inline spell checker listens to mouse events and keyboard navigation+ // events.
|
||||
|
@ -229,8 +229,10 @@ public:
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(mozInlineSpellChecker, nsIDOMEventListener)
|
||||
|
||||
// returns true if it looks likely that we can enable real-time spell checking
|
||||
// returns true if there are any spell checking dictionaries available
|
||||
static PRBool CanEnableInlineSpellChecking();
|
||||
// update the cached value whenever the list of available dictionaries changes
|
||||
static void UpdateCanEnableInlineSpellChecking();
|
||||
|
||||
nsresult Blur(nsIDOMEvent* aEvent);
|
||||
nsresult MouseClick(nsIDOMEvent* aMouseEvent);
|
||||
|
@ -18,6 +18,7 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): David Einstein Deinst@world.std.com
|
||||
* Jesper Kristensen <mail@jesperkristensen.dk>
|
||||
*
|
||||
* 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
|
||||
@ -77,9 +78,6 @@ mozSpellChecker::Init()
|
||||
mPersonalDictionary = do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
|
||||
|
||||
mSpellCheckingEngine = nsnull;
|
||||
mCurrentEngineContractId = nsnull;
|
||||
mDictionariesMap.Init();
|
||||
InitSpellCheckDictionaryMap();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -307,35 +305,45 @@ mozSpellChecker::GetPersonalDictionary(nsTArray<nsString> *aWordList)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
struct AppendNewStruct
|
||||
{
|
||||
nsTArray<nsString> *dictionaryList;
|
||||
PRBool failed;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
AppendNewString(const nsAString& aString, nsCString*, void* aClosure)
|
||||
{
|
||||
AppendNewStruct *ans = (AppendNewStruct*) aClosure;
|
||||
|
||||
if (!ans->dictionaryList->AppendElement(aString))
|
||||
{
|
||||
ans->failed = PR_TRUE;
|
||||
return PL_DHASH_STOP;
|
||||
}
|
||||
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozSpellChecker::GetDictionaryList(nsTArray<nsString> *aDictionaryList)
|
||||
{
|
||||
AppendNewStruct ans = {aDictionaryList, PR_FALSE};
|
||||
nsresult rv;
|
||||
|
||||
mDictionariesMap.EnumerateRead(AppendNewString, &ans);
|
||||
// For catching duplicates
|
||||
nsClassHashtable<nsStringHashKey, nsCString> dictionaries;
|
||||
dictionaries.Init();
|
||||
|
||||
if (ans.failed)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsCOMArray<mozISpellCheckingEngine> spellCheckingEngines;
|
||||
rv = GetEngineList(&spellCheckingEngines);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (PRUint32 i = 0; i < spellCheckingEngines.Count(); i++) {
|
||||
nsCOMPtr<mozISpellCheckingEngine> engine = spellCheckingEngines[i];
|
||||
|
||||
PRUint32 count = 0;
|
||||
PRUnichar **words = NULL;
|
||||
engine->GetDictionaryList(&words, &count);
|
||||
for (PRUint32 k = 0; k < count; k++) {
|
||||
nsAutoString dictName;
|
||||
|
||||
dictName.Assign(words[k]);
|
||||
|
||||
// Skip duplicate dictionaries. Only take the first one
|
||||
// for each name.
|
||||
if (dictionaries.Get(dictName, NULL))
|
||||
continue;
|
||||
|
||||
dictionaries.Put(dictName, NULL);
|
||||
|
||||
if (!aDictionaryList->AppendElement(dictName)) {
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, words);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, words);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -343,11 +351,12 @@ mozSpellChecker::GetDictionaryList(nsTArray<nsString> *aDictionaryList)
|
||||
NS_IMETHODIMP
|
||||
mozSpellChecker::GetCurrentDictionary(nsAString &aDictionary)
|
||||
{
|
||||
if (!mSpellCheckingEngine) {
|
||||
aDictionary.AssignLiteral("");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsXPIDLString dictname;
|
||||
|
||||
if (!mSpellCheckingEngine)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
mSpellCheckingEngine->GetDictionary(getter_Copies(dictname));
|
||||
aDictionary = dictname;
|
||||
return NS_OK;
|
||||
@ -356,44 +365,62 @@ mozSpellChecker::GetCurrentDictionary(nsAString &aDictionary)
|
||||
NS_IMETHODIMP
|
||||
mozSpellChecker::SetCurrentDictionary(const nsAString &aDictionary)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCString *contractId;
|
||||
mSpellCheckingEngine = nsnull;
|
||||
|
||||
if (aDictionary.IsEmpty()) {
|
||||
mCurrentEngineContractId = nsnull;
|
||||
mSpellCheckingEngine = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!mDictionariesMap.Get(aDictionary, &contractId)){
|
||||
NS_WARNING("Dictionary not found");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
nsresult rv;
|
||||
nsCOMArray<mozISpellCheckingEngine> spellCheckingEngines;
|
||||
rv = GetEngineList(&spellCheckingEngines);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (PRUint32 i = 0; i < spellCheckingEngines.Count(); i++) {
|
||||
// We must set mSpellCheckingEngine before we call SetDictionary, since
|
||||
// SetDictionary calls back to this spell checker to check if the
|
||||
// dictionary was set
|
||||
mSpellCheckingEngine = spellCheckingEngines[i];
|
||||
|
||||
rv = mSpellCheckingEngine->SetDictionary(PromiseFlatString(aDictionary).get());
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<mozIPersonalDictionary> personalDictionary = do_GetService("@mozilla.org/spellchecker/personaldictionary;1");
|
||||
mSpellCheckingEngine->SetPersonalDictionary(personalDictionary.get());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mCurrentEngineContractId || !mCurrentEngineContractId->Equals(*contractId)){
|
||||
mSpellCheckingEngine = do_GetService(contractId->get(), &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
mSpellCheckingEngine = NULL;
|
||||
|
||||
mCurrentEngineContractId = contractId;
|
||||
// We could not find any engine with the requested dictionary
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
mozSpellChecker::CheckCurrentDictionary()
|
||||
{
|
||||
// If the current dictionary has been uninstalled, we need to stop using it.
|
||||
// This happens when there is a current engine, but that engine has no
|
||||
// current dictionary.
|
||||
|
||||
if (!mSpellCheckingEngine) {
|
||||
// We didn't have a current dictionary
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult res;
|
||||
res = mSpellCheckingEngine->SetDictionary(PromiseFlatString(aDictionary).get());
|
||||
if(NS_FAILED(res)){
|
||||
NS_WARNING("Dictionary load failed");
|
||||
return res;
|
||||
nsXPIDLString dictname;
|
||||
mSpellCheckingEngine->GetDictionary(getter_Copies(dictname));
|
||||
|
||||
if (!dictname.IsEmpty()) {
|
||||
// We still have a current dictionary
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mSpellCheckingEngine->SetPersonalDictionary(mPersonalDictionary);
|
||||
|
||||
nsXPIDLString language;
|
||||
|
||||
nsCOMPtr<mozISpellI18NManager> serv(do_GetService("@mozilla.org/spellchecker/i18nmanager;1", &res));
|
||||
if(serv && NS_SUCCEEDED(res)){
|
||||
res = serv->GetUtil(language.get(),getter_AddRefs(mConverter));
|
||||
}
|
||||
return res;
|
||||
// We had a current dictionary, but it has gone, so we cannot use it anymore.
|
||||
mSpellCheckingEngine = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -477,11 +504,10 @@ mozSpellChecker::GetCurrentBlockIndex(nsITextServicesDocument *aDoc, PRInt32 *ou
|
||||
}
|
||||
|
||||
nsresult
|
||||
mozSpellChecker::InitSpellCheckDictionaryMap()
|
||||
mozSpellChecker::GetEngineList(nsCOMArray<mozISpellCheckingEngine>* aSpellCheckingEngines)
|
||||
{
|
||||
nsresult rv;
|
||||
PRBool hasMoreEngines;
|
||||
nsTArray<nsCString> contractIds;
|
||||
|
||||
nsCOMPtr<nsICategoryManager> catMgr = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
|
||||
if (!catMgr)
|
||||
@ -508,52 +534,24 @@ mozSpellChecker::InitSpellCheckDictionaryMap()
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
contractIds.AppendElement(contractId);
|
||||
}
|
||||
|
||||
contractIds.AppendElement(NS_LITERAL_CSTRING(DEFAULT_SPELL_CHECKER));
|
||||
|
||||
// Retrieve dictionaries from all available spellcheckers and
|
||||
// fill mDictionariesMap hash (only the first dictionary with the
|
||||
// each name is used).
|
||||
for (PRUint32 i=0;i < contractIds.Length();i++){
|
||||
PRUint32 count,k;
|
||||
PRUnichar **words;
|
||||
|
||||
const nsCString& contractId = contractIds[i];
|
||||
|
||||
// Try to load spellchecker engine. Ignore errors silently
|
||||
// except for the last one (HunSpell).
|
||||
nsCOMPtr<mozISpellCheckingEngine> engine =
|
||||
do_GetService(contractId.get(), &rv);
|
||||
if (NS_FAILED(rv)){
|
||||
// Fail if not succeeded to load HunSpell. Ignore errors
|
||||
// for external spellcheck engines.
|
||||
if (i==contractIds.Length()-1){
|
||||
return rv;
|
||||
}
|
||||
|
||||
continue;
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aSpellCheckingEngines->AppendObject(engine);
|
||||
}
|
||||
|
||||
engine->GetDictionaryList(&words,&count);
|
||||
for(k=0;k<count;k++){
|
||||
nsAutoString dictName;
|
||||
|
||||
dictName.Assign(words[k]);
|
||||
|
||||
nsCString dictCName = NS_ConvertUTF16toUTF8(dictName);
|
||||
|
||||
// Skip duplicate dictionaries. Only take the first one
|
||||
// for each name.
|
||||
if (mDictionariesMap.Get(dictName, NULL))
|
||||
continue;
|
||||
|
||||
mDictionariesMap.Put(dictName, new nsCString(contractId));
|
||||
}
|
||||
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, words);
|
||||
}
|
||||
|
||||
// Try to load HunSpell spellchecker engine.
|
||||
nsCOMPtr<mozISpellCheckingEngine> engine =
|
||||
do_GetService(DEFAULT_SPELL_CHECKER, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Fail if not succeeded to load HunSpell. Ignore errors
|
||||
// for external spellcheck engines.
|
||||
return rv;
|
||||
}
|
||||
aSpellCheckingEngines->AppendObject(engine);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s): David Einstein Deinst@world.std.com
|
||||
* Jesper Kristensen <mail@jesperkristensen.dk>
|
||||
*
|
||||
* 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
|
||||
@ -39,6 +40,7 @@
|
||||
#define mozSpellChecker_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsISpellChecker.h"
|
||||
#include "nsString.h"
|
||||
#include "nsITextServicesDocument.h"
|
||||
@ -75,17 +77,13 @@ public:
|
||||
NS_IMETHOD GetDictionaryList(nsTArray<nsString> *aDictionaryList);
|
||||
NS_IMETHOD GetCurrentDictionary(nsAString &aDictionary);
|
||||
NS_IMETHOD SetCurrentDictionary(const nsAString &aDictionary);
|
||||
NS_IMETHOD CheckCurrentDictionary();
|
||||
|
||||
protected:
|
||||
nsCOMPtr<mozISpellI18NUtil> mConverter;
|
||||
nsCOMPtr<nsITextServicesDocument> mTsDoc;
|
||||
nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
|
||||
|
||||
// Hastable maps directory name to the spellchecker contract ID
|
||||
nsClassHashtable<nsStringHashKey, nsCString> mDictionariesMap;
|
||||
|
||||
nsString mDictionaryName;
|
||||
nsCString *mCurrentEngineContractId;
|
||||
nsCOMPtr<mozISpellCheckingEngine> mSpellCheckingEngine;
|
||||
PRBool mFromStart;
|
||||
|
||||
@ -93,6 +91,6 @@ protected:
|
||||
|
||||
nsresult GetCurrentBlockIndex(nsITextServicesDocument *aDoc, PRInt32 *outBlockIndex);
|
||||
|
||||
nsresult InitSpellCheckDictionaryMap();
|
||||
nsresult GetEngineList(nsCOMArray<mozISpellCheckingEngine> *aDictionaryList);
|
||||
};
|
||||
#endif // mozSpellChecker_h__
|
||||
|
@ -59,39 +59,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(mozHunspellDirProvider)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozSpellChecker, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(mozPersonalDictionary, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozSpellI18NManager)
|
||||
|
||||
// This special constructor for the inline spell checker asks the inline
|
||||
// spell checker if we can create spell checking objects at all (ie, if there
|
||||
// are any dictionaries loaded) before trying to create one. The static
|
||||
// CanEnableInlineSpellChecking caches the value so this will be faster (we
|
||||
// have to run this code for every edit box we create, as well as for every
|
||||
// right click in those edit boxes).
|
||||
static nsresult
|
||||
mozInlineSpellCheckerConstructor(nsISupports *aOuter, REFNSIID aIID,
|
||||
void **aResult)
|
||||
{
|
||||
if (! mozInlineSpellChecker::CanEnableInlineSpellChecking())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv;
|
||||
|
||||
*aResult = NULL;
|
||||
if (NULL != aOuter) {
|
||||
rv = NS_ERROR_NO_AGGREGATION;
|
||||
return rv;
|
||||
}
|
||||
|
||||
mozInlineSpellChecker* inst = new mozInlineSpellChecker();
|
||||
if (NULL == inst) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
return rv;
|
||||
}
|
||||
NS_ADDREF(inst);
|
||||
rv = inst->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(inst);
|
||||
|
||||
return rv;
|
||||
}
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(mozInlineSpellChecker)
|
||||
|
||||
NS_DEFINE_NAMED_CID(MOZ_HUNSPELL_CID);
|
||||
NS_DEFINE_NAMED_CID(HUNSPELLDIRPROVIDER_CID);
|
||||
|
48
extensions/spellcheck/tests/Makefile.in
Normal file
48
extensions/spellcheck/tests/Makefile.in
Normal file
@ -0,0 +1,48 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = extensions/spellcheck/tests
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = chrome
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
54
extensions/spellcheck/tests/chrome/Makefile.in
Normal file
54
extensions/spellcheck/tests/chrome/Makefile.in
Normal file
@ -0,0 +1,54 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = extensions/spellcheck/tests/chrome
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = base map
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = test_add_remove_dictionaries.xul \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
|
52
extensions/spellcheck/tests/chrome/base/Makefile.in
Normal file
52
extensions/spellcheck/tests/chrome/base/Makefile.in
Normal file
@ -0,0 +1,52 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = extensions/spellcheck/tests/chrome/base
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = base_utf.dic \
|
||||
base_utf.aff \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
|
198
extensions/spellcheck/tests/chrome/base/base_utf.aff
Normal file
198
extensions/spellcheck/tests/chrome/base/base_utf.aff
Normal file
@ -0,0 +1,198 @@
|
||||
# OpenOffice.org’s en_US.aff file
|
||||
# with Unicode apostrophe: ’
|
||||
|
||||
SET UTF-8
|
||||
TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
|
||||
|
||||
MAXNGRAMSUGS 1
|
||||
WORDCHARS .'’
|
||||
|
||||
PFX A Y 1
|
||||
PFX A 0 re .
|
||||
|
||||
PFX I Y 1
|
||||
PFX I 0 in .
|
||||
|
||||
PFX U Y 1
|
||||
PFX U 0 un .
|
||||
|
||||
PFX C Y 1
|
||||
PFX C 0 de .
|
||||
|
||||
PFX E Y 1
|
||||
PFX E 0 dis .
|
||||
|
||||
PFX F Y 1
|
||||
PFX F 0 con .
|
||||
|
||||
PFX K Y 1
|
||||
PFX K 0 pro .
|
||||
|
||||
SFX V N 2
|
||||
SFX V e ive e
|
||||
SFX V 0 ive [^e]
|
||||
|
||||
SFX N Y 3
|
||||
SFX N e ion e
|
||||
SFX N y ication y
|
||||
SFX N 0 en [^ey]
|
||||
|
||||
SFX X Y 3
|
||||
SFX X e ions e
|
||||
SFX X y ications y
|
||||
SFX X 0 ens [^ey]
|
||||
|
||||
SFX H N 2
|
||||
SFX H y ieth y
|
||||
SFX H 0 th [^y]
|
||||
|
||||
SFX Y Y 1
|
||||
SFX Y 0 ly .
|
||||
|
||||
SFX G Y 2
|
||||
SFX G e ing e
|
||||
SFX G 0 ing [^e]
|
||||
|
||||
SFX J Y 2
|
||||
SFX J e ings e
|
||||
SFX J 0 ings [^e]
|
||||
|
||||
SFX D Y 4
|
||||
SFX D 0 d e
|
||||
SFX D y ied [^aeiou]y
|
||||
SFX D 0 ed [^ey]
|
||||
SFX D 0 ed [aeiou]y
|
||||
|
||||
SFX T N 4
|
||||
SFX T 0 st e
|
||||
SFX T y iest [^aeiou]y
|
||||
SFX T 0 est [aeiou]y
|
||||
SFX T 0 est [^ey]
|
||||
|
||||
SFX R Y 4
|
||||
SFX R 0 r e
|
||||
SFX R y ier [^aeiou]y
|
||||
SFX R 0 er [aeiou]y
|
||||
SFX R 0 er [^ey]
|
||||
|
||||
SFX Z Y 4
|
||||
SFX Z 0 rs e
|
||||
SFX Z y iers [^aeiou]y
|
||||
SFX Z 0 ers [aeiou]y
|
||||
SFX Z 0 ers [^ey]
|
||||
|
||||
SFX S Y 4
|
||||
SFX S y ies [^aeiou]y
|
||||
SFX S 0 s [aeiou]y
|
||||
SFX S 0 es [sxzh]
|
||||
SFX S 0 s [^sxzhy]
|
||||
|
||||
SFX P Y 3
|
||||
SFX P y iness [^aeiou]y
|
||||
SFX P 0 ness [aeiou]y
|
||||
SFX P 0 ness [^y]
|
||||
|
||||
SFX M Y 1
|
||||
SFX M 0 's .
|
||||
|
||||
SFX B Y 3
|
||||
SFX B 0 able [^aeiou]
|
||||
SFX B 0 able ee
|
||||
SFX B e able [^aeiou]e
|
||||
|
||||
SFX L Y 1
|
||||
SFX L 0 ment .
|
||||
|
||||
REP 88
|
||||
REP a ei
|
||||
REP ei a
|
||||
REP a ey
|
||||
REP ey a
|
||||
REP ai ie
|
||||
REP ie ai
|
||||
REP are air
|
||||
REP are ear
|
||||
REP are eir
|
||||
REP air are
|
||||
REP air ere
|
||||
REP ere air
|
||||
REP ere ear
|
||||
REP ere eir
|
||||
REP ear are
|
||||
REP ear air
|
||||
REP ear ere
|
||||
REP eir are
|
||||
REP eir ere
|
||||
REP ch te
|
||||
REP te ch
|
||||
REP ch ti
|
||||
REP ti ch
|
||||
REP ch tu
|
||||
REP tu ch
|
||||
REP ch s
|
||||
REP s ch
|
||||
REP ch k
|
||||
REP k ch
|
||||
REP f ph
|
||||
REP ph f
|
||||
REP gh f
|
||||
REP f gh
|
||||
REP i igh
|
||||
REP igh i
|
||||
REP i uy
|
||||
REP uy i
|
||||
REP i ee
|
||||
REP ee i
|
||||
REP j di
|
||||
REP di j
|
||||
REP j gg
|
||||
REP gg j
|
||||
REP j ge
|
||||
REP ge j
|
||||
REP s ti
|
||||
REP ti s
|
||||
REP s ci
|
||||
REP ci s
|
||||
REP k cc
|
||||
REP cc k
|
||||
REP k qu
|
||||
REP qu k
|
||||
REP kw qu
|
||||
REP o eau
|
||||
REP eau o
|
||||
REP o ew
|
||||
REP ew o
|
||||
REP oo ew
|
||||
REP ew oo
|
||||
REP ew ui
|
||||
REP ui ew
|
||||
REP oo ui
|
||||
REP ui oo
|
||||
REP ew u
|
||||
REP u ew
|
||||
REP oo u
|
||||
REP u oo
|
||||
REP u oe
|
||||
REP oe u
|
||||
REP u ieu
|
||||
REP ieu u
|
||||
REP ue ew
|
||||
REP ew ue
|
||||
REP uff ough
|
||||
REP oo ieu
|
||||
REP ieu oo
|
||||
REP ier ear
|
||||
REP ear ier
|
||||
REP ear air
|
||||
REP air ear
|
||||
REP w qu
|
||||
REP qu w
|
||||
REP z ss
|
||||
REP ss z
|
||||
REP shun tion
|
||||
REP shun sion
|
||||
REP shun cion
|
||||
McDonalds’sá/w
|
||||
McDonald’sszá/g3) st:McDonaldâs po:noun_prs is:TRANS
|
||||
McDonald’sszal/g4) st:McDonaldâs po:noun_prs is:INSTR
|
||||
McDonald’ssal/w
|
29
extensions/spellcheck/tests/chrome/base/base_utf.dic
Normal file
29
extensions/spellcheck/tests/chrome/base/base_utf.dic
Normal file
@ -0,0 +1,29 @@
|
||||
28
|
||||
created/U
|
||||
create/XKVNGADS
|
||||
imply/GNSDX
|
||||
natural/PUY
|
||||
like/USPBY
|
||||
convey/BDGS
|
||||
look/GZRDS
|
||||
text
|
||||
hello
|
||||
said
|
||||
sawyer
|
||||
NASA
|
||||
rotten
|
||||
day
|
||||
tomorrow
|
||||
seven
|
||||
FAQ/SM
|
||||
can’t
|
||||
doesn’t
|
||||
etc
|
||||
won’t
|
||||
lip
|
||||
text
|
||||
horrifying
|
||||
speech
|
||||
suggest
|
||||
uncreate/V
|
||||
Hunspell
|
52
extensions/spellcheck/tests/chrome/map/Makefile.in
Normal file
52
extensions/spellcheck/tests/chrome/map/Makefile.in
Normal file
@ -0,0 +1,52 @@
|
||||
#
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Netscape Communications Corporation.
|
||||
# Portions created by the Initial Developer are Copyright (C) 1998
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = extensions/spellcheck/tests/chrome/map
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = maputf.dic \
|
||||
maputf.aff \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
|
11
extensions/spellcheck/tests/chrome/map/maputf.aff
Normal file
11
extensions/spellcheck/tests/chrome/map/maputf.aff
Normal file
@ -0,0 +1,11 @@
|
||||
# With MAP suggestion, Hunspell can add missing accents to a word.
|
||||
|
||||
SET UTF-8
|
||||
|
||||
# switch off ngram suggestion for testing
|
||||
MAXNGRAMSUGS 0
|
||||
|
||||
MAP 3
|
||||
MAP uúü
|
||||
MAP öóo
|
||||
MAP ß(ss)
|
4
extensions/spellcheck/tests/chrome/map/maputf.dic
Normal file
4
extensions/spellcheck/tests/chrome/map/maputf.dic
Normal file
@ -0,0 +1,4 @@
|
||||
3
|
||||
Frühstück
|
||||
tükörfúró
|
||||
groß
|
@ -0,0 +1,110 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
|
||||
<window title="Add and remove dictionaries test"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="RunTest();">
|
||||
<title>Add and remove dictionaries test</title>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function getMisspelledWords(editor) {
|
||||
return editor.selectionController.getSelection(Components.interfaces.nsISelectionController.SELECTION_SPELLCHECK).toString();
|
||||
}
|
||||
|
||||
function getDictionaryList(editor) {
|
||||
var spellchecker = editor.getInlineSpellChecker(true).spellChecker;
|
||||
var o1 = {};
|
||||
spellchecker.GetDictionaryList(o1, {});
|
||||
return o1.value;
|
||||
}
|
||||
|
||||
function getCurrentDictionary(editor) {
|
||||
var spellchecker = editor.getInlineSpellChecker(true).spellChecker;
|
||||
return spellchecker.GetCurrentDictionary();
|
||||
}
|
||||
|
||||
function setCurrentDictionary(editor, dictionary) {
|
||||
var spellchecker = editor.getInlineSpellChecker(true).spellChecker;
|
||||
spellchecker.SetCurrentDictionary(dictionary);
|
||||
}
|
||||
|
||||
function RunTest() {
|
||||
var editor = document.getElementById('textbox').editor;
|
||||
|
||||
var dir = Components.classes["@mozilla.org/file/directory_service;1"].
|
||||
getService(Components.interfaces.nsIProperties).
|
||||
get("CurWorkD", Components.interfaces.nsIFile);
|
||||
dir.append("chrome");
|
||||
dir.append("extensions");
|
||||
dir.append("spellcheck");
|
||||
dir.append("tests");
|
||||
dir.append("chrome");
|
||||
|
||||
var hunspell = Components
|
||||
.classes["@mozilla.org/spellchecker/engine;1"]
|
||||
.getService(Components.interfaces.mozISpellCheckingEngine);
|
||||
|
||||
// install base dictionary
|
||||
var base = dir.clone();
|
||||
base.append("base");
|
||||
ok(base.exists());
|
||||
hunspell.addDirectory(base);
|
||||
|
||||
// install map dictionary
|
||||
var map = dir.clone();
|
||||
map.append("map");
|
||||
ok(map.exists());
|
||||
hunspell.addDirectory(map);
|
||||
|
||||
// test that base and map dictionaries are available
|
||||
var dicts = getDictionaryList(editor);
|
||||
isnot(dicts.indexOf("base_utf"), -1, "base is available");
|
||||
isnot(dicts.indexOf("maputf"), -1, "map is available");
|
||||
|
||||
// select base dictionary
|
||||
setCurrentDictionary(editor, "base_utf");
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
// test that base dictionary is in use
|
||||
is(getMisspelledWords(editor), "Frühstück" + "qwertyu", "base misspellings");
|
||||
is(getCurrentDictionary(editor), "base_utf", "current dictionary");
|
||||
|
||||
// select map dictionary
|
||||
setCurrentDictionary(editor, "maputf");
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
// test that map dictionary is in use
|
||||
is(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings");
|
||||
is(getCurrentDictionary(editor), "maputf", "current dictionary");
|
||||
|
||||
// uninstall map dictionary
|
||||
hunspell.removeDirectory(map);
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
// test that map dictionary is not in use
|
||||
isnot(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings");
|
||||
isnot(getCurrentDictionary(editor), "maputf", "current dictionary");
|
||||
|
||||
// test that base dictionary is available and map dictionary is unavailable
|
||||
var dicts = getDictionaryList(editor);
|
||||
isnot(dicts.indexOf("base_utf"), -1, "base is available");
|
||||
is(dicts.indexOf("maputf"), -1, "map is unavailable");
|
||||
|
||||
// uninstall base dictionary
|
||||
hunspell.removeDirectory(base);
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
<textbox id="textbox" spellcheck="true" value="created imply Frühstück tomorrow qwertyu"/>
|
||||
</window>
|
@ -2522,6 +2522,7 @@ BasicShadowableImageLayer::Paint(gfxContext* aContext)
|
||||
nsRefPtr<gfxASurface> backSurface =
|
||||
BasicManager()->OpenDescriptor(mBackBuffer);
|
||||
nsRefPtr<gfxContext> tmpCtx = new gfxContext(backSurface);
|
||||
tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
PaintContext(pat,
|
||||
nsIntRegion(nsIntRect(0, 0, mSize.width, mSize.height)),
|
||||
nsnull, 1.0, tmpCtx);
|
||||
|
@ -586,7 +586,7 @@ namespace JSC {
|
||||
}
|
||||
char const * off_sign = (posOffset) ? ("+") : ("-");
|
||||
js::JaegerSpew(js::JSpew_Insns,
|
||||
IPFX "%sr%s%s, [%s, #%s%u]\n",
|
||||
IPFX "%sr%s%s %s, [%s, #%s%u]\n",
|
||||
MAYBE_PAD, mnemonic_act, mnemonic_sign, mnemonic_size,
|
||||
nameGpReg(rd), nameGpReg(rb), off_sign, offset);
|
||||
if (size == 32 || (size == 8 && !isSigned)) {
|
||||
@ -626,7 +626,7 @@ namespace JSC {
|
||||
}
|
||||
char const * off_sign = (posOffset) ? ("+") : ("-");
|
||||
js::JaegerSpew(js::JSpew_Insns,
|
||||
IPFX "%sr%s%s, [%s, #%s%s]\n", MAYBE_PAD, mnemonic_act, mnemonic_sign, mnemonic_size,
|
||||
IPFX "%sr%s%s %s, [%s, #%s%s]\n", MAYBE_PAD, mnemonic_act, mnemonic_sign, mnemonic_size,
|
||||
nameGpReg(rd), nameGpReg(rb), off_sign, nameGpReg(rm));
|
||||
if (size == 32 || (size == 8 && !isSigned)) {
|
||||
/* All (the one) 32 bit ops and the signed 8 bit ops use the original encoding.*/
|
||||
@ -1052,7 +1052,7 @@ namespace JSC {
|
||||
static void repatchInt32(void* from, int32_t to)
|
||||
{
|
||||
js::JaegerSpew(js::JSpew_Insns,
|
||||
ISPFX "##repatchInt32 ((%p)) holds ((%p))\n",
|
||||
ISPFX "##repatchInt32 ((%p)) holds ((%#x))\n",
|
||||
from, to);
|
||||
|
||||
patchPointerInternal(reinterpret_cast<intptr_t>(from), reinterpret_cast<void*>(to));
|
||||
@ -1606,7 +1606,7 @@ namespace JSC {
|
||||
void fcpyd_r(int dd, int dm, Condition cc = AL)
|
||||
{
|
||||
js::JaegerSpew(js::JSpew_Insns,
|
||||
IPFX "%-15s %s, %s, %s\n", MAYBE_PAD, "vmov.f64",
|
||||
IPFX "%-15s %s, %s\n", MAYBE_PAD, "vmov.f64",
|
||||
nameFpRegD(dd), nameFpRegD(dm));
|
||||
// TODO: emitInst doesn't work for VFP instructions, though it
|
||||
// seems to work for current usage.
|
||||
@ -1650,7 +1650,7 @@ namespace JSC {
|
||||
void fabsd_r(int dd, int dm, Condition cc = AL)
|
||||
{
|
||||
js::JaegerSpew(js::JSpew_Insns,
|
||||
IPFX "%-15s %s, %s, %s, %s\n", MAYBE_PAD, "fabsd", nameFpRegD(dd), nameFpRegD(dm));
|
||||
IPFX "%-15s %s, %s\n", MAYBE_PAD, "fabsd", nameFpRegD(dd), nameFpRegD(dm));
|
||||
m_buffer.putInt(static_cast<ARMWord>(cc) | FABSD | DD(dd) | DM(dm));
|
||||
}
|
||||
|
||||
|
@ -291,6 +291,28 @@ case "$target" in
|
||||
android_platform_tools="$android_sdk"/../../platform-tools
|
||||
if test ! -d "$android_platform_tools" ; then
|
||||
android_platform_tools="$android_sdk"/tools # SDK Tools < r8
|
||||
else
|
||||
if ! test -e "$android_sdk"/source.properties ; then
|
||||
AC_MSG_ERROR([The path in --with-android-sdk isn't valid (source.properties hasn't been found).])
|
||||
fi
|
||||
|
||||
# Minimum Android SDK API Level we require.
|
||||
android_min_api_level=13
|
||||
|
||||
# Get the api level from "$android_sdk"/source.properties.
|
||||
android_api_level=`$AWK -F = '$1 == "AndroidVersion.ApiLevel" {print $2}' "$android_sdk"/source.properties`
|
||||
|
||||
if test -z "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: no AndroidVersion.ApiLevel field has been found in source.properties.])
|
||||
fi
|
||||
|
||||
if ! test "$android_api_level" -eq "$android_api_level" ; then
|
||||
AC_MSG_ERROR([Unexpected error: the found android api value isn't a number! (found $android_api_level)])
|
||||
fi
|
||||
|
||||
if test $android_api_level -lt $android_min_api_level ; then
|
||||
AC_MSG_ERROR([The given Android SDK provides API level $android_api_level ($android_min_api_level or higher required).])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -z "$android_toolchain" ; then
|
||||
|
@ -2224,13 +2224,14 @@ inline uint32 frameCountersOffset(JSContext *cx)
|
||||
LookupStatus
|
||||
BaseIC::disable(JSContext *cx, const char *reason, void *stub)
|
||||
{
|
||||
if (cx->hasRunOption(JSOPTION_PCCOUNT)) {
|
||||
JITScript *jit = cx->fp()->jit();
|
||||
if (jit->pcLengths) {
|
||||
uint32 offset = frameCountersOffset(cx);
|
||||
cx->fp()->jit()->pcLengths[offset].picsLength = 0;
|
||||
jit->pcLengths[offset].picsLength = 0;
|
||||
}
|
||||
|
||||
spew(cx, "disabled", reason);
|
||||
Repatcher repatcher(cx->fp()->jit());
|
||||
Repatcher repatcher(jit);
|
||||
repatcher.relink(slowPathCall, FunctionPtr(stub));
|
||||
return Lookup_Uncacheable;
|
||||
}
|
||||
@ -2238,9 +2239,10 @@ BaseIC::disable(JSContext *cx, const char *reason, void *stub)
|
||||
void
|
||||
BaseIC::updatePCCounters(JSContext *cx, Assembler &masm)
|
||||
{
|
||||
if (cx->hasRunOption(JSOPTION_PCCOUNT)) {
|
||||
JITScript *jit = cx->fp()->jit();
|
||||
if (jit->pcLengths) {
|
||||
uint32 offset = frameCountersOffset(cx);
|
||||
cx->fp()->jit()->pcLengths[offset].picsLength += masm.size();
|
||||
jit->pcLengths[offset].picsLength += masm.size();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4527,6 +4527,9 @@ Help(JSContext *cx, uintN argc, jsval *vp)
|
||||
const char *p = strchr(msg, '(');
|
||||
JS_ASSERT(p);
|
||||
|
||||
if (size_t(p - msg) != str->length())
|
||||
continue;
|
||||
|
||||
if (strncmp(funcName.ptr(), msg, p - msg) == 0) {
|
||||
if (!did_header) {
|
||||
did_header = 1;
|
||||
|
@ -176,7 +176,6 @@ function snapshot(elem)
|
||||
pos[count] = elem.getBoundingClientRect().top;
|
||||
++count;
|
||||
if (count <= 1) {
|
||||
ok(true, "trying to open the second submenu");
|
||||
// close the submenu and open the bottom submenu
|
||||
synthesizeKey("VK_LEFT", {});
|
||||
synthesizeKey("9", {});
|
||||
@ -193,7 +192,6 @@ function doTest() {
|
||||
|
||||
function openSubmenu()
|
||||
{
|
||||
ok(true, "openSubMenu() called");
|
||||
// open a submenu in the middle
|
||||
synthesizeKey("5", {});
|
||||
}
|
||||
|
@ -811,11 +811,12 @@ RenderFrameParent::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
// We're the subdoc for <browser remote="true"> and it has
|
||||
// painted content. Display its shadow layer tree.
|
||||
nsDisplayList shadowTree;
|
||||
if (aBuilder->IsForEventDelivery()) {
|
||||
ContainerLayer* container = GetRootLayer();
|
||||
if (aBuilder->IsForEventDelivery() && container) {
|
||||
nsRect bounds = aFrame->EnsureInnerView()->GetBounds();
|
||||
ViewTransform offset =
|
||||
ViewTransform(GetRootFrameOffset(aFrame, aBuilder), 1, 1);
|
||||
BuildListForLayer(GetRootLayer(), mFrameLoader, offset,
|
||||
BuildListForLayer(container, mFrameLoader, offset,
|
||||
aBuilder, shadowTree, aFrame);
|
||||
} else {
|
||||
shadowTree.AppendToTop(
|
||||
|
@ -69,7 +69,6 @@
|
||||
#define NS_MATHML_ACTION_TYPE_TOGGLE 1
|
||||
#define NS_MATHML_ACTION_TYPE_STATUSLINE 2
|
||||
#define NS_MATHML_ACTION_TYPE_TOOLTIP 3 // unsupported
|
||||
#define NS_MATHML_ACTION_TYPE_RESTYLE 4
|
||||
|
||||
|
||||
nsIFrame*
|
||||
@ -128,37 +127,6 @@ nsMathMLmactionFrame::Init(nsIContent* aContent,
|
||||
mActionType = NS_MATHML_ACTION_TYPE_STATUSLINE;
|
||||
}
|
||||
|
||||
if (NS_MATHML_ACTION_TYPE_NONE == mActionType) {
|
||||
// expected restyle prefix (8ch)...
|
||||
if (8 < value.Length() && 0 == value.Find("restyle#")) {
|
||||
mActionType = NS_MATHML_ACTION_TYPE_RESTYLE;
|
||||
mRestyle = value;
|
||||
|
||||
// Here is the situation:
|
||||
// When the attribute [actiontype="restyle#id"] is set, the Style System has
|
||||
// given us the associated style. But we want to start with our default style.
|
||||
|
||||
// So... first, remove the attribute actiontype="restyle#id"
|
||||
// XXXbz this is pretty messed up, since this can change whether we
|
||||
// should have a frame at all. This really needs a better solution.
|
||||
PRBool notify = PR_FALSE; // don't trigger a reflow yet!
|
||||
aContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::actiontype_, notify);
|
||||
|
||||
// then, re-resolve our style
|
||||
nsStyleContext* parentStyleContext = GetStyleContext()->GetParent();
|
||||
newStyleContext = PresContext()->StyleSet()->
|
||||
ResolveStyleFor(aContent->AsElement(), parentStyleContext);
|
||||
|
||||
if (!newStyleContext)
|
||||
mRestyle.Truncate();
|
||||
else {
|
||||
if (newStyleContext != GetStyleContext())
|
||||
SetStyleContextWithoutNotification(newStyleContext);
|
||||
else
|
||||
mRestyle.Truncate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Let the base class do the rest
|
||||
@ -440,21 +408,4 @@ nsMathMLmactionFrame::MouseClick()
|
||||
NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
}
|
||||
else if (NS_MATHML_ACTION_TYPE_RESTYLE == mActionType) {
|
||||
if (!mRestyle.IsEmpty()) {
|
||||
nsCOMPtr<nsIDOMElement> node( do_QueryInterface(mContent) );
|
||||
if (node.get()) {
|
||||
if (nsContentUtils::HasNonEmptyAttr(mContent, kNameSpaceID_None,
|
||||
nsGkAtoms::actiontype_))
|
||||
node->RemoveAttribute(NS_LITERAL_STRING("actiontype"));
|
||||
else
|
||||
node->SetAttribute(NS_LITERAL_STRING("actiontype"), mRestyle);
|
||||
|
||||
// Trigger a style change reflow
|
||||
PresContext()->PresShell()->
|
||||
FrameNeedsReflow(mSelectedFrame, nsIPresShell::eStyleChange,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ let Elements = {};
|
||||
["contentShowing", "bcast_contentShowing"],
|
||||
["urlbarState", "bcast_urlbarState"],
|
||||
["stack", "stack"],
|
||||
["tabList", "tabs"],
|
||||
["tabs", "tabs-container"],
|
||||
["controls", "browser-controls"],
|
||||
["panelUI", "panel-container"],
|
||||
@ -383,7 +384,7 @@ var BrowserUI = {
|
||||
|
||||
sizeControls: function(windowW, windowH) {
|
||||
// tabs
|
||||
document.getElementById("tabs").resize();
|
||||
Elements.tabList.resize();
|
||||
AwesomeScreen.doResize(windowW, windowH);
|
||||
|
||||
// content navigator helper
|
||||
@ -665,6 +666,7 @@ var BrowserUI = {
|
||||
// new page is opened, so a call to Browser.hideSidebars() fill this
|
||||
// requirement and fix the sidebars position.
|
||||
Browser.hideSidebars();
|
||||
Elements.tabList.removeClosedTab();
|
||||
|
||||
// Delay doing the fixup so the raw URI is passed to loadURIWithFlags
|
||||
// and the proper third-party fixup can be done
|
||||
@ -781,6 +783,7 @@ var BrowserUI = {
|
||||
selectTab: function selectTab(aTab) {
|
||||
AwesomeScreen.activePanel = null;
|
||||
Browser.selectedTab = aTab;
|
||||
Elements.tabList.removeClosedTab();
|
||||
},
|
||||
|
||||
undoCloseTab: function undoCloseTab(aIndex) {
|
||||
@ -907,18 +910,14 @@ var BrowserUI = {
|
||||
this._tabSelect(aEvent);
|
||||
break;
|
||||
case "TabOpen":
|
||||
case "TabRemove":
|
||||
{
|
||||
// Workaround to hide the tabstrip if it is partially visible
|
||||
// See bug 524469 and bug 626660
|
||||
let [tabsVisibility,,,] = Browser.computeSidebarVisibility();
|
||||
if (tabsVisibility > 0.0 && tabsVisibility < 1.0)
|
||||
Browser.hideSidebars();
|
||||
|
||||
Elements.tabList.removeClosedTab();
|
||||
Browser.hidePartialTabSidebar();
|
||||
break;
|
||||
}
|
||||
case "PanFinished":
|
||||
let tabs = document.getElementById("tabs");
|
||||
case "TabRemove":
|
||||
Browser.hidePartialTabSidebar();
|
||||
break;
|
||||
case "PanFinished": {
|
||||
let tabs = Elements.tabList;
|
||||
let [tabsVisibility,,oldLeftWidth, oldRightWidth] = Browser.computeSidebarVisibility();
|
||||
if (tabsVisibility == 0.0 && tabs.hasClosedTab) {
|
||||
let { x: x1, y: y1 } = Browser.getScrollboxPosition(Browser.controlsScrollboxScroller);
|
||||
@ -936,6 +935,7 @@ var BrowserUI = {
|
||||
Browser.tryFloatToolbar(0, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SizeChanged":
|
||||
this.sizeControls(ViewableAreaObserver.width, ViewableAreaObserver.height);
|
||||
break;
|
||||
|
@ -554,6 +554,13 @@ var Browser = {
|
||||
this.tryUnfloatToolbar();
|
||||
},
|
||||
|
||||
/** Workaround to hide the tabstrip if it is partially visible (bug 524469 and bug 626660) */
|
||||
hidePartialTabSidebar: function hidePartialSidebars() {
|
||||
let [tabsVisibility,,,] = this.computeSidebarVisibility();
|
||||
if (tabsVisibility > 0.0 && tabsVisibility < 1.0)
|
||||
this.hideSidebars();
|
||||
},
|
||||
|
||||
hideTitlebar: function hideTitlebar() {
|
||||
let rect = Elements.browsers.getBoundingClientRect();
|
||||
this.pageScrollboxScroller.scrollBy(0, Math.round(rect.top));
|
||||
@ -2847,7 +2854,7 @@ Tab.prototype = {
|
||||
},
|
||||
|
||||
create: function create(aURI, aParams) {
|
||||
this._chromeTab = document.getElementById("tabs").addTab();
|
||||
this._chromeTab = Elements.tabList.addTab();
|
||||
let browser = this._createBrowser(aURI, null);
|
||||
|
||||
// Should we fully load the new browser, or wait until later
|
||||
@ -2866,7 +2873,7 @@ Tab.prototype = {
|
||||
},
|
||||
|
||||
destroy: function destroy() {
|
||||
document.getElementById("tabs").removeTab(this._chromeTab);
|
||||
Elements.tabList.removeTab(this._chromeTab);
|
||||
this._chromeTab = null;
|
||||
this._destroyBrowser();
|
||||
},
|
||||
@ -3092,7 +3099,7 @@ Tab.prototype = {
|
||||
browser.setAttribute("type", "content-primary");
|
||||
Elements.browsers.selectedPanel = notification;
|
||||
browser.active = true;
|
||||
document.getElementById("tabs").selectedTab = this._chromeTab;
|
||||
Elements.tabList.selectedTab = this._chromeTab;
|
||||
browser.focus();
|
||||
} else {
|
||||
browser.messageManager.sendAsyncMessage("Browser:Blur", { });
|
||||
|
@ -445,13 +445,11 @@ var NewTabPopup = {
|
||||
let boxRect = this.box.getBoundingClientRect();
|
||||
this.box.top = tabRect.top + (tabRect.height / 2) - (boxRect.height / 2);
|
||||
|
||||
let tabs = document.getElementById("tabs");
|
||||
|
||||
// We don't use anchorTo() here because the tab
|
||||
// being anchored to might be overflowing the tabs
|
||||
// scrollbox which confuses the dynamic arrow direction
|
||||
// calculation (see bug 662520).
|
||||
if (tabs.getBoundingClientRect().left < 0)
|
||||
if (Elements.tabList.getBoundingClientRect().left < 0)
|
||||
this.box.pointLeftAt(aTab);
|
||||
else
|
||||
this.box.pointRightAt(aTab);
|
||||
@ -523,7 +521,7 @@ var FindHelperUI = {
|
||||
Elements.browsers.addEventListener("PanFinished", this, false);
|
||||
|
||||
// Listen for events where form assistant should be closed
|
||||
document.getElementById("tabs").addEventListener("TabSelect", this, true);
|
||||
Elements.tabList.addEventListener("TabSelect", this, true);
|
||||
Elements.browsers.addEventListener("URLChanged", this, true);
|
||||
},
|
||||
|
||||
@ -675,7 +673,7 @@ var FormHelperUI = {
|
||||
messageManager.addMessageListener("FormAssist:AutoComplete", this);
|
||||
|
||||
// Listen for events where form assistant should be closed or updated
|
||||
let tabs = document.getElementById("tabs");
|
||||
let tabs = Elements.tabList;
|
||||
tabs.addEventListener("TabSelect", this, true);
|
||||
tabs.addEventListener("TabClose", this, true);
|
||||
Elements.browsers.addEventListener("URLChanged", this, true);
|
||||
|
@ -37,6 +37,7 @@
|
||||
%define padding_xsmall 0.21mozmm
|
||||
%define padding_tiny 0.11mozmm
|
||||
|
||||
%define border_width_xxlarge 0.64mozmm
|
||||
%define border_width_xlarge 0.42mozmm
|
||||
%define border_width_large 0.32mozmm
|
||||
%define border_width_small 0.21mozmm
|
||||
|
@ -31,7 +31,7 @@
|
||||
}
|
||||
|
||||
#tabs-container[tablet] {
|
||||
-moz-border-end: 0px;
|
||||
-moz-border-end: @border_width_xxlarge@ solid #eaeaea;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
|
@ -64,16 +64,16 @@ pref("browser.cache.disk.enable", true);
|
||||
pref("browser.cache.disk.smart_size.first_run", true);
|
||||
// Does the user want smart-sizing?
|
||||
pref("browser.cache.disk.smart_size.enabled", true);
|
||||
// Size explicitly set by the user. Used when smart_size.enabled == false
|
||||
// Size (in KB) explicitly set by the user. Used when smart_size.enabled == false
|
||||
pref("browser.cache.disk.capacity", 256000);
|
||||
// User-controllable max-size for entries in disk-cache. Regardless of this
|
||||
// setting, no entries bigger than 1/8 of disk-cache will be cached
|
||||
pref("browser.cache.disk.max_entry_size", 5120);
|
||||
// Max-size (in KB) for entries in disk cache. Set to -1 for no limit.
|
||||
// (Note: entries bigger than 1/8 of disk-cache are never cached)
|
||||
pref("browser.cache.disk.max_entry_size", 51200); // 50 MB
|
||||
pref("browser.cache.memory.enable", true);
|
||||
// -1 = determine dynamically, 0 = none, n = memory capacity in kilobytes
|
||||
//pref("browser.cache.memory.capacity", -1);
|
||||
// User-controllable max-size for entries in mem-cache. Regardless of this
|
||||
// setting, no entries bigger than 90% of the mem-cache will be cached
|
||||
// Max-size (in KB) for entries in memory cache. Set to -1 for no limit.
|
||||
// (Note: entries bigger than than 90% of the mem-cache are never cached)
|
||||
pref("browser.cache.memory.max_entry_size", 5120);
|
||||
pref("browser.cache.disk_cache_ssl", true);
|
||||
// 0 = once-per-session, 1 = each-time, 2 = never, 3 = when-appropriate/automatically
|
||||
|
@ -1946,9 +1946,9 @@ NS_GetContentDispositionFromHeader(const nsACString& aHeader, nsIChannel *aChan
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// special case (see bug 272541): empty disposition type handled as "inline"
|
||||
return rv == NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY
|
||||
? nsIChannel::DISPOSITION_INLINE
|
||||
: nsIChannel::DISPOSITION_ATTACHMENT;
|
||||
if (rv == NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY)
|
||||
return nsIChannel::DISPOSITION_INLINE;
|
||||
return nsIChannel::DISPOSITION_ATTACHMENT;
|
||||
}
|
||||
|
||||
return NS_GetContentDispositionFromToken(dispToken);
|
||||
|
6
netwerk/cache/nsCacheService.h
vendored
6
netwerk/cache/nsCacheService.h
vendored
@ -163,9 +163,11 @@ public:
|
||||
static void SetDiskCacheEnabled(PRBool enabled);
|
||||
// Sets the disk cache capacity (in kilobytes)
|
||||
static void SetDiskCacheCapacity(PRInt32 capacity);
|
||||
// Set max size for a disk-cache entry (in bytes). -1 disables this limit
|
||||
// Set max size for a disk-cache entry (in KB). -1 disables limit up to
|
||||
// 1/8th of disk cache size
|
||||
static void SetDiskCacheMaxEntrySize(PRInt32 maxSize);
|
||||
// Set max size for a memory-cache entry (in bytes). -1 disables this limit
|
||||
// Set max size for a memory-cache entry (in kilobytes). -1 disables
|
||||
// limit up to 90% of memory cache size
|
||||
static void SetMemoryCacheMaxEntrySize(PRInt32 maxSize);
|
||||
|
||||
static void SetOfflineCacheEnabled(PRBool enabled);
|
||||
|
@ -11,6 +11,15 @@ function get_cache_service() {
|
||||
getService(Ci.nsICacheService);
|
||||
}
|
||||
|
||||
var _PSvc;
|
||||
function get_pref_service() {
|
||||
if (_PSvc)
|
||||
return _PSvc;
|
||||
|
||||
return _PSvc = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
}
|
||||
|
||||
function get_ostream_for_entry(key, asFile, append, entryRef)
|
||||
{
|
||||
var cache = get_cache_service();
|
||||
@ -79,9 +88,13 @@ function write_datafile()
|
||||
var oStr = get_ostream_for_entry("data", true, false, entry);
|
||||
var data = gen_1MiB();
|
||||
|
||||
// 6MiB
|
||||
// max size in MB
|
||||
var max_size = get_pref_service().
|
||||
getIntPref("browser.cache.disk.max_entry_size") / 1024;
|
||||
|
||||
// write larger entry than is allowed
|
||||
var i;
|
||||
for (i=0 ; i<6 ; i++)
|
||||
for (i=0 ; i<(max_size+1) ; i++)
|
||||
write_and_check(oStr, data, data.length);
|
||||
|
||||
oStr.close();
|
||||
|
@ -144,6 +144,9 @@ function $(n)
|
||||
function doGlobalGC()
|
||||
{
|
||||
Cu.forceGC();
|
||||
var os = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "child-gc-request", null);
|
||||
update();
|
||||
}
|
||||
|
||||
@ -152,6 +155,9 @@ function doCC()
|
||||
window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils)
|
||||
.cycleCollect();
|
||||
var os = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(null, "child-cc-request", null);
|
||||
update();
|
||||
}
|
||||
|
||||
|
@ -72,11 +72,31 @@ function getString(aName) {
|
||||
return strings.GetStringFromName("action." + aName);
|
||||
}
|
||||
|
||||
function getSourceString(aSource) {
|
||||
if (!aSource)
|
||||
return "";
|
||||
|
||||
var strings = Services.strings.createBundle("chrome://mozapps/locale/extensions/selectAddons.properties");
|
||||
switch (aSource) {
|
||||
case APP:
|
||||
return strings.GetStringFromName("source.bundled");
|
||||
case PROFILE:
|
||||
return strings.GetStringFromName("source.profile");
|
||||
default:
|
||||
return strings.GetStringFromName("source.other");
|
||||
}
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gProvider = new MockProvider();
|
||||
|
||||
// Set prefs for Distributed Extension Source tests.
|
||||
Services.prefs.setBoolPref("extensions.installedDistroAddon.test3@tests.mozilla.org", true);
|
||||
Services.prefs.setBoolPref("extensions.installedDistroAddon.test12@tests.mozilla.org", true);
|
||||
Services.prefs.setBoolPref("extensions.installedDistroAddon.test15@tests.mozilla.org", true);
|
||||
|
||||
ADDONS.forEach(function(aAddon, aPos) {
|
||||
var addon = new MockAddon("test" + aPos + "@tests.mozilla.org",
|
||||
"Test Add-on " + aPos, "extension");
|
||||
@ -208,6 +228,14 @@ add_test(function selection_test() {
|
||||
var keep = gWin.document.getAnonymousElementByAttribute(row, "anonid", "keep");
|
||||
var action = gWin.document.getAnonymousElementByAttribute(row, "class", "addon-action-message");
|
||||
var update = gWin.document.getAnonymousElementByAttribute(row, "anonid", "update");
|
||||
var source = gWin.document.getAnonymousElementByAttribute(row, "class", "addon-source");
|
||||
|
||||
if (id == 3 || id == 12 || id == 15) {
|
||||
// Distro Installed To Profile
|
||||
is(source.textContent, getSourceString(APP), "Source message should have the right text for Distributed Addons");
|
||||
} else {
|
||||
is(source.textContent, getSourceString(addon[6]), "Source message should have the right text");
|
||||
}
|
||||
|
||||
// Non-profile add-ons don't appear to have updates since we won't install
|
||||
// them
|
||||
|
@ -169,7 +169,7 @@ function testIdleTime()
|
||||
// 1 second leniency.
|
||||
ok(timeDiff < 1000, "The idle time should have increased by roughly the " +
|
||||
"amount of time it took for the timeout to fire. " +
|
||||
"You didn't touch the mouse or keyboard during the" +
|
||||
"You didn't touch the mouse or keyboard during the " +
|
||||
"test did you?");
|
||||
finishedTimeoutOK = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user