Re: Widgets and :context
Charles McCathieNevile wrote: On Thu, 17 Jul 2008 20:31:13 +0200, Andrew Fedoniouk [EMAIL PROTECTED] wrote: That is what I thought: widgets if used as components on some page behave as a micro documents - fragments of the DOM with local style systems rooted to the widget. But it seems that this is not the case - that Widgets are more about free floating frames that live in top level windows on desktop(?), something like Konfabulator desktoplets. Assuming I understand you correctly, then yes. The Widgets spec at W3C is about a way to package web standards-based applications to use them as locally installed applications. cheers Chaals Thanks for the clarification. Seems like I mixed up Web Widget[1], Web Control[2] and Behavior[3] [1] http://en.wikipedia.org/wiki/Web_widget [2] http://www.whatwg.org/specs/web-controls/current-work/ [3] http://www.w3.org/TR/becss/ Simply thought that scoped style sheet are somehow related to one of those. -- Andrew Fedoniouk. http://terrainformatica.com
Re: [selectors-api] comments on Selectors API Level 2
Daniel Glazman wrote: I would recommend dropping the pseudo-class :scope and make a simpler model where a fictional :scope pseudo-class and a descendant combinator are prepended to all selectors passed as the argument of the corresponding APIs. There are cases where you will need to match only immediate children using such queryScopedSelector() function. Possible solutions: element.$( .child); element.$(:root .child); :root here is the element itself - root of the lookup. BTW: the name of the function queryScopedSelectorAll() has at least one technical and one grammatical error. Can we rename it somehow? -- Andrew Fedoniouk. http://terrainformatica.com
[webcomponents]: Custom HTML elements
If someone wants to use custom elements in HTML then is the following possible in principle? Let's assume that I want to use checkboxLabel/checkbox element. 1. Parsing: When parsing document containing this the parser creates DOM element with the tagName checkbox. The element is created as an instance of class: interface CustomElement: Element {} 2. Script binding: Script may register custom extenders - classes that extend default set of methods/properties of native CustomElement implementation. For example: document.behaviors[checkbox] = { attached: function() { ...the behavior gets attached to the DOM element `this` here is the element ... } mousedown: function(event) { ... } ... someMethod: function(params) { ... } get someProp: function() { ... } set someProp: function(val) { ... } }; The initialization of document.behaviors collection should be made presumably before onload/documentready DOM event. 2a. Before generating onload/documentready event the UA shall assign (extend) behaviors in document.behaviors collection and call elem.attached() method (if any) passing the element in 'this' envariable. 3. In principle this method: document.behaviors[checkbox] can accept not only tag names but selectors too. For example: document.behaviors[button[type=checkbox]] = ...; 4. Any DOM modifications (adding new elements, removing) is made with respect of the document.behaviors collection so if new element with tag checkbox is created it gets attached() call for it. In principle the attached() method plays role of constructor in the behaviors realm. It could be also detached() method that is invoked before DOM element removal, kind of dtor in other words. Does this sound feasible/reasonable to do in conventional UA? -- Mentioned mechanism works in my Sciter engine pretty well. The only difference is that instead of document.behaviors I am using custom 'prototype' CSS property: checkbox { display: inline-block; prototype: CheckBox url(code/controls.tis); } and if code/controls.tis script has declaration class CheckBox: Behavior { function attached() {...} function mousedown() {...} property someProp(v) {...} } the element will get CheckBox prototype (class here). (Sciter uses tis script[1]) [1] http://www.codeproject.com/Articles/33662/TIScript-language-a-gentle-extension-of-JavaScript -- Andrew Fedoniouk. http://terrainformatica.com
Paginated views, print preview and printing.
(I am not sure if these topics are subjects of discussion in this WG so my pardon in advance if not.) While everything is moving these days to paper-less technologies need for HTML/CSS printing is still actual. If not exactly for printing then for applications that use paginated form of presenting HTML documents. Mobile book readers for example. Here is a brief explanation of so called pager mechanism that I use in Sciter engine [1]. In my case the pager implementation is attached to frame type=pager element (or iframe) as it hosts loadable document being viewed in paginated view - pretty much in the same way as normal frame/iframe. Here is an example of how frame type=pager may look like: http://terrainformatica.com/w3/sciter-pager.png (box with gradient background with two page boxes in it). Page boxes are plain div elements in shadow DOM with special role assigned. So that view is styleable by standard CSS means. Such pager frame among others accepts these two attributes: src=url - standard @src - url of document being paginated. page-template=url - url of so called page-template document. page-template is normal html document with one requirement: it shall contain block element with id=content-box. When rendering each page the pager renders first that page-template document and then fragment of paginated document inside box established by the #content-box element. Here is an illustration of such 2-levels document/view relationship: http://www.terrainformatica.com/wp-content/uploads/2010/02/print-preview-schema.png Usually the page-template contains various elements other than #content-box. For example it may contain page header/footer with page number field, etc. Layout and style of page-template is defined by standard CSS means. Separately for odd/even pages or even pages with particular number. See screenshot above. Paginated functionality is accessible from script so functionality like total-on-the-page and the alike is easily implementable. The pager implementation allows to customize page layout like margins, paper size, etc. interactively and solely from client side. PS: Initially I planned to implement http://www.w3.org/TR/css3-page/ spec but found it very limiting for requirements I had at that moment - customizeable printing of financial and legal HTML documents. So I came up with the pager. PSS: I also have experimental implementation of contenteditable functionality combined with such pager mechanism to provide editing of paginated documents. [1] The Sciter: http://www.terrainformatica.com/sciter/ -- Andrew Fedoniouk. http://terrainformatica.com
Persistent Storage vs. Database
I am not sure if my approach in Sciter/TIScript for data persistence is applicable to JS engines used in browsers... but I'll try to explain it with the hope that its idea can be useful at least to some extent. The whole data persistence in TIScript [1,2] is defined by two objects [classes]: - Storage - the data storage, and - Storage.Index - index, persistable ordered key/value map. Each Storage instance has property named `root`. Any object that is reachable from this root is persistent - will survive VM shutdown. Example: var storage = ...; storage.root = { one: 1, two: [ 1,2,3 ], three: { a:A, b: B, c: C } }; this will initialize persistent storage by the structure above. After this, in current or next script session, access to the storage.root will return that object. From that object all its descendants are reachable as usual. Physical commit (write) of objects to storage happens on either a) GC cycle or b) on explicit storage.commit() call or on c) VM shutdown. Objects from storage are loaded on demand - when they accessed. Therefore the storage provides transparent (for the JS programmer) set of operations. Data access to persistent objects is made exactly in the same way as to other objects in script heap. The only limitation: not all objects in script heap can be persistent this way. Only JSON subset (array,object, numeric, bool, string and null), Dates and Indexes. For obvious reasons. This persistence schema uses minimum number of abstractions and has full set of operations needed for accessing and storing structured data. At least it is easier than http://www.w3.org/TR/IndexedDB/ :) My pardon if all above is not exactly in mainstream. Persistence in TIScript is based on Konstantin Knizhnik's DyBase [3]. [1] TIScript high level definition: http://www.codeproject.com/Articles/33662/TIScript-language-a-gentle-extension-of-JavaScript [2] TIScript source code: https://code.google.com/p/tiscript/ [3] DyBase http://www.garret.ru/dybase.html -- Andrew Fedoniouk. http://terrainformatica.com
Re: Persistent Storage vs. Database
On Thu, Mar 7, 2013 at 10:36 PM, Kyle Huey m...@kylehuey.com wrote: On Thu, Mar 7, 2013 at 10:20 PM, Andrew Fedoniouk n...@terrainformatica.com wrote: Physical commit (write) of objects to storage happens on either a) GC cycle or b) on explicit storage.commit() call or on c) VM shutdown. Persisting data off a GC cycle (via finalizers or something else) is a pretty well known antipattern.[0] Raymond is right in general when he speaks about .NET runtime environment. But JS computing environment is quite different from the .NET one - at least these two have different lifespans of VMs and memory heaps. In my case persistence is closer to virtual memory mechanism - when there is not enough memory persistable objects get swapped to the storage from the heap. That is quite widespread pattern if we want to use this language. In any case there is always storage.commit() if you need guarantees and deterministic storage state. At least it is easier than http://www.w3.org/TR/IndexedDB/ :) Easier doesn't necessarily mean better. LocalStorage is certainly easier to use than any async storage system ;-) At least my implementation does not use any events. Proposed system of events in IndexedDB is the antipattern indeed. Exactly for the same reasons as finalizer *events* you've mentioned above - there is no guarantee that all events will be delivered to the code awaiting and relaying on them. -- Andrew Fedoniouk. http://terrainformatica.com - Kyle [0] e.g. http://blogs.msdn.com/b/oldnewthing/archive/2010/08/09/10047586.aspx
Re: Persistent Storage vs. Database
On Fri, Mar 8, 2013 at 11:30 AM, Kyle Huey m...@kylehuey.com wrote: On Fri, Mar 8, 2013 at 11:02 AM, Andrew Fedoniouk n...@terrainformatica.com wrote: On Thu, Mar 7, 2013 at 10:36 PM, Kyle Huey m...@kylehuey.com wrote: On Thu, Mar 7, 2013 at 10:20 PM, Andrew Fedoniouk n...@terrainformatica.com wrote: At least it is easier than http://www.w3.org/TR/IndexedDB/ :) Easier doesn't necessarily mean better. LocalStorage is certainly easier to use than any async storage system ;-) At least my implementation does not use any events. Proposed system of events in IndexedDB is the antipattern indeed. Exactly for the same reasons as finalizer *events* you've mentioned above - there is no guarantee that all events will be delivered to the code awaiting and relaying on them. That's not true at all. If you don't understand the difference between finalizers and events you're not going to be able to make a very informed criticism of IndexedDB. I would appreciate if you will define term `event`. After that we can discuss it further. As of common practice there are two types so called outbound calls: 1. Synchronous *callbacks* that are not strictly speaking events - just function references: after/before-doing-this-call-that. 'finalized' is that kind of callback. 2. Events - these are objects and event dispatching system associated with them. For example UI events use capture/bubble dispatching system and event queue. Events operate independently from their handlers. Let's take a look on this example from IndexedDB spec: var request = indexedDB.open('AddressBook', 15); request.onsuccess = function(evt) {...}; request.onerror = function(evt) {...}; It looks *very* wrong to me: What should happen if db.open() will open the DB immediately? Will request.onsuccess be called in this case? If indexedDB.open is purely async operation then why it has to be exactly async? What may take time there other than opening local file in worst case? If that request is async then when precisely request.onsuccess will be called? I would understand if DB.open call will be defined this way: function onsuccess(evt) {...}; function onerror(evt) {...}; var request = indexedDB.open('AddressBook', 15, onsuccess, onerror ); (so pure callback operation). But purpose of such event-aganza is still not clear to me. Why not classical: try { request = indexedDB.open('AddressBook', 15 ); } catch(err) { ... } ? In principle: what are operations in IndexedDB that may take so long time that they need to be async? Size of client side DB has and will always have some reasonable cap limiting its size and so any lookup or update operation in indexed DB will take some finite and *very* short time (if to compare with the time needed to relayout average page). Why these so strange events are there at all? And so why all this has to be that complex? Andrew Fedoniouk. http://terrainformatica.com
Re: Persistent Storage vs. Database
On Fri, Mar 8, 2013 at 8:16 PM, Jonas Sicking jo...@sicking.cc wrote: On Fri, Mar 8, 2013 at 2:27 PM, Andrew Fedoniouk n...@terrainformatica.com wrote: On Fri, Mar 8, 2013 at 11:30 AM, Kyle Huey m...@kylehuey.com wrote: On Fri, Mar 8, 2013 at 11:02 AM, Andrew Fedoniouk n...@terrainformatica.com wrote: On Thu, Mar 7, 2013 at 10:36 PM, Kyle Huey m...@kylehuey.com wrote: On Thu, Mar 7, 2013 at 10:20 PM, Andrew Fedoniouk n...@terrainformatica.com wrote: At least it is easier than http://www.w3.org/TR/IndexedDB/ :) Easier doesn't necessarily mean better. LocalStorage is certainly easier to use than any async storage system ;-) At least my implementation does not use any events. Proposed system of events in IndexedDB is the antipattern indeed. Exactly for the same reasons as finalizer *events* you've mentioned above - there is no guarantee that all events will be delivered to the code awaiting and relaying on them. That's not true at all. If you don't understand the difference between finalizers and events you're not going to be able to make a very informed criticism of IndexedDB. I would appreciate if you will define term `event`. After that we can discuss it further. https://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-event Thanks, but these are DOM events. How they are related to DB events or whatever they are named? What does it mean bubbling/capturing for them? As of common practice there are two types so called outbound calls: 1. Synchronous *callbacks* that are not strictly speaking events - just function references: after/before-doing-this-call-that. 'finalized' is that kind of callback. 2. Events - these are objects and event dispatching system associated with them. For example UI events use capture/bubble dispatching system and event queue. Events operate independently from their handlers. Let's take a look on this example from IndexedDB spec: var request = indexedDB.open('AddressBook', 15); request.onsuccess = function(evt) {...}; request.onerror = function(evt) {...}; It looks *very* wrong to me: What should happen if db.open() will open the DB immediately? The event fires asynchronously. Since JS is single threaded that means that the onsuccess and onerror properties will be set before the event is fired. 1. Who said that JS *must* always be single threaded? 2. Is there any requirement that IndexedDB must be used only with JS? 3. Are you sure that opening DB or doing look-up on b-tree is always more expensive than posting and dispatching events? Windows for example uses 18ms precise timers ( used for dispatching non-UI events, or similar mechanism ). Are you saying that all operations in IndexedDB simply cannot work faster than that? If yes then who needs such brake by design? If to compare look-up in b-tree on memory pages that are already in cached and the task of posting/dispatching messages including handler function invocation in script then ratio will be around 1:50. What's the name of the design that puts such overhead upfront? Will request.onsuccess be called in this case? Yes. If indexedDB.open is purely async operation then why it has to be exactly async? Because it requires IO. 1. Why exactly it requires IO? Why it cannot be implemented by using main memory or memory-mapped files at the end ( not exactly IO in classic sense )? 2. localStorage also uses IO, what's the problem you see with it at the moment? 3. Which operation in IndexedDB require significantly more time to execute than corresponding one from localStorage? 4. What's wrong with Web Workers that were designed specifically for cases when operations takes long time? I do not see what operation can take long time in IndexedDB but still would like to know answer. What may take time there other than opening local file in worst case? If that request is async then when precisely request.onsuccess will be called? I would understand if DB.open call will be defined this way: function onsuccess(evt) {...}; function onerror(evt) {...}; var request = indexedDB.open('AddressBook', 15, onsuccess, onerror ); (so pure callback operation). If I write var x = 0; function onsuccess(evt) { x = 1 }; function onerror(evt) {...}; var request = indexedDB.open('AddressBook', 15, onsuccess, onerror ); console.log(x); would you expect the console to sometimes show 1 and sometimes show 0? If not, why not? I am not sure I understand you here. This form: indexedDB.open('AddressBook', 15, onsuccess, onerror ); does not limit UA engineers to chose the most optimal implementation. So such open() may or may not use async model. But current spec mandates the most ineffective variant. By design. But in general there is no need for callback/events for operations on such small DBs. SQLite API does not have async operations... Why IndexedDB needs it? And SQLite data
Re: Why can't we just use constructor instead of createdCallback?
On Thu, Jan 9, 2014 at 9:27 PM, Boris Zbarsky bzbar...@mit.edu wrote: On 1/9/14 10:57 PM, Ryosuke Niwa wrote: Given that, we could maybe cheat and in fact do some sort of delayed calling of the constructor of ES6 subclasses of elements. You'd still be able to observe these objects in an unconstructed state from the subclass pov, but at least it wouldn't be a security issue in terms of operating on a DOM that's in an inconsistent state from the point of view of privileged code. Calling constructors after the tree had been constructed will be an issue because then you could access “unconstructed” nodes via nextSibling, parentNode, etc... Right, I did say that above. Is that really a problem in practice, though? One idea that came out of our discussion is was to add an additional step in the parser to call constructors on all “pending” elements before they’re being constructed into the DOM tree. Isn't that the bad thing we _don't_ want to do? That is, invoke arbitrary page JS from the middle of the parsing algorithm? On the other hand, solving this seems to require running some author scripts at the element creation time, at some later time but before the node is inserted into the document. The parser is expected to insert the nodes into the document pretty much immediately after creating them, no? -Boris Calling of constructors (in JS/ES sense) instead of callbacks is not semantically correct I would say. Consider this declaration: class MyElement inherits HTMLElement { public prop = 1; constructor( text ) { super(my-element); this.textContent = text; } } UA simply cannot call such constructor as it requires parameter. UA can call only implicit default constructor, : ({ prop:1 }).__proto__ = MyElement; in this case. And call some designated method of the class ('callback' in this discussion) when element gets attached to the DOM tree. Constructors are used for 'external' element creation: var myel = new MyElement(woo-hoo!); About callbacks: It should be two callbacks actually: attached() - called when element *gets attached to the DOM*, it is not a constructor, sic! detached() - when it gets detached from the DOM. so here: var myel = new MyElement(woo-hoo!); someParent.append(myel); call of myel.attached() will happen inside the append() above. detached() is called when parent.removeChild() for the element is called. Just in case: this is how it is implemented and works in my Sciter [1] and I didn't find any problems with element/script life cycles. And yet. I also have dynamic element class assignment by CSS with custom 'prototype' property, e.g.: input[type=masked] { prototype: MaskedInput url(code/widgets.tis); } In that case attached/detached are also called when the element gets/looses that style. But that's probably another story. [1] http://terrainformatica.com/sciter -- Andrew Fedoniouk. http://terrainformatica.com