@lblod/ember-rdfa-editor-lblod-plugins 8.0.1 → 8.1.0

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,16 +2,12 @@ matrix:
2
2
  scenario:
3
3
  - ember-lts-3.28
4
4
 
5
- pipeline:
6
- ${scenario}:
5
+ steps:
6
+ - name: ${scenario}
7
7
  image: danlynn/ember-cli:4.8.0
8
8
  commands:
9
9
  - npm ci
10
- - npx ember try:one ${scenario}
10
+ - ember try:one ${scenario} --skip-cleanup=true
11
11
 
12
12
  when:
13
- event:
14
- - pull_request
15
-
16
- depends_on:
17
- - test
13
+ branch: [ master ]
@@ -1,23 +1,52 @@
1
-
2
- pipeline:
1
+ steps:
2
+ changelog:
3
+ image: danlynn/ember-cli:4.8.0
4
+ commands:
5
+ - git fetch origin master
6
+ - git diff -wb --name-only origin/master..HEAD | grep CHANGELOG.md
7
+ when:
8
+ event: pull_request
3
9
  install:
4
10
  image: danlynn/ember-cli:4.8.0
5
11
  commands:
6
12
  - npm ci
13
+ # ember-try already runs ember test, so we don't need another test step
7
14
  lint-js:
8
15
  image: danlynn/ember-cli:4.8.0
9
- group: lint
16
+ group: check
10
17
  commands:
11
18
  - npm run lint:js
12
19
  lint-hbs:
13
20
  image: danlynn/ember-cli:4.8.0
14
- group: lint
21
+ group: check
15
22
  commands:
16
23
  - npm run lint:hbs
17
24
  test:
18
25
  image: danlynn/ember-cli:4.8.0
26
+ group: check
19
27
  commands:
20
- - npm run test:ember
28
+ - ember test
29
+
30
+
31
+ release:
32
+ image: plugins/npm
33
+ settings:
34
+ token:
35
+ from_secret: npm_access_token
36
+ when:
37
+ event: tag
38
+ ref: refs/tags/v*
39
+
40
+ push-tagged-build:
41
+ image: plugins/docker
42
+ settings:
43
+ repo: lblod/ember-rdfa-editor-lblod-plugins
44
+ tags: "${CI_COMMIT_TAG##v}"
45
+ purge: true
46
+ secrets: [ docker_username, docker_password ]
47
+ when:
48
+ event: tag
49
+ ref: refs/tags/v*
50
+ # according to docs, this also runs on prs targetting master
21
51
  when:
