- From: Wojciech Masłowski <wmaslowski@opera.com>
- Date: Fri, 18 Jun 2010 12:41:12 +0200
- To: Rich Tibbett <rich.tibbett@gmail.com>
- CC: public-device-apis@w3.org
- Message-ID: <4C1B4D48.7060109@opera.com>
W dniu 2010-06-17 16:23, Rich Tibbett pisze: > I've been thinking about the general interface patterns that we are > using in the some of the APIs, particularly with a focus on Contacts > and System-Info. > > On the one hand there is a requirement that API calls be asynchronous. > On the other hand, in order to ensure a reasonable user experience > (i.e. don't bombard the user with more than one permission request at > a time) I think we should include a requirement for serial access to > each API (or collectively, all APIs) - that no more than one API call > should be executable concurrently. I'd like to explore if this is a > reasonable assumption for e.g. Contacts and whether any changes to the > pattern used may be required for this. > > The following pattern, as used in the IndexedDB specification [1], > would be applied to System-Info and Contacts APIs: > > /_SystemInfo API example:_/ > > navigator.system.request.onsuccess = function() { > var batteries = navigator.system.request.result; > for(i in batteries) alert(batteries[i].level); > }; > navigator.system.get('Power'); > > > /_Contacts API example:_/ > > navigator.contacts.request.onsuccess = function() { > var contacts = navigator.contacts.request.result; > // do something with contacts > for(i in contacts) alert(contacts[i].displayName); > } > navigator.contacts.request.onerror = function{ > var error = navigator.contacts.request.error; > alert("[" + error.code + "]" + error.message); > } > navigator.contacts.find(['displayName', 'addresses'], {multiple: true, > limit: 3}); > > I don't really think that mandating that only one call is going to help with a problem of annoying user with security requests in any way. Consider the following use case: web app wants to get power and network info. With your suggested solution it would look like that. navigator.system.request.onsuccess = function() { doSomethingWithBatteries(navigator.system.request.result); navigator.system.request.onsuccess = function() { doSomethingWithNetworks(navigator.system.request.result); }; navigator.system.get('Network'); // triggers 2nd permission request }; navigator.system.request.onerror = function() { // even if we don't get access to Power we want to try to get Network info navigator.system.request.onsuccess = function() { doSomethingWithNetworks(navigator.system.request.result); }; navigator.system.get('Network'); // triggers 2nd permission request }; navigator.system.get('Power'); // triggers 1st permission request If we allow concurrent request the code looks like this navigator.system.get('Power', doSomethingWithBatteries ); // triggers 1st permission request navigator.system.get('Network' doSomethingWithNetworks); // triggers 2nd permission request In both examples the user will be asked for permission twice. The first one is much more complicated. Additionally with your solution we have to specify what happens in this case : navigator.system.request.onsuccess = fun1 navigator.system.get('Network'); navigator.system.request.onsuccess = fun2 will fun1 be called or fun2? > This pattern provides two additional benefits over the current APIs: > > 1. only one async method (e.g. in the Contacts API this includes > find(), save() and remove()) can be requested at any one time (i.e. > serial access only). I don't see how mandating only one async call gives advantage over possibility of many concurrent calls. In both cases developer will spam user with permission requests if he requests data too often. > 2. the 'result' and 'error' objects become a permanent well-known > fixture on the DOM (@ navigator.contacts.request for Contacts and > navigator.system.request for SysInfo). A common DOM node is useful > if/when integrating such APIs with HTML <input...> elements (very much > in a similar vein to the File API [2]). > > In an ideal world a Contact input element would be implemented as > <input type="contact" ... /> which, on click, would bring up a > 'contacts picker' [2]. When contacts are selected by the user and this > element goes in to an equivalent of the 'File Upload' state, as > defined in [3], the *.onsuccess (or *.onerror) callbacks above would > be invoked according to whatever the current web app has specified. In > any current user agent this could be implemented as follows: > > <input type="button" id="getcontacts" /> > <script type="text/javascript"> > function getContacts() { > navigator.contacts.find(['displayName', 'addresses'], > {multiple: true, limit: 3}); > } > > navigator.contacts.request.onsuccess = function() { > var contacts = navigator.contacts.request.result; > // do something with contacts > for(i in contacts) alert(contacts[i].displayName); > } > navigator.contacts.request.onerror = function{ > var error = navigator.contacts.request.error; > alert("[" + error.code + "]" + error.message); > } > > // Bind button > var el = document.getElementById("getcontacts"); > el.addEventListener("click", getContacts, false); > </script> > > Final thought: we may want to bind access to navigator.contacts.* and > navigator.system.* methods to click events (specifically, bind such > methods to HTML anchor and button element click events only). > The concept of having contact input field is interesting but I don't know if having them bound to global objects would be the cleanest solution. Lets say the web app wants to provide 2 buttons one to search for contacts and one to delete contact. In that case onsuccess callback would be called both for find and delete success which would probably lead to messy code? Personally I'd rather have something like this: <input id="getcontacts" type="contact" properties="name,address" filter="work"> ... var el = document.getElementById("getcontacts"); el.addEventListener("contactSelected", doSthWithContacts, false); > Just thought I would throw this out there as I thought it might be > worth exploring further particularly in the context of some of the > feedback from the WebApps WG. Any thoughts or developments on this > proposal would be appreciated. > > regards, Richard > > > [1] http://www.w3.org/TR/IndexedDB/ > [2] http://dev.w3.org/html5/spec/Overview.html#file-upload-state > [3] http://dev.w3.org/2009/dap/contacts/contacts_picker.png -- Wojciech Masłowski Engeneering CORE Wrocław Opera Software ASA http://www.opera.com
Received on Friday, 18 June 2010 10:42:00 UTC