article-content-renderer-vue2 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  "fileFormat": "article-content-protocol",
3
3
  "fileFormatVersion": 1,
4
4
  "mediaType": "application/vnd.article-content-protocol+json",
5
- "id": "article-content-v1",
5
+ "id": "article-content-v1-with-extensions",
6
6
  "version": 1,
7
- "name": "Article Content Protocol v1",
7
+ "name": "Article Content Protocol v1 + Extensions",
8
8
  "status": "draft",
9
9
  "rootNode": "doc",
10
10
  "nodes": [
@@ -35,13 +35,34 @@
35
35
  "right",
36
36
  "justify"
37
37
  ]
38
+ },
39
+ {
40
+ "name": "anchorId",
41
+ "type": "string",
42
+ "required": false,
43
+ "description": "Stable paragraph/heading anchor, unique within the article."
44
+ },
45
+ {
46
+ "name": "fontSize",
47
+ "type": "integer",
48
+ "required": false,
49
+ "description": "Applied to paragraph.attrs.fontSize alongside the unchanged v1 paragraph attributes. Omit to inherit the default size. Consumers must support this optional extension.",
50
+ "minimum": 8,
51
+ "maximum": 96
38
52
  }
39
53
  ],
40
54
  "render": {
41
55
  "mode": "element",
42
56
  "element": "p",
43
57
  "styleBindings": {
44
- "textAlign": "text-align"
58
+ "textAlign": "text-align",
59
+ "fontSize": "font-size"
60
+ },
61
+ "styleUnits": {
62
+ "fontSize": "px"
63
+ },
64
+ "attributeBindings": {
65
+ "anchorId": "data-anchor-id"
45
66
  }
46
67
  }
47
68
  },
@@ -78,6 +99,12 @@
78
99
  "right",
79
100
  "justify"
80
101
  ]
102
+ },
103
+ {
104
+ "name": "anchorId",
105
+ "type": "string",
106
+ "required": false,
107
+ "description": "Stable paragraph/heading anchor, unique within the article."
81
108
  }
82
109
  ],
83
110
  "render": {
@@ -94,6 +121,9 @@
94
121
  ],
95
122
  "styleBindings": {
96
123
  "textAlign": "text-align"
124
+ },
125
+ "attributeBindings": {
126
+ "anchorId": "data-anchor-id"
97
127
  }
98
128
  }
99
129
  },
@@ -238,6 +268,15 @@
238
268
  "center",
239
269
  "right"
240
270
  ]
271
+ },
272
+ {
273
+ "name": "imageLayout",
274
+ "type": "string",
275
+ "required": false,
276
+ "description": "Applied to image.attrs.imageLayout. Adjacent two-column images flow two per row in document order. Other blocks break the row. Omit for the original full-row image layout.",
277
+ "allowedValues": [
278
+ "two-column"
279
+ ]
241
280
  }
242
281
  ],
243
282
  "render": {
@@ -250,8 +289,14 @@
250
289
  "title": "title",
251
290
  "width": "width",
252
291
  "height": "height",
253
- "imageAlign": "data-image-align"
254
- }
292
+ "imageAlign": "data-image-align",
293
+ "imageLayout": "data-image-layout"
294
+ },
295
+ "layoutNotes": [
296
+ "Constrain display width to the container. When width and height are supplied, scale height proportionally; do not crop the image. Preserve the original dimensions in JSON.",
297
+ "Adjacent sibling images with imageLayout=two-column occupy half a row each, with a gap. Every two images wrap; intervening non-image blocks start a new row. Omit imageLayout for a full-row container.",
298
+ "imageAlign controls horizontal alignment inside the image layout container; omission means center."
299
+ ]
255
300
  }
256
301
  },
