@@ -251,19 +251,131 @@ class EmptyContentElement extends ReplacedElement {
251
251
Widget toWidget (_) => null ;
252
252
}
253
253
254
+ //TODO(Sub6Resources): <ruby> formatting should adhere to
255
+ // the most recent CSS WD specification: https://drafts.csswg.org/css-ruby/
254
256
class RubyElement extends ReplacedElement {
255
257
dom.Element element;
256
258
257
259
RubyElement ({@required this .element, String name = "ruby" })
258
260
: super (name: name, alignment: PlaceholderAlignment .middle);
259
261
262
+ static RubyElementInfo parseRuby (dom.Node root) {
263
+ final RubyElementInfo info = RubyElementInfo ();
264
+ if (root.parent.localName != 'ruby' ) {
265
+ dom.Node currentParent = root;
266
+ int index = 0 ;
267
+ int startIndex;
268
+ int savedStartIndex;
269
+ int lookaheadIndex;
270
+
271
+ BaseTextSegment currentBaseText;
272
+
273
+ //Start mode
274
+ if (index >= currentParent.children.length) {
275
+ //Jump to end mode
276
+
277
+ }
278
+
279
+ if (currentParent.children[index].localName == 'rt' || currentParent.children[index].localName == 'rp' ) {
280
+ //Jump to annotation mode
281
+
282
+ }
283
+
284
+ startIndex = index;
285
+
286
+ //Base mode
287
+ if (currentParent.children[index].localName == 'ruby' && currentParent == root) {
288
+ currentParent = currentParent.children[index];
289
+ index = 0 ;
290
+ savedStartIndex = startIndex;
291
+ startIndex = null ;
292
+ //Jump to start mode
293
+
294
+ }
295
+
296
+ if (currentParent.children[index].localName == 'rt' || currentParent.children[index].localName == 'rp' ) {
297
+ BaseTextSegment newBaseTextSegment = BaseTextSegment ();
298
+ newBaseTextSegment.baseText = List <dom.Node >();
299
+ for (int i = startIndex; i < index; i++ ) {
300
+ newBaseTextSegment.baseText.add (currentParent.children[i]);
301
+ }
302
+ currentBaseText = newBaseTextSegment;
303
+ info.baseTextSegments.add (newBaseTextSegment);
304
+ //Jump to annotation mode
305
+ }
306
+
307
+ index++ ;
308
+
309
+ //Base mode post-increment
310
+ if (index >= currentParent.children.length) {
311
+ //Jump to end mode
312
+ }
313
+
314
+ // Jump back to base mode
315
+
316
+ //Annotation mode
317
+ if (currentParent.children[index].localName == 'rt' ) {
318
+ final rt = currentParent.children[index];
319
+ AnnotationSegment annotationSegment = AnnotationSegment ();
320
+ annotationSegment.annotation = [rt];
321
+ if (currentBaseText != null ) {
322
+ annotationSegment.segment = currentBaseText;
323
+ }
324
+ info.annotationSegments.add (annotationSegment);
325
+ //Jump to annotation mode increment
326
+ }
327
+
328
+ if (currentParent.children[index].localName == 'rp' ) {
329
+ //Jump to annotation mode increment
330
+ }
331
+
332
+ if (currentParent.children[index] is ! dom.Text || (currentParent.children[index] is dom.Text && currentParent.children[index].text.trim ().isNotEmpty)) {
333
+ //Jump to base mode
334
+ }
335
+
336
+ //Annotation mode increment
337
+ lookaheadIndex = index + 1 ;
338
+
339
+ //Annotation mode white-space skipper
340
+ if (lookaheadIndex == currentParent.children.length) {
341
+ //Jump to end mode
342
+ }
343
+
344
+ if (currentParent.children[lookaheadIndex].localName == 'rt' || currentParent.children[lookaheadIndex].localName == 'rp' ) {
345
+ index = lookaheadIndex;
346
+ //Jump to annotation mode
347
+ }
348
+
349
+ if (currentParent.children[lookaheadIndex] is ! dom.Text || (currentParent.children[lookaheadIndex] is dom.Text && currentParent.children[lookaheadIndex].text.trim ().isNotEmpty)) {
350
+ //Jump to base mode (without incrementing index)
351
+ }
352
+ lookaheadIndex++ ;
353
+
354
+ //Jump to annotation mode white space skipper
355
+
356
+ //End mode
357
+ if (currentParent != root) {
358
+ index = root.children.indexOf (currentParent);
359
+ currentParent = root;
360
+ index++ ;
361
+ startIndex = savedStartIndex;
362
+ savedStartIndex = null ;
363
+ //Jump to base mode post increment.
364
+ }
365
+
366
+ }
367
+
368
+ //End
369
+ return info;
370
+ }
371
+
260
372
@override
261
373
Widget toWidget (RenderContext context) {
262
- dom.Node textNode = null ;
374
+ dom.Node textNode;
263
375
List <Widget > widgets = List <Widget >();
264
376
//TODO calculate based off of parent font size.
265
- final rubySize = max ( 9.0 , context.style.fontSize.size / 2 ) ;
266
- final rubyYPos = rubySize + 2 ;
377
+ final rubySize = context.style.fontSize.size / 2 ;
378
+ final rubyYPos = rubySize + 4 ;
267
379
element.nodes.forEach ((c) {
268
380
if (c.nodeType == dom.Node .TEXT_NODE ) {
269
381
textNode = c;
@@ -301,6 +413,26 @@ class RubyElement extends ReplacedElement {
301
413
}
302
414
}
303
415
416
+ class RubyElementInfo {
417
+ List <BaseTextSegment > baseTextSegments;
418
+ List <AnnotationSegment > annotationSegments;
419
+
420
+ RubyElementInfo () {
421
+ baseTextSegments = List <BaseTextSegment >();
422
+ annotationSegments = List <AnnotationSegment >();
423
+ }
424
+ }
425
+
426
+ class BaseTextSegment {
427
+ List <BaseTextSegment > subSegments;
428
+ List <dom.Node > baseText;
429
+ }
430
+
431
+ class AnnotationSegment {
432
+ List <dom.Node > annotation;
433
+ BaseTextSegment segment;
434
+ }
435
+
304
436
ReplacedElement parseReplacedElement (dom.Element element) {
305
437
switch (element.localName) {
306
438
case "audio" :
0 commit comments