@@ -10,14 +10,14 @@ Editor: Shane Stephens, shanestephens@google.com
1010Editor : Daniel Glazman, daniel.glazman@disruptive-innovations.com
1111Editor : Elliot Sprehn, esprehn@chromium.org
1212Editor : Greg Whitworth, gwhit@microsoft.com
13- Ignored Terms : boolean, Animatable, Map
13+ Ignored Terms : boolean, Animatable, Map, Context
1414</pre>
1515
16- Introduction
17- ============
16+ Introduction {#intro}
17+ =====================
1818
19- Registering custom properties
20- =============================
19+ Registering custom properties {#registering-custom-properties}
20+ ==============================================================
2121
2222<pre class='idl'>
2323dictionary PropertyDescriptor {
@@ -68,31 +68,30 @@ that doesn't match an existing property then an exception is thrown.
6868
6969Calls to both {{registerProperty()}} and {{unregisterProperty()}} trigger a reparse of all parsed CSS.
7070
71- The apply hook
72- ==============
71+ The apply hook {#the-apply-hook}
72+ ================================
7373
7474<pre class='idl'>
7575
76- interface StyleWriter {
77- // affordances for writing to used values, but only those in outputProperties
76+ interface ElementProxy {
77+ // includes affordances for writing to used values, but only those in outputProperties.
78+ // Also for reading computed style values, but only those in inputProperties..
7879};
7980
80- callback ApplyCallback = void (Animatable element, StyleWriter writer, Map<DOMString, any> computedValues );
81+ callback ApplyCallback = void (ElementProxy element);
8182
8283dictionary ApplyDescriptor {
8384 ApplyCallback applyHook;
8485 sequence<DOMString>? inputProperties;
8586 sequence<DOMString> outputProperties;
8687};
8788
88- partial interface CSS {
89+ partial interface Context {
8990 long registerApplyHook(ApplyDescriptor apply);
9091 void unregisterApplyHook(long hookID);
9192};
9293</pre>
9394
94- Issue: CSS? Document?
95-
9695
9796: <dfn dict-member for=ApplyDescriptor>inputProperties</dfn>
9897:: If this value is not null, then the apply function is only called for elements or
@@ -106,6 +105,117 @@ If a {{registerApplyHook()}} call is made with a list of outputProperties that c
106105properties that have already been registered for output, then an exception is thrown and
107106the call fails.
108107
108+ Examples {#examples}
109+ ====================
110+
111+ Example 1: Polyfill scale, translate, rotate {#example-1}
112+ ---------------------------------------------------------
113+
114+ This approach prohibits the direct use of the transform property.
115+
116+ <pre class='lang-markup'>
117+ <script>
118+ ["--scale-x", "--scale-y"] .forEach(function(prop){
119+ document.registerProperty({
120+ name: prop,
121+ inherits: false,
122+ initial: 1,
123+ syntax: "<number>"
124+ });
125+ });
126+
127+ ["--translate-x", "--translate-y"] .forEach(function(name) {
128+ document.registerProperty({
129+ name: name,
130+ initial: "0px",
131+ inherits: false,
132+ type: "<length>"
133+ });
134+ });
135+
136+ document.registerProperty({
137+ name: "--rotate",
138+ initial: "0deg",
139+ type: "<angle>"
140+ inherits: false
141+ });
142+ </script>
143+ <style>
144+ * {
145+ transform: translate(var(--translate-x), var(--translate-y)) rotate(var(--rotate)) scale(var(--scale-x), var(--scale-y));
146+ }
147+
148+ #myElement {
149+ --translate-x: 5px;
150+ --translate-y: 10px;
151+ --rotate: 10deg;
152+ --scale-x: 25;
153+ --scale-y: 25;
154+ }
155+
156+ .foobar {
157+ --rotate: 20deg;
158+ }
159+ </style>
160+ </pre>
161+
162+ Example 2: as above, but with transform property still operational {#example-2}
163+ -------------------------------------------------------------------------------
164+
165+ <pre class='lang-javascript'>
166+ this.registerApplyHook({
167+ apply: function(el) {
168+ el.outputStyle.transform = 'translate(' + el.style.get('--translate-x' ) + ', ' + el.style.get('--translate-y' ) +
169+ ') rotate(' + el.style.get('--rotate' ) +
170+ ') scale(' + el.style.get('--scale-x' ) + ', ' + el.style.get('--scale-y' ) + ')' +
171+ el.style.get('transform' );
172+ },
173+ inputProperties: ["--translate-*", "--scale-*", "--rotate", "transform"] ,
174+ outputProperties: ["transform"]
175+ });
176+ </pre>
177+
178+ Example 3: Disabling floats {#example-3}
179+ ----------------------------------------
180+
181+ <pre class='lang-javascript'>
182+ this.registerApplyHook({
183+ apply: function(el) {
184+ el.outputStyle.float = 'none' ;
185+ },
186+ inputProperties: ["float"] ,
187+ outputProperties: ["float"]
188+ }); // \m/
189+ </pre>
190+
191+ Example 4: Simple "layout" - media block {#example-4}
192+ -----------------------------------------------------
193+ This example lays out two children, with the right child taking the leftover space not taken by the left child.
194+
195+ <pre class='lang-javascript'>
196+ document.registerProperty({
197+ name: '--media-block' ,
198+ syntax: '<ident>' ,
199+ inherits: false,
200+ initial: 'no'
201+ });
202+
203+ this.registerApplyHook({
204+ apply: function(element) {
205+ let [right, left] = element.childElements;
206+ let outerWidth = el.style.get("width"); // This is just the CSS value... what happens with 'auto' ;
207+ let rightWidth = right.style.get("width");
208+ left.outputStyle.width = "calc("+outerWidth+" - "+ rightWidth +")";
209+ right.outputStyle.float = "left";
210+ left.outputStyle.float = "left";
211+ },
212+ inputProperties: ["--media-block", "width", "child/width"] ,
213+ outputProperties: ["width", "float"]
214+ });
215+ </pre>
216+
217+ Notes {#Notes}
218+ ==============
109219
110220<pre class='note'>
111221
0 commit comments