257
302
  {
@@ -372,6 +417,58 @@
372
417
  "render": {
373
418
  "mode": "text"
374
419
  }
420
+ },
421
+ {
422
+ "type": "resourceQuestion",
423
+ "description": "Top-level resource question snapshot. Rendering never fetches resource data.",
424
+ "attributes": [
425
+ {
426
+ "name": "id",
427
+ "type": "string",
428
+ "required": true,
429
+ "description": "See documentSchema.definitions.resourceQuestion.properties.attrs.properties.id"
430
+ },
431
+ {
432
+ "name": "resourceId",
433
+ "type": "string",
434
+ "required": true,
435
+ "description": "See documentSchema.definitions.resourceQuestion.properties.attrs.properties.resourceId"
436
+ },
437
+ {
438
+ "name": "title",
439
+ "type": "string",
440
+ "required": true,
441
+ "description": "See documentSchema.definitions.resourceQuestion.properties.attrs.properties.title"
442
+ },
443
+ {
444
+ "name": "description",
445
+ "type": "string",
446
+ "required": true,
447
+ "description": "See documentSchema.definitions.resourceQuestion.properties.attrs.properties.description"
448
+ },
449
+ {
450
+ "name": "options",
451
+ "type": "array",
452
+ "required": true,
453
+ "description": "See documentSchema.definitions.resourceQuestion.properties.attrs.properties.options"
454
+ },
455
+ {
456
+ "name": "hideFollowing",
457
+ "type": "boolean",
458
+ "required": true,
459
+ "description": "See documentSchema.definitions.resourceQuestion.properties.attrs.properties.hideFollowing"
460
+ },
461
+ {
462
+ "name": "revealKey",
463
+ "type": "string",
464
+ "required": true,
465
+ "description": "See documentSchema.definitions.resourceQuestion.properties.attrs.properties.revealKey"
466
+ }
467
+ ],
468
+ "render": {
469
+ "mode": "component",
470
+ "element": "resource-question"
471
+ }
375
472
  }
376
473
  ],
377
474
  "marks": [
@@ -486,12 +583,52 @@
486
583
  "target": "target"
487
584
  }
488
585
  }
586
+ },
587
+ {
588
+ "type": "textStyle",
589
+ "description": "Text foreground color.",
590
+ "attributes": [
591
+ {
592
+ "name": "color",
593
+ "type": "string",
594
+ "required": true,
595
+ "description": "A six-digit hexadecimal CSS color, including the leading #.",
596
+ "pattern": "^#[0-9a-fA-F]{6}$"
597
+ }
598
+ ],
599
+ "render": {
600
+ "mode": "element",
601
+ "element": "span",
602
+ "styleBindings": {
603
+ "color": "color"
604
+ }
605
+ }
606
+ },
607
+ {
608
+ "type": "highlight",
609
+ "description": "Text background highlight color.",
610
+ "attributes": [
611
+ {
612
+ "name": "color",
613
+ "type": "string",
614
+ "required": true,
615
+ "description": "A six-digit hexadecimal CSS color, including the leading #.",
616
+ "pattern": "^#[0-9a-fA-F]{6}$"
617
+ }
618
+ ],
619
+ "render": {
620
+ "mode": "element",
621
+ "element": "mark",
622
+ "styleBindings": {
623
+ "color": "background-color"
624
+ }
625
+ }
489
626
  }
490
627
  ],
491
628
  "documentSchema": {
492
629
  "$schema": "http://json-schema.org/draft-07/schema#",
493
- "$id": "urn:article-content-protocol:v1",
494
- "title": "Article Content Protocol v1",
630
+ "$id": "urn:article-content-protocol:v1:with-formatting-extensions",
631
+ "title": "Article Content Protocol v1 + Extensions",
495
632
  "type": "object",
496
633
  "additionalProperties": false,
497
634
  "required": [
@@ -505,7 +642,14 @@
505
642
  "content": {
506
643
  "type": "array",
507
644
  "items": {
508
- "$ref": "#/definitions/blockNode"
645
+ "oneOf": [
646
+ {
647
+ "$ref": "#/definitions/blockNode"
648
+ },
649
+ {
650
+ "$ref": "#/definitions/resourceQuestion"
651
+ }
652
+ ]
509
653
  }
510
654
  }
511
655
  },
@@ -560,6 +704,21 @@
560
704
  "properties": {
561
705
  "textAlign": {
562
706
  "$ref": "#/definitions/textAlign"
707
+ },
708
+ "fontSize": {
709
+ "$schema": "http://json-schema.org/draft-07/schema#",
710
+ "$id": "urn:article-content-protocol:paragraph-font-size:v1",
711
+ "title": "Optional paragraph fontSize attribute (pixels)",
712
+ "description": "Applied to paragraph.attrs.fontSize alongside the unchanged v1 paragraph attributes. Omit to inherit the default size. Consumers must support this optional extension.",
713
+ "type": "integer",
714
+ "minimum": 8,
715
+ "maximum": 96
716
+ },
717
+ "anchorId": {
718
+ "type": "string",
719
+ "minLength": 1,
720
+ "pattern": "\\S",
721
+ "description": "Stable paragraph/heading anchor, unique within the article."
563
722
  }
564
723
  }
565
724
  },
