On 11/28/2011 01:13 PM, Andreas Gal wrote:
> navigator.language is the default, but we should probably add an
> optional language parameter so its possible to spellcheck for a
> different language than the default
I think we should use the document's language [1] by default instead of
UA's language (navigator.language) and fallback to UA's language if
there is no matching dictionary available.
If I speak English, French, German and Japanese but my UA is in English,
I might still have four dictionaries and will be very interested to have
this API using the French one if I happen to write a comment on a French
website.
I think we should also allow the language to be specified.
Maybe even allowing an element to be passed. That might be useful to say
"use that element's language" which is unfortunately harder than doing
element.lang because the language of an element is element.lang if
specified or the the closest parent's language. Though, this is assuming
script might not know already the element's language. That might be the
case if the content is generated and localized. If that seems unusual
enough, that could wait for another iteration of the specification.
Actually, in the use case of an IME, passing the element to the method
would be a great help I believe.
> Words can be added to/removed from the personal dictionary:
>
> navigator.spelling.recognize("word")
> navigator.spelling.forget("word")
>
> The personal dictionary can be queried with:
>
> navigator.spelling.enumerate(callback)
What would be the uses cases for this for a website without any specific
permission? Why would a website want me to recognize a specific set of
words only when I am in this website?
I agree that a website with some privileges might want to add and remove
words from the user personal dictionaries. Though, I don't see the point
with allowing iterating those. Also, I don't think we should try to add
privileged-only parts in the API for the first iteration.
On 11/30/2011 02:56 AM, Hajime Morrita wrote:
> For spelling API, the only tricky bit is about privacy.
> Users' "learned" words can be thought as a part of their personal information,
> So revealing it to the page without any notification is a possible
> privacy leakage.
>
> There are some options to address this:
>
> A: Use only anonymous (default) dictionary for the API.
> B: Ask user's permission by the way some other API (ex. Filesystem
> API) is doing.
> C: Combination of A+B
> D: Assuming there is no practical abuse for the API, just allow it.
I would like to add that being able to check even simple words is
already a privacy concern because it lets the website know about two things:
1. Does the user have a dictionary;
2. What are the available dictionaries languages.
Those issues might be considered as small; I even doubt a user can
download a release of a popular browser without a pre-installed
dictionary. However, I guess that makes having no dictionary a highly
sensitive privacy bit.
Also, your dictionaries and their languages might become an efficient
way to fingerprint you even if the website has no access to your
personal dictionary. People having more than one dictionary are unusual
enough (and the combination large enough) to be easily traceable with
that information.
I don't see any non-invasive or two restrictive way to prevent (1). I
think we could hope that UA will allow this API to be disabled so users
with no dictionary and cautious regarding their privacy will be able to
protect themselves.
Iterating trough dictionaries could be (nearly) prevented if we require
a user interaction to be able to access the API and forbid changing the
language without another interaction. This is not entirely fixing the
privacy issue but should highly reduce the abuses.
> Honestly I'm tempted to pick D.
> But expecting that the discussion about privacy will happen in public anyway
> and we should be conservative on this kind of topic,
This discussion is already public ;)
> C looks reasonable for me. It's flexible and extensible enough.
> (And for some platforms including iOS, it would be difficult to
> support A-only option because,
> for example, the iOS UITextChecker provides no anonymous dictionary access.)
I see two solutions for the personal dictionary issue:
We could leave this use case for a next iteration of the specification
and highly discourage/forbid its usage in the first iteration. In the
next iteration, we could add a method requesting privileges to access
personal dictionaries in navigator.spellcheck or use a DAP Permissions
API-like API to request those privileges [2].
The alternative would be to forbid having more than one call to the API
per user interaction which would make fingerprinting using user
dictionary seriously complex unless there a way to do a highly valuable
fingerprinting with only one (or a few words).
> The permission based API can look like this:
>
> [Callback]
> interface SpellCheckHolderCallback {
> void handle(SpellChecker spelling);
> };
>
> [Supplemental=Navigator]
> interface SpellCheckerHodler {
> const String SPELLCHECK_ANONYMOUS = ...; // will return without any
> permission.
> const String SPELLCHECK_USER = ...; // will ask permission.
> void requestSpellChecker(SpellCheckHolderCallback, String type);
> };
I would suggest the following API:
interface NavigatorSpelling {
readonly atribute SpellingManager; spelling;
}
Navigator implements NavigatorSpelling;
interface SpellingManager {
SpellCheckRequest check(DOMString word, [optional] DOMString lang);
SpellCheckRequest check(DOMString word, [optional] HTMLElement element);
SpellSuggestRequest suggest(DOMString word, [optional] DOMString lang);
SpellSuggestRequest suggest(DOMString word, [optional] HTMLElement
element);
};
interface SpellCheckRequest : EventTarget {
// readyState can be "processing" or "done".
readonly attribute DOMString readyState;
readonly attribute DOMError? error;
attribute EventListener onsuccess;
attribute EventListener onerror;
attribute readonly boolean? result;
};
interface SpellSuggestRequest : EventTarget {
// readyState can be "processing" or "done".
readonly attribute DOMString readyState;
readonly attribute DOMError? error;
attribute EventListener onsuccess;
attribute EventListener onerror;
attribute readonly DOMString[]? result;
};
Examples:
var r = navigator.spelling.check("this");
r.onsuccess = function() { alert("Spelling correctness is " + r.result); };
r.onerror = function() { alert("The following error occured: " +
r.error.name); };
var r = navigator.spelling.suggest("th");
r.onsuccess = function() { alert("Suggestions are: " + r.result); };
r.onerror = function() { alert("The following error occured: " +
r.error.name); };
Error handling would be able to handle the following situations:
- various errors: we are doing I/O and using third party libraries so
errors can always occur;
- no dictionary (we shouldn't show it as "NoDictionary" for privacy
reasons but show it as "various" I guess);
- unauthorized call (if the proposal of allowing only one call per user
interaction is accepted).
I believe most use cases are going to be like the following:
var r = navigator.spelling.check("something");
r.onsuccess = r.onerror = function() {
if (!r.result) {
// probably log the error
return;
}
// do something with the result
};
Feedbacks would be very welcome :)
[1] html.lang
[2]
http://www.w3.org/TR/2010/WD-api-perms-20101005/
Thanks,
--
Mounir