adb-shared 6.2.23 → 6.2.26

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.
@@ -1874,10 +1874,13 @@ class AdbRichEditorComponent {
1874
1874
  hasTaxon = false;
1875
1875
  hasReference = false;
1876
1876
  rows = 3;
1877
+ label = 'Set label';
1878
+ id;
1877
1879
  constructor(el) {
1878
1880
  this.el = el;
1879
1881
  }
1880
1882
  getTextarea() {
1883
+ this.id = this.getId();
1881
1884
  return this.el.nativeElement.querySelector('textarea');
1882
1885
  }
1883
1886
  onDoubleClick() {
@@ -1912,8 +1915,10 @@ class AdbRichEditorComponent {
1912
1915
  value.slice(start);
1913
1916
  this.updateValue(newValue);
1914
1917
  const cursor = start + marker.length;
1915
- textarea.focus();
1916
- textarea.setSelectionRange(cursor, cursor);
1918
+ requestAnimationFrame(() => {
1919
+ textarea.focus();
1920
+ textarea.setSelectionRange(cursorStart, cursorEnd);
1921
+ });
1917
1922
  return;
1918
1923
  }
1919
1924
  const existingMarker = this.findWrappingMarker(value, start, end, FORMAT_MARKERS[type]);
@@ -1934,8 +1939,10 @@ class AdbRichEditorComponent {
1934
1939
  const cursorEnd = existingMarker
1935
1940
  ? end - marker.length
1936
1941
  : end + marker.length;
1937
- textarea.focus();
1938
- textarea.setSelectionRange(cursorStart, cursorEnd);
1942
+ requestAnimationFrame(() => {
1943
+ textarea.focus();
1944
+ textarea.setSelectionRange(cursorStart, cursorEnd);
1945
+ });
1939
1946
  }
1940
1947
  findWrappingMarker(value, start, end, markers) {
1941
1948
  return (markers.find(marker => value.substring(start - marker.length, start) === marker &&
@@ -1998,15 +2005,18 @@ class AdbRichEditorComponent {
1998
2005
  this.text = value;
1999
2006
  this.onChange(this.text);
2000
2007
  }
2008
+ getId() {
2009
+ return '' + Math.floor(Math.random() * Date.now());
2010
+ }
2001
2011
  ngOnDestroy() { }
2002
2012
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AdbRichEditorComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
2003
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: AdbRichEditorComponent, isStandalone: false, selector: "adb-rich-editor", inputs: { hasTaxon: "hasTaxon", hasReference: "hasReference", rows: "rows" }, providers: [
2013
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: AdbRichEditorComponent, isStandalone: false, selector: "adb-rich-editor", inputs: { hasTaxon: "hasTaxon", hasReference: "hasReference", rows: "rows", label: "label" }, providers: [
2004
2014
  {
2005
2015
  provide: NG_VALUE_ACCESSOR,
2006
2016
  useExisting: forwardRef(() => AdbRichEditorComponent),
2007
2017
  multi: true
2008
2018
  }
2009
- ], ngImport: i0, template: "<div>\r\n <div class=\"d-flex justify-content-end gap-3 mb-1\">\r\n <button class=\"btn btn-secondary\" (click)=\"onItalicClick()\" title=\"Italic\" aria-label=\"Italic\" type=\"button\"><span class=\"fas fa-italic\"></span></button>\r\n <button class=\"btn btn-secondary\" (click)=\"onBoldClick()\" title=\"Italic\" aria-label=\"strong\" type=\"button\"><span class=\"fas fa-bold\"></span></button>\r\n @if (hasTaxon) {\r\n <button class=\"btn btn-secondary\" (click)=\"onTaxonClick()\" title=\"Taxon\" aria-label=\"Taxon\" type=\"button\"><span class=\"fas fa-bug\"></span></button>\r\n }\r\n @if (hasReference) {\r\n <button class=\"btn btn-secondary\" (click)=\"onReferenceClick()\" title=\"Reference\" aria-label=\"Reference\" type=\"button\"><span class=\"fas fa-asterisk\"></span></button>\r\n }\r\n </div>\r\n <textarea class=\"form-control\" [(ngModel)]=\"text\" (ngModelChange)=\"onTextChange()\" [rows]=\"rows\" (dblclick)=\"onDoubleClick()\"></textarea>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
2019
+ ], ngImport: i0, template: "<div>\r\n <div class=\"d-flex justify-content-end align-items-end gap-3 mb-1\">\r\n <label class=\"me-auto\" [for]=\"id\">{{label|translate}}</label>\r\n <button class=\"btn btn-sm btn-secondary\" (click)=\"onItalicClick()\" title=\"Italic\" aria-label=\"Italic\" type=\"button\"><span class=\"fas fa-italic\"></span></button>\r\n <button class=\"btn btn-sm btn-secondary\" (click)=\"onBoldClick()\" title=\"Italic\" aria-label=\"strong\" type=\"button\"><span class=\"fas fa-bold\"></span></button>\r\n @if (hasTaxon) {\r\n <button class=\"btn btn-sm btn-secondary\" (click)=\"onTaxonClick()\" title=\"Taxon\" aria-label=\"Taxon\" type=\"button\"><span class=\"fas fa-bug\"></span></button>\r\n }\r\n @if (hasReference) {\r\n <button class=\"btn btn-sm btn-secondary\" (click)=\"onReferenceClick()\" title=\"Reference\" aria-label=\"Reference\" type=\"button\"><span class=\"fas fa-asterisk\"></span></button>\r\n }\r\n </div>\r\n <textarea [id]=\"id\" class=\"form-control\" [(ngModel)]=\"text\" (ngModelChange)=\"onTextChange()\" [rows]=\"rows\" (dblclick)=\"onDoubleClick()\"></textarea>\r\n</div>\r\n", dependencies: [{ kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "pipe", type: i1$1.TranslatePipe, name: "translate" }] });
2010
2020
  }
2011
2021
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AdbRichEditorComponent, decorators: [{
2012
2022
  type: Component,
@@ -2016,13 +2026,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImpor
2016
2026
  useExisting: forwardRef(() => AdbRichEditorComponent),
2017
2027
  multi: true
2018
2028
  }
2019
- ], standalone: false, template: "<div>\r\n <div class=\"d-flex justify-content-end gap-3 mb-1\">\r\n <button class=\"btn btn-secondary\" (click)=\"onItalicClick()\" title=\"Italic\" aria-label=\"Italic\" type=\"button\"><span class=\"fas fa-italic\"></span></button>\r\n <button class=\"btn btn-secondary\" (click)=\"onBoldClick()\" title=\"Italic\" aria-label=\"strong\" type=\"button\"><span class=\"fas fa-bold\"></span></button>\r\n @if (hasTaxon) {\r\n <button class=\"btn btn-secondary\" (click)=\"onTaxonClick()\" title=\"Taxon\" aria-label=\"Taxon\" type=\"button\"><span class=\"fas fa-bug\"></span></button>\r\n }\r\n @if (hasReference) {\r\n <button class=\"btn btn-secondary\" (click)=\"onReferenceClick()\" title=\"Reference\" aria-label=\"Reference\" type=\"button\"><span class=\"fas fa-asterisk\"></span></button>\r\n }\r\n </div>\r\n <textarea class=\"form-control\" [(ngModel)]=\"text\" (ngModelChange)=\"onTextChange()\" [rows]=\"rows\" (dblclick)=\"onDoubleClick()\"></textarea>\r\n</div>\r\n" }]
2029
+ ], standalone: false, template: "<div>\r\n <div class=\"d-flex justify-content-end align-items-end gap-3 mb-1\">\r\n <label class=\"me-auto\" [for]=\"id\">{{label|translate}}</label>\r\n <button class=\"btn btn-sm btn-secondary\" (click)=\"onItalicClick()\" title=\"Italic\" aria-label=\"Italic\" type=\"button\"><span class=\"fas fa-italic\"></span></button>\r\n <button class=\"btn btn-sm btn-secondary\" (click)=\"onBoldClick()\" title=\"Italic\" aria-label=\"strong\" type=\"button\"><span class=\"fas fa-bold\"></span></button>\r\n @if (hasTaxon) {\r\n <button class=\"btn btn-sm btn-secondary\" (click)=\"onTaxonClick()\" title=\"Taxon\" aria-label=\"Taxon\" type=\"button\"><span class=\"fas fa-bug\"></span></button>\r\n }\r\n @if (hasReference) {\r\n <button class=\"btn btn-sm btn-secondary\" (click)=\"onReferenceClick()\" title=\"Reference\" aria-label=\"Reference\" type=\"button\"><span class=\"fas fa-asterisk\"></span></button>\r\n }\r\n </div>\r\n <textarea [id]=\"id\" class=\"form-control\" [(ngModel)]=\"text\" (ngModelChange)=\"onTextChange()\" [rows]=\"rows\" (dblclick)=\"onDoubleClick()\"></textarea>\r\n</div>\r\n" }]
2020
2030
  }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { hasTaxon: [{
2021
2031
  type: Input
2022
2032
  }], hasReference: [{
2023
2033
  type: Input
2024
2034
  }], rows: [{
2025
2035
  type: Input
2036
+ }], label: [{
2037
+ type: Input
2026
2038
  }] } });