@@ -596,6 +755,12 @@
596
755
  },
597
756
  "textAlign": {
598
757
  "$ref": "#/definitions/textAlign"
758
+ },
759
+ "anchorId": {
760
+ "type": "string",
761
+ "minLength": 1,
762
+ "pattern": "\\S",
763
+ "description": "Stable paragraph/heading anchor, unique within the article."
599
764
  }
600
765
  }
601
766
  },
@@ -793,6 +958,16 @@
793
958
  },
794
959
  "imageAlign": {
795
960
  "$ref": "#/definitions/imageAlign"
961
+ },
962
+ "imageLayout": {
963
+ "$schema": "http://json-schema.org/draft-07/schema#",
964
+ "$id": "urn:article-content-protocol:image-layout:v1",
965
+ "title": "Optional two-column image layout",
966
+ "description": "Applied to image.attrs.imageLayout. Adjacent two-column images flow two per row in document order. Other blocks break the row. Omit for the original full-row image layout.",
967
+ "type": "string",
968
+ "enum": [
969
+ "two-column"
970
+ ]
796
971
  }
797
972
  }
798
973
  }
@@ -1074,9 +1249,198 @@
1074
1249
  ]
1075
1250
  }
1076
1251
  }
1252
+ },
1253
+ {
1254
+ "$schema": "http://json-schema.org/draft-07/schema#",
1255
+ "$id": "urn:article-content-protocol:text-formatting:v1",
1256
+ "title": "Optional text formatting marks for Article Content Protocol v1",
1257
+ "description": "Additional marks accepted alongside the unchanged v1 marks. Existing v1 documents require no migration. Consumers must support these marks to render colored documents.",
1258
+ "type": "object",
1259
+ "additionalProperties": false,
1260
+ "required": [
1261
+ "type",
1262
+ "attrs"
1263
+ ],
1264
+ "properties": {
1265
+ "type": {
1266
+ "enum": [
1267
+ "textStyle",
1268
+ "highlight"
1269
+ ]
1270
+ },
1271
+ "attrs": {
1272
+ "type": "object",
1273
+ "additionalProperties": false,
1274
+ "required": [
1275
+ "color"
1276
+ ],
1277
+ "properties": {
1278
+ "color": {
1279
+ "type": "string",
1280
+ "pattern": "^#[0-9a-fA-F]{6}$"
1281
+ }
1282
+ }
1283
+ }
1284
+ }
1077
1285
  }
1078
1286
  ]
