Re: [IndexedDB] Closing on bug 9903 (collations)
On 3 May 2011 23:59, Aryeh Gregor simetrical+...@gmail.com wrote: On Tue, May 3, 2011 at 10:56 AM, Keean Schupke ke...@fry-it.com wrote: Why does it need to be persisted? I would prefer the database to be stateless. Obviously all users of the database need to use the same function. And if they don't use exactly the same function, maybe due to a transient bug, the index is silently and permanently corrupted, until all affected rows happen to be updated again? That doesn't sound like a good idea to me. I thought only the app that created the db could open it (for security reasons)... so it becomes the app's responsibility to do version control. The comparison function is not going to change by itself - someone has to go into the code and change it, when they do that they should up the revision of the database, if that change is incompatible. There is exactly the same problem with object properties. If the app changes to expect a new property on all objects stored, then the app has to correctly deal with the update. There are two issues here: 1) doing things correctly - there is no problem here, providing the closure works. 2) making things easy for the user - for me a simpler more predictable API is better for the user. Having a function stored inside the database is bad, because you cannot see what function might be stored in there... it might be a function from a previous version of the code and cause all sorts of strange bugs (which will only affect certain users with a certain version of the function stored in their DB). By having the sort function in plain sight in the source code it is visible and readable. Yes, there is a risk that the code is changed and the order method is different from that in the DB, which will cause breakage, but so can a function hidden in the database. Of the two I would always choose to have everything clearly visible in the source code where you can check it. Cheers, Keean.
Re: [IndexedDB] Closing on bug 9903 (collations)
On 4 May 2011 00:57, Jonas Sicking jo...@sicking.cc wrote: On Tue, May 3, 2011 at 12:19 AM, Keean Schupke ke...@fry-it.com wrote: The more I think about it, the more I want a user-specified comparison function. Efficiency should not be an issue here - the engines should tweek the JIT compiler to fix any efficiency issues. Just let the user pass a closure (remember functions are first-class in JavaScript so this is not a callback nor an event). I don't think we should do callbacks for the first version of javascript. It gets very messy since we can't rely on that the script function will be returning stable values. Additionally we'd either have to ask that the callback function is re-registered each time the database is opened, or somehow store a serialized copy of the callback function in the browser so that it's available the next time the database is opened. Neither of these things have been done in other APIs in the past, so if we hold up v1 until we solve the challenges involved I think it will delay the release of a stable spec. So the choice here really is between only supporting some form of binary sorting, or supporting a built-in set of collations. Anything else will have to wait for version 2 in my opinion. / Jonas Thats fine with me, providing the other issues around collation orders are solved. If something like the unicode algorithm is used (and if not I would want to be convinced there is a good reason for doing something different than everyone else) there is the issue of what orderings are provided by everyone (maybe DUCET + current CLDR). Then there is how often the CLDR should be updated. Should there be a live fetch / version check every time the DB is started (seems like a sensible route to me, where possible), otherwise the CLDR version could be specified by the standard and updated with each version of the standard? Cheers, Keean.
Re: [IndexedDB] Closing on bug 9903 (collations)
On 4 May 2011 00:57, Jonas Sicking jo...@sicking.cc wrote: On Tue, May 3, 2011 at 12:19 AM, Keean Schupke ke...@fry-it.com wrote: The more I think about it, the more I want a user-specified comparison function. Efficiency should not be an issue here - the engines should tweek the JIT compiler to fix any efficiency issues. Just let the user pass a closure (remember functions are first-class in JavaScript so this is not a callback nor an event). I don't think we should do callbacks for the first version of javascript. It gets very messy since we can't rely on that the script function will be returning stable values. garbage in = garbage out. The programmers job is to write a correct comparison function. All functions have this problem. By this argument we had all better give up programming because there is a risk we may write a function that returns incorrect results. Additionally we'd either have to ask that the callback function is re-registered each time the database is opened, or somehow store a I still think re-registering is a non-issue. It is trivial to declare a local open function openNameIndex than calls openIndex with the correct callback and provide that as a software-module - either in the main code, or in a separate JS file that can be included in each page. Modular programming is a good thing, should be encouraged, and is the traditional software engineering solution to this kind of problem. serialized copy of the callback function in the browser so that it's available the next time the database is opened. Neither of these things have been done in other APIs in the past, so if we hold up v1 until we solve the challenges involved I think it will delay the release of a stable spec. So the choice here really is between only supporting some form of binary sorting, or supporting a built-in set of collations. Anything else will have to wait for version 2 in my opinion. / Jonas Cheers, Keean.
Re: [widgets] Dig Sig spec
On Tuesday, May 3, 2011 at 12:00 AM, timeless wrote: It's pretty much impossible for me to figure out which things are new or which i've missed in previous rounds. (It's also possible that I didn't review this spec, in which case, I'm sorry.) I don't believe these comments significantly affect the document, i.e. they're mostly editorial, although some are technically errors which should definitely be fixed. http://dev.w3.org/2006/waf/widgets-digsig/ A widget package can be digitally signed by an author to produce a signature file that cryptographically includes all of the files of a widget package that are not i don't think includes is right, perhaps covers or attests. Covers it is. A user agent or other entity can use author signature to determine: use _an_ author fixed. As the following terms are used throughout this specification, they are gathered here for the readers convenience. reader's fixed A file name is the name of a file contained in a widget package (excludes path information), as defined in the [Widgets Packaging] specification. probably s/excludes/excluding/ fixed Set the a URI attribute for each ds:Reference to be the zip relative path that identifies a file inside the widget package. drop a I changed it the fie... just saying file Generate a identifier property in the manner specified in [Signature Properties]. an fixed Serialized the signature as a [UTF-8] encoded [XML] document using the appropriate naming convention depending on its role: Serialize ? (present tense, action/command v. past tense) Fixed. To validate the siganture files of a widget package, a validator MUST run the algorithm to validate digital signatures. signature is misspelled fixed terminate this algorithm and treat as an unsigned widget package: treat _it_ as... fixed Check that signature has a ds:Reference for every file that is not a signature file. If every non-signature file is not included, then signature is in error. s/every/any/ s/not included/not listed/ fixed and fixed If the role property is missing or or invalid, then signature is in error. s/or or/or/ fixed If all signatures validated successfully, treat this as a signed widget package. s/validated/validate/ fixed Search the root of the widget package for any file name that case-sesitively sensitively is misspelled Fixed. This implies that, in order to verify a signature file, a user agent need needs fixed A signature .. does not limit .. decompression and unpacking code used during signature extraction and verification. This doesn't seem to be a complete thought. Agreed. This is redundant anyway so I killed it. I just said in the first paragraph: the security considerations of [Widget Packaging] also apply to this specification. A signature file can also be renamed, which can affect the order in which distributor signatures are processed. This could have been addressed by embedding the signature file name into the file, oh well :) True... oh well. Something for v2, I guess. Mechanisms to install new root certificates in a user agent need to be subject to security critical mechanisms. 'security critical mechanisms' doesn't sound right Agreed. Removed that sentence. Changed the paragraph to: If the user agent supports installing a new root certificate, an end-user should be made aware of what they are doing, and why. Thanks for the review, Josh!
RE: [IndexedDB] deleteObjectStore method and updates to IDBDatabase.objectStoreNames on the client
The reason I was thinking that deleteObjectStore was async was because it returns an IDBRequest interface and the pattern implies that the onsuccess handler needs to be called for me to be sure that the operation happened successfully. Regarding the createObjectStore, it returns immediately but the the actual object store creation could happen asynchronously in the background. At least there is language in the spec that alludes to that fact: In some implementations it's possible for the implementation to asynchronously run into problems creating the object store after the createObjectStore function has returned. . Such implementations must still create and return a IDBObjectStore object. Instead, once the implementation realizes that creating the objectStore has failed, it must abort the transaction using the steps for aborting a transaction. If we believe that the actual object store creation needs to happen synchronously to establish a common behavior between platforms, we should stipulate that in the spec. Back to the original issue, I like your statement of ensuring that the deleteObjectStore removes the objectStore name from the IDBDatabase.objectStoreNames immediately after it executes. If everyone else agrees, we should add some text or a note to the spec to capture this. Israel On Wed, May 4, 2011 at 9:17 PM, Jeremy Orlow wrote: Well, createObjectStore is synchronous, so that one's easy. Everything happens at once in terms of side effects. As for delete: why is this asynchronous again? It seems easiest just to make it sync unless there's some major problem with doing so. Either way, it seems that the change to objectStoreNames should either happen immediately or when firing the onsuccess event (i.e. not just at some random time in between). J On Wed, May 4, 2011 at 7:13 AM, Israel Hilerio isra...@microsoft.com wrote: In looking at createObjectStore on IDBDatabase, it seems that we would have to update the IDBDatabase.objectStoreNames attribute on the client side after returning the IDBObjectStore. Otherwise, it would be difficult to detect that an objectStore with the same name already exists and throw a CONSTRAINT_ERR exception. Following this pattern, would it make sense to update the IDBDatabase.objectStoreNames attribute on the client side after executing deleteObjectStore before the async operation is executed. This would allow us to support scenarios like: var b = db.createObjectStore(B); var req = db.deleteObjectStore(B); b = db.createObjectStore(B); What do you think? Israel
Re: [widgets] localizing author
Hi, I just realised that I actually localise my own name in certain languages (most particularly to ensure that I get my preferred transliterations when I am publishing). But I cannot do that in config.xml. Likewise, I would like to localise the href for me which would be possible if I could localise the author element but isn't at the moment. Yes, this was a mistake. I don't now if this is too late for the current version, in which case please log it as an issue for the future. I think it is too late for this version. We have runtimes now at 99% and even 100% conformance and adding this would make most runtimes non-conforming. I think its more important now to push this spec to REC and address these kinds of cases in a future version of the spec. Changing it to allow localisation would mean a change to the schema - and at least to Opera's implementation. I haven't yet checked (I only realised I want to do this but it isn't allowed today) whether we have any preference for making that change now or later. I think we should definitely add this to any future versions of the spec. In fact, authors could actually start using multiple localized author elements today and have them work in the future. If it is ok with you, we will add this to a future version of the spec?
Re: 'view-mode' Media Feature spec - corrections
Some off list fixes I received to view mode spec... [3. Security Considerations] Currently: Application could be designed to trick users Should be: An application could be designed to trick users Fixed Currently: tiny web page Should be: tiny web pages Fixed Currently: masquerade some other existing objects Should be: masquerade as some other existing objects fixed
Re: clarification on 9.1.3
In section 9.1.3 of the Widget PC, the first step of the algorithm to find a file says: Let path be the valid path to the file entry being sought by the user agent. valid path is defined by a rather strict grammar — paths that have a double slash aren't matched by the grammar e.g. path//to/file. What the spec doesn't say is what to do if step one fails, i.e. the path is not valid. Should null be returned? An error? Or is that implementation defined? Spec now says: [[ 1. Let path be the path to the file entry being sought by the user agent. 2. If path is not a valid path, return an error and terminate this algorithm. ]]
Re: [IndexedDB] deleteObjectStore method and updates to IDBDatabase.objectStoreNames on the client
On Wed, May 4, 2011 at 9:40 PM, Israel Hilerio isra...@microsoft.comwrote: The reason I was thinking that deleteObjectStore was async was because it returns an IDBRequest interface and the pattern implies that the onsuccess handler needs to be called for me to be sure that the operation happened successfully. I'm pretty sure this is just an oversight. There's no mention of things being async in the description, it returns exceptions, and deleteIndex returns void. I don't see any reason why deleteObjectStore would be different. Regarding the createObjectStore, it returns immediately but the the actual object store creation could happen asynchronously in the background. At least there is language in the spec that alludes to that fact: In some implementations it's possible for the implementation to asynchronously run into problems creating the object store after the createObjectStore function has returned. . Such implementations must still create and return a IDBObjectStore object. Instead, once the implementation realizes that creating the objectStore has failed, it must abort the transaction using the steps for aborting a transaction. Sure, but besides the fact that the transaction may spuriously abort (which is unfortunate), all other side effects should be hidden from the user. We should just spec that the name should immediately show up in the list. If we believe that the actual object store creation needs to happen synchronously to establish a common behavior between platforms, we should stipulate that in the spec. The entire design revolves around ensuring you'll never block on disk io. So we definitely should not do this. Back to the original issue, I like your statement of ensuring that the deleteObjectStore removes the objectStore name from the IDBDatabase.objectStoreNames immediately after it executes. If everyone else agrees, we should add some text or a note to the spec to capture this. Making it return void should be enough. Israel On Wed, May 4, 2011 at 9:17 PM, Jeremy Orlow wrote: Well, createObjectStore is synchronous, so that one's easy. Everything happens at once in terms of side effects. As for delete: why is this asynchronous again? It seems easiest just to make it sync unless there's some major problem with doing so. Either way, it seems that the change to objectStoreNames should either happen immediately or when firing the onsuccess event (i.e. not just at some random time in between). J On Wed, May 4, 2011 at 7:13 AM, Israel Hilerio isra...@microsoft.com wrote: In looking at createObjectStore on IDBDatabase, it seems that we would have to update the IDBDatabase.objectStoreNames attribute on the client side after returning the IDBObjectStore. Otherwise, it would be difficult to detect that an objectStore with the same name already exists and throw a CONSTRAINT_ERR exception. Following this pattern, would it make sense to update the IDBDatabase.objectStoreNames attribute on the client side after executing deleteObjectStore before the async operation is executed. This would allow us to support scenarios like: var b = db.createObjectStore(B); var req = db.deleteObjectStore(B); b = db.createObjectStore(B); What do you think? Israel
Re: [widgets] localizing author
On May/4/2011 12:29 PM, ext Marcos Caceres wrote: Hi, I just realised that I actually localise my own name in certain languages (most particularly to ensure that I get my preferred transliterations when I am publishing). But I cannot do that in config.xml. Likewise, I would like to localise the href for me which would be possible if I could localise the author element but isn't at the moment. Yes, this was a mistake. I don't now if this is too late for the current version, in which case please log it as an issue for the future. I think it is too late for this version. We have runtimes now at 99% and even 100% conformance and adding this would make most runtimes non-conforming. I think its more important now to push this spec to REC and address these kinds of cases in a future version of the spec. Changing it to allow localisation would mean a change to the schema - and at least to Opera's implementation. I haven't yet checked (I only realised I want to do this but it isn't allowed today) whether we have any preference for making that change now or later. I think we should definitely add this to any future versions of the spec. In fact, authors could actually start using multiple localized author elements today and have them work in the future. If it is ok with you, we will add this to a future version of the spec? FYI, the widget spec v2 feature list is: http://www.w3.org/2008/webapps/wiki/Widgets2_UC%26R
Re: bug in example in step 6 of media type algorithm in WD-widgets-20110322 ?
(forgot to cc the list!) On Wednesday, May 4, 2011 at 7:41 PM, Marcos Caceres wrote: http://www.w3.org/TR/2011/WD-widgets-20110322/#rule-for-identifying-the-media-type-of-a0 says: says If the first character of the name is not a U+002E 'FULL STOP' character, but name contains one or more U+002E 'FULL STOP' characters, then let extension be the sequence of characters from the last U+002E 'FULL STOP' (inclusive) to the end of name (if any). The value of extension for the file name cat.html would be .html. The value of extension for ...html would be .html. And the value of extension for hello. would be an empty string. /says Wouldn't the value of extension for hello. be . according to this rule? If any doesn't make sense - there has to be *some* sequence of characters from the full stop to the end. Best Jonathan The spec now reads: [[ If the first character or last character of the name is not a U+002E 'FULL STOP' character, but name contains one or more U+002E 'FULL STOP' characters, then let extension be the sequence of characters from the last U+002E 'FULL STOP' (inclusive) to the end of name. ]] That should address the issue above.
widgets PC rule 9.1.12...
Hi Marcos and Webapps, This is a personal last call comment [chair hat off]. I realize that it is late, but I was on vacation A developer recently sent me a code review implementing the latest spec and I found some code that was utterly mystifying to me. It turns out that he implemented rule 9.1.12 in the current spec, which defines user_agent_locales. This text seems really odd to me. What I expected was from looking at step 8 in section 9.1.17 was to have a language priority list containing the locale(s) to search for using the Lookup algorithm from BCP 47. I expected that this list would usually consist of a single locale identifier (language tag) representing the current Widget runtime locale, although an implementation might occasionally use Accept-Language or some other source for a full language priority list such as shown in the examples. I read user_agent_locales to be the Widget's version of a language priority list. The odd thing is that the rules in 9.1.12 explode each language range, but the BCP 47 Lookup algorithm already does this. For example, 9.1.12 would convert the language priority list zh-Hans-CN,* to the user_agent_locales string zh-Hans-CN,zh-Hans,zh,*. But this is unnecessary because the Lookup algorithm's remove from right logic already does this (or, for xml:lang matching, you can use prefix matching). If you do both the lookup algorithm *and* the computation of user_agent_locales, you will do a bunch of unnecessary searching with lower efficiency. If what you want is to define lookup by computing user_agent_locales and then doing exact path matches for each element, then that's okay, I suppose, although personally I would (and have) implemented it in memory rather than by computing an exploded user_agent_locales list. So my request/proposal would be to either (a) eliminate section 9.1.12 and just specify BCP 47 Lookup or (b) specify the complete match algorithm using the list computed in 9.1.12 and state that it is compatible with BCP 47 lookup. I would strongly prefer (a) personally. The internationalization work in ECMAScript and at least one implementation do it that way. Addison Phillips Globalization Architect (Lab126) Chair (W3C I18N WG) Internationalization is not a feature. It is an architecture.
Re: [widgets] Processing comments from 22-Mar-2011 LCWD of Widgets PC
On Monday, May 2, 2011 at 3:32 PM, Arthur Barstow wrote: Marcos, All - re processing comments submitted against the 22-Mar-2011 PC LCWD, FYI, below are the comments I noted. Are there any other comments, bugs, etc. that need to be considered? Not from me. BTW, Aplix is also now claiming to be passing 100% of the test suite, which is fantastic. Opera is only 5 tests out from reaching 100% (they actually pass 100% if the widgets are treated as Opera Extensions). There is a small bug in Opera's Desktop implementation that rejects widget without a name. I'm hopeful this will be fixed RSN. I recorded the following comments since that LCWD was published: = Charles McCathieNevile; 8-Apr-2011; localizingauthor http://lists.w3.org/Archives/Public/public-webapps/2011AprJun/0121.html Addressed: http://lists.w3.org/Archives/Public/public-webapps/2011AprJun/0457.html = Addison Phillips; 30-Mar-2011; clarification on 9.1.3 http://lists.w3.org/Archives/Public/public-webapps/2011JanMar/1076.html Addressed: http://lists.w3.org/Archives/Public/public-webapps/2011AprJun/0459.html = Jonathan Rees; 23-Mar-2011; bug in example in step 6 of media type algorithm in WD-widgets-20110322 ? http://lists.w3.org/Archives/Public/public-webapps/2011JanMar/1042.html Addressed: http://lists.w3.org/Archives/Public/public-webapps/2011AprJun/0462.html Marcos - are there any other LCWD comments? I think that is it! :)
RE: [indexeddb] result attribute for IDBRequest is set to undefined when calling IDBObjectStore.clear()
If that is the case we need to ensure that the async implementations for deleteDatabase and deleteObjectStore have consistent results on their IDBRequest. deleteDatabase stipulates that the result of the request is null and deleteObjectStore stipulates that the result of the request is undefined. Using your logic they both should return undefined results. Furthermore, we should be using this pattern everywhere there is an async function that returns an IDB Request and there is a counterpart sync void function. That would mean that for each of the following functions the result of the request should be undefined: * IDBFactorySync.deleteDatabase -- IDBFactory.deleteDatabase * IDBDatabaseSync.deleteObjectStore -- IDBDatabase.deleteObjectStore * IDBObjectStoreSync.delete -- IDBObjectStore.delete * IDBObjectStoreSync.clear -- IDBObjectStore.clear * IDBCursorSync.delete -- IDBCursor.delete These functions are okay. They are both void functions: * IDBObjectStoreSync.deleteIndex -- IDBObjectStore.deleteIndex * IDBDatabaseSync.close -- IDBDatabase.close * IDBCursorSync.advance -- IDBCursor.advance * IDBTransactionSync.abort -- IDBTransaction.abort This one should be okay to because because it has a callback: * IDBDatabaseSync.transaction(...) Do you agree? Israel On Mon, Tuesday, May 03, 2011 9:07 PM, Jeremy Orlow wrote: Undefined is also the return value for void functions. The result is essentially the return value of our async methods. And in most cases, the behavior of each async method is just a transformation of the sync method and vice versa. So my thinking is that it should stay as it is. J On Mon, May 2, 2011 at 11:22 PM, Israel Hilerio isra...@microsoft.com wrote: After calling the clear() method on IDBObjectStore, the result of the IDBRequest is set to undefined according to the steps for clearing an object store. However, the result property in IDBRequest says that the result value is undefined when the request results in an error: This is undefined when the request resulted in an error. In IE, we've been using undefined to signal properties that are not available to developers and null to signal unassigned values. It seems that null would be a better result value when the object store has been cleared. This would follow the same pattern we use in the deleteDatabase method where we return a null value for the result of the IDBRequest: If the steps above are successful, the implementation must set the result of the request to null and fire a success event at the request. What do you think? Israel
Re: widgets PC rule 9.1.12...
On Wednesday, May 4, 2011 at 7:53 PM, Phillips, Addison wrote: Hi Marcos and Webapps, This is a personal last call comment [chair hat off]. I realize that it is late, but I was on vacation A developer recently sent me a code review implementing the latest spec and I found some code that was utterly mystifying to me. It turns out that he implemented rule 9.1.12 in the current spec, which defines user_agent_locales. This text seems really odd to me. What I expected was from looking at step 8 in section 9.1.17 was to have a language priority list containing the locale(s) to search for using the Lookup algorithm from BCP 47. I expected that this list would usually consist of a single locale identifier (language tag) representing the current Widget runtime locale, although an implementation might occasionally use Accept-Language or some other source for a full language priority list such as shown in the examples. I read user_agent_locales to be the Widget's version of a language priority list. The odd thing is that the rules in 9.1.12 explode each language range, but the BCP 47 Lookup algorithm already does this. For example, 9.1.12 would convert the language priority list zh-Hans-CN,* to the user_agent_locales string zh-Hans-CN,zh-Hans,zh,*. But this is unnecessary because the Lookup algorithm's remove from right logic already does this (or, for xml:lang matching, you can use prefix matching). If you do both the lookup algorithm *and* the computation of user_agent_locales, you will do a bunch of unnecessary searching with lower efficiency. If what you want is to define lookup by computing user_agent_locales and then doing exact path matches for each element, then that's okay, I suppose, although personally I would (and have) implemented it in memory rather than by computing an exploded user_agent_locales list. So my request/proposal would be to either (a) eliminate section 9.1.12 and just specify BCP 47 Lookup or (b) specify the complete match algorithm using the list computed in 9.1.12 and state that it is compatible with BCP 47 lookup. I would strongly prefer (a) personally. The internationalization work in ECMAScript and at least one implementation do it that way. I am all for using (a), so long as the result is the same as what we currently have today (i.e., we don't break existing implementations and the test suite).
Re: [IndexedDB] Closing on bug 9903 (collations)
On Wed, May 4, 2011 at 1:10 AM, Keean Schupke ke...@fry-it.com wrote: On 4 May 2011 00:57, Jonas Sicking jo...@sicking.cc wrote: On Tue, May 3, 2011 at 12:19 AM, Keean Schupke ke...@fry-it.com wrote: The more I think about it, the more I want a user-specified comparison function. Efficiency should not be an issue here - the engines should tweek the JIT compiler to fix any efficiency issues. Just let the user pass a closure (remember functions are first-class in JavaScript so this is not a callback nor an event). I don't think we should do callbacks for the first version of javascript. It gets very messy since we can't rely on that the script function will be returning stable values. garbage in = garbage out. The programmers job is to write a correct comparison function. All functions have this problem. By this argument we had all better give up programming because there is a risk we may write a function that returns incorrect results. Browsers can certainly deal with this, and ensure that the only one suffering is the author of the buggy algorithm. However this comes at a cost in that the browser sorting algorithm can't go into infinite loops or crash even in the face of the most ridiculous comparison algorithm. In other words, the browser will likely have to use a slower sorting implementation in order to be robust. Additionally, there is a significant cost involved in transitioning between the C++ code implementing the sorting algorithm, and the javascript implemented callback. That is on top of the cost of implementing the comparison function in javascript. Even in the best JITs, there is a significant overhead to both these parts. So rather than repeating myself, i'll just quote myself: So the choice here really is between only supporting some form of binary sorting, or supporting a built-in set of collations. Anything else will have to wait for version 2 in my opinion. :) / Jonas
Re: [IndexedDB] deleteObjectStore method and updates to IDBDatabase.objectStoreNames on the client
On Wed, May 4, 2011 at 9:49 AM, Jeremy Orlow jor...@chromium.org wrote: On Wed, May 4, 2011 at 9:40 PM, Israel Hilerio isra...@microsoft.com wrote: The reason I was thinking that deleteObjectStore was async was because it returns an IDBRequest interface and the pattern implies that the onsuccess handler needs to be called for me to be sure that the operation happened successfully. I'm pretty sure this is just an oversight. There's no mention of things being async in the description, it returns exceptions, and deleteIndex returns void. I don't see any reason why deleteObjectStore would be different. Regarding the createObjectStore, it returns immediately but the the actual object store creation could happen asynchronously in the background. At least there is language in the spec that alludes to that fact: In some implementations it's possible for the implementation to asynchronously run into problems creating the object store after the createObjectStore function has returned. . Such implementations must still create and return a IDBObjectStore object. Instead, once the implementation realizes that creating the objectStore has failed, it must abort the transaction using the steps for aborting a transaction. Sure, but besides the fact that the transaction may spuriously abort (which is unfortunate), all other side effects should be hidden from the user. We should just spec that the name should immediately show up in the list. If we believe that the actual object store creation needs to happen synchronously to establish a common behavior between platforms, we should stipulate that in the spec. The entire design revolves around ensuring you'll never block on disk io. So we definitely should not do this. Back to the original issue, I like your statement of ensuring that the deleteObjectStore removes the objectStore name from the IDBDatabase.objectStoreNames immediately after it executes. If everyone else agrees, we should add some text or a note to the spec to capture this. Making it return void should be enough. Israel On Wed, May 4, 2011 at 9:17 PM, Jeremy Orlow wrote: Well, createObjectStore is synchronous, so that one's easy. Everything happens at once in terms of side effects. As for delete: why is this asynchronous again? It seems easiest just to make it sync unless there's some major problem with doing so. Either way, it seems that the change to objectStoreNames should either happen immediately or when firing the onsuccess event (i.e. not just at some random time in between). J On Wed, May 4, 2011 at 7:13 AM, Israel Hilerio isra...@microsoft.com wrote: In looking at createObjectStore on IDBDatabase, it seems that we would have to update the IDBDatabase.objectStoreNames attribute on the client side after returning the IDBObjectStore. Otherwise, it would be difficult to detect that an objectStore with the same name already exists and throw a CONSTRAINT_ERR exception. Following this pattern, would it make sense to update the IDBDatabase.objectStoreNames attribute on the client side after executing deleteObjectStore before the async operation is executed. This would allow us to support scenarios like: var b = db.createObjectStore(B); var req = db.deleteObjectStore(B); b = db.createObjectStore(B); What do you think? Israel I agree with Jeremy. We should just make deleteObjectStore return void and then define that deleteObjectStore/createObjectStore/deleteIndex/createIndex all act synchronously and modify .objectStoreNames/.indexNames synchronously. Israel: I'm not sure what you mean by that you think object store creation needs to happen synchronously. I definitely agree that creating the IDBObjectStore object should happen synchronously, and that it should be added to the .objectStoreNames array synchronously. Anything beyond that is opaque to the website and so I don't think it makes sense to say anything normative about it. / Jonas
Re: [IndexedDB] Closing on bug 9903 (collations)
On 4 May 2011 21:01, Jonas Sicking jo...@sicking.cc wrote: On Wed, May 4, 2011 at 1:10 AM, Keean Schupke ke...@fry-it.com wrote: On 4 May 2011 00:57, Jonas Sicking jo...@sicking.cc wrote: On Tue, May 3, 2011 at 12:19 AM, Keean Schupke ke...@fry-it.com wrote: The more I think about it, the more I want a user-specified comparison function. Efficiency should not be an issue here - the engines should tweek the JIT compiler to fix any efficiency issues. Just let the user pass a closure (remember functions are first-class in JavaScript so this is not a callback nor an event). I don't think we should do callbacks for the first version of javascript. It gets very messy since we can't rely on that the script function will be returning stable values. garbage in = garbage out. The programmers job is to write a correct comparison function. All functions have this problem. By this argument we had all better give up programming because there is a risk we may write a function that returns incorrect results. Browsers can certainly deal with this, and ensure that the only one suffering is the author of the buggy algorithm. However this comes at a cost in that the browser sorting algorithm can't go into infinite loops or crash even in the face of the most ridiculous comparison algorithm. In other words, the browser will likely have to use a slower sorting implementation in order to be robust. Additionally, there is a significant cost involved in transitioning between the C++ code implementing the sorting algorithm, and the javascript implemented callback. That is on top of the cost of implementing the comparison function in javascript. Even in the best JITs, there is a significant overhead to both these parts. So rather than repeating myself, i'll just quote myself: So the choice here really is between only supporting some form of binary sorting, or supporting a built-in set of collations. Anything else will have to wait for version 2 in my opinion. :) / Jonas I gave my answer, and some follow up questions in a previous email, so I am not avoiding the question. My point was any event handler (onMouseDown?) could have an infinite loop - why so fussy about this one function when so many others have the same problem? The performance point of calling to JavaScript is a valid one, but is this a problem? Perhaps it is fast enough. I have seen no evidence that is will be too slow for people to use - perhaps the bottle neck will be the disk/flash access speed for fetching the blocks and not the JavaScript comparison function. Cheers, Keean.
Re: [indexeddb] result attribute for IDBRequest is set to undefined when calling IDBObjectStore.clear()
On Wed, May 4, 2011 at 11:04 AM, Israel Hilerio isra...@microsoft.com wrote: If that is the case we need to ensure that the async implementations for deleteDatabase and deleteObjectStore have consistent results on their IDBRequest. deleteDatabase stipulates that the result of the request is null and deleteObjectStore stipulates that the result of the request is undefined. Using your logic they both should return undefined results. Yes. I think that deleteDatabase should return undefined. deleteObjectStore should be a synchronous method (per other thread) returning void and so no return value would need to be defined. Furthermore, we should be using this pattern everywhere there is an async function that returns an IDB Request and there is a counterpart sync void function. That would mean that for each of the following functions the result of the request should be undefined: * IDBFactorySync.deleteDatabase -- IDBFactory.deleteDatabase * IDBDatabaseSync.deleteObjectStore -- IDBDatabase.deleteObjectStore * IDBObjectStoreSync.delete -- IDBObjectStore.delete * IDBObjectStoreSync.clear -- IDBObjectStore.clear * IDBCursorSync.delete -- IDBCursor.delete IDBObjectStore(Sync).delete and IDBCursor(Sync).delete currently return true/false depending on if the value existed or not. I think that is useful and should remain. For the other methods I agree that they should return void and so have no return value at all (or have .result set to undefined in the asynchronous versions). Potentially deleteDatabase could return true/false just like objectStore and cursors. However I can't really come up with any use cases for this so it might be better to stick with using void/undefined for now. We can always add a return value later if a use case arises. These functions are okay. They are both void functions: * IDBObjectStoreSync.deleteIndex -- IDBObjectStore.deleteIndex * IDBDatabaseSync.close -- IDBDatabase.close * IDBCursorSync.advance -- IDBCursor.advance * IDBTransactionSync.abort -- IDBTransaction.abort This one should be okay to because because it has a callback: * IDBDatabaseSync.transaction(...) Do you agree? Largely yes. Though looking at cursor.advance, it should behave like cursor.continue as it provides basically the same functionality. This means that the asynchronous version should return the cursor itself if it iterates to a valid position, or null if it iterates off of the end. The synchronous version should return true if it iterates to a valid position and false if it iterates off of the end. I think there are some bugs in the spec currently, both for cursor.advance and cursor.continue. Other than that I think you're spot on. / Jonas
Concerns regarding cross-origin copy/paste security
There was a recent discussion involving directly exposing the HTML fragment in a paste to a page, since we're doing the parsing anyway for security reasons. I have some concerns regarding http://www.w3.org/TR/clipboard-apis/#cross-origin-copy-paste-of-source-codethough. From my understanding, we are trying to protect against [1] hidden data being copied without a user's knowledge and [2] XSS via pasting hostile HTML. In my opinion, the algorithm as written is either going to remove too much information or not enough. If it removes too much, the HTML paste is effectively useless to a client app. If it doesn't remove enough, then the client app is going to have to sanitize the HTML itself anyway. I would argue that we should primarily be trying to prevent [1] and leave it up to web pages to prevent [2]. [2] is no different than using data from any other untrusted source, like dragging HTML or data from an XHR. It doesn't make sense to special-case HTML pastes. In order to achieve [1], the algorithm merely needs to be: - Remove HTML comments, script, input type=hidden, and all other elements that have no effect on layout (display: none). Possibly remove applet as well. - Remove event handlers, data- and form action attributes. - Blanking input type=password elements. To me, it doesn't make sense to remove the other elements: - OBJECT: Could be used for SVG as I understand. - FORM: Essentially harmless once the action attribute is cleared. - INPUT (non-hidden, non-password): Content is already available via text/plain. - TEXTAREA: See above. - BUTTON, INPUT buttons: Most of the content is already available via text/plain. We can scrub the value attribute if there is concern about that. - SELECT/OPTION/OPTGROUP: See above. The draft also does not mention how EMBED elements should be handled. Finally: If a script calls getData('text/html'), the implementation supports pasting HTML, and the data available on the clipboard is from a different origin, the implementation must sanitize the content by following these steps: Should this sanitization be done during a copy as well to prevent data a paste in a non-conforming browser from pasting unexpected things? Daniel (resending from the right address, sorry for the spam Hallvord)
RE: [indexeddb] result attribute for IDBRequest is set to undefined when calling IDBObjectStore.clear()
Great, I believe we have consensus. This is the summary of changes we've discussed plus one question/clarification: 1. IDBDatabase.deleteObjectStore should change to: * void deleteObjectStore (in DOMString name) raises (IDBDatabaseException); 2. IDBDatabase.createObjectStore and IDBDatabase.removeObjectStore will act synchronously and modify IDBDatabase.objectStoreNames. 3. IDBObjectStore.createIndex and IDBObjectStore.deleteIndex will act synchronously and modify IDBObjectStore.indexNames. 4. The result value on the IDBRequest returned by IDBFactory.deleteDatabase will be set to undefined when the function executes correctly. 5. The result value on the IDBRequest returned by IDBObjectStore.clear will be set to undefined when the function executes correctly. 6. IDBCursorSync.advance should change to: * boolean advance (in int count); Returns true if it iterates to a valid position and false if it iterates off of the end. Also, the result value on the IDBRequest returned by IDBCursor.advance should be the cursor itself if it iterates to a valid position, or null if it iterates off of the end. Additional questions - 7. I don't see in the spec that IDBObjectStoreSync.delete and IDBCursorSync.delete currently return true/false. I see them both as void functions. If it was previously agreed to have these functions return Booleans, we should update the spec to reflect it. 8. Assuming we update the spec with the change above, I believe you're also suggesting we make the following change: * The result value on the IDBRequest returned by IDBObjectStore.delete and IDBCursor.delete holds true or false depending on if the value existed or not. If we feel good about these changes, I can work with Eliot to update the spec. Let me know. Israel On Wed, May 4, 2011 at 1:35 PM, Jonas Sicking wrote: On Wed, May 4, 2011 at 11:04 AM, Israel Hilerio isra...@microsoft.com wrote: If that is the case we need to ensure that the async implementations for deleteDatabase and deleteObjectStore have consistent results on their IDBRequest. deleteDatabase stipulates that the result of the request is null and deleteObjectStore stipulates that the result of the request is undefined. Using your logic they both should return undefined results. Yes. I think that deleteDatabase should return undefined. deleteObjectStore should be a synchronous method (per other thread) returning void and so no return value would need to be defined. Furthermore, we should be using this pattern everywhere there is an async function that returns an IDB Request and there is a counterpart sync void function. That would mean that for each of the following functions the result of the request should be undefined: * IDBFactorySync.deleteDatabase -- IDBFactory.deleteDatabase * IDBDatabaseSync.deleteObjectStore -- IDBDatabase.deleteObjectStore * IDBObjectStoreSync.delete -- IDBObjectStore.delete * IDBObjectStoreSync.clear -- IDBObjectStore.clear * IDBCursorSync.delete -- IDBCursor.delete IDBObjectStore(Sync).delete and IDBCursor(Sync).delete currently return true/false depending on if the value existed or not. I think that is useful and should remain. For the other methods I agree that they should return void and so have no return value at all (or have .result set to undefined in the asynchronous versions). Potentially deleteDatabase could return true/false just like objectStore and cursors. However I can't really come up with any use cases for this so it might be better to stick with using void/undefined for now. We can always add a return value later if a use case arises. These functions are okay. They are both void functions: * IDBObjectStoreSync.deleteIndex -- IDBObjectStore.deleteIndex * IDBDatabaseSync.close -- IDBDatabase.close * IDBCursorSync.advance -- IDBCursor.advance * IDBTransactionSync.abort -- IDBTransaction.abort This one should be okay to because because it has a callback: * IDBDatabaseSync.transaction(...) Do you agree? Largely yes. Though looking at cursor.advance, it should behave like cursor.continue as it provides basically the same functionality. This means that the asynchronous version should return the cursor itself if it iterates to a valid position, or null if it iterates off of the end. The synchronous version should return true if it iterates to a valid position and false if it iterates off of the end. I think there are some bugs in the spec currently, both for cursor.advance and cursor.continue. Other than that I think you're spot on. / Jonas
Re: [indexeddb] result attribute for IDBRequest is set to undefined when calling IDBObjectStore.clear()
On Wed, May 4, 2011 at 2:57 PM, Israel Hilerio isra...@microsoft.com wrote: Great, I believe we have consensus. This is the summary of changes we've discussed plus one question/clarification: 1. IDBDatabase.deleteObjectStore should change to: * void deleteObjectStore (in DOMString name) raises (IDBDatabaseException); 2. IDBDatabase.createObjectStore and IDBDatabase.removeObjectStore will act synchronously and modify IDBDatabase.objectStoreNames. 3. IDBObjectStore.createIndex and IDBObjectStore.deleteIndex will act synchronously and modify IDBObjectStore.indexNames. 4. The result value on the IDBRequest returned by IDBFactory.deleteDatabase will be set to undefined when the function executes correctly. 5. The result value on the IDBRequest returned by IDBObjectStore.clear will be set to undefined when the function executes correctly. Agreed! 6. IDBCursorSync.advance should change to: * boolean advance (in int count); Returns true if it iterates to a valid position and false if it iterates off of the end. Also, the result value on the IDBRequest returned by IDBCursor.advance should be the cursor itself if it iterates to a valid position, or null if it iterates off of the end. Agreed! I just checked in a patch to implement this. So the spec should now be correct here. Additional questions - 7. I don't see in the spec that IDBObjectStoreSync.delete and IDBCursorSync.delete currently return true/false. I see them both as void functions. If it was previously agreed to have these functions return Booleans, we should update the spec to reflect it. Indeed. I checked in a fix for the synchronous API. 8. Assuming we update the spec with the change above, I believe you're also suggesting we make the following change: * The result value on the IDBRequest returned by IDBObjectStore.delete and IDBCursor.delete holds true or false depending on if the value existed or not. The asynchronous API already returned true/false as needed since the algorithms defined in section 5 already returned true/false. If we feel good about these changes, I can work with Eliot to update the spec. Let me know. Sounds good to me! / Jonas
Re: [whatwg] Can we remove forminput and formchange events and related dispatch methods?
On Thu, 20 Jan 2011, Olli Pettay wrote: On 10/22/2010 10:09 PM, Jonas Sicking wrote: On Fri, Oct 22, 2010 at 11:15 AM, Erik Arvidssona...@chromium.org wrote: On Oct 22, 2010 2:00 AM, Anne van Kesterenann...@opera.com wrote: Yeah, I don't mind moving these features to libraries. Anyone implemented them apart from Opera? Neither WebKit nor Gecko implements it: https://bugs.webkit.org/show_bug.cgi?id=26141 https://bugzilla.mozilla.org/show_bug.cgi?id=605997 IE9 beta does not have it either. This means that we should also remove dispatchFormInput/dispatchFormChange from the HTML5 spec, right? I agree, the events or at least the methods should be removed. Just to close the loop on this, these were removed a few weeks ago. -- Ian Hickson U+1047E)\._.,--,'``.fL http://ln.hixie.ch/ U+263A/, _.. \ _\ ;`._ ,. Things that are impossible just take longer. `._.-(,_..'--(,_..'`-.;.'
Re: Model-driven Views
Rafael, I am co-chair of the W3C Forms Working Group. As Charles McCathieNevile pointed out in this discussion: It probably makes sense to ask the Forms group as well, given that it doesn't require much squinting to get to the perspective where you're pretty much reinventing a wheel they've already got two of. And as Dave Raggett pointed out: Note that a particularly long standing effort on applying the MVC design pattern to the Web is XForms where the model is represented as a DOM tree. We're very interested in continuing this discussion with you. Please see http://www.w3.org/TR/xforms11 for our current W3C Recommendation and http://www.w3.org/MarkUp/Forms/ for our group page with implementation news, courses, etc. You'll find our Working Group has over ten years of W3C Recommendations and many implementations of MVC and declarative, markup-based interfaces to (and extensions of) underlying HTML functionality. We're currently quite interested in promoting declarative interfaces to some of the new functionality that HTML5 is pouring into desktop and mobile browsers, as we have done with existing functionality from the HTML4/XHTML1 series. Additionally, we're working to try to bring forward some of the stagnant XBL2 work in a form that gives the web a markup-based component architecture. Finally, we are interested in your point in [http://lists.w3.org/Archives/Public/public-webapps/2011AprJun/0428.html] that We can create a feature which is fast by default. Libraries almost never do. The Mozilla implementation of XForms used Mozilla XBL and underlying C++ code (Transformix and others) to provide a fast implementation of XForms. Unfortunately, it was limited to Mozilla. Recently, a cross-browser approach has lately taken hold, and the more recent XSLTForms and Ubiquity Forms projects provide a JavaScript library-based approach to implementing XForms in today's desktop and mobile browsers. We recognize that not everyone wants an MVC and markup based approach to declarative programming, but given that this is your area of interest, we'd be very interested in working with you to help design new APIs for browser features that enable implementations of XForms to be fast, stable, and secure in new desktop and mobile browsers. Upper level libraries could make use of these features to provide convenient interfaces for web authors, and so the lower-level features themselves are free to be designed in a more specific fashion. Limiting what fundamental capabilities are added to those which are necessary for a number of approaches may, and then letting the upper-level implementations provide convenient interfaces may answer Maciej's concern that API is forever, on the Web and echo Olli's comment better to add primitives which allow creating script libraries. (For an example of how we have done this, see XForms submission element with XHR, or XML Events wrapping of DOM Events. ) In particular, we'd love to see support for the shadow-DOM notion from XBL2 so that a component system along the lines of XBL could be developed and written. For XForms, the benefit would be this: a component system would allow developers to implement XForms via expansion into underlying browser facilities dynamically, and would also allow XForms authors to design their own components made up of XForms and other HTML and SVG elements (component widgets, macros, what have you). Since such a component system would be orthogonal, it would be useful to all, whatever form of expression your preference for MVC takes. Thank you, Leigh L. Klotz, Jr. Senior Software Architect Xerox Corporation Co-Chair, W3C Forms Working Group
Re: [IndexedDB] Closing on bug 9903 (collations)
On Tue, May 3, 2011 at 7:57 PM, Jonas Sicking jo...@sicking.cc wrote: I don't think we should do callbacks for the first version of javascript. It gets very messy since we can't rely on that the script function will be returning stable values. The worst that would happen if it didn't return stable values is that sorting would return unpredictable results. So the choice here really is between only supporting some form of binary sorting, or supporting a built-in set of collations. Anything else will have to wait for version 2 in my opinion. I think it would be a mistake to try supporting a limited set of natural-language collations. Binary collation is fine for a first version. MySQL only supported binary collation up through version 4, for instance. On Wed, May 4, 2011 at 3:49 AM, Keean Schupke ke...@fry-it.com wrote: I thought only the app that created the db could open it (for security reasons)... so it becomes the app's responsibility to do version control. The comparison function is not going to change by itself - someone has to go into the code and change it, when they do that they should up the revision of the database, if that change is incompatible. Why should we let such a pitfall exist if we can just store the function and avoid the issue? There is exactly the same problem with object properties. If the app changes to expect a new property on all objects stored, then the app has to correctly deal with the update. If a requested property doesn't exist, I assume the API will fail immediately with a clear error code. It will not fail silently and mysteriously with no error code. (Again, I haven't looked at it closely, or tried to use it.) 2) making things easy for the user - for me a simpler more predictable API is better for the user. Having a function stored inside the database is bad, because you cannot see what function might be stored in there... We could let you query the stored function. it might be a function from a previous version of the code and cause all sorts of strange bugs (which will only affect certain users with a certain version of the function stored in their DB). It will cause *much* less strange bugs than if you have one index that used two different collations, which is the alternative possibility. If the function is stored, the worst case will be that the collation function is out of date. In practice, authors will mostly want to use established collation functions like UCA and won't mind if they're out of date. They'll also only very rarely have occasion to deliberately change the function. On Wed, May 4, 2011 at 4:01 PM, Jonas Sicking jo...@sicking.cc wrote: Browsers can certainly deal with this, and ensure that the only one suffering is the author of the buggy algorithm. However this comes at a cost in that the browser sorting algorithm can't go into infinite loops or crash even in the face of the most ridiculous comparison algorithm. In other words, the browser will likely have to use a slower sorting implementation in order to be robust. The browser will only run the function once every time the given field changes, and change the value used in the index if it's different from the current one. The actual sorting will still be binary, just with a user-provided key. So there's no possibility of especially bad effects if you're given a bad function. You're only running it once per value, so it's no worse than any other function that's run a bunch of times. We aren't talking about a sort()-style comparison function that returns -1 or 0 or 1. We're talking about a function that takes a string as input, and outputs a string to be used in the index as the key for the object in question. I guess you *could* also do it as a comparison function too -- would probably be easier to write, but also a lot easier to get badly wrong, and you'd have to do a bunch of function calls on insert or update instead of just one. Additionally, there is a significant cost involved in transitioning between the C++ code implementing the sorting algorithm, and the javascript implemented callback. That is on top of the cost of implementing the comparison function in javascript. Even in the best JITs, there is a significant overhead to both these parts. It would only have to be run once per row (object?) modified. Not run at all for reads. Would that really be so bad? Also, most authors would be content with built-in CLDR-based sort functions, which could be C++.
Re: copy events and content from server
On , Paul Libbrecht p...@hoplahup.net wrote: Hello list, As noted in the thread about security started by Halvord: In many of the scenarios I have working for, the content to be put on the clipboard would come from a luxury knowledge structure on the server, one that has access to some semantic source and can infer useful representations out of it; these get put to the clipboard. An offline HTML would also be an example of it. but I am realizing that this is probably not possible to do because the only way to do obtain something from the server is to wait until a callback is called (and this is good so) at which time the copy event might be long gone already. Would it be thinkable to *lock* the copy event until either a timeout occurs or an unlock is called? This way the script in the client would be able to fetch rich transformations from the server. A synchronous XHR solves this use case and there are no magic locks.
Re: [widgets] localizing author
On Wed, 04 May 2011 18:29:50 +0200, Marcos Caceres marcosscace...@gmail.com wrote: Hi, I just realised that I actually localise my own name... But I cannot do that in config.xml. Likewise, I would like to localise the href for me which would be possible if I could localise the author element but isn't at the moment. Yes, this was a mistake. If we were at REC I would suggest this go into an erratum... I don't know if this is too late for the current version, in which case please log it as an issue for the future. I think it is too late for this version. We have runtimes now at 99% and even 100% conformance and adding this would make most runtimes non-conforming. I think its more important now to push this spec to REC and address these kinds of cases in a future version of the spec. Do we have a test for this? I propose that we allow our run-time (and other implementations, such as the validation used by Opera stores) to localise author, and if that makes us non-conforming we're letting good be an enemy of better (and the argument that we have conformant run-times then looks weaker). If we don't have a test for it, then we know there is a requirement in our spec that isn't tested anyway. In paticular, since we have at least one live product (addons.opera.com submission process) that validates against the existing schema, we have the choice of either supporting the spec or supporting best practice here. What would you prefer us to do? Changing it to allow localisation would mean a change to the schema - and at least to Opera's implementation. I haven't yet checked (I only realised I want to do this but it isn't allowed today) whether we have any preference for making that change now or later. I think we should definitely add this to any future versions of the spec. In fact, authors could actually start using multiple localized author elements today and have them work in the future. If it is ok with you, we will add this to a future version of the spec? Notwithstanding the above, given that if you do add localised versions the required behaviour is clear in v1 processing, I can live with that if the group decides to take that approach. Pity though. Turns out we're not infallible yet ;) cheers -- Charles McCathieNevile Opera Software, Standards Group je parle français -- hablo español -- jeg lærer norsk http://my.opera.com/chaals Try Opera: http://www.opera.com