2027
2039
 
2028
2040
  const RICH_MODULE_CONFIG = new InjectionToken('richModule.config');
@@ -2041,76 +2053,78 @@ class RichTextComponent {
2041
2053
  }
2042
2054
  parseCustomMarkdown(input) {
2043
2055
  const parts = [];
2044
- const boldRegex = /(\*\*|__)(.+?)\1/g;
2045
- const italicRegex = /(\*|_)([^*_]+?)\1/g;
2046
- const taxonRegex = /\[([^\]]+)\]\(taxon:([^)]+)\)/g;
2047
- const termRegex = /\[([^\]]+)\]\(term:([^)]+)\)/g;
2048
- const referenceRegex = /\[([^\]]+)\]\(reference:([^)]+)\)/g;
2049
- const combinedRegex = new RegExp([
2050
- boldRegex.source,
2051
- italicRegex.source,
2052
- taxonRegex.source,
2053
- termRegex.source,
2054
- referenceRegex.source
2055
- ].join('|'), 'g');
2056
- let lastIndex = 0;
2057
- let match;
2058
- while ((match = combinedRegex.exec(input)) !== null) {
2059
- if (match.index > lastIndex) {
2060
- parts.push({
2061
- type: 'text',
2062
- content: input.slice(lastIndex, match.index)
2063
- });
2056
+ let i = 0;
2057
+ const pushText = (text) => {
2058
+ if (text) {
2059
+ parts.push({ type: 'text', content: text });
2064
2060
  }
2065
- if (match[2]) {
2066
- parts.push({
2067
- type: 'bold',
2068
- content: match[2]
2069
- });
2061
+ };
2062
+ while (i < input.length) {
2063
+ if (input.startsWith('**', i) || input.startsWith('__', i)) {
2064
+ const marker = input.substr(i, 2);
2065
+ const end = input.indexOf(marker, i + 2);
2066
+ if (end !== -1) {
2067
+ parts.push({
2068
+ type: 'bold',
2069
+ content: input.slice(i + 2, end)
2070
+ });
2071
+ i = end + 2;
2072
+ continue;
2073
+ }
2070
2074
  }
2071
- else if (match[4]) {
2072
- parts.push({
2073
- type: 'italic',
2074
- content: match[4]
2075
- });
2075
+ if (input[i] === '*' || input[i] === '_') {
2076
+ const marker = input[i];
2077
+ const end = input.indexOf(marker, i + 1);
2078
+ if (end !== -1) {
2079
+ parts.push({
2080
+ type: 'italic',
2081
+ content: input.slice(i + 1, end)
2082
+ });
2083
+ i = end + 1;
2084
+ continue;
2085
+ }
2076
2086
  }
2077
- else if (match[5]) {
2078
- parts.push({
2079
- type: 'taxon',
2080
- content: match[5],
2081
- id: match[6]
2082
- });
2087
+ if (input[i] === '[') {
2088
+ const textEnd = input.indexOf(']', i);
2089
+ const linkStart = input.indexOf('(', textEnd);
2090
+ const linkEnd = input.indexOf(')', linkStart);
2091
+ if (textEnd !== -1 && linkStart !== -1 && linkEnd !== -1) {
2092
+ const label = input.slice(i + 1, textEnd);
2093
+ const link = input.slice(linkStart + 1, linkEnd);
2094
+ const [type, id] = link.split(':');
2095
+ if (type === 'taxon' || type === 'term' || type === 'reference') {
2096
+ parts.push({
2097
+ type: type,
2098
+ content: label,
2099
+ id
2100
+ });
2101
+ i = linkEnd + 1;
2102
+ continue;
2103
+ }
2104
+ }
2083
2105
  }
2084
- else if (match[7]) {
2085
- parts.push({
2086
- type: 'term',
2087
- content: match[7],
2088
- id: match[8]
2089
- });
2106
+ let next = input.length;
2107
+ for (const c of ['*', '_', '[']) {
2108
+ const idx = input.indexOf(c, i + 1);
2109
+ if (idx !== -1 && idx < next) {
2110
+ next = idx;
2111
+ }
2090
2112
  }
2091
- else if (match[9]) {
2092
- parts.push({
2093
- type: 'reference',
2094
- content: match[9],
2095
- id: match[10]
2096
- });
2113
+ if (next === input.length) {
2114
+ pushText(input.slice(i));
2115
+ break;
2097
2116
  }
2098
- lastIndex = combinedRegex.lastIndex;
2099
- }
2100
- if (lastIndex < input.length) {
2101
- parts.push({
2102
- type: 'text',
2103
- content: input.slice(lastIndex)
2104
- });
2117
+ pushText(input.slice(i, next));
2118
+ i = next;
2105
2119
  }
2106
2120
  return parts;
2107
2121
  }
2108
2122
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: RichTextComponent, deps: [{ token: RICH_MODULE_CONFIG }], target: i0.ɵɵFactoryTarget.Component });
2109
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: RichTextComponent, isStandalone: false, selector: "adb-rich-text", inputs: { text: "text" }, usesOnChanges: true, ngImport: i0, template: "<div style=\"white-space: pre-wrap;\">\r\n @for (part of parts; track part) {\r\n @if (part.type === 'text') {\r\n <span>{{ part.content }}</span>\r\n }\r\n @if (part.type === 'italic') {\r\n <em>{{ part.content }}</em>\r\n }\r\n @if (part.type === 'bold') {\r\n <b>{{ part.content }}</b>\r\n }\r\n @if (part.type === 'taxon') {\r\n <a [href]=\"taxonUrl + part.id\">{{ part.content }}</a>\r\n }\r\n @if (part.type === 'term') {\r\n <span>{{ part.content }}</span>\r\n }\r\n @if (part.type === 'reference') {\r\n <span>{{ part.content }}</span>\r\n }\r\n }\r\n</div>\r\n" });
2123
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.0", type: RichTextComponent, isStandalone: false, selector: "adb-rich-text", inputs: { text: "text" }, usesOnChanges: true, ngImport: i0, template: "<div style=\"white-space: pre-wrap;\">\r\n @for (part of parts; track $index) {\r\n @switch (part.type) {\r\n @case ('text') { <span>{{ part.content }}</span> }\r\n @case ('italic') { <em>{{ part.content }}</em> }\r\n @case ('bold') { <b>{{ part.content }}</b> }\r\n @case ('taxon') { <a [href]=\"taxonUrl + part.id\">{{ part.content }}</a> }\r\n @default { <span>{{ part.content }}</span> }\r\n }\r\n}\r\n</div>" });
2110
2124
  }