1287
+ },
1288
+ "resourceQuestion": {
1289
+ "$id": "urn:article-content-protocol:resource-question:v1",
1290
+ "type": "object",
1291
+ "additionalProperties": false,
1292
+ "required": [
1293
+ "type",
1294
+ "attrs"
1295
+ ],
1296
+ "properties": {
1297
+ "type": {
1298
+ "const": "resourceQuestion"
1299
+ },
1300
+ "attrs": {
1301
+ "type": "object",
1302
+ "additionalProperties": false,
1303
+ "required": [
1304
+ "id",
1305
+ "resourceId",
1306
+ "title",
1307
+ "description",
1308
+ "options",
1309
+ "hideFollowing",
1310
+ "revealKey"
1311
+ ],
1312
+ "properties": {
1313
+ "id": {
1314
+ "type": "string",
1315
+ "minLength": 1,
1316
+ "pattern": "\\S"
1317
+ },
1318
+ "resourceId": {
1319
+ "type": "string"
1320
+ },
1321
+ "title": {
1322
+ "type": "string"
1323
+ },
1324
+ "description": {
1325
+ "type": "string"
1326
+ },
1327
+ "options": {
1328
+ "type": "array",
1329
+ "items": {
1330
+ "type": "object",
1331
+ "additionalProperties": false,
1332
+ "required": [
1333
+ "id",
1334
+ "label"
1335
+ ],
1336
+ "properties": {
1337
+ "id": {
1338
+ "type": "string",
1339
+ "minLength": 1,
1340
+ "pattern": "\\S"
1341
+ },
1342
+ "label": {
1343
+ "type": "string",
1344
+ "minLength": 1,
1345
+ "pattern": "\\S"
1346
+ },
1347
+ "targetAnchorId": {
1348
+ "type": "string",
1349
+ "minLength": 1,
1350
+ "pattern": "\\S"
1351
+ }
1352
+ }
1353
+ }
1354
+ },
1355
+ "hideFollowing": {
1356
+ "type": "boolean"
1357
+ },
1358
+ "revealKey": {
1359
+ "type": "string",
1360
+ "minLength": 1,
1361
+ "pattern": "\\S"
1362
+ }
1363
+ },
1364
+ "allOf": [
1365
+ {
1366
+ "if": {
1367
+ "properties": {
1368
+ "resourceId": {
1369
+ "const": ""
1370
+ }
1371
+ }
1372
+ },
1373
+ "then": {
1374
+ "properties": {
1375
+ "title": {
1376
+ "const": ""
1377
+ },
1378
+ "description": {
1379
+ "const": ""
1380
+ },
1381
+ "options": {
1382
+ "maxItems": 0
1383
+ }
1384
+ }
1385
+ },
1386
+ "else": {
1387
+ "properties": {
1388
+ "resourceId": {
1389
+ "pattern": "\\S"
1390
+ },
1391
+ "title": {
1392
+ "minLength": 1,
1393
+ "pattern": "\\S"
1394
+ },
1395
+ "options": {
1396
+ "minItems": 1
1397
+ }
1398
+ }
1399
+ }
1400
+ }
1401
+ ]
1402
+ }
1403
+ }
1079
1404
  }
1080
1405
  }
1406
+ },
1407
+ "baseProtocol": {
1408
+ "id": "article-content-v1",
1409
+ "version": 1
1410
+ },
1411
+ "extensions": [
1412
+ {
1413
+ "id": "text-formatting",
1414
+ "version": 1,
1415
+ "schemaId": "urn:article-content-protocol:text-formatting:v1"
1416
+ },
1417
+ {
1418
+ "id": "paragraph-font-size",
1419
+ "version": 1,
1420
+ "schemaId": "urn:article-content-protocol:paragraph-font-size:v1"
1421
+ },
1422
+ {
1423
+ "id": "image-layout",
1424
+ "version": 1,
1425
+ "schemaId": "urn:article-content-protocol:image-layout:v1"
1426
+ },
1427
+ {
1428
+ "id": "resource-question",
1429
+ "version": 1,
1430
+ "schemaId": "urn:article-content-protocol:resource-question:v1"
1431
+ },
1432
+ {
1433
+ "id": "paragraph-anchor",
1434
+ "version": 1
1435
+ }
1436
+ ],
1437
+ "resourceQuestionRules": {
1438
+ "data": "Save the selected resourceId, title, description and options as a snapshot. Option IDs are stable strings supplied by the resource. Do not fetch on render.",
1439
+ "identity": "Question id, revealKey and paragraph/heading anchorId must each be unique within the document; option id must be unique within its question. Enforce these semantic checks in addition to JSON Schema.",
1440
+ "draft": "resourceId=\"\" with empty title, description and options is an unconfigured placeholder. Render a neutral placeholder; never unlock automatically.",
1441
+ "placement": "resourceQuestion is allowed only as a direct child of doc.",
1442
+ "navigation": "Match the selected option.targetAnchorId to a paragraph or heading in this article instance. Missing/unbound targets do not navigate. After business-controlled reveal, wait for layout before scrolling.",
1443
+ "visibility": "Scan top-level nodes in order. Include a resourceQuestion, then stop if hideFollowing=true and its revealKey is absent from the host-supplied revealed keys. Recompute from the original document when keys change. Clicking an option does not automatically unlock.",
1444
+ "security": "Visibility is presentation only, not authorization. Hidden article data remains in the JSON; sensitive data must be protected on the server."
1081
1445
  }
1082
1446
  }