22
- event:
23
- - pull_request
52
+ branch: [ master, hotfix/* ]
package/CHANGELOG.md CHANGED
@@ -7,11 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [8.1.0] - 2023-06-22
11
+ ### Added
12
+ - Numbers inputted into a number variable are validated on defined min/max and if it is a number
13
+
14
+ ### Fixed
15
+ - Fixed woodpecker builds crashing on syntax errors
16
+ - Use dutch language in static version of table of contents
17
+ - fix typo "Vlaams Codex" → "Vlaamse Codex"
18
+ - add missing argument to citation card in dummy app
19
+ - correct erroneous arguments to AuAlert
20
+
21
+ ### Changed
22
+ - remove the unnecessary type and add the html-safe tag at the rendering site
23
+
24
+ ### Removed
25
+ - remove ensure-changelog github action
26
+
27
+ ### Dependencies
28
+ - Bumps `@types/rdfjs__dataset` from 2.0.0 to 2.0.2
29
+ - Bumps `@types/ember__array` from 4.0.3 to 4.0.4
30
+ - Bumps `@typescript-eslint/parser` from 5.45.0 to 5.60.0
31
+ - Bumps `@types/ember__engine` from 4.0.4 to 4.0.5
32
+ - Bumps `typescript` to 5.0.4
33
+ - Bumps `prosemirror-dev-tools` from 3.1.0 to 4.0.0
34
+
10
35
  ## [8.0.1] - 2023-06-15
11
36
  ### Fixed
12
37
  - Change problematic type in citation that made it to break with new ember
13
38
 
14
-
15
39
  ## [8.0.0] - 2023-06-15
16
40
  ### Fixed
17
41
  - Bump `@lblod/ember-rdfa-editor` package to fix annotation not present for some structures
@@ -473,7 +497,7 @@ add onclick handler to pencil icon in variable plugin
473
497
 
474
498
  # Changelog
475
499
 
476
- [unreleased]: https://github.com/lblod/ember-rdfa-editor-lblod-plugins/compare/v8.0.1...HEAD
500
+ [unreleased]: https://github.com/lblod/ember-rdfa-editor-lblod-plugins/compare/v8.1.0...HEAD
477
501
  [8.0.0]: https://github.com/lblod/ember-rdfa-editor-lblod-plugins/compare/v8.0.0...v8.0.1
478
502
  [8.0.0]: https://github.com/lblod/ember-rdfa-editor-lblod-plugins/compare/v7.1.0...v8.0.0
479
503
  [7.1.0]: https://github.com/lblod/ember-rdfa-editor-lblod-plugins/compare/v7.0.0...v7.1.0
@@ -489,3 +513,4 @@ add onclick handler to pencil icon in variable plugin
489
513
  [3.0.0]: https://github.com/lblod/ember-rdfa-editor-lblod-plugins/compare/v2.1.2...v3.0.0
490
514
  [2.1.2]: https://github.com/lblod/ember-rdfa-editor-lblod-plugins/compare/v2.1.1...v2.1.2
491
515
  [2.1.1]: https://github.com/lblod/ember-rdfa-editor-lblod-plugins/compare/v2.1.0...v2.1.1
516
+ [8.1.0]: https://github.com/lblod/ember-rdfa-editor-lblod-plugins/compare/v8.0.1...v8.1.0
@@ -3,7 +3,7 @@
3
3
  {{@article.number}} ({{@article.dateInForce}} - {{if @article.dateNoLongerInForce @article.dateNoLongerInForce "…"}})
4
4
  </AuHeading>
5
5
  <p>
6
- {{@article.content}}
6
+ {{html-safe @article.content}}
7
7
  </p>
8
8
  <AuButton
9
9
  @skin="primary"
@@ -1,8 +1,8 @@
1
1
  <AuAlert
2
- @alertTitle="{{t "citaten-plugin.alert.error-title"}}"
3
- @alertSkin="error"
4
- @alertIcon="alert-triangle"
5
- @alertSize="{{if @fullSize "default" "small"}}"
2
+ @title="{{t "citaten-plugin.alert.error-title"}}"
3
+ @skin="error"
4
+ @icon="alert-triangle"
5
+ @size="{{if @fullSize "default" "small"}}"
6
6
  @closable={{false}}
7
7
  ...attributes>
8
8
  <p>{{t "citaten-plugin.alert.error-intro"}}</p>
@@ -1,8 +1,8 @@
1
1
  <AuAlert
2
- @alertTitle="{{t "citaten-plugin.alert.no-results"}}"
3
- @alertSkin="warning"
4
- @alertIcon="cross"
5
- @alertSize="{{if @fullSize "default" "small"}}"
2
+ @title="{{t "citaten-plugin.alert.no-results"}}"
3
+ @skin="warning"
4
+ @icon="cross"
5
+ @size="{{if @fullSize "default" "small"}}"
6
6
  @closable={{false}}
7
7
  class="{{unless @fullSize "au-u-margin-small"}}"
8
8
  ...attributes>
@@ -0,0 +1,54 @@
1
+ <Velcro
2
+ @placement='bottom-start'
3
+ @offsetOptions={{hash mainAxis=3}} as |velcro|
4
+ >
5
+ <AuPill
6
+ @icon='pencil'
7
+ @iconAlignment='right'
8
+ class='variable'
9
+ {{velcro.hook}}
10
+ {{on 'click' this.selectThisNode}}
11
+ >
12
+ {{#if this.formattedNumber}}
13
+ {{this.formattedNumber}}
14
+ {{else}}
15
+ <span class='mark-highlight-manual'>
16
+ {{t 'variable.number.placeholder'}}
17
+ </span>
18
+ {{/if}}
19
+ {{#if @node.attrs.label}}
20
+ <span class='label'>
21
+ ({{@node.attrs.label}})
22
+ </span>
23
+ {{/if}}
24
+ </AuPill>
25
+ {{#if this.selected}}
26
+ <div class='say-tooltip say-number-tooltip' {{velcro.loop}}>
27
+ {{! AuCard gives weird behaviour when using velcro without div (cause is position:fixed in css)}}
28
+ <AuCard
29
+ @shadow={{true}}
30
+ @size='small'
31
+ id='number-input-tooltip'
32
+ @standOut={{true}} as |card|
33
+ >
34
+ <card.content>
35
+ {{!-- template-lint-disable no-down-event-binding --}}
36
+ <AuInput
37
+ @value={{this.inputNumber}}
38
+ placeholder={{t 'variable.number.type-number'}}
39
+ {{did-insert this.focus}}
40
+ {{on 'input' this.onInputNumberChange}}
41
+ {{on 'keyup' this.leaveOnEnter}}
42
+ {{on 'keyup' this.leaveWithArrows}}
43
+ {{on 'keydown' this.setPosBeforeKeypress}}
44
+ />
45
+ {{#if this.errorMessage}}
46
+ <AuHelpText @small={{true}} @error={{true}}>
47
+ {{this.errorMessage}}
48
+ </AuHelpText>
49
+ {{/if}}
50
+ </card.content>
51
+ </AuCard>
52
+ </div>
53
+ {{/if}}
54
+ </Velcro>
@@ -0,0 +1,159 @@
1
+ import Component from '@glimmer/component';
2
+ import {
3
+ DecorationSource,
4
+ NodeSelection,
5
+ PNode,
6
+ SayController,
7
+ SayView,
8
+ TextSelection,
9
+ } from '@lblod/ember-rdfa-editor';
10
+ import { action } from '@ember/object';
11
+ import { tracked } from '@glimmer/tracking';
12
+ import { service } from '@ember/service';
13
+ import intlService from 'ember-intl/services/intl';
14
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
15
+ // @ts-ignore
16
+ import { localCopy } from 'tracked-toolbox';
17
+ import {
18
+ MAXIMUM_VALUE_PNODE_KEY,
19
+ MINIMUM_VALUE_PNODE_KEY,
20
+ } from '@lblod/ember-rdfa-editor-lblod-plugins/plugins/variable-plugin/utils/constants';
21
+ import { isBlank } from '@ember/utils';
22
+
23
+ type Args = {
24
+ getPos: () => number | undefined;
25
+ node: PNode;
26
+ updateAttribute: (attr: string, value: unknown) => void;
27
+ controller: SayController;
28
+ view: SayView;
29
+ selected: boolean;
30
+ contentDecorations?: DecorationSource;
31
+ };
32
+ export default class VariableNumberPluginNumberComponent extends Component<Args> {
33
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-call
34
+ @localCopy('args.node.attrs.value', '') declare inputNumber: string;
35
+ @tracked errorMessage = '';
36
+ @service declare intl: intlService;
37
+ cursorPositionKeyDown: number | null = null;
38
+
39
+ focus(element: HTMLInputElement) {
40
+ element.focus();
41
+ }
42
+
43
+ get node() {
44
+ return this.args.node;
45
+ }
46
+ get formattedNumber() {
47
+ return this.node.attrs.value as string;
48
+ }
49
+
50
+ get selected() {
51
+ return this.args.selected;
52
+ }
53
+
54
+ get minValue() {
55
+ return this.node.attrs[MINIMUM_VALUE_PNODE_KEY] as number;
56
+ }
57
+
58
+ get maxValue() {
59
+ return this.node.attrs[MAXIMUM_VALUE_PNODE_KEY] as number;
60
+ }
61
+
62
+ @action onInputNumberChange(event: InputEvent) {
63
+ this.inputNumber = (event.target as HTMLInputElement).value;
64
+ this.validateAndSave();
65
+ }
66
+
67
+ validateAndSave() {
68
+ if (isBlank(this.inputNumber)) {
69
+ this.errorMessage = '';
70
+ this.args.updateAttribute('value', '');
71
+ return;
72
+ }
73
+
74
+ const number = Number(this.inputNumber);
75
+ if (Number.isNaN(number)) {
76
+ this.errorMessage = this.intl.t('variable.number.error-not-number');
77
+ return;
78
+ }
79
+ const validMinimum = !this.minValue || number >= this.minValue;
80
+ const validMaximum = !this.maxValue || number <= this.maxValue;
81
+
82
+ if (!validMinimum || !validMaximum) {
83
+ if (this.minValue && this.maxValue) {
84
+ this.errorMessage = this.intl.t(
85
+ 'variable.number.error-number-between',
86
+ { minValue: this.minValue, maxValue: this.maxValue }
87
+ );
88
+ } else if (this.minValue) {
89
+ this.errorMessage = this.intl.t('variable.number.error-number-above', {
90
+ minValue: this.minValue,
91
+ });
92
+ } else if (this.maxValue) {
93
+ this.errorMessage = this.intl.t('variable.number.error-number-below', {
94
+ maxValue: this.maxValue,
95
+ });
96
+ }
97
+ return;
98
+ }
99
+
100
+ this.errorMessage = '';
101
+ this.args.updateAttribute('value', this.inputNumber);
102
+ }
103
+
104
+ @action
105
+ selectThisNode() {
106
+ const tr = this.args.controller.activeEditorState.tr;
107
+ tr.setSelection(
108
+ NodeSelection.create(
109
+ this.args.controller.activeEditorState.doc,
110
+ this.args.getPos() as number
111
+ )
112
+ );
113
+ this.args.controller.activeEditorView.dispatch(tr);
114
+ }
115
+
116
+ @action
117
+ leaveOnEnter(event: KeyboardEvent) {
118
+ if (event.key === 'Enter') {
119
+ this.selectAfterNode();
120
+ }
121
+ }
122
+
123
+ @action setPosBeforeKeypress(event: KeyboardEvent) {
124
+ if (event.key === 'ArrowRight' || event.key === 'ArrowLeft') {
125
+ this.cursorPositionKeyDown = (
126
+ event.target as HTMLInputElement
127
+ ).selectionStart;
128
+ }
129
+ }
130
+ @action leaveWithArrows(event: KeyboardEvent) {
131
+ const finalPos = (event.target as HTMLInputElement).value.length;
132
+ if (event.key === 'ArrowRight' && this.cursorPositionKeyDown === finalPos) {
133
+ this.selectAfterNode();
134
+ }
135
+ if (event.key === 'ArrowLeft' && this.cursorPositionKeyDown === 0) {
136
+ this.selectBeforeNode();
137
+ }
138
+ this.cursorPositionKeyDown = null;
139
+ }
140
+
141
+ setSelectionAt(pos: number) {
142
+ const tr = this.args.controller.activeEditorState.tr;
143
+ tr.setSelection(
144
+ TextSelection.create(this.args.controller.activeEditorState.doc, pos)
145
+ );
146
+ this.args.controller.focus();
147
+ this.args.controller.activeEditorView.dispatch(tr);
148
+ }
149
+
150
+ selectAfterNode() {
151
+ this.setSelectionAt(
152
+ (this.args.getPos() as number) + this.args.node.nodeSize
153
+ );
154
+ }
155
+
156
+ selectBeforeNode() {
157
+ this.setSelectionAt(this.args.getPos() as number);
158
+ }
159
+ }
@@ -1,11 +1,9 @@
1
1
  import { LEGISLATION_TYPE_CONCEPTS } from './legislation-types';
2
2
  import { warn } from '@ember/debug';
3
- import { htmlSafe } from '@ember/template';
4
3
  import {
5
4
  Option,
6
5
  optionMapOr,
7
6
  } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
8
- type SafeString = ReturnType<typeof htmlSafe>;
9
7
 
10
8
  interface DecisionArgs {
11
9
  uri: string;
@@ -54,7 +52,7 @@ interface ArticleArgs {
54
52
  export class Article {
55
53
  uri: string;
56
54
  number?: number;
57
- content: SafeString | null;
55
+ content: string | null;
58
56
  dateInForce: string | null;
59
57
  dateNoLongerInForce: string | null;
60
58
 
@@ -67,7 +65,7 @@ export class Article {
67
65
  }: ArticleArgs) {
68
66
  this.uri = uri;
69
67
  this.number = number;
70
- this.content = optionMapOr(null, htmlSafe, content);
68
+ this.content = content;
71
69
  this.dateInForce = dateInForce;
72
70
  this.dateNoLongerInForce = dateNoLongerInForce;
73
71
  }
@@ -33,14 +33,14 @@ export const emberNodeConfig: (
33
33
  'data-ember-node': 'table-of-contents',
34
34
  class: 'table-of-contents',
35
35
  },
36
- ['h3', {}, 'Table Of Contents'],
36
+ ['h3', {}, 'Inhoudstafel'],
37
37
  ];
38
38
  }
39
39
 
40
40
  return [
41
41
  'div',
42
42
  { 'data-ember-node': 'table-of-contents', class: 'table-of-contents' },
43
- ['h3', {}, 'Table Of Contents'],
43
+ ['h3', {}, 'Inhoudstafel'],
44
44
  createTableOfContents(entries),
45
45
  ];
46
46
  },
@@ -15,9 +15,9 @@ import {
15
15
  MINIMUM_VALUE_HTML_ATTRIBUTE_KEY,
16
16
  MINIMUM_VALUE_PNODE_KEY,
17
17
  } from './utils/constants';
18
- import { PNode } from '@lblod/ember-rdfa-editor';
18
+ import { Attrs, DOMOutputSpec, PNode } from '@lblod/ember-rdfa-editor';
19
19
 
20
- const CONTENT_SELECTOR = `span[property~='${EXT('content').prefixed}'],
20
+ export const CONTENT_SELECTOR = `span[property~='${EXT('content').prefixed}'],
21
21
  span[property~='${EXT('content').full}']`;
22
22
 
23
23
  export const getHTMLNodeExtraAttributes = ({
@@ -58,7 +58,110 @@ export const getPNodeExtraAttributes = ({
58
58
  return {};
59
59
  };
60
60
 
61
- const emberNodeConfig: EmberNodeConfig = {
61
+ export const parseAttributes = (node: HTMLElement): false | Attrs => {
62
+ if (
63
+ hasRDFaAttribute(node, 'typeof', EXT('Mapping')) &&
64
+ node.querySelector(CONTENT_SELECTOR)
65
+ ) {
66
+ const variableInstance = [...node.children]
67
+ .find((el) => hasRDFaAttribute(el, 'property', EXT('instance')))
68
+ ?.getAttribute('resource');
69
+ const mappingResource = node.getAttribute('resource');
70
+ const codelistSpan = [...node.children].find((el) =>
71
+ hasRDFaAttribute(el, 'property', EXT('codelist'))
72
+ );
73
+ const codelistResource =
74
+ codelistSpan?.getAttribute('resource') ??
75
+ codelistSpan?.getAttribute('content');
76
+ const source = [...node.children]
77
+ .find((el) => hasRDFaAttribute(el, 'property', DCT('source')))
78
+ ?.getAttribute('resource');
79
+ const type = [...node.children]
80
+ .find((el) => hasRDFaAttribute(el, 'property', DCT('type')))
81
+ ?.getAttribute('content');
82
+ const label = node.getAttribute('data-label') || type;
83
+ const datatype = [...node.children]
84
+ .find((el) => hasRDFaAttribute(el, 'property', EXT('content')))
85
+ ?.getAttribute('datatype');
86
+ if (!mappingResource || !type) {
87
+ return false;
88
+ }
89
+ return {
90
+ variableInstance:
91
+ variableInstance ?? `http://data.lblod.info/variables/${uuidv4()}`,
92
+ mappingResource,
93
+ codelistResource,
94
+ source,
95
+ type,
96
+ datatype,
97
+ label,
98
+ ...getHTMLNodeExtraAttributes({ type, node }),
99
+ };
100
+ }
101
+
102
+ return false;
103
+ };
104
+
105
+ export const attributesToDOM = (node: PNode, content = null): DOMOutputSpec => {
106
+ const {
107
+ mappingResource,
108
+ codelistResource,
109
+ variableInstance,
110
+ type,
111
+ datatype,
112
+ source,
113
+ label,
114
+ } = node.attrs;
115
+
116
+ const sourceSpan = source
117
+ ? [
118
+ [
119
+ 'span',
120
+ {
121
+ property: DCT('source').prefixed,
122
+ resource: source as string,
123
+ },
124
+ ],
125
+ ]
126
+ : [];
127
+ const codelistResourceSpan = codelistResource
128
+ ? [
129
+ [
130
+ 'span',
131
+ {
132
+ property: EXT('codelist').prefixed, //becomes EXT('instance')
133
+ resource: codelistResource as string,
134
+ },
135
+ ],
136
+ ]
137
+ : [];
138
+ return [
139
+ 'span',
140
+ {
141
+ resource: mappingResource as string,
142
+ typeof: EXT('Mapping').prefixed,
143
+ 'data-label': label as string,
144
+ ...getPNodeExtraAttributes({ node, type: type as string }),
145
+ },
146
+ [
147
+ 'span',
148
+ { property: EXT('instance'), resource: variableInstance as string },
149
+ ],
150
+ ['span', { property: DCT('type').prefixed, content: type as string }],
151
+ ...sourceSpan,
152
+ ...codelistResourceSpan,
153
+ [
154
+ 'span',
155
+ {
156
+ property: EXT('content').prefixed,
157
+ ...(!!datatype && { datatype: datatype as string }),
158
+ },
159
+ content ? content : 0,
160
+ ],
161
+ ];
162
+ };
163
+
164
+ export const emberNodeConfig: EmberNodeConfig = {
62
165
  name: 'variable',
63
166
  componentPath: 'variable-plugin/variable',
64
167
  inline: true,
@@ -95,109 +198,18 @@ const emberNodeConfig: EmberNodeConfig = {
95
198
  },
96
199
  },
97
200
  toDOM: (node) => {
98
- const {
99
- mappingResource,
100
- codelistResource,
101
- variableInstance,
102
- type,
103
- datatype,
104
- source,
105
- label,
106
- } = node.attrs;
107
-
108
- const sourceSpan = source
109
- ? [
110
- [
111
- 'span',
112
- {
113
- property: DCT('source').prefixed,
114
- resource: source as string,
115
- },
116
- ],
117
- ]
118
- : [];
119
- const codelistResourceSpan = codelistResource
120
- ? [
121
- [
122
- 'span',
123
- {
124
- property: EXT('codelist').prefixed, //becomes EXT('instance')
125
- resource: codelistResource as string,
126
- },
127
- ],
128
- ]
129
- : [];
130
- return [
131
- 'span',
132
- {
133
- resource: mappingResource as string,
134
- typeof: EXT('Mapping').prefixed,
135
- 'data-label': label as string,
136
- ...getPNodeExtraAttributes({ node, type: type as string }),
137
- },
138
- [
139
- 'span',
140
- { property: EXT('instance'), resource: variableInstance as string },
141
- ],
142
- ['span', { property: DCT('type').prefixed, content: type as string }],
143
- ...sourceSpan,
144
- ...codelistResourceSpan,
145
- [
146
- 'span',
147
- {
148
- property: EXT('content').prefixed,
149
- ...(!!datatype && { datatype: datatype as string }),
150
- },
151
- 0,
152
- ],
153
- ];
201
+ return attributesToDOM(node);
154
202
  },
155
203
  parseDOM: [
156
204
  {
157
205
  tag: 'span',
158
206
  getAttrs: (node: HTMLElement) => {
159
- if (
160
- hasRDFaAttribute(node, 'typeof', EXT('Mapping')) &&
161
- node.querySelector(CONTENT_SELECTOR)
162
- ) {
163
- const variableInstance = [...node.children]
164
- .find((el) => hasRDFaAttribute(el, 'property', EXT('instance')))
165
- ?.getAttribute('resource');
166
- const mappingResource = node.getAttribute('resource');
167
- const codelistSpan = [...node.children].find((el) =>
168
- hasRDFaAttribute(el, 'property', EXT('codelist'))
169
- );
170
- const codelistResource =
171
- codelistSpan?.getAttribute('resource') ??
172
- codelistSpan?.getAttribute('content');
173
- const source = [...node.children]
174
- .find((el) => hasRDFaAttribute(el, 'property', DCT('source')))
175
- ?.getAttribute('resource');
176
- const type = [...node.children]
177
- .find((el) => hasRDFaAttribute(el, 'property', DCT('type')))
178
- ?.getAttribute('content');
179
- const label = node.getAttribute('data-label') || type;
180
- const datatype = [...node.children]
181
- .find((el) => hasRDFaAttribute(el, 'property', EXT('content')))
182
- ?.getAttribute('datatype');
183
- if (!mappingResource || !type) {
184
- return false;
185
- }
186
- return {
187
- variableInstance:
188
- variableInstance ??
189
- `http://data.lblod.info/variables/${uuidv4()}`,
190
- mappingResource,
191
- codelistResource,
192
- source,
193
- type,
194
- datatype,
195
- label,
196
- ...getHTMLNodeExtraAttributes({ type, node }),
197
- };
207
+ const attr = parseAttributes(node);
208
+ if (attr && attr.type !== 'number') {
209
+ return attr;
210
+ } else {
211
+ return false;
198
212
  }
199
-
200
- return false;
201
213
  },
202
214
  contentElement: CONTENT_SELECTOR,
203
215
  },
@@ -0,0 +1,50 @@
1
+ import {
2
+ createEmberNodeSpec,
3
+ createEmberNodeView,
4
+ EmberNodeConfig,
5
+ } from '@lblod/ember-rdfa-editor/utils/ember-node';
6
+ import {
7
+ attributesToDOM,
8
+ emberNodeConfig as baseVariableConfig,
9
+ CONTENT_SELECTOR,
10
+ parseAttributes,
11
+ } from './nodes';
12
+ import { PNode } from '@lblod/ember-rdfa-editor';
13
+ import { hasRDFaAttribute } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/namespace';
14
+ import { EXT } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/constants';
15
+
16
+ const emberNodeConfig = (): EmberNodeConfig => {
17
+ const { attrs, ...baseConfig } = baseVariableConfig;
18
+ return {
19
+ ...baseConfig,
20
+ attrs: { ...attrs, value: { default: null } },
21
+ componentPath: 'variable-number/number',
22
+ leafText: (node: PNode) => {
23
+ const { value } = node.attrs;
24
+ return value as string;
25
+ },
26
+ parseDOM: [
27
+ {
28
+ tag: 'span',
29
+ getAttrs: (node: HTMLElement) => {
30
+ const attrs = parseAttributes(node);
31
+ if (attrs && attrs.type === 'number') {
32
+ const content = [...node.children].find((el) =>
33
+ hasRDFaAttribute(el, 'property', EXT('content'))
34
+ )?.innerHTML;
35
+ return { ...attrs, value: content };
36
+ } else {
37
+ return false;
38
+ }
39
+ },
40
+ contentElement: CONTENT_SELECTOR,
41
+ },
42
+ ],
43
+ toDOM: (node) => {
44
+ return attributesToDOM(node, node.attrs.value);
45
+ },
46
+ };
47
+ };
48
+
49
+ export const number = createEmberNodeSpec(emberNodeConfig());
50
+ export const numberView = createEmberNodeView(emberNodeConfig());
@@ -42,17 +42,15 @@ export const DEFAULT_VARIABLE_TYPES: Record<string, VariableType> = {
42
42
  const mappingURI = `http://data.lblod.info/mappings/${uuidv4()}`;
43
43
  const variableInstance = `http://data.lblod.info/variables/${uuidv4()}`;
44
44
 
45
- return schema.node(
46
- 'variable',
47
- {
45
+ return unwrap(
46
+ schema.nodes.number.createAndFill({
48
47
  mappingResource: mappingURI,
49
48
  variableInstance,
50
49
  type: 'number',
51
50
  datatype: XSD('integer').prefixed,
52
51
  label,
53
52
  ...attributes,
54
- },
55
- schema.node('placeholder', { placeholderText: 'number' })
53
+ })
56
54
  );
57
55
  },
58
56
  },
@@ -0,0 +1 @@
1
+ export { default } from '@lblod/ember-rdfa-editor-lblod-plugins/components/variable-number/number';
@@ -99,3 +99,17 @@
99
99
  width: 100%;
100
100
  }
101
101
  }
102
+
103
+ // show tooltips above everything else
104
+ .say-tooltip {
105
+ z-index: 3;
106
+ }
107
+
108
+ .say-number-tooltip {
109
+ width: 140px;
110
+
111
+ // AuInput @type='number' overrides width to be 100px, we have to override it again
112
+ input[type='number'] {
113
+ width: 100%;
114
+ }
115
+ }
@@ -0,0 +1,34 @@
1
+ import Component from '@glimmer/component';
2
+ import { DecorationSource, PNode, SayController, SayView } from '@lblod/ember-rdfa-editor';
3
+ import intlService from 'ember-intl/services/intl';
4
+ type Args = {
5
+ getPos: () => number | undefined;
6
+ node: PNode;
7
+ updateAttribute: (attr: string, value: unknown) => void;
8
+ controller: SayController;
9
+ view: SayView;
10
+ selected: boolean;
11
+ contentDecorations?: DecorationSource;
12
+ };
13
+ export default class VariableNumberPluginNumberComponent extends Component<Args> {
14
+ inputNumber: string;
15
+ errorMessage: string;
16
+ intl: intlService;
17
+ cursorPositionKeyDown: number | null;
18
+ focus(element: HTMLInputElement): void;
19
+ get node(): PNode;
20
+ get formattedNumber(): string;
21
+ get selected(): boolean;
22
+ get minValue(): number;
23
+ get maxValue(): number;
24
+ onInputNumberChange(event: InputEvent): void;
25
+ validateAndSave(): void;
26
+ selectThisNode(): void;
27
+ leaveOnEnter(event: KeyboardEvent): void;
28
+ setPosBeforeKeypress(event: KeyboardEvent): void;
29
+ leaveWithArrows(event: KeyboardEvent): void;
30
+ setSelectionAt(pos: number): void;
31
+ selectAfterNode(): void;
32
+ selectBeforeNode(): void;
33
+ }
34
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lblod/ember-rdfa-editor-lblod-plugins",
3
- "version": "8.0.1",
3
+ "version": "8.1.0",
4
4
  "description": "Ember addon providing lblod specific plugins for the ember-rdfa-editor",
5
5
  "keywords": [
6
6
  "ember-addon",
@@ -137,12 +137,12 @@
137
137
  "loader.js": "^4.7.0",
138
138
  "npm-run-all": "^4.1.5",
139
139
  "prettier": "^2.7.1",
140
- "prosemirror-dev-tools": "^3.1.0",
140
+ "prosemirror-dev-tools": "^4.0.0",
141
141
  "qunit": "^2.19.2",
142
142
  "qunit-dom": "^2.0.0",
143
143
  "release-it": "^15.5.0",
144
144
  "sass": "^1.49.7",
145
- "typescript": "^4.9.3",
145
+ "typescript": "~5.0.4",
146
146
  "webpack": "^5.74.0"
147
147
  },
148
148
  "peerDependencies": {
@@ -150,6 +150,11 @@
150
150
  "@lblod/ember-rdfa-editor": "^3.8.0",
151
151
  "ember-concurrency": "^2.3.7"
152
152
  },
153
+ "overrides": {
154
+ "ember-intl": {
155
+ "typescript": "^5.0.4"
156
+ }
157
+ },
153
158
  "engines": {
154
159
  "node": ">= 18"
155
160
  },
@@ -1,6 +1,4 @@
1
- import { htmlSafe } from '@ember/template';
2
1
  import { Option } from '@lblod/ember-rdfa-editor-lblod-plugins/utils/option';
3
- type SafeString = ReturnType<typeof htmlSafe>;
4
2
  interface DecisionArgs {
5
3
  uri: string;
6
4
  legislationTypeUri: Option<string>;
@@ -30,7 +28,7 @@ interface ArticleArgs {
30
28
  export declare class Article {
31
29
  uri: string;
32
30
  number?: number;
33
- content: SafeString | null;
31
+ content: string | null;
34
32
  dateInForce: string | null;
35
33
  dateNoLongerInForce: string | null;
36
34
  constructor({ uri, number, content, dateInForce, dateNoLongerInForce, }: ArticleArgs);
@@ -1,4 +1,6 @@
1
- import { PNode } from '@lblod/ember-rdfa-editor';
1
+ import { EmberNodeConfig } from '@lblod/ember-rdfa-editor/utils/ember-node';
2
+ import { Attrs, DOMOutputSpec, PNode } from '@lblod/ember-rdfa-editor';
3
+ export declare const CONTENT_SELECTOR: string;
2
4
  export declare const getHTMLNodeExtraAttributes: ({ node, type, }: {
3
5
  node: HTMLElement;
4
6
  type: string;
@@ -19,5 +21,8 @@ export declare const getPNodeExtraAttributes: ({ node, type, }: {
19
21
  "data-minimum-value"?: undefined;
20
22
  "data-maximum-value"?: undefined;
21
23
  };
24
+ export declare const parseAttributes: (node: HTMLElement) => false | Attrs;
25
+ export declare const attributesToDOM: (node: PNode, content?: null) => DOMOutputSpec;
26
+ export declare const emberNodeConfig: EmberNodeConfig;
22
27
  export declare const variable: import("prosemirror-model").NodeSpec;
23
28
  export declare const variableView: (controller: import("@lblod/ember-rdfa-editor").SayController) => import("prosemirror-view").NodeViewConstructor;
@@ -0,0 +1,2 @@
1
+ export declare const number: import("prosemirror-model").NodeSpec;
2
+ export declare const numberView: (controller: import("@lblod/ember-rdfa-editor").SayController) => import("prosemirror-view").NodeViewConstructor;
@@ -179,6 +179,15 @@ date-plugin:
179
179
  required: 'This field cannot be empty'
180
180
  fractions: 'Fractions of a second, such as S or T, are not supported.'
181
181
  unknown: 'Invalid format'
182
+ variable:
183
+ number:
184
+ placeholder: number
185
+ type-number: Type a number...
186
+ error-not-integer: Enkel gehele getallen zijn toegelaten
187
+ error-not-number: Enkel getallen zijn toegelaten
188
+ error-number-between: Het getal moet tussen {minValue} en {maxValue} liggen
189
+ error-number-above: Het getal moet groter dan {minValue} zijn
190
+ error-number-below: Het getal moet kleiner dan {maxValue} zijn
182
191
  variable-plugin:
183
192
  insert-variable: Insert variable
184
193
  button: Insert
@@ -94,7 +94,7 @@ citaten-plugin:
94
94
  details: Details
95
95
  refer-whole: Verwijs naar volledig document
96
96
  refer-article: Verwijs naar artikel
97
- lookup-codex: Bekijk in Vlaams Codex
97
+ lookup-codex: Bekijk in Vlaamse Codex
98
98
  alert:
99
99
  loading: Laden…
100
100
  no-results: Geen resultaten gevonden
@@ -191,7 +191,15 @@ table-of-contents-plugin:
191
191
  title: Inhoudstafel
192
192
  toggle: Toon Inhoudstafel
193
193
 
194
-
194
+ variable:
195
+ number:
196
+ placeholder: nummer
197
+ type-number: typ een nummer...
198
+ error-not-integer: Only integers are allowed
199
+ error-not-number: Only numbers are allowed
200
+ error-number-between: The number should be between {minValue} and {maxValue}
201
+ error-number-above: The number should be bigger than {minValue}
202
+ error-number-below: The number should be smaller than {maxValue}
195
203
  variable-plugin:
196
204
  insert-variable: Voeg variabele in
197
205
  button: Voeg in
@@ -223,4 +231,4 @@ generic-rdfa-variable:
223
231
  insert: RDFA invoegen
224
232
  modal:
225
233
  insert: Invoegen
226
- cancel: Terug
234
+ cancel: Terug
@@ -1,22 +0,0 @@
1
- pipeline:
2
- install:
3
- image: danlynn/ember-cli:4.8.0
4
- commands:
5
- - npm ci
6
- release:
7
- image: plugins/npm
8
- settings:
9
- token:
10
- from_secret: npm_access_token
11
- push-tagged-build:
12
- image: plugins/docker
13
- settings:
14
- repo: lblod/ember-rdfa-editor-lblod-plugins
15
- tags: "${CI_COMMIT_TAG##v}"
16
- purge: true
17
- secrets: [ docker_username, docker_password ]
18
- # Pipeline level conditions aren't supported yet:
19
- # https://github.com/woodpecker-ci/woodpecker/issues/283
20
- when:
21
- event: tag
22
- tag: v*