2111
2125
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: RichTextComponent, decorators: [{
2112
2126
  type: Component,
2113
- args: [{ selector: 'adb-rich-text', standalone: false, template: "<div style=\"white-space: pre-wrap;\">\r\n @for (part of parts; track part) {\r\n @if (part.type === 'text') {\r\n <span>{{ part.content }}</span>\r\n }\r\n @if (part.type === 'italic') {\r\n <em>{{ part.content }}</em>\r\n }\r\n @if (part.type === 'bold') {\r\n <b>{{ part.content }}</b>\r\n }\r\n @if (part.type === 'taxon') {\r\n <a [href]=\"taxonUrl + part.id\">{{ part.content }}</a>\r\n }\r\n @if (part.type === 'term') {\r\n <span>{{ part.content }}</span>\r\n }\r\n @if (part.type === 'reference') {\r\n <span>{{ part.content }}</span>\r\n }\r\n }\r\n</div>\r\n" }]
2127
+ args: [{ selector: 'adb-rich-text', standalone: false, template: "<div style=\"white-space: pre-wrap;\">\r\n @for (part of parts; track $index) {\r\n @switch (part.type) {\r\n @case ('text') { <span>{{ part.content }}</span> }\r\n @case ('italic') { <em>{{ part.content }}</em> }\r\n @case ('bold') { <b>{{ part.content }}</b> }\r\n @case ('taxon') { <a [href]=\"taxonUrl + part.id\">{{ part.content }}</a> }\r\n @default { <span>{{ part.content }}</span> }\r\n }\r\n}\r\n</div>" }]
2114
2128
  }], ctorParameters: () => [{ type: undefined, decorators: [{
2115
2129
  type: Inject,
2116
2130
  args: [RICH_MODULE_CONFIG]
@@ -2128,13 +2142,13 @@ class AdbRichEditorModule {
2128
2142
  };
2129
2143
  }
2130
2144
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AdbRichEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2131
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: AdbRichEditorModule, declarations: [AdbRichEditorComponent, RichTextComponent], imports: [CommonModule, FormsModule], exports: [AdbRichEditorComponent, RichTextComponent] });
2132
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AdbRichEditorModule, imports: [CommonModule, FormsModule] });
2145
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.0", ngImport: i0, type: AdbRichEditorModule, declarations: [AdbRichEditorComponent, RichTextComponent], imports: [CommonModule, FormsModule, i1$1.TranslateModule], exports: [AdbRichEditorComponent, RichTextComponent] });
2146
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AdbRichEditorModule, imports: [CommonModule, FormsModule, TranslateModule.forChild()] });
2133
2147
  }
2134
2148
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.0", ngImport: i0, type: AdbRichEditorModule, decorators: [{
2135
2149
  type: NgModule,
2136
2150
  args: [{
2137
- imports: [CommonModule, FormsModule],
2151
+ imports: [CommonModule, FormsModule, TranslateModule.forChild()],
2138
2152
  declarations: [AdbRichEditorComponent, RichTextComponent],
2139
2153
  exports: [AdbRichEditorComponent, RichTextComponent]
2140
2154
  }]