@teipublisher/pb-components 1.32.2 → 1.34.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.
- package/CHANGELOG.md +41 -0
- package/dist/demo/demos.json +4 -1
- package/dist/demo/pb-timeline.html +122 -0
- package/dist/demo/pb-timeline2.html +94 -0
- package/dist/demo/timeline-dev-data.json +3 -0
- package/dist/pb-components-bundle.js +508 -252
- package/dist/pb-elements.json +287 -0
- package/i18n/common/de.json +4 -0
- package/i18n/common/en.json +4 -0
- package/package.json +1 -1
- package/pb-elements.json +287 -0
- package/src/parse-date-service.js +266 -0
- package/src/pb-browse-docs.js +25 -8
- package/src/pb-components.js +1 -0
- package/src/pb-load.js +17 -6
- package/src/pb-timeline.js +741 -0
- package/src/pb-view.js +59 -10
- package/src/search-result-service.js +521 -0
package/pb-elements.json
CHANGED
|
@@ -1328,6 +1328,12 @@
|
|
|
1328
1328
|
"type": "string",
|
|
1329
1329
|
"default": "\"title\""
|
|
1330
1330
|
},
|
|
1331
|
+
{
|
|
1332
|
+
"name": "static",
|
|
1333
|
+
"description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required",
|
|
1334
|
+
"type": "boolean",
|
|
1335
|
+
"default": "false"
|
|
1336
|
+
},
|
|
1331
1337
|
{
|
|
1332
1338
|
"name": "url",
|
|
1333
1339
|
"description": "The URL for the AJAX request. If a relative URL is passed, it will be resolved\nagainst the current API endpoint.",
|
|
@@ -1497,6 +1503,13 @@
|
|
|
1497
1503
|
"type": "string",
|
|
1498
1504
|
"default": "\"title\""
|
|
1499
1505
|
},
|
|
1506
|
+
{
|
|
1507
|
+
"name": "static",
|
|
1508
|
+
"attribute": "static",
|
|
1509
|
+
"description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required",
|
|
1510
|
+
"type": "boolean",
|
|
1511
|
+
"default": "false"
|
|
1512
|
+
},
|
|
1500
1513
|
{
|
|
1501
1514
|
"name": "url",
|
|
1502
1515
|
"attribute": "url",
|
|
@@ -9471,6 +9484,254 @@
|
|
|
9471
9484
|
}
|
|
9472
9485
|
]
|
|
9473
9486
|
},
|
|
9487
|
+
{
|
|
9488
|
+
"name": "pb-timeline",
|
|
9489
|
+
"path": "./src/pb-timeline.js",
|
|
9490
|
+
"description": "A timeline component to display time series data in a bar chart like view.\n\nTime series data can be displayed in one of 6 different scales:\n\n- by decade (10Y)\n- by 5 years (5Y)\n- by years (Y)\n- by month (M)\n- by week (W)\n- by day (D)\n\nThe endpoint is expected to return a JSON object. Each property should either be a date or the special\nmarker `?`, which indicates undated resources.\nThe value associated with each entry\nshould either correspond to a count of resources or an object with properties `count` and `info`. \n`info` should be an array, containing HTML to be shown in a list within the tooltips.",
|
|
9491
|
+
"attributes": [
|
|
9492
|
+
{
|
|
9493
|
+
"name": "start-date",
|
|
9494
|
+
"description": "start date for timeline to display",
|
|
9495
|
+
"type": "string",
|
|
9496
|
+
"default": "\"\""
|
|
9497
|
+
},
|
|
9498
|
+
{
|
|
9499
|
+
"name": "end-date",
|
|
9500
|
+
"description": "endDate for timeline to display",
|
|
9501
|
+
"type": "string",
|
|
9502
|
+
"default": "\"\""
|
|
9503
|
+
},
|
|
9504
|
+
{
|
|
9505
|
+
"name": "scope",
|
|
9506
|
+
"description": "The scope for the timeline. Must be one of the pre-defined scopes.\nIf not set, the component automatically tries to determine the best scope fitting the\ngiven time series.",
|
|
9507
|
+
"type": "string",
|
|
9508
|
+
"default": "\"\""
|
|
9509
|
+
},
|
|
9510
|
+
{
|
|
9511
|
+
"name": "scopes",
|
|
9512
|
+
"description": "The scopes to consider for automatic scoping.\n\nDefaults to [\"D\", \"W\", \"M\", \"Y\", \"5Y\", \"10Y\"]",
|
|
9513
|
+
"type": "array",
|
|
9514
|
+
"default": "[\"D\",\"W\",\"M\",\"Y\",\"5Y\",\"10Y\"]"
|
|
9515
|
+
},
|
|
9516
|
+
{
|
|
9517
|
+
"name": "url",
|
|
9518
|
+
"description": "Endpoint to load timeline data from. Expects response to be an\nobject with key value pairs for (date, hits).\n\nWill be reloaded whenever 'start-date' or 'end-date' attributes change.",
|
|
9519
|
+
"type": "string",
|
|
9520
|
+
"default": "\"\""
|
|
9521
|
+
},
|
|
9522
|
+
{
|
|
9523
|
+
"name": "auto",
|
|
9524
|
+
"description": "If set, data will be retrieved automatically on first load.",
|
|
9525
|
+
"type": "boolean",
|
|
9526
|
+
"default": "false"
|
|
9527
|
+
},
|
|
9528
|
+
{
|
|
9529
|
+
"name": "resettable",
|
|
9530
|
+
"type": "boolean",
|
|
9531
|
+
"default": "false"
|
|
9532
|
+
},
|
|
9533
|
+
{
|
|
9534
|
+
"name": "subscribe",
|
|
9535
|
+
"description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
|
|
9536
|
+
"type": "string"
|
|
9537
|
+
},
|
|
9538
|
+
{
|
|
9539
|
+
"name": "subscribe-config",
|
|
9540
|
+
"description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to listen to.",
|
|
9541
|
+
"type": "object"
|
|
9542
|
+
},
|
|
9543
|
+
{
|
|
9544
|
+
"name": "emit",
|
|
9545
|
+
"description": "The name of the channel to send events to.",
|
|
9546
|
+
"type": "string"
|
|
9547
|
+
},
|
|
9548
|
+
{
|
|
9549
|
+
"name": "emit-config",
|
|
9550
|
+
"description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to be dispatched.",
|
|
9551
|
+
"type": "object"
|
|
9552
|
+
},
|
|
9553
|
+
{
|
|
9554
|
+
"name": "wait-for",
|
|
9555
|
+
"description": "A selector pointing to other components this component depends on.\nWhen method `wait` is called, it will wait until all referenced\ncomponents signal with a `pb-ready` event that they are ready and listening\nto events.",
|
|
9556
|
+
"type": "string"
|
|
9557
|
+
},
|
|
9558
|
+
{
|
|
9559
|
+
"name": "disabled",
|
|
9560
|
+
"description": "Common property to disable the functionality associated with a component.\n`pb-highlight` and `pb-popover` react to this.",
|
|
9561
|
+
"type": "boolean",
|
|
9562
|
+
"default": "false"
|
|
9563
|
+
}
|
|
9564
|
+
],
|
|
9565
|
+
"properties": [
|
|
9566
|
+
{
|
|
9567
|
+
"name": "label"
|
|
9568
|
+
},
|
|
9569
|
+
{
|
|
9570
|
+
"name": "maxHeight",
|
|
9571
|
+
"type": "number",
|
|
9572
|
+
"default": "80"
|
|
9573
|
+
},
|
|
9574
|
+
{
|
|
9575
|
+
"name": "multiplier",
|
|
9576
|
+
"type": "number",
|
|
9577
|
+
"default": "0.75"
|
|
9578
|
+
},
|
|
9579
|
+
{
|
|
9580
|
+
"name": "mousedown",
|
|
9581
|
+
"type": "boolean",
|
|
9582
|
+
"default": "false"
|
|
9583
|
+
},
|
|
9584
|
+
{
|
|
9585
|
+
"name": "startDate",
|
|
9586
|
+
"attribute": "start-date",
|
|
9587
|
+
"description": "start date for timeline to display",
|
|
9588
|
+
"type": "string",
|
|
9589
|
+
"default": "\"\""
|
|
9590
|
+
},
|
|
9591
|
+
{
|
|
9592
|
+
"name": "endDate",
|
|
9593
|
+
"attribute": "end-date",
|
|
9594
|
+
"description": "endDate for timeline to display",
|
|
9595
|
+
"type": "string",
|
|
9596
|
+
"default": "\"\""
|
|
9597
|
+
},
|
|
9598
|
+
{
|
|
9599
|
+
"name": "scope",
|
|
9600
|
+
"attribute": "scope",
|
|
9601
|
+
"description": "The scope for the timeline. Must be one of the pre-defined scopes.\nIf not set, the component automatically tries to determine the best scope fitting the\ngiven time series.",
|
|
9602
|
+
"type": "string",
|
|
9603
|
+
"default": "\"\""
|
|
9604
|
+
},
|
|
9605
|
+
{
|
|
9606
|
+
"name": "scopes",
|
|
9607
|
+
"attribute": "scopes",
|
|
9608
|
+
"description": "The scopes to consider for automatic scoping.\n\nDefaults to [\"D\", \"W\", \"M\", \"Y\", \"5Y\", \"10Y\"]",
|
|
9609
|
+
"type": "array",
|
|
9610
|
+
"default": "[\"D\",\"W\",\"M\",\"Y\",\"5Y\",\"10Y\"]"
|
|
9611
|
+
},
|
|
9612
|
+
{
|
|
9613
|
+
"name": "url",
|
|
9614
|
+
"attribute": "url",
|
|
9615
|
+
"description": "Endpoint to load timeline data from. Expects response to be an\nobject with key value pairs for (date, hits).\n\nWill be reloaded whenever 'start-date' or 'end-date' attributes change.",
|
|
9616
|
+
"type": "string",
|
|
9617
|
+
"default": "\"\""
|
|
9618
|
+
},
|
|
9619
|
+
{
|
|
9620
|
+
"name": "auto",
|
|
9621
|
+
"attribute": "auto",
|
|
9622
|
+
"description": "If set, data will be retrieved automatically on first load.",
|
|
9623
|
+
"type": "boolean",
|
|
9624
|
+
"default": "false"
|
|
9625
|
+
},
|
|
9626
|
+
{
|
|
9627
|
+
"name": "resettable",
|
|
9628
|
+
"attribute": "resettable",
|
|
9629
|
+
"type": "boolean",
|
|
9630
|
+
"default": "false"
|
|
9631
|
+
},
|
|
9632
|
+
{
|
|
9633
|
+
"name": "subscribe",
|
|
9634
|
+
"attribute": "subscribe",
|
|
9635
|
+
"description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
|
|
9636
|
+
"type": "string"
|
|
9637
|
+
},
|
|
9638
|
+
{
|
|
9639
|
+
"name": "subscribeConfig",
|
|
9640
|
+
"attribute": "subscribe-config",
|
|
9641
|
+
"description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to listen to.",
|
|
9642
|
+
"type": "object"
|
|
9643
|
+
},
|
|
9644
|
+
{
|
|
9645
|
+
"name": "emit",
|
|
9646
|
+
"attribute": "emit",
|
|
9647
|
+
"description": "The name of the channel to send events to.",
|
|
9648
|
+
"type": "string"
|
|
9649
|
+
},
|
|
9650
|
+
{
|
|
9651
|
+
"name": "emitConfig",
|
|
9652
|
+
"attribute": "emit-config",
|
|
9653
|
+
"description": "Configuration object to define a channel/event mapping. Every property\nin the object is interpreted as the name of a channel and its value should\nbe an array of event names to be dispatched.",
|
|
9654
|
+
"type": "object"
|
|
9655
|
+
},
|
|
9656
|
+
{
|
|
9657
|
+
"name": "waitFor",
|
|
9658
|
+
"attribute": "wait-for",
|
|
9659
|
+
"description": "A selector pointing to other components this component depends on.\nWhen method `wait` is called, it will wait until all referenced\ncomponents signal with a `pb-ready` event that they are ready and listening\nto events.",
|
|
9660
|
+
"type": "string"
|
|
9661
|
+
},
|
|
9662
|
+
{
|
|
9663
|
+
"name": "disabled",
|
|
9664
|
+
"attribute": "disabled",
|
|
9665
|
+
"description": "Common property to disable the functionality associated with a component.\n`pb-highlight` and `pb-popover` react to this.",
|
|
9666
|
+
"type": "boolean",
|
|
9667
|
+
"default": "false"
|
|
9668
|
+
}
|
|
9669
|
+
],
|
|
9670
|
+
"events": [
|
|
9671
|
+
{
|
|
9672
|
+
"name": "pb-timeline-date-changed",
|
|
9673
|
+
"description": "Triggered when user clicks on a single entry"
|
|
9674
|
+
},
|
|
9675
|
+
{
|
|
9676
|
+
"name": "pb-timeline-daterange-changed",
|
|
9677
|
+
"description": "Triggered when user selects a range of entries"
|
|
9678
|
+
},
|
|
9679
|
+
{
|
|
9680
|
+
"name": "pb-timeline-reset-selection",
|
|
9681
|
+
"description": "Requests that the timeline is reset to initial state"
|
|
9682
|
+
},
|
|
9683
|
+
{
|
|
9684
|
+
"name": "pb-timeline-loaded",
|
|
9685
|
+
"description": "Timeline was loaded"
|
|
9686
|
+
}
|
|
9687
|
+
],
|
|
9688
|
+
"slots": [
|
|
9689
|
+
{
|
|
9690
|
+
"name": "label",
|
|
9691
|
+
"description": "Inserted before the label showing the currently displayed time range"
|
|
9692
|
+
}
|
|
9693
|
+
],
|
|
9694
|
+
"cssProperties": [
|
|
9695
|
+
{
|
|
9696
|
+
"name": "--pb-timeline-height"
|
|
9697
|
+
},
|
|
9698
|
+
{
|
|
9699
|
+
"name": "--pb-timeline-padding"
|
|
9700
|
+
},
|
|
9701
|
+
{
|
|
9702
|
+
"name": "--pb-timeline-color-highlight"
|
|
9703
|
+
},
|
|
9704
|
+
{
|
|
9705
|
+
"name": "--pb-timeline-color-light"
|
|
9706
|
+
},
|
|
9707
|
+
{
|
|
9708
|
+
"name": "--pb-timeline-color-dark"
|
|
9709
|
+
},
|
|
9710
|
+
{
|
|
9711
|
+
"name": "--pb-timeline-color-selected"
|
|
9712
|
+
},
|
|
9713
|
+
{
|
|
9714
|
+
"name": "--pb-timeline-color-bin"
|
|
9715
|
+
},
|
|
9716
|
+
{
|
|
9717
|
+
"name": "--pb-timeline-title-font-size"
|
|
9718
|
+
},
|
|
9719
|
+
{
|
|
9720
|
+
"name": "--pb-timeline-tooltip-font-size"
|
|
9721
|
+
}
|
|
9722
|
+
],
|
|
9723
|
+
"cssParts": [
|
|
9724
|
+
{
|
|
9725
|
+
"name": "label"
|
|
9726
|
+
},
|
|
9727
|
+
{
|
|
9728
|
+
"name": "tooltip"
|
|
9729
|
+
},
|
|
9730
|
+
{
|
|
9731
|
+
"name": "title"
|
|
9732
|
+
}
|
|
9733
|
+
]
|
|
9734
|
+
},
|
|
9474
9735
|
{
|
|
9475
9736
|
"name": "pb-toggle-feature",
|
|
9476
9737
|
"path": "./src/pb-toggle-feature.js",
|
|
@@ -9961,6 +10222,12 @@
|
|
|
9961
10222
|
"description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
|
|
9962
10223
|
"type": "string"
|
|
9963
10224
|
},
|
|
10225
|
+
{
|
|
10226
|
+
"name": "static",
|
|
10227
|
+
"description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
|
|
10228
|
+
"type": "boolean",
|
|
10229
|
+
"default": "false"
|
|
10230
|
+
},
|
|
9964
10231
|
{
|
|
9965
10232
|
"name": "subscribe",
|
|
9966
10233
|
"description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
|
|
@@ -10156,6 +10423,13 @@
|
|
|
10156
10423
|
"description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
|
|
10157
10424
|
"type": "string"
|
|
10158
10425
|
},
|
|
10426
|
+
{
|
|
10427
|
+
"name": "static",
|
|
10428
|
+
"attribute": "static",
|
|
10429
|
+
"description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
|
|
10430
|
+
"type": "boolean",
|
|
10431
|
+
"default": "false"
|
|
10432
|
+
},
|
|
10159
10433
|
{
|
|
10160
10434
|
"name": "subscribe",
|
|
10161
10435
|
"attribute": "subscribe",
|
|
@@ -10412,6 +10686,12 @@
|
|
|
10412
10686
|
"description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
|
|
10413
10687
|
"type": "string"
|
|
10414
10688
|
},
|
|
10689
|
+
{
|
|
10690
|
+
"name": "static",
|
|
10691
|
+
"description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
|
|
10692
|
+
"type": "boolean",
|
|
10693
|
+
"default": "false"
|
|
10694
|
+
},
|
|
10415
10695
|
{
|
|
10416
10696
|
"name": "subscribe",
|
|
10417
10697
|
"description": "The name of the channel to subscribe to. Only events on a channel corresponding\nto this property are listened to.",
|
|
@@ -10590,6 +10870,13 @@
|
|
|
10590
10870
|
"description": "If set to the name of an event, the content of the pb-view will not be replaced\nimmediately upon updates. Instead, an event is emitted, which contains the new content\nin property `root`. An event handler intercepting the event can thus modify the content.\nOnce it is done, it should pass the modified content to the callback function provided\nin the event detail under the name `render`. See the demo for an example.",
|
|
10591
10871
|
"type": "string"
|
|
10592
10872
|
},
|
|
10873
|
+
{
|
|
10874
|
+
"name": "static",
|
|
10875
|
+
"attribute": "static",
|
|
10876
|
+
"description": "If set, rewrite URLs to load pages as static HTML files,\nso no TEI Publisher instance is required. Use this in combination with\n[tei-publisher-static](https://github.com/eeditiones/tei-publisher-static).",
|
|
10877
|
+
"type": "boolean",
|
|
10878
|
+
"default": "false"
|
|
10879
|
+
},
|
|
10593
10880
|
{
|
|
10594
10881
|
"name": "subscribe",
|
|
10595
10882
|
"attribute": "subscribe",
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
export class ParseDateService {
|
|
2
|
+
/*
|
|
3
|
+
* PARSE DATE SERVICE
|
|
4
|
+
* whenever the user types a date, it should be allowed
|
|
5
|
+
* to type in a lot of dirrerent date formats. This service
|
|
6
|
+
* should detect all of the supported formats. Some supported formats:
|
|
7
|
+
* - 1. April 1970 => 1970-04-01
|
|
8
|
+
* - 1970 => 1970-01-01
|
|
9
|
+
* - 1970-12-23 => 1970-12-23
|
|
10
|
+
* - 1900 12 23 => 1900-12-23
|
|
11
|
+
* - 1 jan 1970 => 1970-01-01
|
|
12
|
+
* - 2020-W12 => 2020-03-16
|
|
13
|
+
* - 2020-01 => 2020-01-01
|
|
14
|
+
* For all formats check the tests written in AVA `test/parse-date-service-test.js`
|
|
15
|
+
*
|
|
16
|
+
* public methods
|
|
17
|
+
* run()
|
|
18
|
+
*/
|
|
19
|
+
constructor() {
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
run (input) {
|
|
23
|
+
this.input = input;
|
|
24
|
+
this.day = "??";
|
|
25
|
+
this.month = "??";
|
|
26
|
+
this.year = "????";
|
|
27
|
+
|
|
28
|
+
const resultIsoMatch = this.input.match(this._isoMatchRegex());
|
|
29
|
+
const resultCustomMatch = this.input.match(this._customRegex());
|
|
30
|
+
const resultWeekMatch = this.input.match(this._weekMatchRegex());
|
|
31
|
+
const resultYearAndMonthMatch = this.input.match(this._yearAndMonthRegex());
|
|
32
|
+
if (resultIsoMatch) {
|
|
33
|
+
const split = resultIsoMatch[0].split(/-|\/|\s/);
|
|
34
|
+
this.year = split[0];
|
|
35
|
+
this.month = this._setWithLeadingZero(split[1]);
|
|
36
|
+
this.day = this._setWithLeadingZero(split[2]);
|
|
37
|
+
} else if (resultYearAndMonthMatch) {
|
|
38
|
+
const split = resultYearAndMonthMatch[0].split("-");
|
|
39
|
+
this.year = split[0];
|
|
40
|
+
this.month = this._setWithLeadingZero(split[1]);
|
|
41
|
+
this.day = "01";
|
|
42
|
+
} else if (resultCustomMatch) {
|
|
43
|
+
const split = resultCustomMatch[0].split(/\.|\s|\/|-/);
|
|
44
|
+
this.day = this._setWithLeadingZero(split[0]);
|
|
45
|
+
this.month = this._setWithLeadingZero(split[1]);
|
|
46
|
+
this.year = split[2];
|
|
47
|
+
} else if (resultWeekMatch) {
|
|
48
|
+
const split = resultWeekMatch[0].split(/\.|\s|\/|-/);
|
|
49
|
+
const year = Number(split[0]);
|
|
50
|
+
const week = Number(split[1].replace("W0", "").replace("W", ""));
|
|
51
|
+
return this._getDateStrOfISOWeek(year, week);
|
|
52
|
+
} else {
|
|
53
|
+
this._findYear();
|
|
54
|
+
this._findMonth();
|
|
55
|
+
this._findDay();
|
|
56
|
+
}
|
|
57
|
+
return this._buildResult();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
_buildResult() {
|
|
61
|
+
if (this.year != "????" && this.month === "??") {
|
|
62
|
+
this.month = "01";
|
|
63
|
+
}
|
|
64
|
+
if (this.month != "??" && this.day === "??") {
|
|
65
|
+
this.day = "01";
|
|
66
|
+
}
|
|
67
|
+
return `${this.year}-${this.month}-${this.day}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/*
|
|
71
|
+
* matches ISO string format (with some extensions)
|
|
72
|
+
* | 2012-01-31 | 2012-1-31 | 2012/01/31 |
|
|
73
|
+
* | 2012/1/31 | 2012 1 31 | 2012 01 31 |
|
|
74
|
+
*/
|
|
75
|
+
_isoMatchRegex() {
|
|
76
|
+
return /(?<=\s|^)\d{4}(-|\s|\/)([0][1-9]|[1-9]|10|11|12)(-|\s|\/)([0][1-9]|[1-2][0-9]|3[01]|[1-9])(?=\s|$|\.)/;
|
|
77
|
+
/* | | year | 01-09 | 1-9 | 10-12 | |01-09 |10-29 |30,31| 1-9 |
|
|
78
|
+
* | | dash or slash | dash or slash |
|
|
79
|
+
* |preceding with space or start of string end with space endofstr or dot <-|*/
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/*
|
|
83
|
+
* matches a custom date string format (reversed order, day-month-year)
|
|
84
|
+
* | 12.3.2000 | 1.2.2012 | 1-2-2012 |
|
|
85
|
+
* | 12/3/2000 | 1 2 2012 | 1/2/2012 |
|
|
86
|
+
*/
|
|
87
|
+
_customRegex() {
|
|
88
|
+
return /\d{1,2}(\.|\s|\/|-)\d{1,2}(\.|\s|\/|-)\d{4}/;
|
|
89
|
+
/* | day | | month | | year
|
|
90
|
+
* |___________________|
|
|
91
|
+
* |
|
|
92
|
+
* seperated by dot, space, slash or dash */
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/*
|
|
96
|
+
* matches a date format that specifies the week
|
|
97
|
+
* | 2012-W1 | 2012 W1 | 2012 W01 |
|
|
98
|
+
* | 2020.W2 | 2020-W53 | 2012/W1 |
|
|
99
|
+
*/
|
|
100
|
+
_weekMatchRegex() {
|
|
101
|
+
return /\d{4}(\.|\s|\/|-)W\d{1,2}(?=\s|$|\.)/;
|
|
102
|
+
/* |year | |W1-W53 |
|
|
103
|
+
* |___________________|
|
|
104
|
+
* |
|
|
105
|
+
* seperated by dot, space, slash or dash */
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/*
|
|
109
|
+
* matches a date format with only year and month
|
|
110
|
+
* YYYY-MM (1-12)
|
|
111
|
+
* | 2020-01 | 2020-12 | 2012-1 |
|
|
112
|
+
*/
|
|
113
|
+
_yearAndMonthRegex() {
|
|
114
|
+
return /(?<=\s|^)\d{4}-([0][1-9]|[1-9]|10|11|12)(?=\s|$)/;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
_findYear() {
|
|
118
|
+
let regex = /[1-9]{1}[0-9]{3}/;
|
|
119
|
+
const result = this.input.match(regex)
|
|
120
|
+
if (result) {
|
|
121
|
+
this.year = result[0];
|
|
122
|
+
this._removeMatchFromInput(result);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
_findMonth() {
|
|
127
|
+
const months = this._monthDictionaryValues();
|
|
128
|
+
months.forEach(month => {
|
|
129
|
+
let re = new RegExp(`(?<=\\s|^)(${month})(?=\\s|$|\\.)`, "i")
|
|
130
|
+
const result = this.input.match(re);
|
|
131
|
+
if (result) { // yes => get dict and value + return
|
|
132
|
+
this.month = this._monthDictionary()[result[0].toLowerCase()];
|
|
133
|
+
this._removeMatchFromInput(result);
|
|
134
|
+
return this.month;
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
return undefined;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/*
|
|
141
|
+
* find single numbers from 1-31
|
|
142
|
+
*/
|
|
143
|
+
_findDay() {
|
|
144
|
+
let regex = /(?<=\s|^)([0][1-9]|[1-2][0-9]|3[01]|[1-9])(?=\s|$|\.|st|nd|rd|th)/;
|
|
145
|
+
/* | | 01-09 | 10-29 |30,31|1-9 | ends with whitespace, endofstr or dot.
|
|
146
|
+
* | starts with whitepace or startoftr | won't be included in match (lookbehind operator)
|
|
147
|
+
* | look behind operator (not included)
|
|
148
|
+
* | https://stackoverflow.com/a/6713378/6272061 */
|
|
149
|
+
const result = this.input.match(regex)
|
|
150
|
+
if (result) {
|
|
151
|
+
this.day = this._setWithLeadingZero(result[0]);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/*
|
|
156
|
+
* if a string or number has only 1 digit or char
|
|
157
|
+
* a leading zro is added
|
|
158
|
+
* returns a string
|
|
159
|
+
*/
|
|
160
|
+
_setWithLeadingZero(input) {
|
|
161
|
+
input = input.toString();
|
|
162
|
+
if (input.length == 1) {
|
|
163
|
+
return "0" + input;
|
|
164
|
+
} else {
|
|
165
|
+
return input;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
_removeMatchFromInput(matchObj) {
|
|
170
|
+
if (matchObj && matchObj[0] && matchObj.index) {
|
|
171
|
+
let len = matchObj[0].length;
|
|
172
|
+
let charArr = this.input.split('');
|
|
173
|
+
charArr.splice(matchObj.index, len);
|
|
174
|
+
this.input = charArr.join("");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
_monthDictionaryValues() {
|
|
179
|
+
return Object.keys(this._monthDictionary());
|
|
180
|
+
}
|
|
181
|
+
_monthDictionary() {
|
|
182
|
+
return {
|
|
183
|
+
// german
|
|
184
|
+
"jan": "01", "januar": "01",
|
|
185
|
+
"feb": "02", "februar": "02",
|
|
186
|
+
"mär": "03", "märz": "03",
|
|
187
|
+
"apr": "04", "april": "04",
|
|
188
|
+
"mai": "05", "mai": "05",
|
|
189
|
+
"jun": "06", "juni": "06",
|
|
190
|
+
"jul": "07", "juli": "07",
|
|
191
|
+
"aug": "08", "august": "08",
|
|
192
|
+
"sep": "09", "september": "09",
|
|
193
|
+
"okt": "10", "oktober": "10",
|
|
194
|
+
"nov": "11", "november": "11",
|
|
195
|
+
"dez": "12", "dezember": "12",
|
|
196
|
+
// english
|
|
197
|
+
"jan": "01", "january": "01",
|
|
198
|
+
"feb": "02", "february": "02",
|
|
199
|
+
"mar": "03", "march": "03",
|
|
200
|
+
"apr": "04", "april": "04",
|
|
201
|
+
"may": "05", "may": "05",
|
|
202
|
+
"jun": "06", "june": "06",
|
|
203
|
+
"jul": "07", "july": "07",
|
|
204
|
+
"aug": "08", "august": "08",
|
|
205
|
+
"sep": "09", "september": "09",
|
|
206
|
+
"oct": "10", "october": "10",
|
|
207
|
+
"nov": "11", "november": "11",
|
|
208
|
+
"dec": "12", "december": "12",
|
|
209
|
+
// french
|
|
210
|
+
"janv":"01", "janvier": "01",
|
|
211
|
+
"févr":"02", "février'": "02",
|
|
212
|
+
"mars":"03", "mars": "03",
|
|
213
|
+
"avr": "04", "avril": "04",
|
|
214
|
+
"mai": "05", "mai": "05",
|
|
215
|
+
"juin":"06", "juin": "06",
|
|
216
|
+
"juil":"07", "juillet": "07",
|
|
217
|
+
"août":"08", "août": "08",
|
|
218
|
+
"sept":"09", "septembre": "09",
|
|
219
|
+
"oct": "10", "octobre": "10",
|
|
220
|
+
"nov": "11", "novembre": "11",
|
|
221
|
+
"déc": "12", "décembre": "12",
|
|
222
|
+
//italian
|
|
223
|
+
"gen": "01", "gennaio": "01",
|
|
224
|
+
"feb": "02", "febbraio": "02",
|
|
225
|
+
"mar": "03", "marzo": "03",
|
|
226
|
+
"apr": "04", "aprile": "04",
|
|
227
|
+
"mag": "05", "maggio": "05",
|
|
228
|
+
"giu": "06", "giugno": "06",
|
|
229
|
+
"lug": "07", "luglio": "07",
|
|
230
|
+
"ago": "08", "agosto": "08",
|
|
231
|
+
"set": "09", "settembre": "09",
|
|
232
|
+
"ott": "10", "ottobre": "10",
|
|
233
|
+
"nov": "11", "novembre": "11",
|
|
234
|
+
"dic": "12", "dicembre": "12",
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
_getDateStrOfISOWeek(y, w) {
|
|
239
|
+
let simple = new Date(y, 0, 1 + (w - 1) * 7);
|
|
240
|
+
let dow = simple.getDay();
|
|
241
|
+
let ISOweekStart = simple;
|
|
242
|
+
if (dow <= 4) {
|
|
243
|
+
ISOweekStart.setDate(simple.getDate() - simple.getDay() + 1);
|
|
244
|
+
} else {
|
|
245
|
+
ISOweekStart.setDate(simple.getDate() + 8 - simple.getDay());
|
|
246
|
+
}
|
|
247
|
+
// do not rollover to next or previous year
|
|
248
|
+
if (ISOweekStart.getFullYear() > y) {
|
|
249
|
+
return `${y}-12-31`;
|
|
250
|
+
} else if (ISOweekStart.getFullYear() < y) {
|
|
251
|
+
return `${y}-01-01`;
|
|
252
|
+
}
|
|
253
|
+
return this._dateToDateStr(ISOweekStart);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/*
|
|
257
|
+
* formats date object to dateStr YYYY-MM-DD
|
|
258
|
+
*/
|
|
259
|
+
_dateToDateStr(date) {
|
|
260
|
+
let d = new Date(date);
|
|
261
|
+
let month = this._setWithLeadingZero((d.getMonth() + 1));
|
|
262
|
+
let day = this._setWithLeadingZero(d.getDate());
|
|
263
|
+
let year = d.getFullYear();
|
|
264
|
+
return `${year}-${month}-${day}`;
|
|
265
|
+
}
|
|
266
|
+
}
|
package/src/pb-browse-docs.js
CHANGED
|
@@ -87,6 +87,13 @@ export class PbBrowseDocs extends PbLoad {
|
|
|
87
87
|
subforms: {
|
|
88
88
|
type: String
|
|
89
89
|
},
|
|
90
|
+
/**
|
|
91
|
+
* If set, rewrite URLs to load pages as static HTML files,
|
|
92
|
+
* so no TEI Publisher instance is required
|
|
93
|
+
*/
|
|
94
|
+
static: {
|
|
95
|
+
type: Boolean
|
|
96
|
+
},
|
|
90
97
|
_file: {
|
|
91
98
|
type: String
|
|
92
99
|
},
|
|
@@ -120,6 +127,8 @@ export class PbBrowseDocs extends PbLoad {
|
|
|
120
127
|
this.filterBy = 'title';
|
|
121
128
|
this._allowModification = false;
|
|
122
129
|
this._suggestions = [];
|
|
130
|
+
|
|
131
|
+
this.static = false;
|
|
123
132
|
}
|
|
124
133
|
|
|
125
134
|
connectedCallback() {
|
|
@@ -177,14 +186,16 @@ export class PbBrowseDocs extends PbLoad {
|
|
|
177
186
|
});
|
|
178
187
|
this.shadowRoot.getElementById('autocomplete').addEventListener('autocomplete-change', this._autocomplete.bind(this));
|
|
179
188
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
this.
|
|
186
|
-
|
|
187
|
-
|
|
189
|
+
if (this.login) {
|
|
190
|
+
const login = document.getElementById(this.login);
|
|
191
|
+
if (!login) {
|
|
192
|
+
console.error('<pb-browse-docs> connected pb-login element not found!');
|
|
193
|
+
} else {
|
|
194
|
+
this.subscribeTo('pb-login', (ev) => {
|
|
195
|
+
this._allowModification = this._loggedIn(ev.detail.user, ev.detail.group);
|
|
196
|
+
}, []);
|
|
197
|
+
this._allowModification = login.loggedIn && this._loggedIn(login.user, login.groups);
|
|
198
|
+
}
|
|
188
199
|
}
|
|
189
200
|
|
|
190
201
|
this.shadowRoot.getElementById('sort-list').addEventListener('selected-item-changed', this._sort.bind(this));
|
|
@@ -206,6 +217,7 @@ export class PbBrowseDocs extends PbLoad {
|
|
|
206
217
|
}
|
|
207
218
|
</style>
|
|
208
219
|
</custom-style>
|
|
220
|
+
<slot name="header"></slot>
|
|
209
221
|
<div class="toolbar">
|
|
210
222
|
<paper-dropdown-menu id="sort" label="${translate(this.sortLabel)}" part="sort-dropdown">
|
|
211
223
|
<paper-listbox id="sort-list" selected="${this.sortBy}" slot="dropdown-content" class="dropdown-content" attr-for-selected="value">
|
|
@@ -312,6 +324,10 @@ export class PbBrowseDocs extends PbLoad {
|
|
|
312
324
|
}
|
|
313
325
|
|
|
314
326
|
getURL(params) {
|
|
327
|
+
if (this.static) {
|
|
328
|
+
// use a static URL
|
|
329
|
+
return `collections/${this.collection ? this.collection + '/' : ''}${params.start || '1'}.html`;
|
|
330
|
+
}
|
|
315
331
|
const url = super.getURL(params);
|
|
316
332
|
return this.collection ? `${url}/${this.collection}` : url;
|
|
317
333
|
}
|
|
@@ -424,6 +440,7 @@ export class PbBrowseDocs extends PbLoad {
|
|
|
424
440
|
link.addEventListener('click', (ev) => {
|
|
425
441
|
ev.preventDefault();
|
|
426
442
|
this.collection = link.getAttribute('data-collection');
|
|
443
|
+
this.start = 1;
|
|
427
444
|
this.setParameter('collection', this.collection);
|
|
428
445
|
this.pushHistory('browse collection');
|
|
429
446
|
console.log('<pb-browse-docs> loading collection %s', this.collection);
|
package/src/pb-components.js
CHANGED
|
@@ -58,6 +58,7 @@ import './pb-blacklab-results.js';
|
|
|
58
58
|
import './pb-blacklab-highlight.js';
|
|
59
59
|
import './pb-table-grid.js';
|
|
60
60
|
import './pb-split-list.js';
|
|
61
|
+
import './pb-timeline.js';
|
|
61
62
|
|
|
62
63
|
import '@polymer/iron-icons/editor-icons';
|
|
63
64
|
import '@polymer/iron-icons/social-icons';
|