qms-angular 1.0.39 → 1.0.40

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.
Files changed (71) hide show
  1. package/bundles/qms-angular.umd.js +2845 -253
  2. package/bundles/qms-angular.umd.js.map +1 -1
  3. package/esm2015/lib/model/en.js +14 -1
  4. package/esm2015/lib/model/no.js +18 -5
  5. package/esm2015/lib/qms-ckeditor-components/common/constants/ckeditorEvent.constant.js +3 -1
  6. package/esm2015/lib/qms-ckeditor-components/common/constants/iconSvg.constants.js +8 -0
  7. package/esm2015/lib/qms-ckeditor-components/common/enums/image-mode.enum.js +9 -0
  8. package/esm2015/lib/qms-ckeditor-components/common/enums/protocol-type.enum.js +11 -3
  9. package/esm2015/lib/qms-ckeditor-components/common/enums/target-type.enum.js +8 -1
  10. package/esm2015/lib/qms-ckeditor-components/common/functions/common.function.js +3 -1
  11. package/esm2015/lib/qms-ckeditor-components/common/models/qms-ckeditor-data.model.js +1 -1
  12. package/esm2015/lib/qms-ckeditor-components/common/models/qms-ckeditor-input.model.js +1 -9
  13. package/esm2015/lib/qms-ckeditor-components/components/qms-ckeditor-imagemap/qms-ckeditor-imagemap.component.js +524 -0
  14. package/esm2015/lib/qms-ckeditor-components/components/qms-ckeditor-imagemap/qms-ckeditor-imagemap.lib.js +1948 -0
  15. package/esm2015/lib/qms-ckeditor-components/components/qms-ckeditor-imagemap/qms-ckeditor-imagemap.validator.js +7 -0
  16. package/esm2015/lib/qms-ckeditor-components/components/qms-ckeditor-link/qms-ckeditor-link.component.js +4 -4
  17. package/esm2015/lib/qms-ckeditor-components/models/qms-ckeditor-imagemap.model.js +22 -0
  18. package/esm2015/lib/qms-ckeditor-components/qms-ckeditor.component.js +45 -12
  19. package/esm2015/lib/qms-ckeditor-components/qms-ckeditor.module.js +11 -1
  20. package/esm2015/qms-angular.js +3 -1
  21. package/fesm2015/qms-angular.js +2822 -252
  22. package/fesm2015/qms-angular.js.map +1 -1
  23. package/lib/model/en.d.ts +13 -0
  24. package/lib/model/no.d.ts +13 -0
  25. package/lib/qms-ckeditor-components/common/constants/ckeditorEvent.constant.d.ts +2 -0
  26. package/lib/qms-ckeditor-components/common/constants/iconSvg.constants.d.ts +7 -0
  27. package/lib/qms-ckeditor-components/common/enums/image-mode.enum.d.ts +7 -0
  28. package/lib/qms-ckeditor-components/common/enums/protocol-type.enum.d.ts +9 -2
  29. package/lib/qms-ckeditor-components/common/enums/target-type.enum.d.ts +6 -0
  30. package/lib/qms-ckeditor-components/common/models/qms-ckeditor-data.model.d.ts +1 -0
  31. package/lib/qms-ckeditor-components/common/models/qms-ckeditor-input.model.d.ts +7 -7
  32. package/lib/qms-ckeditor-components/components/qms-ckeditor-imagemap/qms-ckeditor-imagemap.component.d.ts +123 -0
  33. package/lib/qms-ckeditor-components/components/qms-ckeditor-imagemap/qms-ckeditor-imagemap.lib.d.ts +542 -0
  34. package/lib/qms-ckeditor-components/components/qms-ckeditor-imagemap/qms-ckeditor-imagemap.validator.d.ts +2 -0
  35. package/lib/qms-ckeditor-components/models/qms-ckeditor-imagemap.model.d.ts +20 -0
  36. package/lib/qms-ckeditor-components/qms-ckeditor.component.d.ts +5 -4
  37. package/package.json +1 -1
  38. package/qms-angular.d.ts +2 -0
  39. package/qms-angular.metadata.json +1 -1
  40. package/src/assets/qms-ckeditor-plugin/build/ckeditor.js +2 -2
  41. package/src/assets/qms-ckeditor-plugin/build/ckeditor.js.map +1 -1
  42. package/src/assets/qms-ckeditor-plugin/package-lock.json +12177 -9
  43. package/src/assets/qms-ckeditor-plugin/src/ckeditor.js +3 -2
  44. package/src/assets/qms-ckeditor-plugin/src/plugins/common/qmsCKEditorConstant.js +4 -0
  45. package/src/assets/qms-ckeditor-plugin/src/plugins/common/qmsCKEditorService.js +10 -0
  46. package/src/assets/qms-ckeditor-plugin/src/plugins/fullscreen/dist/qmsCKEditorFullscreenPlugin.dev.js +87 -0
  47. package/src/assets/qms-ckeditor-plugin/src/plugins/imagemap/converters.js +378 -0
  48. package/src/assets/qms-ckeditor-plugin/src/plugins/imagemap/imagemap.js +14 -0
  49. package/src/assets/qms-ckeditor-plugin/src/plugins/imagemap/imagemapediting.js +183 -0
  50. package/src/assets/qms-ckeditor-plugin/src/plugins/imagemap/imagemapui.js +49 -0
  51. package/src/assets/qms-ckeditor-plugin/src/plugins/imagemap/insertimagemapcommand.js +127 -0
  52. package/src/assets/qms-ckeditor-plugin/src/plugins/imagemap/resizeimagemapcommand.js +82 -0
  53. package/src/assets/qms-ckeditor-plugin/src/plugins/imagemap/utils.js +234 -0
  54. package/src/assets/qms-ckeditor-plugin/src/plugins/link/linkediting.js +1 -1
  55. package/src/assets/qms-ckeditor-plugin/src/plugins/link/linkimage.js +1 -1
  56. package/src/assets/qms-ckeditor-plugin/src/plugins/link/ui/linkactionsview.js +1 -1
  57. package/src/assets/qms-ckeditor-plugin/src/plugins/link/ui/linkformview.js +1 -1
  58. package/src/assets/qms-ckeditor-plugin/src/plugins/tooltip/inserttooltipcommand.js +1 -1
  59. package/src/assets/qms-ckeditor-plugin/src/plugins/tooltip/tooltipediting.js +1 -1
  60. package/src/assets/qms-ckeditor-plugin/src/plugins/tooltip/ui/actionsview.js +1 -1
  61. package/src/assets/qms-ckeditor-plugin/src/themes/icons/imagemap.svg +56 -0
  62. package/src/assets/qms-ckeditor-plugin/src/themes/{tyles → styles}/anchor.css +0 -0
  63. package/src/assets/qms-ckeditor-plugin/src/themes/{tyles → styles}/link.css +0 -0
  64. package/src/assets/qms-ckeditor-plugin/src/themes/{tyles → styles}/linkactions.css +0 -0
  65. package/src/assets/qms-ckeditor-plugin/src/themes/{tyles → styles}/linkform.css +0 -0
  66. package/src/assets/qms-ckeditor-plugin/src/themes/{tyles → styles}/linkimage.css +0 -0
  67. package/src/assets/qms-ckeditor-plugin/src/themes/{tyles → styles}/tooltip.css +0 -0
  68. package/src/lib/qms-ckeditor-components/components/qms-ckeditor-imagemap/qms-ckeditor-imagemap.component.scss +27 -0
  69. package/src/themes/_color.scss +8 -0
  70. package/src/themes/core/_colors.scss +2 -0
  71. package/src/themes/core/_tab.scss +50 -49
@@ -4,7 +4,7 @@ import { BehaviorSubject, Subject, forkJoin } from 'rxjs';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import { FormBuilder, NgControl, NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule, NG_VALIDATORS, FormControl, FormGroup, Validators } from '@angular/forms';
6
6
  import { MAT_FORM_FIELD_DEFAULT_OPTIONS, MatFormFieldModule } from '@angular/material/form-field';
7
- import { MAT_RADIO_DEFAULT_OPTIONS } from '@angular/material/radio';
7
+ import { MAT_RADIO_DEFAULT_OPTIONS, MatRadioModule } from '@angular/material/radio';
8
8
  import { MatDialogRef, MAT_DIALOG_DATA, MatDialog, MatDialogModule, MatDialogConfig } from '@angular/material/dialog';
9
9
  import { MatAutocompleteTrigger, MatAutocompleteModule } from '@angular/material/autocomplete';
10
10
  import { Overlay, OverlayPositionBuilder } from '@angular/cdk/overlay';
@@ -32,14 +32,15 @@ import { takeUntil, debounceTime } from 'rxjs/operators';
32
32
  import { FlatTreeControl } from '@angular/cdk/tree';
33
33
  import * as i1 from '@angular/common/http';
34
34
  import { HttpHeaders, HttpClient, HttpClientModule } from '@angular/common/http';
35
+ import { MatButtonToggleModule } from '@angular/material/button-toggle';
35
36
  import { MatSelectModule } from '@angular/material/select';
36
37
  import { MatSnackBarConfig, MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
37
38
  import { CKEditorModule as CKEditorModule$1 } from '@ckeditor/ckeditor5-angular';
38
39
  import { __awaiter } from 'tslib';
39
40
  import * as $ from 'jquery';
40
41
  import * as _ from 'lodash';
41
- import { MatBadgeModule } from '@angular/material/badge';
42
42
  import { MatTooltipModule } from '@angular/material/tooltip';
43
+ import { MatBadgeModule } from '@angular/material/badge';
43
44
  import { MatToolbarModule } from '@angular/material/toolbar';
44
45
  import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper';
45
46
  import { MatStepperModule } from '@angular/material/stepper';
@@ -104,6 +105,8 @@ const en = {
104
105
  "DOCUMENTS_IN": "Documents in"
105
106
  },
106
107
  "QMSCKEDITOR": {
108
+ "REMOVE_MAP": "Remove Map",
109
+ "IMAGE_MAP_PROPERTIES": "Image Map Properties",
107
110
  "INSERT_TOOLTIP": "Insert a tooltip",
108
111
  "CONTENT": "Content",
109
112
  "TEMPLATE": "Template",
@@ -125,6 +128,7 @@ const en = {
125
128
  "CANCEL": "Cancel",
126
129
  "LINK": "Link",
127
130
  "LINK_TYPE": "Link type",
131
+ "ZOOM": "Zoom",
128
132
  "LINK_URL": "URL",
129
133
  "LINK_ANCHOR_IN_TEXT": "Link to anchor in the text",
130
134
  "LINK_EMAIL": "Email",
@@ -162,6 +166,16 @@ const en = {
162
166
  "DOCUMENT": "Document",
163
167
  "CONFIRM": "Confirm",
164
168
  "SEARCH": "Search",
169
+ "IMAGE_MODE_POINTER": "Pointer",
170
+ "IMAGE_MODE_RECTANGLE": "Rectangle",
171
+ "IMAGE_MODE_CIRCLE": "Circle",
172
+ "IMAGE_MODE_POLYGON": "Polygon",
173
+ "IMAGE_MODE_REMOVE": "Remove",
174
+ "POLYGON_DRAW": "Use SHIFT + click for the last control point",
175
+ "RECTANGLE_DRAW": "Hold down SHIFT for square mode",
176
+ "SQUARE_DRAW": "Release SHIFT for rectangle mode",
177
+ "INVALID_URL": "Invalid URL",
178
+ "REQUIRED_URL": "URL is required"
165
179
  },
166
180
  "BPMN": {
167
181
  "DEFAULT": "Default",
@@ -348,6 +362,8 @@ const no = {
348
362
  "DOCUMENTS_IN": "Dokumenter i"
349
363
  },
350
364
  "QMSCKEDITOR": {
365
+ "REMOVE_MAP": "Fjern kartet",
366
+ "IMAGE_MAP_PROPERTIES": "Bilde Kart Egenskaper",
351
367
  "INSERT_TOOLTIP": "Sett inn et verktøytips",
352
368
  "CONTENT": "Innhold",
353
369
  "TEMPLATE": "Mal",
@@ -369,6 +385,7 @@ const no = {
369
385
  "CANCEL": "Avbryt",
370
386
  "LINK": "Link",
371
387
  "LINK_TYPE": "Koblingstype",
388
+ "ZOOM": "Zoom",
372
389
  "LINK_URL": "URL",
373
390
  "LINK_ANCHOR_IN_TEXT": "Lenke til anker i teksten",
374
391
  "LINK_EMAIL": "E-post",
@@ -379,10 +396,10 @@ const no = {
379
396
  "TARGET_SAME": "Samme vindu (selv)",
380
397
  "TARGET_PARENT": "Overordnet vindu (_parent)",
381
398
  "PROTOCOL": "Protocol",
382
- "PROTOCOL_HTTP": "http: //",
383
- "PROTOCOL_HTTPS": "https: //",
384
- "PROTOCOL_FTP": "ftp: //",
385
- "PROTOCOL_NEW": "nyheter: //",
399
+ "PROTOCOL_HTTP": "http://",
400
+ "PROTOCOL_HTTPS": "https://",
401
+ "PROTOCOL_FTP": "ftp://",
402
+ "PROTOCOL_NEW": "nyheter://",
386
403
  "PROTOCOL_OTHER": "<other>",
387
404
  "ADVISORY_TITLE": "Rådgivende tittel",
388
405
  "HANDBOOK": "eHandbook",
@@ -406,6 +423,16 @@ const no = {
406
423
  "DOCUMENT": "Dokument",
407
424
  "CONFIRM": "Bekreft",
408
425
  "SEARCH": "Søk",
426
+ "IMAGE_MODE_POINTER": "Peker",
427
+ "IMAGE_MODE_RECTANGLE": "Rektangel",
428
+ "IMAGE_MODE_CIRCLE": "Sirkel",
429
+ "IMAGE_MODE_POLYGON": "Polygon",
430
+ "IMAGE_MODE_REMOVE": "Ta bort",
431
+ "POLYGON_DRAW": "Bruk SKIFT + klikk for det siste kontrollpunktet",
432
+ "RECTANGLE_DRAW": "Hold nede SKIFT for kvadratisk modus",
433
+ "SQUARE_DRAW": "Slipp SKIFT for rektangelmodus",
434
+ "INVALID_URL": "Ugyldig URL",
435
+ "REQUIRED_URL": "URL er påkrevd"
409
436
  },
410
437
  "BPMN": {
411
438
  "DEFAULT": "Standard",
@@ -6265,10 +6292,18 @@ var ProtocolType;
6265
6292
  (function (ProtocolType) {
6266
6293
  ProtocolType[ProtocolType["http"] = 0] = "http";
6267
6294
  ProtocolType[ProtocolType["https"] = 1] = "https";
6268
- ProtocolType[ProtocolType["fpt"] = 2] = "fpt";
6269
- ProtocolType[ProtocolType["new"] = 3] = "new";
6295
+ ProtocolType[ProtocolType["ftp"] = 2] = "ftp";
6296
+ ProtocolType[ProtocolType["news"] = 3] = "news";
6270
6297
  ProtocolType[ProtocolType["other"] = 4] = "other";
6271
- })(ProtocolType || (ProtocolType = {}));
6298
+ })(ProtocolType || (ProtocolType = {}));
6299
+ var ProtocolTypeName;
6300
+ (function (ProtocolTypeName) {
6301
+ ProtocolTypeName["http"] = "http://";
6302
+ ProtocolTypeName["https"] = "https://";
6303
+ ProtocolTypeName["ftp"] = "ftp://";
6304
+ ProtocolTypeName["news"] = "news://";
6305
+ ProtocolTypeName["other"] = "";
6306
+ })(ProtocolTypeName || (ProtocolTypeName = {}));
6272
6307
 
6273
6308
  var TargetType;
6274
6309
  (function (TargetType) {
@@ -6276,7 +6311,14 @@ var TargetType;
6276
6311
  TargetType[TargetType["topmost"] = 1] = "topmost";
6277
6312
  TargetType[TargetType["same"] = 2] = "same";
6278
6313
  TargetType[TargetType["parent"] = 3] = "parent";
6279
- })(TargetType || (TargetType = {}));
6314
+ })(TargetType || (TargetType = {}));
6315
+ var TargetTypeName;
6316
+ (function (TargetTypeName) {
6317
+ TargetTypeName["new"] = "_blank";
6318
+ TargetTypeName["topmost"] = "_top";
6319
+ TargetTypeName["same"] = "_self";
6320
+ TargetTypeName["parent"] = "_parent";
6321
+ })(TargetTypeName || (TargetTypeName = {}));
6280
6322
 
6281
6323
  class QMSCKEditorRelation {
6282
6324
  constructor() {
@@ -6784,8 +6826,8 @@ class QMSCKEditorLinkComponent extends QMSCKEditorBaseComponent {
6784
6826
  if (this.protocols) {
6785
6827
  this.protocols.push({ id: ProtocolType.http, name: this.LANG.QMSCKEDITOR.PROTOCOL_HTTP });
6786
6828
  this.protocols.push({ id: ProtocolType.https, name: this.LANG.QMSCKEDITOR.PROTOCOL_HTTPS });
6787
- this.protocols.push({ id: ProtocolType.fpt, name: this.LANG.QMSCKEDITOR.PROTOCOL_FTP });
6788
- this.protocols.push({ id: ProtocolType.new, name: this.LANG.QMSCKEDITOR.PROTOCOL_NEW });
6829
+ this.protocols.push({ id: ProtocolType.ftp, name: this.LANG.QMSCKEDITOR.PROTOCOL_FTP });
6830
+ this.protocols.push({ id: ProtocolType.news, name: this.LANG.QMSCKEDITOR.PROTOCOL_NEW });
6789
6831
  this.protocols.push({ id: ProtocolType.other, name: this.LANG.QMSCKEDITOR.PROTOCOL_OTHER });
6790
6832
  }
6791
6833
  }
@@ -7003,7 +7045,7 @@ class QMSCKEditorLinkComponent extends QMSCKEditorBaseComponent {
7003
7045
  QMSCKEditorLinkComponent.decorators = [
7004
7046
  { type: Component, args: [{
7005
7047
  selector: 'qms-ckeditor-link',
7006
- template: "<div id=\"qmsckeditor_link\" class=\"qmsckeditor qmsckeditor__link__container\">\r\n <div id=\"qmsckeditor_link_header\">\r\n <span\r\n id=\"qmsckeditor_link_header_001\"\r\n mat-icon-button\r\n class=\"qmsckeditor button__close\"\r\n (click)=\"onCloseDialog()\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n <div id=\"qmsckeditor_link_header_002\" mat-dialog-content>\r\n <h2 id=\"qmsckeditor_link_header_001\">\r\n {{ LANG.QMSCKEDITOR.LINK }}\r\n </h2>\r\n </div>\r\n </div>\r\n <div id=\"qmsckeditor_link_type\" class=\"row\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-3\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.LINK_TYPE }}</mat-label>\r\n <mat-select\r\n disableOptionCentering\r\n name=\"linkTypeList\"\r\n [(ngModel)]=\"selectedLink\"\r\n (ngModelChange)=\"onSelectedLinkType()\"\r\n >\r\n <mat-option *ngFor=\"let link of linkTypes\" [value]=\"link.id\">\r\n {{ link.name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div id=\"qmsckeditor_link_content\">\r\n <form\r\n [formGroup]=\"linkFormGroup\"\r\n class=\"qmsckeditor link__content height row\"\r\n *ngIf=\"selectedLink === 0\"\r\n >\r\n <div id=\"qmsckeditor_link_url\" class=\"col-12 mt-1 pl-3 pr-3\">\r\n <mat-expansion-panel\r\n id=\"qmsckeditor_link_url_panel\"\r\n [expanded]=\"isExpanded\"\r\n (opened)=\"isExpanded = true\"\r\n (closed)=\"isExpanded = false\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n {{ LANG.QMSCKEDITOR.URL_HEADER }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div id=\"qmsckeditor_link_url_001\" class=\"row mt-2\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.TARGET }}</mat-label>\r\n <mat-select\r\n [(ngModel)]=\"selectedTarget\"\r\n formControlName=\"targetList\"\r\n disableOptionCentering\r\n >\r\n <mat-option *ngFor=\"let target of targets\" [value]=\"target.id\">\r\n {{ target.name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_url_002\" class=\"row\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-3\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.PROTOCOL }}</mat-label>\r\n <mat-select\r\n [(ngModel)]=\"selectedProtocol\"\r\n formControlName=\"protocolList\"\r\n disableOptionCentering\r\n >\r\n <mat-option\r\n *ngFor=\"let protocol of protocols\"\r\n [value]=\"protocol.id\"\r\n >\r\n {{ protocol.name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_url_003\" class=\"row\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.LINK_URL }}</mat-label>\r\n <input matInput [(ngModel)]=\"url\" formControlName=\"url\" />\r\n <mat-error\r\n *ngIf=\"linkFormGroup.get('url').hasError('required')\"\r\n class=\"mt5\"\r\n >\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_url_004\" class=\"row\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.ADVISORY_TITLE }}</mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"advisoryTitle\"\r\n formControlName=\"advisoryTitle\"\r\n />\r\n <mat-error\r\n *ngIf=\"linkFormGroup.get('advisoryTitle').hasError('required')\"\r\n class=\"mt5\"\r\n >\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n <div\r\n id=\"qmsckeditor_link_url_005\"\r\n class=\"qmsckeditor button__groups row\"\r\n >\r\n <div class=\"col-6 pl-3\">\r\n <button\r\n class=\"save\"\r\n mat-flat-button\r\n (click)=\"eHandbook(false, false)\"\r\n >\r\n {{ LANG.QMSCKEDITOR.HANDBOOK }}\r\n </button>\r\n </div>\r\n <div class=\"col-6 pr-3\">\r\n <button class=\"save\" mat-flat-button (click)=\"attachment()\">\r\n {{ LANG.QMSCKEDITOR.ATTACHMENT }}\r\n </button>\r\n </div>\r\n </div>\r\n </mat-expansion-panel>\r\n </div>\r\n </form>\r\n\r\n <form\r\n [formGroup]=\"anchorTextFormGroup\"\r\n class=\"qmsckeditor link__content height row\"\r\n *ngIf=\"selectedLink === 1\"\r\n >\r\n <div id=\"qmsckeditor_link_anchor_text\" class=\"col-12 mt-1 pl-3 pr-3\">\r\n <mat-expansion-panel\r\n id=\"qmsckeditor_link_anchor_text_panel\"\r\n [expanded]=\"isExpanded\"\r\n (opened)=\"isExpanded = true\"\r\n (closed)=\"isExpanded = false\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n {{ LANG.QMSCKEDITOR.ANCHOR_TEXT_HEADER }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div id=\"qmsckeditor_link_anchor_text_001\" class=\"row mt-2\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.ANCHOR_BY_NAME }}</mat-label>\r\n <mat-select [(ngModel)]=\"anchorText\" formControlName=\"anchorText\">\r\n <mat-option\r\n *ngFor=\"let editorAnchor of editorAnchors\"\r\n [value]=\"editorAnchor.anchorValue\"\r\n disableOptionCentering\r\n >\r\n {{ editorAnchor.viewValue }}\r\n </mat-option>\r\n </mat-select>\r\n <mat-error\r\n *ngIf=\"\r\n anchorTextFormGroup.get('anchorText').hasError('required')\r\n \"\r\n class=\"mt5\"\r\n >\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </mat-expansion-panel>\r\n </div>\r\n </form>\r\n\r\n <form\r\n [formGroup]=\"emailFormGroup\"\r\n class=\"qmsckeditor link__content height row\"\r\n *ngIf=\"selectedLink === 2\"\r\n >\r\n <div id=\"qmsckeditor_link_email\" class=\"col-12 mt-1 pl-3 pr-3\">\r\n <mat-expansion-panel\r\n id=\"qmsckeditor_link_email_panel\"\r\n [expanded]=\"isExpanded\"\r\n (opened)=\"isExpanded = true\"\r\n (closed)=\"isExpanded = false\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n {{ LANG.QMSCKEDITOR.EMAIL_HEADER }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div id=\"qmsckeditor_link_email_001\" class=\"row\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.EMAIL_ADDRESS }}</mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"emailAddress\"\r\n formControlName=\"emailAddress\"\r\n />\r\n <mat-error\r\n *ngIf=\"emailFormGroup.get('emailAddress').hasError('required')\"\r\n class=\"mt5\"\r\n >\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_email_002\" class=\"row\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.EMAIL_SUBJECT }}</mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"emailSubject\"\r\n formControlName=\"emailSubject\"\r\n />\r\n <mat-error\r\n *ngIf=\"emailFormGroup.get('emailSubject').hasError('required')\"\r\n class=\"mt5\"\r\n >\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_email_003\" class=\"row\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.EMAIL_BODY }}</mat-label>\r\n <textarea\r\n matInput\r\n [(ngModel)]=\"emailBody\"\r\n formControlName=\"emailBody\"\r\n ></textarea>\r\n <mat-error\r\n *ngIf=\"emailFormGroup.get('emailBody').hasError('required')\"\r\n class=\"mt5\"\r\n >\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </mat-expansion-panel>\r\n </div>\r\n </form>\r\n\r\n <form\r\n [formGroup]=\"anchorDocFormGroup\"\r\n class=\"qmsckeditor link__content height row\"\r\n *ngIf=\"selectedLink === 3\"\r\n >\r\n <div id=\"qmsckeditor_link_anchor_doc\" class=\"col-12 mt-1 pl-3 pr-3\">\r\n <mat-expansion-panel\r\n id=\"qmsckeditor_link_email_panel\"\r\n [expanded]=\"isExpanded\"\r\n (opened)=\"isExpanded = true\"\r\n (closed)=\"isExpanded = false\"\r\n >\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n {{ LANG.QMSCKEDITOR.EMAIL_HEADER }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div\r\n id=\"qmsckeditor_link_anchor_doc_001\"\r\n class=\"qmsckeditor button__groups row\"\r\n >\r\n <div class=\"col-6 pl-3\">\r\n <button\r\n class=\"cancel\"\r\n mat-flat-button\r\n (click)=\"eHandbook(true, true)\"\r\n >\r\n {{ LANG.QMSCKEDITOR.HANDBOOK }}\r\n </button>\r\n </div>\r\n </div>\r\n <div id=\"qmsckeditor_link_anchor_doc_002\" class=\"row mt-4\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.DOCUMENT }}</mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"anchorTitle\"\r\n formControlName=\"anchorTitle\"\r\n />\r\n <mat-error\r\n *ngIf=\"\r\n anchorDocFormGroup.get('anchorTitle').hasError('required')\r\n \"\r\n class=\"mt5\"\r\n >\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_anchor_doc_003\" class=\"row mt-2\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.ANCHOR_BY_NAME }}</mat-label>\r\n <mat-select\r\n [(ngModel)]=\"anchorByName\"\r\n formControlName=\"anchorByName\"\r\n disableOptionCentering\r\n >\r\n <mat-option\r\n *ngFor=\"let docAnchor of documentAnchors\"\r\n [value]=\"docAnchor.anchorValue\"\r\n >\r\n {{ docAnchor.viewValue }}\r\n </mat-option>\r\n </mat-select>\r\n <mat-error\r\n *ngIf=\"\r\n anchorDocFormGroup.get('anchorByName').hasError('required')\r\n \"\r\n class=\"mt5\"\r\n >\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </mat-expansion-panel>\r\n </div>\r\n </form>\r\n </div>\r\n\r\n <div id=\"qmsckeditor_link_footer\" class=\"qmsckeditor button__groups row\">\r\n <div class=\"col-12 mt-3 pl-3 pr-3\">\r\n <button\r\n class=\"save\"\r\n mat-flat-button\r\n (click)=\"setLink()\"\r\n [disabled]=\"disableOkButton()\"\r\n >\r\n {{ LANG.QMSCKEDITOR.OK }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>\r\n",
7048
+ template: "<div id=\"qmsckeditor_link\" class=\"qmsckeditor qmsckeditor__link__container\">\r\n <div id=\"qmsckeditor_link_header\">\r\n <span id=\"qmsckeditor_link_header_001\" mat-icon-button class=\"qmsckeditor button__close\" (click)=\"onCloseDialog()\">\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n <div id=\"qmsckeditor_link_header_002\" mat-dialog-content>\r\n <h2 id=\"qmsckeditor_link_header_001\">\r\n {{ LANG.QMSCKEDITOR.LINK }}\r\n </h2>\r\n </div>\r\n </div>\r\n <div id=\"qmsckeditor_link_type\" class=\"row\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-3\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.LINK_TYPE }}</mat-label>\r\n <mat-select disableOptionCentering name=\"linkTypeList\" [(ngModel)]=\"selectedLink\"\r\n (ngModelChange)=\"onSelectedLinkType()\">\r\n <mat-option *ngFor=\"let link of linkTypes\" [value]=\"link.id\">\r\n {{ link.name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n\r\n <div id=\"qmsckeditor_link_content\">\r\n <form [formGroup]=\"linkFormGroup\" class=\"qmsckeditor link__content height row\" *ngIf=\"selectedLink === 0\">\r\n <div id=\"qmsckeditor_link_url\" class=\"col-12 mt-1 pl-3 pr-3\">\r\n <mat-expansion-panel id=\"qmsckeditor_link_url_panel\" [expanded]=\"isExpanded\" (opened)=\"isExpanded = true\"\r\n (closed)=\"isExpanded = false\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n {{ LANG.QMSCKEDITOR.URL_HEADER }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div id=\"qmsckeditor_link_url_001\" class=\"row mt-2\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.TARGET }}</mat-label>\r\n <mat-select [(ngModel)]=\"selectedTarget\" formControlName=\"targetList\" disableOptionCentering>\r\n <mat-option *ngFor=\"let target of targets\" [value]=\"target.id\">\r\n {{ target.name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_url_002\" class=\"row\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-3\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.PROTOCOL }}</mat-label>\r\n <mat-select [(ngModel)]=\"selectedProtocol\" formControlName=\"protocolList\" disableOptionCentering>\r\n <mat-option *ngFor=\"let protocol of protocols\" [value]=\"protocol.id\">\r\n {{ protocol.name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_url_003\" class=\"row\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.LINK_URL }}</mat-label>\r\n <input matInput [(ngModel)]=\"url\" name=\"url\" formControlName=\"url\" />\r\n <mat-error *ngIf=\"linkFormGroup.get('url').hasError('required')\" class=\"mt5\">\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_url_004\" class=\"row\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.ADVISORY_TITLE }}</mat-label>\r\n <input matInput [(ngModel)]=\"advisoryTitle\" formControlName=\"advisoryTitle\" />\r\n <mat-error *ngIf=\"linkFormGroup.get('advisoryTitle').hasError('required')\" class=\"mt5\">\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_url_005\" class=\"qmsckeditor button__groups row\">\r\n <div class=\"col-6 pl-3\">\r\n <button class=\"save\" mat-flat-button (click)=\"eHandbook(false, false)\">\r\n {{ LANG.QMSCKEDITOR.HANDBOOK }}\r\n </button>\r\n </div>\r\n <div class=\"col-6 pr-3\">\r\n <button class=\"save\" mat-flat-button (click)=\"attachment()\">\r\n {{ LANG.QMSCKEDITOR.ATTACHMENT }}\r\n </button>\r\n </div>\r\n </div>\r\n </mat-expansion-panel>\r\n </div>\r\n </form>\r\n\r\n <form [formGroup]=\"anchorTextFormGroup\" class=\"qmsckeditor link__content height row\" *ngIf=\"selectedLink === 1\">\r\n <div id=\"qmsckeditor_link_anchor_text\" class=\"col-12 mt-1 pl-3 pr-3\">\r\n <mat-expansion-panel id=\"qmsckeditor_link_anchor_text_panel\" [expanded]=\"isExpanded\"\r\n (opened)=\"isExpanded = true\" (closed)=\"isExpanded = false\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n {{ LANG.QMSCKEDITOR.ANCHOR_TEXT_HEADER }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div id=\"qmsckeditor_link_anchor_text_001\" class=\"row mt-2\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.ANCHOR_BY_NAME }}</mat-label>\r\n <mat-select [(ngModel)]=\"anchorText\" formControlName=\"anchorText\">\r\n <mat-option *ngFor=\"let editorAnchor of editorAnchors\" [value]=\"editorAnchor.anchorValue\"\r\n disableOptionCentering>\r\n {{ editorAnchor.viewValue }}\r\n </mat-option>\r\n </mat-select>\r\n <mat-error *ngIf=\"\r\n anchorTextFormGroup.get('anchorText').hasError('required')\r\n \" class=\"mt5\">\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </mat-expansion-panel>\r\n </div>\r\n </form>\r\n\r\n <form [formGroup]=\"emailFormGroup\" class=\"qmsckeditor link__content height row\" *ngIf=\"selectedLink === 2\">\r\n <div id=\"qmsckeditor_link_email\" class=\"col-12 mt-1 pl-3 pr-3\">\r\n <mat-expansion-panel id=\"qmsckeditor_link_email_panel\" [expanded]=\"isExpanded\" (opened)=\"isExpanded = true\"\r\n (closed)=\"isExpanded = false\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n {{ LANG.QMSCKEDITOR.EMAIL_HEADER }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div id=\"qmsckeditor_link_email_001\" class=\"row\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.EMAIL_ADDRESS }}</mat-label>\r\n <input matInput [(ngModel)]=\"emailAddress\" formControlName=\"emailAddress\" />\r\n <mat-error *ngIf=\"emailFormGroup.get('emailAddress').hasError('required')\" class=\"mt5\">\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_email_002\" class=\"row\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.EMAIL_SUBJECT }}</mat-label>\r\n <input matInput [(ngModel)]=\"emailSubject\" formControlName=\"emailSubject\" />\r\n <mat-error *ngIf=\"emailFormGroup.get('emailSubject').hasError('required')\" class=\"mt5\">\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_email_003\" class=\"row\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.EMAIL_BODY }}</mat-label>\r\n <textarea matInput [(ngModel)]=\"emailBody\" formControlName=\"emailBody\"></textarea>\r\n <mat-error *ngIf=\"emailFormGroup.get('emailBody').hasError('required')\" class=\"mt5\">\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </mat-expansion-panel>\r\n </div>\r\n </form>\r\n\r\n <form [formGroup]=\"anchorDocFormGroup\" class=\"qmsckeditor link__content height row\" *ngIf=\"selectedLink === 3\">\r\n <div id=\"qmsckeditor_link_anchor_doc\" class=\"col-12 mt-1 pl-3 pr-3\">\r\n <mat-expansion-panel id=\"qmsckeditor_link_email_panel\" [expanded]=\"isExpanded\" (opened)=\"isExpanded = true\"\r\n (closed)=\"isExpanded = false\">\r\n <mat-expansion-panel-header>\r\n <mat-panel-title>\r\n {{ LANG.QMSCKEDITOR.EMAIL_HEADER }}\r\n </mat-panel-title>\r\n </mat-expansion-panel-header>\r\n <div id=\"qmsckeditor_link_anchor_doc_001\" class=\"qmsckeditor button__groups row\">\r\n <div class=\"col-6 pl-3\">\r\n <button class=\"cancel\" mat-flat-button (click)=\"eHandbook(true, true)\">\r\n {{ LANG.QMSCKEDITOR.HANDBOOK }}\r\n </button>\r\n </div>\r\n </div>\r\n <div id=\"qmsckeditor_link_anchor_doc_002\" class=\"row mt-4\">\r\n <mat-form-field class=\"col-12 pl-3 pr-3\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.DOCUMENT }}</mat-label>\r\n <input matInput [(ngModel)]=\"anchorTitle\" formControlName=\"anchorTitle\" />\r\n <mat-error *ngIf=\"\r\n anchorDocFormGroup.get('anchorTitle').hasError('required')\r\n \" class=\"mt5\">\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor_link_anchor_doc_003\" class=\"row mt-2\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.ANCHOR_BY_NAME }}</mat-label>\r\n <mat-select [(ngModel)]=\"anchorByName\" formControlName=\"anchorByName\" disableOptionCentering>\r\n <mat-option *ngFor=\"let docAnchor of documentAnchors\" [value]=\"docAnchor.anchorValue\">\r\n {{ docAnchor.viewValue }}\r\n </mat-option>\r\n </mat-select>\r\n <mat-error *ngIf=\"\r\n anchorDocFormGroup.get('anchorByName').hasError('required')\r\n \" class=\"mt5\">\r\n </mat-error>\r\n </mat-form-field>\r\n </div>\r\n </mat-expansion-panel>\r\n </div>\r\n </form>\r\n </div>\r\n\r\n <div id=\"qmsckeditor_link_footer\" class=\"qmsckeditor button__groups row\">\r\n <div class=\"col-12 mt-3 pl-3 pr-3\">\r\n <button class=\"save\" mat-flat-button (click)=\"setLink()\" [disabled]=\"disableOkButton()\">\r\n {{ LANG.QMSCKEDITOR.OK }}\r\n </button>\r\n </div>\r\n </div>\r\n</div>",
7007
7049
  styles: [".mt5{margin-top:5px!important}.mt10{margin-top:10px!important}.mt7{margin-top:7px!important}.mt15{margin-top:15px!important}.mt20{margin-top:20px!important}.mt30{margin-top:30px!important}.mt40{margin-top:40px!important}.ml2{margin-left:2px!important}.ml3{margin-left:3px!important}.ml5{margin-left:5px!important}.ml15{margin-left:15px!important}.ml10{margin-left:10px!important}.ml12{margin-left:12px!important}.ml16{margin-left:16px!important}.ml-auto{margin-left:auto!important}.ml-25{margin-left:-25px!important}.mr5{margin-right:5px!important}.mr12{margin-right:12px!important}.mr15{margin-right:15px!important}.mb5{margin-bottom:5px!important}.mb10{margin-bottom:10px!important}.mb15{margin-bottom:15px!important}.pt8{padding-top:8px!important}.pt10{padding-top:10px!important}.pt15{padding-top:15px!important}.pt16{padding-top:16px!important}.pl15{padding-left:15px!important}.pl0{padding-left:0!important}.pr0{padding-right:0!important}.pr15{padding-right:15px!important}.fs12{font-size:12px}.fs14{font-size:14px!important}.fs16{font-size:16px!important}.fs22{font-size:22px!important}.fw500{font-weight:500!important}.italic-text{font-style:italic}.display-flex{display:flex}.qmsckeditor{font-family:Roboto,Helvetica Neue,sans-serif;font-size:14px;font-weight:400}.qmsckeditor h2{font-size:20px;font-weight:400}.qmsckeditor .mat-dialog-content{padding:0}.qmsckeditor .mat-icon{color:#909497}.qmsckeditor__fullscreen{position:fixed;top:0;left:0;right:0;bottom:0;background:#fff;overflow-y:auto;max-height:100vh;overflow-x:hidden}.qmsckeditor__cursor{cursor:pointer}.qmsckeditor__notallowed{cursor:not-allowed}.qmsckeditor.button__close,.qmsckeditor.button__done{float:right;top:-24px;right:-24px;cursor:pointer}.qmsckeditor.button__done{margin-right:20px}.qmsckeditor.button__done .mat-icon{color:#28a745;font-weight:700}.qmsckeditor.button__groups button{min-height:40px;width:100%;border-radius:4px;border:1px solid #c5c5c5;font-family:Open Sans;font-weight:600;font-size:14px;letter-spacing:1px;line-height:16px}.qmsckeditor.button__groups .save{background:#f8f9f9}.qmsckeditor.button__groups .save:hover{background:#e5e7e9}.qmsckeditor.button__groups .save:disabled{cursor:not-allowed}.qmsckeditor.button__groups .cancel{background:#f8f9f9}.qmsckeditor.button__groups .cancel:hover{background:#e5e7e9}.qmsckeditor.button__groups .cancel:disabled{cursor:not-allowed}.qmsckeditor.button__groups .delete{background:#f8f9f9}.qmsckeditor.button__groups .delete:hover{background:#e5e7e9}.qmsckeditor.button__groups .delete:disabled{cursor:not-allowed}.qmsckeditor.confirm__button__groups button{min-height:36px;border-radius:4px;width:auto;border:1px solid #c5c5c5;font-family:Open Sans;font-weight:600;font-size:14px;letter-spacing:1px;line-height:16px;padding-left:15px;padding-right:15px}.qmsckeditor.confirm__button__groups .confirm{background:#f8f9f9}.qmsckeditor.confirm__button__groups .confirm:hover{background:#e5e7e9}.qmsckeditor.confirm__button__groups .cancel{background:#f8f9f9}.qmsckeditor.confirm__button__groups .cancel:hover{background:#e5e7e9}.qmsckeditor.template-content.height{min-height:420px;max-height:520px;overflow:auto}.qmsckeditor.template-content.title{margin-left:-9px}.qmsckeditor.link__content.height{min-height:400px;max-height:520px}.qmsckeditor.card{margin-bottom:10px;min-height:60px;box-shadow:none;border:1px solid #e5e5e5}.qmsckeditor.card .title{font-weight:700}.qmsckeditor.card .content{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.qmsckeditor.card .material-icons{font-size:20px}.qmsckeditor.tooltip-content.height{min-height:400px;max-height:470px;overflow:auto}.qmsckeditor.save__as__template.height{height:125px}.ck-content .page-break{width:100%}.qmsckeditor__link__container textarea.mat-input-element{min-height:130px}"]
7008
7050
  },] }
7009
7051
  ];
@@ -7476,6 +7518,8 @@ CKEditorEventConst.QMSCK_LINK_PLUGIN_MSG = 'QMSCK_LINK_PLUGIN_MSG';
7476
7518
  CKEditorEventConst.QMSCK_LINK_PLUGIN_RESP = 'QMSCK_LINK_PLUGIN_RESP';
7477
7519
  CKEditorEventConst.QMSCK_TOOLTIP_PLUGIN_MSG = 'QMSCK_TOOLTIP_PLUGIN_MSG';
7478
7520
  CKEditorEventConst.QMSCK_TOOLTIP_PLUGIN_RESP = 'QMSCK_TOOLTIP_PLUGIN_RESP';
7521
+ CKEditorEventConst.QMSCK_IMAGEMAP_PLUGIN_MSG = 'QMSCK_IMAGEMAP_PLUGIN_MSG';
7522
+ CKEditorEventConst.QMSCK_IMAGEMAP_PLUGIN_RESP = 'QMSCK_IMAGEMAP_PLUGIN_RESP';
7479
7523
  CKEditorEventConst.QMSCK_BPMN_PLUGIN_MSG = 'QMSCK_BPMN_PLUGIN_MSG';
7480
7524
  CKEditorEventConst.QMSCK_BPMN_PLUGIN_RESP = 'QMSCK_BPMN_PLUGIN_RESP';
7481
7525
  CKEditorEventConst.QMSCK_BPMN = 'bpmn';
@@ -7508,6 +7552,8 @@ function getCKEditorConfiguration(itemToolbar) {
7508
7552
  '|',
7509
7553
  'linkImage',
7510
7554
  '|',
7555
+ 'imageMap',
7556
+ '|',
7511
7557
  'qmsBpmn'
7512
7558
  ],
7513
7559
  resizeOptions: [
@@ -7750,80 +7796,6 @@ const CKEditorCommonFunctions = {
7750
7796
  getCKEditorConfiguration
7751
7797
  };
7752
7798
 
7753
- class QMSCKEditorTooltip {
7754
- constructor() {
7755
- this.text = '';
7756
- this.content = '';
7757
- }
7758
- }
7759
-
7760
- class QMSCKEditorTooltipComponent extends QMSCKEditorBaseComponent {
7761
- constructor(cdr, translate, dialogRef, data) {
7762
- super();
7763
- this.cdr = cdr;
7764
- this.translate = translate;
7765
- this.dialogRef = dialogRef;
7766
- this.data = data;
7767
- this.tooltipFormGroup = new FormGroup({
7768
- title: new FormControl('', [Validators.required]),
7769
- content: new FormControl('', [Validators.required])
7770
- });
7771
- this.tooltip = { text: data.text, content: data.content };
7772
- this.editor = data.ckEditor;
7773
- }
7774
- ngOnInit() {
7775
- this.translate.getLanguageSubject$.pipe(takeUntil(this.ngUnsubcribe)).subscribe((res) => {
7776
- if (res) {
7777
- this.LANG = this.translate.getObjectLang(res);
7778
- }
7779
- });
7780
- this.editorConfig = CKEditorCommonFunctions.getCKEditorConfiguration(',heading,|,fontsize,fontfamily,fontColor,fontBackgroundColor,|,bold,italic,underline,strikethrough,|,alignment,|,bulletedList,numberedList,|,outdent,indent,|,subscript,superscript,|,undo,redo,|,specialCharacters,blockQuote,insertTable,|,link,anchor,|,timestamp,|,removeformat');
7781
- }
7782
- ngAfterViewChecked() {
7783
- this.cdr.detectChanges();
7784
- }
7785
- onCloseDialog() {
7786
- this.dialogRef.close();
7787
- }
7788
- getOutputContent(content) {
7789
- this.tooltip.content = content;
7790
- }
7791
- onChanged({ editor }) {
7792
- this.tooltip.content = editor.getData();
7793
- }
7794
- onBlur({ editor }) {
7795
- this.tooltip.content = editor.getData();
7796
- }
7797
- onReady(editor) {
7798
- if (this.tooltip.text) {
7799
- editor.setData(this.tooltip.text);
7800
- }
7801
- editor.ui.getEditableElement().parentElement.insertBefore(editor.ui.view.toolbar.element, editor.ui.getEditableElement());
7802
- }
7803
- saveTooltip() {
7804
- const tooltip = new QMSCKEditorTooltip();
7805
- tooltip.content = this.tooltip.content;
7806
- tooltip.text = this.tooltip.text;
7807
- this.dialogRef.close(tooltip);
7808
- }
7809
- cancelTooltip() {
7810
- this.dialogRef.close();
7811
- }
7812
- }
7813
- QMSCKEditorTooltipComponent.decorators = [
7814
- { type: Component, args: [{
7815
- selector: 'app-qmsck-tooltip',
7816
- template: "<div\r\n id=\"qmsckeditor-tooltip\"\r\n class=\"qmsckeditor qmsckeditor__tooltip__container\"\r\n>\r\n <div id=\"qmsckeditor-tooltip-header\">\r\n <span\r\n id=\"qmsckeditor-tooltip-header_001\"\r\n mat-icon-button\r\n class=\"qmsckeditor button__close\"\r\n (click)=\"onCloseDialog()\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n <div id=\"qmsckeditor-tooltip-header_002\" mat-dialog-content>\r\n <h2 id=\"qmsckeditor-tooltip_002_001\">\r\n {{ LANG.QMSCKEDITOR.INSERT_TOOLTIP }}\r\n </h2>\r\n </div>\r\n </div>\r\n <form [formGroup]=\"tooltipFormGroup\">\r\n <div\r\n id=\"qmsckeditor-tooltip-content\"\r\n class=\"qmsckeditor tooltip-content height\"\r\n >\r\n <div id=\"qmsckeditor-tooltip-content_001\" class=\"col-12 mt-1 pl-2 pr-2\">\r\n <mat-expansion-panel\r\n id=\"qmsckeditor-tooltip-panel\"\r\n [expanded]=\"true\"\r\n (opened)=\"(true)\"\r\n (closed)=\"(false)\"\r\n >\r\n <div id=\"qmsckeditor-tooltip-panel_001\">\r\n <div id=\"qmsckeditor-tooltip-panel_001_001\">\r\n <mat-form-field class=\"col-12 pl-0 pr-0\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.TITLE }}</mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"tooltip.text\"\r\n formControlName=\"title\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor-tooltip-panel_001_002\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.CONTENT }}</mat-label>\r\n <div class=\"qmsckeditor_container col-12 pl-0 pr-0\">\r\n <ckeditor\r\n class=\"qms-ckeditor\"\r\n [(editor)]=\"editor\"\r\n [config]=\"editorConfig\"\r\n (ready)=\"onReady($event)\"\r\n [(ngModel)]=\"tooltip.content\"\r\n (change)=\"onChanged($event)\"\r\n (blur)=\"onBlur($event)\"\r\n formControlName=\"content\"\r\n >\r\n </ckeditor>\r\n </div>\r\n </div>\r\n <div\r\n id=\"qmsckeditor-tooltip-panel_001_003\"\r\n class=\"qmsckeditor button__groups row mr-0 ml-0 mt-4\"\r\n >\r\n <div class=\"col-6 pr-0\">\r\n <button\r\n class=\"save\"\r\n mat-flat-button\r\n (click)=\"saveTooltip()\"\r\n [disabled]=\"tooltipFormGroup.invalid\"\r\n >\r\n {{ LANG.QMSCKEDITOR.SAVE }}\r\n </button>\r\n </div>\r\n <div class=\"col-6 pl-0\">\r\n <button\r\n class=\"cancel\"\r\n mat-flat-button\r\n (click)=\"cancelTooltip()\"\r\n >\r\n {{ LANG.QMSCKEDITOR.CANCEL }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </mat-expansion-panel>\r\n </div>\r\n </div>\r\n </form>\r\n</div>\r\n",
7817
- styles: [".mt5{margin-top:5px!important}.mt10{margin-top:10px!important}.mt7{margin-top:7px!important}.mt15{margin-top:15px!important}.mt20{margin-top:20px!important}.mt30{margin-top:30px!important}.mt40{margin-top:40px!important}.ml2{margin-left:2px!important}.ml3{margin-left:3px!important}.ml5{margin-left:5px!important}.ml15{margin-left:15px!important}.ml10{margin-left:10px!important}.ml12{margin-left:12px!important}.ml16{margin-left:16px!important}.ml-auto{margin-left:auto!important}.ml-25{margin-left:-25px!important}.mr5{margin-right:5px!important}.mr12{margin-right:12px!important}.mr15{margin-right:15px!important}.mb5{margin-bottom:5px!important}.mb10{margin-bottom:10px!important}.mb15{margin-bottom:15px!important}.pt8{padding-top:8px!important}.pt10{padding-top:10px!important}.pt15{padding-top:15px!important}.pt16{padding-top:16px!important}.pl15{padding-left:15px!important}.pl0{padding-left:0!important}.pr0{padding-right:0!important}.pr15{padding-right:15px!important}.fs12{font-size:12px}.fs14{font-size:14px!important}.fs16{font-size:16px!important}.fs22{font-size:22px!important}.fw500{font-weight:500!important}.italic-text{font-style:italic}.display-flex{display:flex}.qmsckeditor{font-family:Roboto,Helvetica Neue,sans-serif;font-size:14px;font-weight:400}.qmsckeditor h2{font-size:20px;font-weight:400}.qmsckeditor .mat-dialog-content{padding:0}.qmsckeditor .mat-icon{color:#909497}.qmsckeditor__fullscreen{position:fixed;top:0;left:0;right:0;bottom:0;background:#fff;overflow-y:auto;max-height:100vh;overflow-x:hidden}.qmsckeditor__cursor{cursor:pointer}.qmsckeditor__notallowed{cursor:not-allowed}.qmsckeditor.button__close,.qmsckeditor.button__done{float:right;top:-24px;right:-24px;cursor:pointer}.qmsckeditor.button__done{margin-right:20px}.qmsckeditor.button__done .mat-icon{color:#28a745;font-weight:700}.qmsckeditor.button__groups button{min-height:40px;width:100%;border-radius:4px;border:1px solid #c5c5c5;font-family:Open Sans;font-weight:600;font-size:14px;letter-spacing:1px;line-height:16px}.qmsckeditor.button__groups .save{background:#f8f9f9}.qmsckeditor.button__groups .save:hover{background:#e5e7e9}.qmsckeditor.button__groups .save:disabled{cursor:not-allowed}.qmsckeditor.button__groups .cancel{background:#f8f9f9}.qmsckeditor.button__groups .cancel:hover{background:#e5e7e9}.qmsckeditor.button__groups .cancel:disabled{cursor:not-allowed}.qmsckeditor.button__groups .delete{background:#f8f9f9}.qmsckeditor.button__groups .delete:hover{background:#e5e7e9}.qmsckeditor.button__groups .delete:disabled{cursor:not-allowed}.qmsckeditor.confirm__button__groups button{min-height:36px;border-radius:4px;width:auto;border:1px solid #c5c5c5;font-family:Open Sans;font-weight:600;font-size:14px;letter-spacing:1px;line-height:16px;padding-left:15px;padding-right:15px}.qmsckeditor.confirm__button__groups .confirm{background:#f8f9f9}.qmsckeditor.confirm__button__groups .confirm:hover{background:#e5e7e9}.qmsckeditor.confirm__button__groups .cancel{background:#f8f9f9}.qmsckeditor.confirm__button__groups .cancel:hover{background:#e5e7e9}.qmsckeditor.template-content.height{min-height:420px;max-height:520px;overflow:auto}.qmsckeditor.template-content.title{margin-left:-9px}.qmsckeditor.link__content.height{min-height:400px;max-height:520px}.qmsckeditor.card{margin-bottom:10px;min-height:60px;box-shadow:none;border:1px solid #e5e5e5}.qmsckeditor.card .title{font-weight:700}.qmsckeditor.card .content{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.qmsckeditor.card .material-icons{font-size:20px}.qmsckeditor.tooltip-content.height{min-height:400px;max-height:470px;overflow:auto}.qmsckeditor.save__as__template.height{height:125px}.ck-content .page-break,.qmsckeditor__tooltip__container .mat-form-field{width:100%}.qmsckeditor__tooltip__container textarea.mat-input-element{min-height:150px}"]
7818
- },] }
7819
- ];
7820
- QMSCKEditorTooltipComponent.ctorParameters = () => [
7821
- { type: ChangeDetectorRef },
7822
- { type: TranslateLibraryService },
7823
- { type: MatDialogRef },
7824
- { type: QMSCKEditorTooltip, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }
7825
- ];
7826
-
7827
7799
  class FlowChartConst {
7828
7800
  }
7829
7801
  FlowChartConst.EXIST_DATA = 'IS_LINKED_DATA';
@@ -11703,165 +11675,2738 @@ QMSCKEditorBpmnComponent.propDecorators = {
11703
11675
  onMessage: [{ type: HostListener, args: ['window:message', ['$event'],] }]
11704
11676
  };
11705
11677
 
11706
- class QMSCKEditorComponent extends QMSCKEditorBaseComponent {
11707
- /**
11708
- * Constructor
11709
- */
11710
- constructor(dialog, globalService, qmsCKEditorFullscreenComponent, renderer, elRef) {
11711
- super();
11712
- this.dialog = dialog;
11713
- this.globalService = globalService;
11714
- this.qmsCKEditorFullscreenComponent = qmsCKEditorFullscreenComponent;
11715
- this.renderer = renderer;
11716
- this.elRef = elRef;
11717
- this.required = false;
11718
- this.qmsckContentOutput = new EventEmitter();
11719
- this.ckEditorEventConst = CKEditorEventConst;
11720
- }
11721
- onMessage(event) {
11722
- switch (event.data.eventName) {
11723
- case this.ckEditorEventConst.QMSCK_FULLSCREEN_PLUGIN_MSG:
11724
- this.fullscreenEventHandling();
11725
- break;
11726
- case this.ckEditorEventConst.QMSCK_TEMPLATE_PLUGIN_MSG:
11727
- this.templateEventHandling();
11728
- break;
11729
- case this.ckEditorEventConst.QMSCK_LOAD_TEMPLATE_PLUGIN_MSG:
11730
- this.loadTemplateEventHandling();
11731
- break;
11732
- case this.ckEditorEventConst.QMSCK_LINK_PLUGIN_MSG:
11733
- this.linkEventHandling(event.data.value);
11734
- break;
11735
- case this.ckEditorEventConst.QMSCK_TOOLTIP_PLUGIN_MSG:
11736
- this.tooltipEventHandling(event.data.value);
11737
- break;
11738
- case this.ckEditorEventConst.QMSCK_BPMN_PLUGIN_MSG:
11739
- this.bpmnEventHandling(event.data.value);
11740
- break;
11741
- default:
11742
- break;
11743
- }
11744
- }
11745
- ngOnInit() {
11746
- this.name = 'CKEditor custom build';
11747
- this.ckEditor = this.qmsckPlugin.pluginObject;
11748
- this.ckeditorConfig = CKEditorCommonFunctions.getCKEditorConfiguration(this.qmsckPlugin.itemToolbar);
11749
- this.globalService.setApiUrl(this.qmsckData.apiUrl);
11750
- if (this.isEnabledCustomizingMathtypeService()) {
11751
- this.customizeMathTypeService();
11752
- }
11753
- if (this.isEnabledCustomizingTimestampFormat()) {
11754
- this.customizeTimestampFormat();
11755
- }
11756
- }
11757
- registerOnChange(fn) {
11758
- this.onChange = fn;
11759
- }
11760
- registerOnTouched(fn) {
11761
- this.onTouched = fn;
11762
- }
11763
- ngAfterViewInit() {
11764
- if (this.isDisabled) {
11765
- this.renderer.addClass(this.elRef.nativeElement, 'ck-disabled');
11766
- }
11678
+ class QMSCKEditorImageMap {
11679
+ constructor() {
11680
+ this.name = '';
11681
+ this.imageUrl = '';
11682
+ this.areas = [];
11683
+ this.entityId = '';
11684
+ this.editorContent = '';
11685
+ this.imageHeight = 0;
11686
+ this.imageWidth = 0;
11687
+ this.linkJavaScriptLinksAllowed = true;
11767
11688
  }
11768
- isEnabledCustomizingTimestampFormat() {
11769
- const pattern = /(timestamp)/gmi;
11770
- return !!this.qmsckData.timestampFormat
11771
- && this.qmsckData.timestampFormat !== ''
11772
- && !!this.qmsckPlugin.itemToolbar
11773
- && this.qmsckPlugin.itemToolbar.search(pattern) > -1;
11689
+ }
11690
+ class QMSCKEditorImageArea {
11691
+ constructor() {
11692
+ this.shape = '';
11693
+ this.coords = '';
11694
+ this.alt = '';
11695
+ this.href = '';
11696
+ this.target = '';
11774
11697
  }
11775
- customizeTimestampFormat() {
11776
- const timestampConfig = {
11777
- timestampConfig: {
11778
- datetimeFormat: this.qmsckData.timestampFormat
11698
+ }
11699
+
11700
+ var ImageModeName;
11701
+ (function (ImageModeName) {
11702
+ ImageModeName["Pointer"] = "pointer";
11703
+ ImageModeName["Rectangle"] = "rect";
11704
+ ImageModeName["Circle"] = "circle";
11705
+ ImageModeName["Polygon"] = "poly";
11706
+ ImageModeName["Remove"] = "remove";
11707
+ })(ImageModeName || (ImageModeName = {}));
11708
+
11709
+ class IconSvg {
11710
+ }
11711
+ IconSvg.VECTOR_POINTER = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="#000000" d="M13.75,10.19L14.38,10.32L18.55,12.4C19.25,12.63 19.71,13.32 19.65,14.06V14.19L19.65,14.32L18.75,20.44C18.69,20.87 18.5,21.27 18.15,21.55C17.84,21.85 17.43,22 17,22H10.12C9.63,22 9.18,21.82 8.85,21.47L2.86,15.5L3.76,14.5C4,14.25 4.38,14.11 4.74,14.13H5.03L9,15V4.5A2,2 0 0,1 11,2.5A2,2 0 0,1 13,4.5V10.19H13.75Z" /></svg>`;
11712
+ IconSvg.VECTOR_RECTANGLE = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="#000000" d="M2,2H8V4H16V2H22V8H20V16H22V22H16V20H8V22H2V16H4V8H2V2M16,8V6H8V8H6V16H8V18H16V16H18V8H16M4,4V6H6V4H4M18,4V6H20V4H18M4,18V20H6V18H4M18,18V20H20V18H18Z" /></svg>`;
11713
+ IconSvg.VECTOR_CIRCLE = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="#000000" d="M9,2V4.06C6.72,4.92 4.92,6.72 4.05,9H2V15H4.06C4.92,17.28 6.72,19.09 9,19.95V22H15V19.94C17.28,19.08 19.09,17.28 19.95,15H22V9H19.94C19.08,6.72 17.28,4.92 15,4.05V2M11,4H13V6H11M9,6.25V8H15V6.25C16.18,6.86 17.14,7.82 17.75,9H16V15H17.75C17.14,16.18 16.18,17.14 15,17.75V16H9V17.75C7.82,17.14 6.86,16.18 6.25,15H8V9H6.25C6.86,7.82 7.82,6.86 9,6.25M4,11H6V13H4M18,11H20V13H18M11,18H13V20H11" /></svg>`;
11714
+ IconSvg.VECTOR_POLYGON = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="24" height="24" viewBox="0 0 24 24"><path fill="#000000" d="M2,2V8H4.28L5.57,16H4V22H10V20.06L15,20.05V22H21V16H19.17L20,9H22V3H16V6.53L14.8,8H9.59L8,5.82V2M4,4H6V6H4M18,5H20V7H18M6.31,8H7.11L9,10.59V14H15V10.91L16.57,9H18L17.16,16H15V18.06H10V16H7.6M11,10H13V12H11M6,18H8V20H6M17,18H19V20H17" /></svg>`;
11715
+ IconSvg.VECTOR_REMOVE = `<svg width="24px" height="24px" viewBox="0 0 24 24" role="img" xmlns="http://www.w3.org/2000/svg" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none" color="#000000"><path fill="#000000" d="M17,12 L7,12"/> <circle cx="12" cy="12" r="10"/> </svg>`;
11716
+
11717
+ /**
11718
+ * Image Map Editor (imgmap) - in-browser imagemap editor
11719
+ * Copyright (C) 2006 - 2008 Adam Maschek (adam.maschek @ gmail.com)
11720
+ *
11721
+ * This program is free software; you can redistribute it and/or
11722
+ * modify it under the terms of the GNU General Public License
11723
+ * as published by the Free Software Foundation; either version 2
11724
+ * of the License, or (at your option) any later version.
11725
+ *
11726
+ * This program is distributed in the hope that it will be useful,
11727
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11728
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11729
+ * GNU General Public License for more details.
11730
+ *
11731
+ * You should have received a copy of the GNU General Public License
11732
+ * along with this program; if not, write to the Free Software
11733
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
11734
+ */
11735
+ /**
11736
+ * @fileoverview
11737
+ * Online Image Map Editor - main script file.
11738
+ * This is the main script file of the Online Image Map Editor.
11739
+ *
11740
+ * @date 26-02-2007 2:24:50
11741
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
11742
+ * @copyright
11743
+ * @version 2.2
11744
+ *
11745
+ */
11746
+ /*jslint browser: true, newcap: false, white: false, onevar: false, plusplus: false, eqeqeq: false, nomen: false */
11747
+ /*global imgmapStrings:true, window:false, G_vmlCanvasManager:false */
11748
+ class QMSCKEditorImageMapLib {
11749
+ constructor(options) {
11750
+ /** Version string of imgmap */
11751
+ this.version = "2.2";
11752
+ /** Build date of imgmap */
11753
+ this.buildDate = "2009/08/12 22:18";
11754
+ /** Sequential build number of imgmap */
11755
+ this.buildNumber = "113";
11756
+ /** Status flag to indicate current drawing mode */
11757
+ this.is_drawing = 0;
11758
+ /** Array to hold language strings */
11759
+ this.strings = [];
11760
+ /** Helper array for some drawing operations */
11761
+ this.memory = [];
11762
+ /** Array to hold reference to all areas (canvases) */
11763
+ this.areas = [];
11764
+ /** Associative array to hold bound event handlers */
11765
+ this.eventHandlers = {};
11766
+ this.currentid = 0;
11767
+ this.draggedId = null;
11768
+ this.selectedId = null;
11769
+ this.nextShape = 'rect';
11770
+ /** Callback events that you can handle in your GUI. */
11771
+ this.event_types = [
11772
+ 'onAddArea',
11773
+ 'onRemoveArea',
11774
+ 'onDrawArea',
11775
+ 'onResizeArea',
11776
+ 'onMoveArea',
11777
+ 'onLoadImage',
11778
+ 'onSelectArea',
11779
+ 'onStatusMessage',
11780
+ 'onAreaChanged'
11781
+ ];
11782
+ this.isLoaded = false;
11783
+ /** holds the name of the actively edited map, use getMapName to read it */
11784
+ this.mapname = '';
11785
+ /** holds the id of the actively edited map, use getMapIdto read it */
11786
+ this.mapid = '';
11787
+ /** global scale of areas (1-normal, 2-doubled, 0.5-half, etc.) */
11788
+ this.globalscale = 1;
11789
+ /** is_drawing draw mode constant */
11790
+ this.DM_RECTANGLE_DRAW = 1;
11791
+ /** is_drawing draw mode constant */
11792
+ this.DM_RECTANGLE_MOVE = 11;
11793
+ /** is_drawing draw mode constant */
11794
+ this.DM_RECTANGLE_RESIZE_TOP = 12;
11795
+ /** is_drawing draw mode constant */
11796
+ this.DM_RECTANGLE_RESIZE_RIGHT = 13;
11797
+ /** is_drawing draw mode constant */
11798
+ this.DM_RECTANGLE_RESIZE_BOTTOM = 14;
11799
+ /** is_drawing draw mode constant */
11800
+ this.DM_RECTANGLE_RESIZE_LEFT = 15;
11801
+ /** is_drawing draw mode constant */
11802
+ this.DM_SQUARE_DRAW = 2;
11803
+ /** is_drawing draw mode constant */
11804
+ this.DM_SQUARE_MOVE = 21;
11805
+ /** is_drawing draw mode constant */
11806
+ this.DM_SQUARE_RESIZE_TOP = 22;
11807
+ /** is_drawing draw mode constant */
11808
+ this.DM_SQUARE_RESIZE_RIGHT = 23;
11809
+ /** is_drawing draw mode constant */
11810
+ this.DM_SQUARE_RESIZE_BOTTOM = 24;
11811
+ /** is_drawing draw mode constant */
11812
+ this.DM_SQUARE_RESIZE_LEFT = 25;
11813
+ /** is_drawing draw mode constant */
11814
+ this.DM_POLYGON_DRAW = 3;
11815
+ /** is_drawing draw mode constant */
11816
+ this.DM_POLYGON_LASTDRAW = 30;
11817
+ /** is_drawing draw mode constant */
11818
+ this.DM_POLYGON_MOVE = 31;
11819
+ //browser sniff
11820
+ this.isMSIE = false;
11821
+ this.isSafari = false;
11822
+ /**
11823
+ * Main setup function.
11824
+ * Can be called manually or constructor will call it.
11825
+ * @date 22-02-2007 0:15:42
11826
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
11827
+ * @param config config object
11828
+ * @return True if all went ok.
11829
+ */
11830
+ this.setup = function (options) {
11831
+ //copy non-default options parameters to this.config
11832
+ for (var i in options) {
11833
+ if (options.hasOwnProperty(i)) {
11834
+ this.config[i] = options[i];
11835
+ }
11836
+ }
11837
+ //set document event hooks
11838
+ this.addEvent(document, 'keydown', this.eventHandlers.doc_keydown = this.doc_keydown.bind(this));
11839
+ this.addEvent(document, 'keyup', this.eventHandlers.doc_keyup = this.doc_keyup.bind(this));
11840
+ this.addEvent(document, 'mousedown', this.eventHandlers.doc_mousedown = this.doc_mousedown.bind(this));
11841
+ //set imageElement element - supposedly it already exists in the DOM
11842
+ this.imageElement = options.imageElement;
11843
+ if (!this.imageElement) {
11844
+ throw 'The image element must be existed in the DOM';
11845
+ }
11846
+ if (!this.imageElement.parentElement) {
11847
+ throw 'The parent of the image element must be existed in the DOM';
11848
+ }
11849
+ this.parentImageElement = this.imageElement.parentElement;
11850
+ this.disableSelection(this.parentImageElement);
11851
+ //wipe all
11852
+ this.removeAllAreas();
11853
+ //reset scale
11854
+ this.globalscale = 1;
11855
+ //setup events
11856
+ this.addEvent(this.imageElement, "dragstart", this.eventHandlers.img_dragstart = this.img_dragstart.bind(this));
11857
+ this.addEvent(this.imageElement, 'mousedown', this.eventHandlers.img_mousedown = this.img_mousedown.bind(this));
11858
+ this.addEvent(this.imageElement, 'mouseup', this.eventHandlers.img_mouseup = this.img_mouseup.bind(this));
11859
+ this.addEvent(this.imageElement, 'mousemove', this.eventHandlers.img_mousemove = this.img_mousemove.bind(this));
11860
+ this.imageElement.style.cursor = this.config.cursor_default;
11861
+ //Load strings from a key:value object
11862
+ if (options.strings) {
11863
+ for (var key in options.strings) {
11864
+ if (options.strings.hasOwnProperty(key)) {
11865
+ this.strings[key] = options.strings[key];
11866
+ }
11867
+ }
11779
11868
  }
11780
- };
11781
- this.ckEditor.defaultConfig = Object.assign(this.ckEditor.defaultConfig || {}, timestampConfig);
11782
- }
11783
- isEnabledCustomizingMathtypeService() {
11784
- const pattern = /(MathType)|(ChemType)/gmi;
11785
- return !!this.qmsckData.mathtypeServiceUrl
11786
- && this.qmsckData.mathtypeServiceUrl !== ''
11787
- && !!this.qmsckPlugin.itemToolbar
11788
- && this.qmsckPlugin.itemToolbar.search(pattern) > -1;
11789
- }
11790
- customizeMathTypeService() {
11791
- const mathTypeConfig = {
11792
- mathTypeParameters: {
11793
- serviceProviderProperties: {
11794
- URI: this.qmsckData.mathtypeServiceUrl,
11795
- server: 'aspx'
11869
+ //validate event hooks
11870
+ var found, j, le;
11871
+ for (i in this.config.custom_callbacks) {
11872
+ if (this.config.custom_callbacks.hasOwnProperty(i)) {
11873
+ found = false;
11874
+ for (j = 0, le = this.event_types.length; j < le; j++) {
11875
+ if (i == this.event_types[j]) {
11876
+ found = true;
11877
+ break;
11878
+ }
11879
+ }
11880
+ //TODO: remove invalid callback
11881
+ if (!found) {
11882
+ this.log("Unknown custom callback: " + i, 1);
11883
+ }
11796
11884
  }
11797
11885
  }
11886
+ return true;
11798
11887
  };
11799
- this.ckEditor.defaultConfig = Object.assign(this.ckEditor.defaultConfig || {}, mathTypeConfig);
11800
- }
11801
- onChanged({ editor }) {
11802
- this.qmsckContentOutput.emit(this.qmsckContentInput);
11803
- }
11804
- onBlur({ editor }) {
11805
- this.qmsckContentOutput.emit(this.qmsckContentInput);
11806
- }
11807
- validate(c) {
11808
- if (!this.required) {
11809
- return null;
11810
- }
11811
- return (this.qmsckContentInput && !this.required) ? null : {
11812
- type: {
11813
- valid: false,
11814
- actual: c.value
11888
+ /**
11889
+ * Attach new 'evt' event handler 'callback' to 'obj'
11890
+ * @date 24-02-2007 21:16:20
11891
+ * @param obj The object on which the handler is defined.
11892
+ * @param evt The name of the event, like mousedown.
11893
+ * @param callback The callback function (named if you want it to be removed).
11894
+ */
11895
+ this.addEvent = function (obj, evt, callback) {
11896
+ if (obj.addEventListener) {
11897
+ //W3C style model
11898
+ obj.addEventListener(evt, callback, false);
11899
+ return true;
11900
+ }
11901
+ else {
11902
+ //Microsoft style registration model
11903
+ return obj.attachEvent("on" + evt, callback);
11815
11904
  }
11816
11905
  };
11817
- }
11818
- /**
11819
- * onReady
11820
- */
11821
- onReady(editor) {
11822
- this.editorInstance = editor;
11823
- if (this.qmsckContentInput) {
11824
- editor.setData(this.qmsckContentInput);
11825
- }
11826
- this.initEditor(editor);
11827
- }
11828
- initEditor(editor) {
11829
- editor.ui
11830
- .getEditableElement()
11831
- .parentElement.insertBefore(editor.ui.view.toolbar.element, editor.ui.getEditableElement());
11832
- editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
11833
- return new UploadAdapter(loader);
11834
- };
11835
- // Apped Wordcount to CKeditor
11836
- editor.plugins.get('WordCount').on('update', (evt, stats) => {
11837
- // Prints the current content statistics.
11838
- const wordsBox = document.querySelector('.wordcount-content');
11839
- wordsBox.textContent = `Words: ${stats.words} / Characters: ${stats.characters}`;
11840
- });
11841
- }
11842
- /**
11843
- * Full screen - Restore down
11844
- */
11845
- fullscreenEventHandling() {
11846
- const ck = window.document.getElementById('qmsckeditor');
11847
- if (ck) {
11848
- if (!ck.classList.contains('qmsckeditor__fullscreen')) {
11849
- this.qmsCKEditorFullscreenComponent.showFullScreen();
11906
+ /**
11907
+ * Detach 'evt' event handled by 'callback' from 'obj' object.
11908
+ * Callback must be a non anonymous function, see eventHandlers.
11909
+ * @see #eventHandlers
11910
+ * Example: myimgmap.removeEvent(myimgmap.pic, 'mousedown', myimgmap.eventHandlers.img_mousedown);
11911
+ * @date 24-11-2007 15:22:17
11912
+ * @param obj The object on which the handler is defined.
11913
+ * @param evt The name of the event, like mousedown.
11914
+ * @param callback The named callback function.
11915
+ */
11916
+ this.removeEvent = function (obj, evt, callback) {
11917
+ if (obj.removeEventListener) {
11918
+ //W3C style model
11919
+ obj.removeEventListener(evt, callback, false);
11920
+ return true;
11850
11921
  }
11851
11922
  else {
11852
- this.qmsCKEditorFullscreenComponent.hideFullScreen();
11923
+ //Microsoft style detach model
11924
+ return obj.detachEvent("on" + evt, callback);
11853
11925
  }
11854
- }
11855
- }
11856
- /**
11857
- * Add template - Load template
11858
- */
11859
- templateEventHandling() {
11860
- const data = new QMSCKEditorTemplate();
11861
- data.id = 0;
11862
- data.content = this.qmsckContentInput;
11863
- data.edit = false;
11864
- const dialogTemplate = this.dialog.open(QMSCKEditorTemplateComponent, {
11926
+ };
11927
+ /**
11928
+ * Fires custom hook onStatusMessage, passing the status string.
11929
+ * Use this to update your GUI.
11930
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
11931
+ * @date 26-07-2008 13:22:54
11932
+ * @param str The status string
11933
+ */
11934
+ this.statusMessage = function (str) {
11935
+ this.fireEvent('onStatusMessage', str);
11936
+ };
11937
+ /**
11938
+ * Adds basic logging functionality using firebug console object if available.
11939
+ * @date 20-02-2007 17:55:18
11940
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
11941
+ * @param obj The object or string you want to debug/echo.
11942
+ */
11943
+ this.log = function (obj, level) {
11944
+ };
11945
+ /**
11946
+ * Get the map name of the current imagemap.
11947
+ * If doesnt exist, nor map id, generate a new name based on timestamp.
11948
+ * The most portable solution is to use the same value for id and name.
11949
+ * This also conforms the HTML 5 specification, that says:
11950
+ * "If the id attribute is also specified, both attributes must have the same value."
11951
+ * @link http://www.w3.org/html/wg/html5/#the-map-element
11952
+ * @author adam
11953
+ * @see #getMapId
11954
+ * @return The name of the map.
11955
+ */
11956
+ this.getMapName = function () {
11957
+ if (!this.mapname) {
11958
+ if (!!this.mapid) {
11959
+ return this.mapid;
11960
+ }
11961
+ var now = new Date();
11962
+ this.mapname = 'imagemap' + now.getFullYear() + (now.getMonth() + 1) + now.getDate() + now.getHours() + now.getMinutes() + now.getSeconds();
11963
+ }
11964
+ return this.mapname;
11965
+ };
11966
+ /**
11967
+ * Get the map id of the current imagemap.
11968
+ * If doesnt exist, use map name.
11969
+ * @author adam
11970
+ * @see #getMapName
11971
+ * @return The id of the map.
11972
+ */
11973
+ this.getMapId = function () {
11974
+ if (!this.mapid) {
11975
+ this.mapid = this.getMapName();
11976
+ }
11977
+ return this.mapid;
11978
+ };
11979
+ this.getMapJson = function () {
11980
+ var mapJson = {
11981
+ name: this.getMapName(),
11982
+ id: this.getMapId(),
11983
+ areas: []
11984
+ };
11985
+ for (var i = 0; i < this.areas.length; i++) {
11986
+ const area = this.areas[i];
11987
+ if (area && area.lastInput && area.shape) {
11988
+ const areaJson = {
11989
+ coords: area.lastInput,
11990
+ shape: area.shape,
11991
+ target: area.atarget,
11992
+ alt: area.aalt,
11993
+ href: area.ahref
11994
+ };
11995
+ mapJson.areas.push(areaJson);
11996
+ }
11997
+ }
11998
+ return mapJson;
11999
+ };
12000
+ /**
12001
+ * Convert wild shape names to normal ones.
12002
+ * @date 25-12-2008 19:27:06
12003
+ * @param shape The name of the shape to convert.
12004
+ * @return The normalized shape name, rect as default.
12005
+ */
12006
+ this._normShape = function (shape) {
12007
+ if (!shape) {
12008
+ return 'rect';
12009
+ }
12010
+ shape = trim(shape).toLowerCase();
12011
+ if (shape.substring(0, 4) == 'rect') {
12012
+ return 'rect';
12013
+ }
12014
+ if (shape.substring(0, 4) == 'circ') {
12015
+ return 'circle';
12016
+ }
12017
+ if (shape.substring(0, 4) == 'poly') {
12018
+ return 'poly';
12019
+ }
12020
+ return 'rect';
12021
+ };
12022
+ /**
12023
+ * Try to normalize coordinates that came from:
12024
+ * 1. html textarea
12025
+ * 2. user input in the active area's input field
12026
+ * 3. from the html source in case of plugins or highlighter
12027
+ * Example of inputs that need to be handled:
12028
+ * 035,035 075,062
12029
+ * 150,217, 190,257, 150,297,110,257
12030
+ * @author adam
12031
+ * @param coords The coordinates in a string.
12032
+ * @param shape The shape of the object (rect, circle, poly).
12033
+ * @param flag Flags that modify the operation. (fromcircle, frompoly, fromrect, preserve)
12034
+ * @returns The normalized coordinates.
12035
+ */
12036
+ this._normCoords = function (coords, shape, flag) {
12037
+ //function level var declarations
12038
+ var i; //generic cycle counter
12039
+ var sx; //smallest x
12040
+ var sy; //smallest y
12041
+ var gx; //greatest x
12042
+ var gy; //greatest y
12043
+ var temp, le;
12044
+ coords = trim(coords);
12045
+ if (coords === '') {
12046
+ return '';
12047
+ }
12048
+ var oldcoords = coords;
12049
+ //replace some general junk
12050
+ coords = coords.replace(/(\d)([^\d\.])+(\d)/g, "$1,$3"); // Other software might create decimal points, respect them
12051
+ coords = coords.replace(/,\D+(\d)/g, ",$1"); //cut leading junk
12052
+ coords = coords.replace(/,0+(\d)/g, ",$1"); //cut leading zeros
12053
+ coords = coords.replace(/(\d)(\D)+,/g, "$1,");
12054
+ coords = coords.replace(/^\D+(\d)/g, "$1"); //cut leading junk
12055
+ coords = coords.replace(/^0+(\d)/g, "$1"); //cut leading zeros
12056
+ coords = coords.replace(/(\d)(\D)+$/g, "$1"); //cut trailing junk
12057
+ //now fix other issues
12058
+ var parts = coords.split(',');
12059
+ if (shape == 'rect') {
12060
+ if (flag == 'fromcircle') {
12061
+ var r = parts[2];
12062
+ parts[0] = parts[0] - r;
12063
+ parts[1] = parts[1] - r;
12064
+ parts[2] = parseInt(parts[0], 10) + 2 * r;
12065
+ parts[3] = parseInt(parts[1], 10) + 2 * r;
12066
+ }
12067
+ else if (flag == 'frompoly') {
12068
+ sx = parseInt(parts[0], 10);
12069
+ gx = parseInt(parts[0], 10);
12070
+ sy = parseInt(parts[1], 10);
12071
+ gy = parseInt(parts[1], 10);
12072
+ for (i = 0, le = parts.length; i < le; i++) {
12073
+ if (i % 2 === 0 && parseInt(parts[i], 10) < sx) {
12074
+ sx = parseInt(parts[i], 10);
12075
+ }
12076
+ if (i % 2 === 1 && parseInt(parts[i], 10) < sy) {
12077
+ sy = parseInt(parts[i], 10);
12078
+ }
12079
+ if (i % 2 === 0 && parseInt(parts[i], 10) > gx) {
12080
+ gx = parseInt(parts[i], 10);
12081
+ }
12082
+ if (i % 2 === 1 && parseInt(parts[i], 10) > gy) {
12083
+ gy = parseInt(parts[i], 10);
12084
+ }
12085
+ }
12086
+ parts[0] = sx;
12087
+ parts[1] = sy;
12088
+ parts[2] = gx;
12089
+ parts[3] = gy;
12090
+ }
12091
+ if (!(parseInt(parts[1], 10) >= 0)) {
12092
+ parts[1] = parts[0];
12093
+ }
12094
+ if (!(parseInt(parts[2], 10) >= 0)) {
12095
+ parts[2] = parseInt(parts[0], 10) + 10;
12096
+ }
12097
+ if (!(parseInt(parts[3], 10) >= 0)) {
12098
+ parts[3] = parseInt(parts[1], 10) + 10;
12099
+ }
12100
+ if (parseInt(parts[0], 10) > parseInt(parts[2], 10)) {
12101
+ temp = parts[0];
12102
+ parts[0] = parts[2];
12103
+ parts[2] = temp;
12104
+ }
12105
+ if (parseInt(parts[1], 10) > parseInt(parts[3], 10)) {
12106
+ temp = parts[1];
12107
+ parts[1] = parts[3];
12108
+ parts[3] = temp;
12109
+ }
12110
+ coords = parts[0] + "," + parts[1] + "," + parts[2] + "," + parts[3];
12111
+ }
12112
+ else if (shape == 'circle') {
12113
+ if (flag == 'fromrect') {
12114
+ sx = parseInt(parts[0], 10);
12115
+ gx = parseInt(parts[2], 10);
12116
+ sy = parseInt(parts[1], 10);
12117
+ gy = parseInt(parts[3], 10);
12118
+ //use smaller side
12119
+ parts[2] = (gx - sx < gy - sy) ? gx - sx : gy - sy;
12120
+ parts[2] = Math.floor(parts[2] / 2); //radius
12121
+ parts[0] = sx + parts[2];
12122
+ parts[1] = sy + parts[2];
12123
+ }
12124
+ else if (flag == 'frompoly') {
12125
+ sx = parseInt(parts[0], 10);
12126
+ gx = parseInt(parts[0], 10);
12127
+ sy = parseInt(parts[1], 10);
12128
+ gy = parseInt(parts[1], 10);
12129
+ for (i = 0, le = parts.length; i < le; i++) {
12130
+ if (i % 2 === 0 && parseInt(parts[i], 10) < sx) {
12131
+ sx = parseInt(parts[i], 10);
12132
+ }
12133
+ if (i % 2 === 1 && parseInt(parts[i], 10) < sy) {
12134
+ sy = parseInt(parts[i], 10);
12135
+ }
12136
+ if (i % 2 === 0 && parseInt(parts[i], 10) > gx) {
12137
+ gx = parseInt(parts[i], 10);
12138
+ }
12139
+ if (i % 2 === 1 && parseInt(parts[i], 10) > gy) {
12140
+ gy = parseInt(parts[i], 10);
12141
+ }
12142
+ }
12143
+ //use smaller side
12144
+ parts[2] = (gx - sx < gy - sy) ? gx - sx : gy - sy;
12145
+ parts[2] = Math.floor(parts[2] / 2); //radius
12146
+ parts[0] = sx + parts[2];
12147
+ parts[1] = sy + parts[2];
12148
+ }
12149
+ if (!(parseInt(parts[1], 10) > 0)) {
12150
+ parts[1] = parts[0];
12151
+ }
12152
+ if (!(parseInt(parts[2], 10) > 0)) {
12153
+ parts[2] = 10;
12154
+ }
12155
+ coords = parts[0] + "," + parts[1] + "," + parts[2];
12156
+ }
12157
+ else if (shape == 'poly') {
12158
+ if (flag == 'fromrect') {
12159
+ parts[4] = parts[2];
12160
+ parts[5] = parts[3];
12161
+ parts[2] = parts[0];
12162
+ parts[6] = parts[4];
12163
+ parts[7] = parts[1];
12164
+ }
12165
+ else if (flag == 'fromcircle') {
12166
+ // @ url http://www.pixelwit.com/blog/2007/06/29/basic-circle-drawing-actionscript/
12167
+ var centerX = parseInt(parts[0], 10);
12168
+ var centerY = parseInt(parts[1], 10);
12169
+ var radius = parseInt(parts[2], 10);
12170
+ var j = 0;
12171
+ parts[j++] = centerX + radius;
12172
+ parts[j++] = centerY;
12173
+ var sides = 60; //constant = sides the fake circle will have
12174
+ for (i = 0; i <= sides; i++) {
12175
+ var pointRatio = i / sides;
12176
+ var xSteps = Math.cos(pointRatio * 2 * Math.PI);
12177
+ var ySteps = Math.sin(pointRatio * 2 * Math.PI);
12178
+ var pointX = centerX + xSteps * radius;
12179
+ var pointY = centerY + ySteps * radius;
12180
+ parts[j++] = Math.round(pointX);
12181
+ parts[j++] = Math.round(pointY);
12182
+ }
12183
+ }
12184
+ coords = parts.join(',');
12185
+ }
12186
+ if (flag == 'preserve' && oldcoords != coords) {
12187
+ //return original and throw error
12188
+ //throw "invalid coords";
12189
+ return oldcoords;
12190
+ }
12191
+ return coords;
12192
+ };
12193
+ /**
12194
+ * Sets the coordinates according to the given JSON map code or DOM object.
12195
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
12196
+ * @date 2006-06-07 11:47:16
12197
+ * @param map DOM object or string of a map you want to apply.
12198
+ * @return True on success
12199
+ */
12200
+ this.setMapJson = function (map) {
12201
+ this.fireEvent('onSetMap', map);
12202
+ //remove all areas
12203
+ this.removeAllAreas();
12204
+ this.mapname = map.name;
12205
+ this.mapid = map.id;
12206
+ var shape, coords, href, alt, title, target, id;
12207
+ for (var i = 0, le = map.areas.length; i < le; i++) {
12208
+ shape = coords = href = alt = title = target = '';
12209
+ id = this.addNewArea(); //btw id == this.currentid, just this form is a bit clearer
12210
+ shape = this._normShape(map.areas[i].shape);
12211
+ this.initArea(id, shape);
12212
+ if (map.areas[i].coords) {
12213
+ //normalize coords
12214
+ coords = this._normCoords(map.areas[i].coords, shape);
12215
+ this.areas[id].lastInput = coords;
12216
+ //for area this one will be set in recalculate
12217
+ }
12218
+ href = map.areas[i].href;
12219
+ if (href) {
12220
+ this.areas[id].ahref = href;
12221
+ }
12222
+ alt = map.areas[i].alt;
12223
+ if (alt) {
12224
+ this.areas[id].aalt = alt;
12225
+ }
12226
+ target = map.areas[i].target;
12227
+ if (target) {
12228
+ target = target.toLowerCase();
12229
+ }
12230
+ this.areas[id].atarget = target;
12231
+ this._recalculate(id, coords); //contains repaint
12232
+ this.relaxArea(id);
12233
+ this.fireEvent('onAreaChanged', this.areas[id]);
12234
+ } //end for areas
12235
+ };
12236
+ /**
12237
+ * Adds a new area. It will later become a canvas.
12238
+ * GUI should use the onAddArea callback to act accordingly.
12239
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
12240
+ * @date 2006-06-06 16:49:25
12241
+ * @see #initArea
12242
+ */
12243
+ this.addNewArea = function () {
12244
+ var lastarea = this._getLastArea();
12245
+ var id = (lastarea) ? lastarea.aid + 1 : 0;
12246
+ //insert new possibly? unknown area (will be initialized at mousedown)
12247
+ var area = this.areas[id] = document.createElement('DIV');
12248
+ area.id = this.mapname + 'area' + id;
12249
+ area.aid = id;
12250
+ area.shape = "undefined";
12251
+ this.blurArea(this.currentid);
12252
+ this.currentid = id;
12253
+ return id;
12254
+ };
12255
+ /**
12256
+ * Initialize a new area.
12257
+ * Create the canvas, initialize it.
12258
+ * Reset area parameters.
12259
+ * @param id The id of the area (already existing with undefined shape)
12260
+ * @param shape The shape the area will have (rect, circle, poly)
12261
+ */
12262
+ this.initArea = function (id, shape) {
12263
+ var area = this.areas[id];
12264
+ if (!area) {
12265
+ return;
12266
+ } //if all was erased, return
12267
+ //remove preinited dummy div or already placed canvas
12268
+ if (area.parentNode) {
12269
+ area.parentNode.removeChild(area);
12270
+ }
12271
+ if (area.label) {
12272
+ area.label.parentNode.removeChild(area.label);
12273
+ }
12274
+ //create CANVAS node
12275
+ area = this.areas[id] = document.createElement('CANVAS');
12276
+ this.parentImageElement.appendChild(area);
12277
+ this.parentImageElement.style.position = 'relative';
12278
+ // if (typeof G_vmlCanvasManager != "undefined") {
12279
+ // //override CANVAS with VML object
12280
+ // area = this.areas[id] = G_vmlCanvasManager.initElement(area);
12281
+ // }
12282
+ area.id = this.mapname + 'area' + id;
12283
+ area.aid = id;
12284
+ area.shape = shape;
12285
+ area.ahref = '';
12286
+ area.atitle = '';
12287
+ area.aalt = '';
12288
+ area.atarget = '';
12289
+ area.style.position = 'absolute';
12290
+ area.style.top = this.imageElement.offsetTop + 'px';
12291
+ area.style.left = this.imageElement.offsetLeft + 'px';
12292
+ this._setopacity(area, this.config.CL_DRAW_BG, this.config.draw_opacity);
12293
+ //hook event handlers
12294
+ area.onmousedown = this.area_mousedown.bind(this);
12295
+ area.onmouseup = this.area_mouseup.bind(this);
12296
+ area.onmousemove = this.area_mousemove.bind(this);
12297
+ area.onmouseover = this.area_mouseover.bind(this);
12298
+ area.onmouseout = this.area_mouseout.bind(this);
12299
+ //initialize memory object
12300
+ this.memory[id] = {};
12301
+ this.memory[id].downx = 0;
12302
+ this.memory[id].downy = 0;
12303
+ this.memory[id].left = 0;
12304
+ this.memory[id].top = 0;
12305
+ this.memory[id].width = 0;
12306
+ this.memory[id].height = 0;
12307
+ this.memory[id].xpoints = [];
12308
+ this.memory[id].ypoints = [];
12309
+ //create label node
12310
+ area.label = document.createElement('DIV');
12311
+ this.parentImageElement.appendChild(area.label);
12312
+ area.label.className = this.config.label_class;
12313
+ this.assignCSS(area.label, this.config.label_style);
12314
+ area.label.style.position = 'absolute';
12315
+ this.fireEvent('onAddArea', id);
12316
+ };
12317
+ /**
12318
+ * Resets area border and opacity to a normal state after drawing.
12319
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
12320
+ * @date 15-02-2007 22:07:28
12321
+ * @param id The id of the area.
12322
+
12323
+ */
12324
+ this.relaxArea = function (id) {
12325
+ var area = this.areas[id];
12326
+ if (!area) {
12327
+ return;
12328
+ }
12329
+ if (id != this.currentid) {
12330
+ this._setBorder(area, 'NORM');
12331
+ this._setopacity(area, this.config.CL_NORM_BG, this.config.norm_opacity);
12332
+ }
12333
+ else
12334
+ this.highlightArea(id);
12335
+ };
12336
+ /**
12337
+ * Set border of a given area according to style flag.
12338
+ * Possible values of style: NORM, HIGHLIGHT, DRAW.
12339
+ * Non-rectangle shapes wont get a border if config.bounding_box is false.
12340
+ * @date 26-12-2008 22:34:41
12341
+ * @param id The id of the area to set the border on.
12342
+ * @param style Coloring style (NORM, HIGHLIGHT, DRAW), see relevant colors in config.
12343
+ * @since 2.1
12344
+ */
12345
+ this._setBorder = function (area, style) {
12346
+ if (area.shape == 'rect' || this.config.bounding_box) {
12347
+ area.style.borderWidth = '1px';
12348
+ area.style.borderStyle = (style == 'DRAW' ? 'dotted' : 'solid');
12349
+ area.style.borderColor = this.config['CL_' + style + '_' + (area.shape == 'rect' ? 'SHAPE' : 'BOX')];
12350
+ }
12351
+ else {
12352
+ //clear border
12353
+ area.style.border = '';
12354
+ }
12355
+ };
12356
+ /**
12357
+ * Set opacity of area to the given percentage, as well as set the background color.
12358
+ * If percentage contains a dash(-), the setting of the opacity will be gradual.
12359
+ * @param area The area object.
12360
+ * @param bgcolor New background color
12361
+ * @param pct Percentage of the opacity.
12362
+ */
12363
+ this._setopacity = function (area, bgcolor, pct) {
12364
+ if (bgcolor) {
12365
+ area.style.backgroundColor = bgcolor;
12366
+ }
12367
+ if (pct && typeof pct == 'string' && pct.match(/^\d*\-\d+$/)) {
12368
+ //gradual fade
12369
+ var parts = pct.split('-');
12370
+ if (typeof parts[0] != 'undefined') {
12371
+ //set initial opacity
12372
+ parts[0] = parseInt(parts[0], 10);
12373
+ this._setopacity(area, bgcolor, parts[0]);
12374
+ }
12375
+ if (typeof parts[1] != 'undefined') {
12376
+ parts[1] = parseInt(parts[1], 10);
12377
+ var curr = this._getopacity(area);
12378
+ var _this = this;
12379
+ var diff = Math.round(parts[1] - curr);
12380
+ if (diff > 5) {
12381
+ window.setTimeout(function () { _this._setopacity(area, null, '-' + parts[1]); }, 20);
12382
+ pct = 1 * curr + 5;
12383
+ }
12384
+ else if (diff < -3) {
12385
+ window.setTimeout(function () { _this._setopacity(area, null, '-' + parts[1]); }, 20);
12386
+ pct = 1 * curr - 3;
12387
+ }
12388
+ else {
12389
+ //final set
12390
+ pct = parts[1];
12391
+ }
12392
+ }
12393
+ }
12394
+ if (!isNaN(pct)) {
12395
+ pct = Math.round(parseInt(pct, 10));
12396
+ area.style.opacity = pct / 100;
12397
+ area.style.filter = 'alpha(opacity=' + pct + ')';
12398
+ }
12399
+ };
12400
+ /**
12401
+ * Get the currently set opacity of a given area.
12402
+ * @author adam
12403
+ * @param area The area (canvas) you want to get opacity info from.
12404
+ * @return Opacity value in a range of 0-100.
12405
+ */
12406
+ this._getopacity = function (area) {
12407
+ if (area.style.opacity <= 1) {
12408
+ return area.style.opacity * 100;
12409
+ }
12410
+ if (area.style.filter) {
12411
+ //alpha(opacity=NaN)
12412
+ return parseInt(area.style.filter.replace(/alpha\(opacity\=([^\)]*)\)/ig, "$1"), 10);
12413
+ }
12414
+ return 100; //default opacity
12415
+ };
12416
+ /**
12417
+ * Removes the area marked by id.
12418
+ * Callback will call the GUI code to remove GUI elements.
12419
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
12420
+ * @date 11-02-2007 20:40:58
12421
+ * @param id The id of the area to remove.
12422
+ * @see #removeAllAreas
12423
+ */
12424
+ this.removeArea = function (id) {
12425
+ if (id === null || typeof id == "undefined") {
12426
+ return;
12427
+ } //exit if no id given
12428
+ try {
12429
+ //remove area and label
12430
+ //explicitly set some values to null to avoid IE circular reference memleak
12431
+ this.areas[id].label.parentNode.removeChild(this.areas[id].label);
12432
+ this.areas[id].parentNode.removeChild(this.areas[id]);
12433
+ this.areas[id].label.className = null;
12434
+ this.areas[id].label = null;
12435
+ this.areas[id].onmouseover = null;
12436
+ this.areas[id].onmouseout = null;
12437
+ this.areas[id].onmouseup = null;
12438
+ this.areas[id].onmousedown = null;
12439
+ this.areas[id].onmousemove = null;
12440
+ }
12441
+ catch (err) {
12442
+ }
12443
+ this.areas[id] = null;
12444
+ this.fireEvent('onRemoveArea', id);
12445
+ };
12446
+ /**
12447
+ * Removes all areas.
12448
+ * Will call removeArea on all areas.
12449
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
12450
+ * @date 2006-06-07 11:55:34
12451
+ * @see #removeArea
12452
+ */
12453
+ this.removeAllAreas = function () {
12454
+ for (var i = 0, le = this.areas.length; i < le; i++) {
12455
+ if (this.areas[i]) {
12456
+ this.removeArea(i);
12457
+ }
12458
+ }
12459
+ };
12460
+ /**
12461
+ * Scales all areas.
12462
+ * Will store scale parameter in globalscale property.
12463
+ * This is needed to know how to draw new areas on an already scaled canvas.
12464
+ * @author adam
12465
+ * @date 02-11-2008 14:13:14
12466
+ * @param scale Scale factor (1-original, 0.5-half, 2-double, etc.)
12467
+ */
12468
+ this.scaleAllAreas = function (scale) {
12469
+ var rscale = scale / this.globalscale; //relative scale
12470
+ this.globalscale = scale;
12471
+ for (var i = 0, le = this.areas.length; i < le; i++) {
12472
+ if (this.areas[i] && this.areas[i].shape != 'undefined') {
12473
+ this.scaleArea(i, rscale);
12474
+ }
12475
+ }
12476
+ };
12477
+ /**
12478
+ * Scales one area.
12479
+ * @author adam
12480
+ * @date 02-11-2008 14:13:14
12481
+ * @param rscale Relative scale factor (1-keep, 0.5-half, 2-double, etc.)
12482
+ */
12483
+ this.scaleArea = function (id, rscale) {
12484
+ var area = this.areas[id];
12485
+ //set position and new dimensions
12486
+ area.style.top = parseInt(area.style.top, 10) * rscale + 'px';
12487
+ area.style.left = parseInt(area.style.left, 10) * rscale + 'px';
12488
+ this.setAreaSize(id, area.width * rscale, area.height * rscale);
12489
+ //handle polygon coordinates scaling
12490
+ if (area.shape == 'poly') {
12491
+ for (var i = 0, le = area.xpoints.length; i < le; i++) {
12492
+ area.xpoints[i] *= rscale;
12493
+ area.ypoints[i] *= rscale;
12494
+ }
12495
+ }
12496
+ this._repaint(area, this.config.CL_NORM_SHAPE);
12497
+ this._updatecoords(id);
12498
+ };
12499
+ /**
12500
+ * Put label in the top left corner according to label config.
12501
+ * By default it will contain the number of the area (area.aid)
12502
+ * @param id The id of the area to add label to.
12503
+ */
12504
+ this._putlabel = function (id) {
12505
+ var area = this.areas[id];
12506
+ if (!area.label) {
12507
+ return;
12508
+ } //not yet inited
12509
+ try {
12510
+ if (!this.config.label) {
12511
+ area.label.innerHTML = '';
12512
+ area.label.style.display = 'none';
12513
+ }
12514
+ else {
12515
+ area.label.style.display = '';
12516
+ var label = this.config.label;
12517
+ label = label.replace(/%n/g, String(id));
12518
+ label = label.replace(/%c/g, String(area.lastInput));
12519
+ label = label.replace(/%h/g, String(area.ahref));
12520
+ label = label.replace(/%a/g, String(area.aalt));
12521
+ label = label.replace(/%t/g, String(area.atitle));
12522
+ area.label.innerHTML = label;
12523
+ }
12524
+ //align to the top left corner
12525
+ area.label.style.top = area.style.top;
12526
+ area.label.style.left = area.style.left;
12527
+ }
12528
+ catch (err) {
12529
+ this.log("Error putting label", 1);
12530
+ }
12531
+ };
12532
+ /**
12533
+ * Set area title and alt (for IE) according to the hint configuration.
12534
+ * This will show up in the usual yellow box when you hover over with the mouse.
12535
+ * @param id The id of the area to set hint at.
12536
+ */
12537
+ this._puthint = function (id) {
12538
+ try {
12539
+ if (!this.config.hint) {
12540
+ this.areas[id].title = '';
12541
+ this.areas[id].alt = '';
12542
+ }
12543
+ else {
12544
+ var hint = this.config.hint;
12545
+ hint = hint.replace(/%n/g, String(id));
12546
+ hint = hint.replace(/%c/g, String(this.areas[id].lastInput));
12547
+ hint = hint.replace(/%h/g, String(this.areas[id].ahref));
12548
+ hint = hint.replace(/%a/g, String(this.areas[id].aalt));
12549
+ hint = hint.replace(/%t/g, String(this.areas[id].atitle));
12550
+ this.areas[id].title = hint;
12551
+ this.areas[id].alt = hint;
12552
+ }
12553
+ }
12554
+ catch (err) {
12555
+ this.log("Error putting hint", 1);
12556
+ }
12557
+ };
12558
+ /**
12559
+ * Will call repaint on all areas.
12560
+ * Useful when you change labeling or hint config on the GUI.
12561
+ * @see #_repaint
12562
+ */
12563
+ this._repaintAll = function () {
12564
+ for (var i = 0, le = this.areas.length; i < le; i++) {
12565
+ if (this.areas[i]) {
12566
+ this._repaint(this.areas[i], this.config.CL_NORM_SHAPE);
12567
+ }
12568
+ }
12569
+ };
12570
+ /**
12571
+ * Repaints the actual canvas content.
12572
+ * This is the only canvas drawing magic that is happening.
12573
+ * In fact rectangles will not have any canvas content, just a normal css border.
12574
+ * After repainting the canvas, it will call putlabel and puthint methods.
12575
+ * @param area The area object.
12576
+ * @param color Color of the line to draw on the canvas.
12577
+ * @param x Only used for polygons as the newest control point x.
12578
+ * @param y Only used for polygons as the newest control point y.
12579
+ */
12580
+ this._repaint = function (area, color, x, y) {
12581
+ var ctx; //canvas context
12582
+ var width, height, left, top; //canvas properties
12583
+ var i, le; //loop counter
12584
+ if (area.shape == 'circle') {
12585
+ width = parseInt(area.style.width, 10);
12586
+ var radius = Math.floor(width / 2) - 1;
12587
+ if (radius < 0)
12588
+ radius = 0;
12589
+ //get canvas context
12590
+ ctx = area.getContext("2d");
12591
+ //clear canvas
12592
+ ctx.clearRect(0, 0, width, width);
12593
+ //draw circle
12594
+ ctx.beginPath();
12595
+ ctx.strokeStyle = color;
12596
+ ctx.arc(radius, radius, radius, 0, Math.PI * 2, 0);
12597
+ ctx.stroke();
12598
+ ctx.closePath();
12599
+ //draw center
12600
+ ctx.strokeStyle = this.config.CL_KNOB;
12601
+ ctx.strokeRect(radius, radius, 1, 1);
12602
+ //put label
12603
+ this._putlabel(area.aid);
12604
+ this._puthint(area.aid);
12605
+ }
12606
+ else if (area.shape == 'rect') {
12607
+ //put label
12608
+ this._putlabel(area.aid);
12609
+ this._puthint(area.aid);
12610
+ }
12611
+ else if (area.shape == 'poly') {
12612
+ width = parseInt(area.style.width, 10);
12613
+ height = parseInt(area.style.height, 10);
12614
+ left = parseInt(area.style.left, 10);
12615
+ top = parseInt(area.style.top, 10);
12616
+ if (area.xpoints) {
12617
+ //get canvas context
12618
+ ctx = area.getContext("2d");
12619
+ //clear canvas
12620
+ ctx.clearRect(0, 0, width, height);
12621
+ //draw polygon
12622
+ ctx.beginPath();
12623
+ ctx.strokeStyle = color;
12624
+ ctx.moveTo(area.xpoints[0] - left, area.ypoints[0] - top);
12625
+ for (i = 1, le = area.xpoints.length; i < le; i++) {
12626
+ ctx.lineTo(area.xpoints[i] - left, area.ypoints[i] - top);
12627
+ }
12628
+ if (this.is_drawing == this.DM_POLYGON_DRAW || this.is_drawing == this.DM_POLYGON_LASTDRAW) {
12629
+ //only draw to the current position if not moving
12630
+ ctx.lineTo(x - left, y - top);
12631
+ }
12632
+ ctx.lineTo(area.xpoints[0] - left, area.ypoints[0] - top);
12633
+ ctx.stroke();
12634
+ ctx.closePath();
12635
+ }
12636
+ //put label
12637
+ this._putlabel(area.aid);
12638
+ this._puthint(area.aid);
12639
+ }
12640
+ };
12641
+ /**
12642
+ * Updates Area coordinates.
12643
+ * Called when needed, eg. on mousemove, mousedown.
12644
+ * Also updates html container value (thru hook).
12645
+ * Calls callback onAreaChanged so that GUI can follow.
12646
+ * This is an important hook to your GUI.
12647
+ * Uses globalscale to scale real coordinates to area coordinates.
12648
+ * @date 2006.10.24. 22:39:27
12649
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
12650
+ * @param id The id of the area.
12651
+ */
12652
+ this._updatecoords = function (id) {
12653
+ var area = this.areas[id];
12654
+ var left = Math.round(parseInt(area.style.left, 10) / this.globalscale);
12655
+ var top = Math.round(parseInt(area.style.top, 10) / this.globalscale);
12656
+ var height = Math.round(parseInt(area.style.height, 10) / this.globalscale);
12657
+ var width = Math.round(parseInt(area.style.width, 10) / this.globalscale);
12658
+ var value = '';
12659
+ if (area.shape == 'rect') {
12660
+ value = left + ',' + top + ',' + (left + width) + ',' + (top + height);
12661
+ area.lastInput = value;
12662
+ }
12663
+ else if (area.shape == 'circle') {
12664
+ var radius = Math.floor(width / 2) - 1;
12665
+ value = (left + radius) + ',' + (top + radius) + ',' + radius;
12666
+ area.lastInput = value;
12667
+ }
12668
+ else if (area.shape == 'poly') {
12669
+ if (area.xpoints) {
12670
+ for (var i = 0, le = area.xpoints.length; i < le; i++) {
12671
+ value += Math.round(area.xpoints[i] / this.globalscale) + ',' +
12672
+ Math.round(area.ypoints[i] / this.globalscale) + ',';
12673
+ }
12674
+ value = value.substring(0, value.length - 1);
12675
+ }
12676
+ area.lastInput = value;
12677
+ }
12678
+ this.fireEvent('onAreaChanged', area);
12679
+ };
12680
+ /**
12681
+ * Updates the visual representation of the area with the given id according
12682
+ * to the new coordinates that typically come from an input on the GUI.
12683
+ * Uses globalscale to scale area coordinates to real coordinates.
12684
+ * @date 2006.10.24. 22:46:55
12685
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
12686
+ * @param id The id of the area.
12687
+ * @param coords The new coords, they will be normalized.
12688
+ */
12689
+ this._recalculate = function (id, coords) {
12690
+ var area = this.areas[id];
12691
+ try {
12692
+ if (coords) {
12693
+ coords = this._normCoords(coords, area.shape, 'preserve');
12694
+ }
12695
+ else {
12696
+ coords = area.lastInput || '';
12697
+ }
12698
+ var parts = coords.split(',');
12699
+ if (area.shape == 'rect') {
12700
+ if (parts.length != 4 ||
12701
+ parseInt(parts[0], 10) > parseInt(parts[2], 10) ||
12702
+ parseInt(parts[1], 10) > parseInt(parts[3], 10)) {
12703
+ throw "invalid coords";
12704
+ }
12705
+ area.style.left = this.globalscale * (this.imageElement.offsetLeft + parseInt(parts[0], 10)) + 'px';
12706
+ area.style.top = this.globalscale * (this.imageElement.offsetTop + parseInt(parts[1], 10)) + 'px';
12707
+ this.setAreaSize(id, this.globalscale * (parts[2] - parts[0]), this.globalscale * (parts[3] - parts[1]));
12708
+ this._repaint(area, this.config.CL_NORM_SHAPE);
12709
+ }
12710
+ else if (area.shape == 'circle') {
12711
+ if (parts.length != 3 ||
12712
+ parseInt(parts[2], 10) < 0) {
12713
+ throw "invalid coords";
12714
+ }
12715
+ var width = 2 * (parts[2]);
12716
+ this.setAreaSize(id, this.globalscale * width, this.globalscale * width);
12717
+ area.style.left = this.globalscale * (this.imageElement.offsetLeft + parseInt(parts[0], 10) - width / 2) + 'px';
12718
+ area.style.top = this.globalscale * (this.imageElement.offsetTop + parseInt(parts[1], 10) - width / 2) + 'px';
12719
+ this._repaint(area, this.config.CL_NORM_SHAPE);
12720
+ }
12721
+ else if (area.shape == 'poly') {
12722
+ if (parts.length < 2) {
12723
+ throw "invalid coords";
12724
+ }
12725
+ area.xpoints = [];
12726
+ area.ypoints = [];
12727
+ for (var i = 0, le = parts.length; i < le; i += 2) {
12728
+ area.xpoints[area.xpoints.length] = this.globalscale * (this.imageElement.offsetLeft + parseInt(parts[i], 10));
12729
+ area.ypoints[area.ypoints.length] = this.globalscale * (this.imageElement.offsetTop + parseInt(parts[i + 1], 10));
12730
+ this._polygongrow(area, this.globalscale * parts[i], this.globalscale * parts[i + 1]);
12731
+ }
12732
+ this._polygonshrink(area); //includes repaint
12733
+ }
12734
+ }
12735
+ catch (err) {
12736
+ var msg = (err.message) ? err.message : 'error calculating coordinates';
12737
+ this.log(msg, 1);
12738
+ this.statusMessage(this.strings.ERR_INVALID_COORDS);
12739
+ if (area.lastInput) {
12740
+ this.fireEvent('onAreaChanged', area);
12741
+ }
12742
+ this._repaint(area, this.config.CL_NORM_SHAPE);
12743
+ return;
12744
+ }
12745
+ //on success update lastInput
12746
+ area.lastInput = coords;
12747
+ };
12748
+ /**
12749
+ * Grow polygon area to be able to contain the given new coordinates.
12750
+ * @author adam
12751
+ * @param area The area to grow.
12752
+ * @param newx The new coordinate x.
12753
+ * @param newy The new coordinate y.
12754
+ * @see #_polygonshrink
12755
+ */
12756
+ this._polygongrow = function (area, newx, newy) {
12757
+ var xdiff = newx - parseInt(area.style.left, 10);
12758
+ var ydiff = newy - parseInt(area.style.top, 10);
12759
+ var pad = 0; //padding on the edges
12760
+ var pad2 = 0; //twice the padding
12761
+ if (newx < parseInt(area.style.left, 10)) {
12762
+ area.style.left = (newx - pad) + 'px';
12763
+ this.setAreaSize(area.aid, parseInt(area.style.width, 10) + Math.abs(xdiff) + pad2, null);
12764
+ }
12765
+ else if (newx > parseInt(area.style.left, 10) + parseInt(area.style.width, 10)) {
12766
+ this.setAreaSize(area.aid, newx - parseInt(area.style.left, 10) + pad2, null);
12767
+ }
12768
+ if (newy < parseInt(area.style.top, 10)) {
12769
+ area.style.top = (newy - pad) + 'px';
12770
+ this.setAreaSize(area.aid, null, parseInt(area.style.height, 10) + Math.abs(ydiff) + pad2);
12771
+ }
12772
+ else if (newy > parseInt(area.style.top, 10) + parseInt(area.style.height, 10)) {
12773
+ this.setAreaSize(area.aid, null, newy - parseInt(area.style.top, 10) + pad2);
12774
+ }
12775
+ };
12776
+ /**
12777
+ * Shrink the polygon bounding area to the necessary size, by first reducing it
12778
+ * to the minimum, and then gradually growing it.
12779
+ * We need this because while we were drawing the polygon, it might have expanded
12780
+ * the canvas more than needed.
12781
+ * Will repaint the area.
12782
+ * @author adam
12783
+ * @param area The area to shrink.
12784
+ * @see #_polygongrow
12785
+ */
12786
+ this._polygonshrink = function (area) {
12787
+ area.style.left = (area.xpoints[0]) + 'px';
12788
+ area.style.top = (area.ypoints[0]) + 'px';
12789
+ this.setAreaSize(area.aid, 0, 0);
12790
+ for (var i = 0, le = area.xpoints.length; i < le; i++) {
12791
+ this._polygongrow(area, area.xpoints[i], area.ypoints[i]);
12792
+ }
12793
+ this._repaint(area, this.config.CL_NORM_SHAPE);
12794
+ };
12795
+ /**
12796
+ * EVENT HANDLER: Handles mousemove on the image.
12797
+ * This is the main drawing routine.
12798
+ * Depending on the current shape, will draw the rect/circle/poly to the new position.
12799
+ * @param e The event object.
12800
+ */
12801
+ this.img_mousemove = function (e) {
12802
+ //function level var declarations
12803
+ var xdiff, ydiff, diff;
12804
+ //event.x is relative to parent element, but page.x is NOT
12805
+ //pos coordinates are the same absolute coords, offset coords are relative to parent
12806
+ const windowEvent = window.event;
12807
+ var pos = this._getPos(this.imageElement), x = (this.isMSIE) ? (windowEvent.x + this.parentImageElement.scrollLeft - this.imageElement.offsetLeft) : (e.clientX - pos.x), y = (this.isMSIE) ? (windowEvent.y + this.parentImageElement.scrollTop - this.imageElement.offsetTop) : (e.clientY - pos.y);
12808
+ x = Math.round(x);
12809
+ y = Math.round(y);
12810
+ //exit if outside image
12811
+ if (x < 0 || y < 0 || x > this.imageElement.width || y > this.imageElement.height) {
12812
+ return;
12813
+ }
12814
+ //old dimensions that need to be updated in this function
12815
+ if (this.memory[this.currentid]) {
12816
+ var top = this.memory[this.currentid].top;
12817
+ var left = this.memory[this.currentid].left;
12818
+ var height = this.memory[this.currentid].height;
12819
+ var width = this.memory[this.currentid].width;
12820
+ }
12821
+ var area = this.areas[this.currentid];
12822
+ // Handle shift state for Safari
12823
+ // Safari doesn't generate keyboard events for modifiers: http://bugs.webkit.org/show_bug.cgi?id=11696
12824
+ if (this.isSafari) {
12825
+ if (e.shiftKey) {
12826
+ if (this.is_drawing == this.DM_RECTANGLE_DRAW) {
12827
+ this.is_drawing = this.DM_SQUARE_DRAW;
12828
+ this.statusMessage(this.strings.SQUARE_DRAW);
12829
+ }
12830
+ }
12831
+ else {
12832
+ if (this.is_drawing == this.DM_SQUARE_DRAW && area.shape == 'rect') {
12833
+ //not for circle!
12834
+ this.is_drawing = this.DM_RECTANGLE_DRAW;
12835
+ this.statusMessage(this.strings.RECTANGLE_DRAW);
12836
+ }
12837
+ }
12838
+ }
12839
+ if (this.is_drawing == this.DM_RECTANGLE_DRAW) {
12840
+ //rectangle mode
12841
+ this.fireEvent('onDrawArea', this.currentid);
12842
+ xdiff = x - this.memory[this.currentid].downx;
12843
+ ydiff = y - this.memory[this.currentid].downy;
12844
+ this.setAreaSize(this.currentid, Math.abs(xdiff), Math.abs(ydiff));
12845
+ if (xdiff < 0) {
12846
+ area.style.left = (x + 1) + 'px';
12847
+ }
12848
+ if (ydiff < 0) {
12849
+ area.style.top = (y + 1) + 'px';
12850
+ }
12851
+ }
12852
+ else if (this.is_drawing == this.DM_SQUARE_DRAW) {
12853
+ //square mode - align to shorter side
12854
+ this.fireEvent('onDrawArea', this.currentid);
12855
+ xdiff = x - this.memory[this.currentid].downx;
12856
+ ydiff = y - this.memory[this.currentid].downy;
12857
+ if (Math.abs(xdiff) < Math.abs(ydiff)) {
12858
+ diff = Math.abs(parseInt(xdiff, 10));
12859
+ }
12860
+ else {
12861
+ diff = Math.abs(parseInt(ydiff, 10));
12862
+ }
12863
+ this.setAreaSize(this.currentid, diff, diff);
12864
+ if (xdiff < 0) {
12865
+ area.style.left = (this.memory[this.currentid].downx + diff * -1) + 'px';
12866
+ }
12867
+ if (ydiff < 0) {
12868
+ area.style.top = (this.memory[this.currentid].downy + diff * -1 + 1) + 'px';
12869
+ }
12870
+ }
12871
+ else if (this.is_drawing == this.DM_POLYGON_DRAW) {
12872
+ //polygon mode
12873
+ this.fireEvent('onDrawArea', this.currentid);
12874
+ this._polygongrow(area, x, y);
12875
+ }
12876
+ else if (this.is_drawing == this.DM_RECTANGLE_MOVE || this.is_drawing == this.DM_SQUARE_MOVE) {
12877
+ this.fireEvent('onMoveArea', this.currentid);
12878
+ x = x - this.memory[this.currentid].rdownx;
12879
+ y = y - this.memory[this.currentid].rdowny;
12880
+ if (x + width > this.imageElement.width || y + height > this.imageElement.height) {
12881
+ return;
12882
+ }
12883
+ if (x < 0 || y < 0) {
12884
+ return;
12885
+ }
12886
+ area.style.left = x + 1 + 'px';
12887
+ area.style.top = y + 1 + 'px';
12888
+ }
12889
+ else if (this.is_drawing == this.DM_POLYGON_MOVE) {
12890
+ this.fireEvent('onMoveArea', this.currentid);
12891
+ x = x - this.memory[this.currentid].rdownx;
12892
+ y = y - this.memory[this.currentid].rdowny;
12893
+ if (x + width > this.imageElement.width || y + height > this.imageElement.height) {
12894
+ return;
12895
+ }
12896
+ if (x < 0 || y < 0) {
12897
+ return;
12898
+ }
12899
+ xdiff = x - left;
12900
+ ydiff = y - top;
12901
+ if (area.xpoints) {
12902
+ for (var i = 0, le = area.xpoints.length; i < le; i++) {
12903
+ area.xpoints[i] = this.memory[this.currentid].xpoints[i] + xdiff;
12904
+ area.ypoints[i] = this.memory[this.currentid].ypoints[i] + ydiff;
12905
+ }
12906
+ }
12907
+ area.style.left = x + 'px';
12908
+ area.style.top = y + 'px';
12909
+ }
12910
+ else if (this.is_drawing == this.DM_SQUARE_RESIZE_LEFT) {
12911
+ this.fireEvent('onResizeArea', this.currentid);
12912
+ diff = x - left;
12913
+ if ((width + (-1 * diff)) > 0) {
12914
+ //real resize left
12915
+ area.style.left = x + 1 + 'px';
12916
+ area.style.top = (top + (diff / 2)) + 'px';
12917
+ this.setAreaSize(this.currentid, parseInt(width + (-1 * diff), 10), parseInt(height + (-1 * diff), 10));
12918
+ }
12919
+ else {
12920
+ //jump to another state
12921
+ this.memory[this.currentid].width = 0;
12922
+ this.memory[this.currentid].height = 0;
12923
+ this.memory[this.currentid].left = x;
12924
+ this.memory[this.currentid].top = y;
12925
+ this.is_drawing = this.DM_SQUARE_RESIZE_RIGHT;
12926
+ }
12927
+ }
12928
+ else if (this.is_drawing == this.DM_SQUARE_RESIZE_RIGHT) {
12929
+ this.fireEvent('onResizeArea', this.currentid);
12930
+ diff = x - left - width;
12931
+ if ((width + (diff)) - 1 > 0) {
12932
+ //real resize right
12933
+ area.style.top = (top + (-1 * diff / 2)) + 'px';
12934
+ this.setAreaSize(this.currentid, (width + (diff)) - 1, (height + (diff)));
12935
+ }
12936
+ else {
12937
+ //jump to another state
12938
+ this.memory[this.currentid].width = 0;
12939
+ this.memory[this.currentid].height = 0;
12940
+ this.memory[this.currentid].left = x;
12941
+ this.memory[this.currentid].top = y;
12942
+ this.is_drawing = this.DM_SQUARE_RESIZE_LEFT;
12943
+ }
12944
+ }
12945
+ else if (this.is_drawing == this.DM_SQUARE_RESIZE_TOP) {
12946
+ this.fireEvent('onResizeArea', this.currentid);
12947
+ diff = y - top;
12948
+ if ((width + (-1 * diff)) > 0) {
12949
+ //real resize top
12950
+ area.style.top = y + 1 + 'px';
12951
+ area.style.left = (left + (diff / 2)) + 'px';
12952
+ this.setAreaSize(this.currentid, (width + (-1 * diff)), (height + (-1 * diff)));
12953
+ }
12954
+ else {
12955
+ //jump to another state
12956
+ this.memory[this.currentid].width = 0;
12957
+ this.memory[this.currentid].height = 0;
12958
+ this.memory[this.currentid].left = x;
12959
+ this.memory[this.currentid].top = y;
12960
+ this.is_drawing = this.DM_SQUARE_RESIZE_BOTTOM;
12961
+ }
12962
+ }
12963
+ else if (this.is_drawing == this.DM_SQUARE_RESIZE_BOTTOM) {
12964
+ this.fireEvent('onResizeArea', this.currentid);
12965
+ diff = y - top - height;
12966
+ if ((width + (diff)) - 1 > 0) {
12967
+ //real resize bottom
12968
+ area.style.left = (left + (-1 * diff / 2)) + 'px';
12969
+ this.setAreaSize(this.currentid, (width + (diff)) - 1, (height + (diff)) - 1);
12970
+ }
12971
+ else {
12972
+ //jump to another state
12973
+ this.memory[this.currentid].width = 0;
12974
+ this.memory[this.currentid].height = 0;
12975
+ this.memory[this.currentid].left = x;
12976
+ this.memory[this.currentid].top = y;
12977
+ this.is_drawing = this.DM_SQUARE_RESIZE_TOP;
12978
+ }
12979
+ }
12980
+ else if (this.is_drawing == this.DM_RECTANGLE_RESIZE_LEFT) {
12981
+ this.fireEvent('onResizeArea', this.currentid);
12982
+ xdiff = x - left;
12983
+ if (width + (-1 * xdiff) > 0) {
12984
+ //real resize left
12985
+ area.style.left = x + 1 + 'px';
12986
+ this.setAreaSize(this.currentid, width + (-1 * xdiff), null);
12987
+ }
12988
+ else {
12989
+ //jump to another state
12990
+ this.memory[this.currentid].width = 0;
12991
+ this.memory[this.currentid].left = x;
12992
+ this.is_drawing = this.DM_RECTANGLE_RESIZE_RIGHT;
12993
+ }
12994
+ }
12995
+ else if (this.is_drawing == this.DM_RECTANGLE_RESIZE_RIGHT) {
12996
+ this.fireEvent('onResizeArea', this.currentid);
12997
+ xdiff = x - left - width;
12998
+ if ((width + (xdiff)) - 1 > 0) {
12999
+ //real resize right
13000
+ this.setAreaSize(this.currentid, (width + (xdiff)) - 1, null);
13001
+ }
13002
+ else {
13003
+ //jump to another state
13004
+ this.memory[this.currentid].width = 0;
13005
+ this.memory[this.currentid].left = x;
13006
+ this.is_drawing = this.DM_RECTANGLE_RESIZE_LEFT;
13007
+ }
13008
+ }
13009
+ else if (this.is_drawing == this.DM_RECTANGLE_RESIZE_TOP) {
13010
+ this.fireEvent('onResizeArea', this.currentid);
13011
+ ydiff = y - top;
13012
+ if ((height + (-1 * ydiff)) > 0) {
13013
+ //real resize top
13014
+ area.style.top = y + 1 + 'px';
13015
+ this.setAreaSize(this.currentid, null, (height + (-1 * ydiff)));
13016
+ }
13017
+ else {
13018
+ //jump to another state
13019
+ this.memory[this.currentid].height = 0;
13020
+ this.memory[this.currentid].top = y;
13021
+ this.is_drawing = this.DM_RECTANGLE_RESIZE_BOTTOM;
13022
+ }
13023
+ }
13024
+ else if (this.is_drawing == this.DM_RECTANGLE_RESIZE_BOTTOM) {
13025
+ this.fireEvent('onResizeArea', this.currentid);
13026
+ ydiff = y - top - height;
13027
+ if ((height + (ydiff)) - 1 > 0) {
13028
+ //real resize bottom
13029
+ this.setAreaSize(this.currentid, null, (height + (ydiff)) - 1);
13030
+ }
13031
+ else {
13032
+ //jump to another state
13033
+ this.memory[this.currentid].height = 0;
13034
+ this.memory[this.currentid].top = y;
13035
+ this.is_drawing = this.DM_RECTANGLE_RESIZE_TOP;
13036
+ }
13037
+ }
13038
+ //repaint canvas elements
13039
+ if (this.is_drawing) {
13040
+ this._repaint(area, this.config.CL_DRAW_SHAPE, x, y);
13041
+ this._updatecoords(this.currentid);
13042
+ }
13043
+ };
13044
+ /**
13045
+ * EVENT HANDLER: Handles mouseup on the image.
13046
+ * Handles dragging and resizing.
13047
+ * @param e The event object.
13048
+ */
13049
+ this.img_mouseup = function (e) {
13050
+ const windowEvent = window.event;
13051
+ var pos = this._getPos(this.imageElement), x = (this.isMSIE) ? (windowEvent.x + this.parentImageElement.scrollLeft - this.imageElement.offsetLeft) : (e.clientX - pos.x), y = (this.isMSIE) ? (windowEvent.y + this.parentImageElement.scrollTop - this.imageElement.offsetTop) : (e.clientY - pos.y);
13052
+ x = Math.round(x);
13053
+ y = Math.round(y);
13054
+ //for everything that is move or resize
13055
+ if (this.is_drawing != this.DM_RECTANGLE_DRAW &&
13056
+ this.is_drawing != this.DM_SQUARE_DRAW &&
13057
+ this.is_drawing != this.DM_POLYGON_DRAW &&
13058
+ this.is_drawing != this.DM_POLYGON_LASTDRAW) {
13059
+ //end dragging
13060
+ this.draggedId = null;
13061
+ //finish state
13062
+ this.is_drawing = 0;
13063
+ this.statusMessage(this.strings.READY);
13064
+ this.relaxArea(this.currentid);
13065
+ if (this.areas[this.currentid] == this._getLastArea()) {
13066
+ return;
13067
+ }
13068
+ this.memory[this.currentid].downx = x;
13069
+ this.memory[this.currentid].downy = y;
13070
+ }
13071
+ };
13072
+ this.img_dragstart = function (e) {
13073
+ e.preventDefault();
13074
+ };
13075
+ /**
13076
+ * EVENT HANDLER: Handles mousedown on the image.
13077
+ * Handles beggining or end of draw, or polygon point set.
13078
+ * @param e The event object.
13079
+ */
13080
+ this.img_mousedown = function (e) {
13081
+ if (!e)
13082
+ e = window.event;
13083
+ var pos = this._getPos(this.imageElement), x = Math.round(e.clientX - pos.x), y = Math.round(e.clientY - pos.y);
13084
+ // Handle the Shift state
13085
+ if (e.shiftKey) {
13086
+ if (this.is_drawing == this.DM_POLYGON_DRAW) {
13087
+ this.is_drawing = this.DM_POLYGON_LASTDRAW;
13088
+ }
13089
+ }
13090
+ var area = this.areas[this.currentid];
13091
+ if (this.is_drawing == this.DM_POLYGON_DRAW) {
13092
+ //its not finish state yet
13093
+ area.xpoints[area.xpoints.length] = x;
13094
+ area.ypoints[area.ypoints.length] = y;
13095
+ this.memory[this.currentid].downx = x;
13096
+ this.memory[this.currentid].downy = y;
13097
+ return;
13098
+ }
13099
+ else if (this.is_drawing && this.is_drawing != this.DM_POLYGON_DRAW) {
13100
+ //finish any other state
13101
+ if (this.is_drawing == this.DM_POLYGON_LASTDRAW) {
13102
+ //add last controlpoint and update coords
13103
+ area.xpoints[area.xpoints.length] = x;
13104
+ area.ypoints[area.ypoints.length] = y;
13105
+ this._updatecoords(this.currentid);
13106
+ this.is_drawing = 0;
13107
+ this._polygonshrink(area);
13108
+ }
13109
+ this.is_drawing = 0;
13110
+ this.statusMessage(this.strings.READY);
13111
+ this.relaxArea(this.currentid);
13112
+ if (this.areas[this.currentid] == this._getLastArea()) {
13113
+ return;
13114
+ }
13115
+ return;
13116
+ }
13117
+ if (!this.nextShape) {
13118
+ return;
13119
+ }
13120
+ this.addNewArea();
13121
+ this.initArea(this.currentid, this.nextShape);
13122
+ if (this.areas[this.currentid].shape == 'poly') {
13123
+ this.is_drawing = this.DM_POLYGON_DRAW;
13124
+ this.statusMessage(this.strings.POLYGON_DRAW);
13125
+ this.areas[this.currentid].style.left = x + 'px';
13126
+ this.areas[this.currentid].style.top = y + 'px';
13127
+ this.areas[this.currentid].style.width = 0;
13128
+ this.areas[this.currentid].style.height = 0;
13129
+ this.areas[this.currentid].xpoints = [];
13130
+ this.areas[this.currentid].ypoints = [];
13131
+ this.areas[this.currentid].xpoints[0] = x;
13132
+ this.areas[this.currentid].ypoints[0] = y;
13133
+ }
13134
+ else if (this.areas[this.currentid].shape == 'rect') {
13135
+ this.is_drawing = this.DM_RECTANGLE_DRAW;
13136
+ this.statusMessage(this.strings.RECTANGLE_DRAW);
13137
+ this.areas[this.currentid].style.left = x + 'px';
13138
+ this.areas[this.currentid].style.top = y + 'px';
13139
+ this.areas[this.currentid].style.width = 0;
13140
+ this.areas[this.currentid].style.height = 0;
13141
+ }
13142
+ else if (this.areas[this.currentid].shape == 'circle') {
13143
+ this.is_drawing = this.DM_SQUARE_DRAW;
13144
+ this.statusMessage(this.strings.CIRCLE_DRAW);
13145
+ this.areas[this.currentid].style.left = x + 'px';
13146
+ this.areas[this.currentid].style.top = y + 'px';
13147
+ this.areas[this.currentid].style.width = 0;
13148
+ this.areas[this.currentid].style.height = 0;
13149
+ }
13150
+ this._setBorder(this.areas[this.currentid], 'DRAW');
13151
+ this.memory[this.currentid].downx = x;
13152
+ this.memory[this.currentid].downy = y;
13153
+ };
13154
+ /**
13155
+ * Highlights a given area.
13156
+ * Sets opacity and repaints.
13157
+ * @date 2007.12.28. 18:23:00
13158
+ * @param id The id of the area to blur.
13159
+
13160
+ */
13161
+ this.highlightArea = function (id) {
13162
+ if (this.is_drawing) {
13163
+ return;
13164
+ } //exit if in drawing state
13165
+ var area = this.areas[id];
13166
+ if (area && area.shape != 'undefined') {
13167
+ //area exists - highlight it
13168
+ this._setBorder(area, 'HIGHLIGHT');
13169
+ this._setopacity(area, this.config.CL_HIGHLIGHT_BG, '-' + this.config.highlight_opacity);
13170
+ this._repaint(area, this.config.CL_HIGHLIGHT_SHAPE);
13171
+ }
13172
+ };
13173
+ /**
13174
+ * Blurs a given area.
13175
+ * Sets opacity and repaints.
13176
+ * @date 2007.12.28. 18:23:26
13177
+ * @param id The id of the area to blur.
13178
+
13179
+ */
13180
+ this.blurArea = function (id) {
13181
+ if (this.is_drawing) {
13182
+ return;
13183
+ } //exit if in drawing state
13184
+ var area = this.areas[id];
13185
+ if (area && area.shape != 'undefined') {
13186
+ //area exists - fade it back
13187
+ this._setBorder(area, 'NORM');
13188
+ this._setopacity(area, this.config.CL_NORM_BG, '-' + this.config.norm_opacity);
13189
+ this._repaint(area, this.config.CL_NORM_SHAPE);
13190
+ }
13191
+ };
13192
+ /**
13193
+ * EVENT HANDLER: Handles event of mousemove on imgmap areas.
13194
+ * - changes cursor depending where we are inside the area (buggy in opera)
13195
+ * - handles area resize
13196
+ * - handles area move
13197
+ * @url http://evolt.org/article/Mission_Impossible_mouse_position/17/23335/index.html
13198
+ * @url http://my.opera.com/community/forums/topic.dml?id=239498&t=1217158015&page=1
13199
+ * @author adam
13200
+ * @param e The event object.
13201
+ */
13202
+ this.area_mousemove = function (e) {
13203
+ if (!this.is_drawing) {
13204
+ if (!e)
13205
+ e = window.event;
13206
+ var obj = (this.isMSIE) ? window.event.srcElement : e.currentTarget;
13207
+ if (obj.tagName == 'DIV') {
13208
+ //do this because of label
13209
+ obj = obj.parentNode;
13210
+ }
13211
+ if (obj.tagName == 'image' || obj.tagName == 'group' ||
13212
+ obj.tagName == 'shape' || obj.tagName == 'stroke') {
13213
+ //do this because of excanvas
13214
+ obj = obj.parentNode.parentNode;
13215
+ }
13216
+ var target = e.target || e.srcElement, rect = target && target.getBoundingClientRect();
13217
+ const windowEvent = window.event;
13218
+ var xdiff = rect ? e.clientX - rect.left : windowEvent.offsetX;
13219
+ var ydiff = rect ? e.clientY - rect.top : windowEvent.offsetY;
13220
+ // Alfonso
13221
+ if (this.isSafari) {
13222
+ xdiff -= window.scrollX;
13223
+ ydiff -= window.scrollY;
13224
+ }
13225
+ var resizable = (obj.shape == 'rect' || obj.shape == 'circle');
13226
+ if (resizable && xdiff < 6 && ydiff > 6) {
13227
+ //move left
13228
+ obj.style.cursor = 'w-resize';
13229
+ }
13230
+ else if (resizable && xdiff > parseInt(obj.style.width, 10) - 6 && ydiff > 6) {
13231
+ //move right
13232
+ obj.style.cursor = 'e-resize';
13233
+ }
13234
+ else if (resizable && xdiff > 6 && ydiff < 6) {
13235
+ //move top
13236
+ obj.style.cursor = 'n-resize';
13237
+ }
13238
+ else if (resizable && ydiff > parseInt(obj.style.height, 10) - 6 && xdiff > 6) {
13239
+ //move bottom
13240
+ obj.style.cursor = 's-resize';
13241
+ }
13242
+ else {
13243
+ //move all
13244
+ obj.style.cursor = 'move';
13245
+ }
13246
+ if (obj.aid != this.draggedId) {
13247
+ //not dragged or different
13248
+ if (obj.style.cursor == 'move') {
13249
+ obj.style.cursor = 'default';
13250
+ }
13251
+ return;
13252
+ }
13253
+ var area = this.areas[this.currentid];
13254
+ //moved here from mousedown
13255
+ if (xdiff < 6 && ydiff > 6) {
13256
+ //move left
13257
+ if (area.shape == 'circle') {
13258
+ this.is_drawing = this.DM_SQUARE_RESIZE_LEFT;
13259
+ this.statusMessage(this.strings.SQUARE_RESIZE_LEFT);
13260
+ }
13261
+ else if (area.shape == 'rect') {
13262
+ this.is_drawing = this.DM_RECTANGLE_RESIZE_LEFT;
13263
+ this.statusMessage(this.strings.RECTANGLE_RESIZE_LEFT);
13264
+ }
13265
+ }
13266
+ else if (xdiff > parseInt(area.style.width, 10) - 6 && ydiff > 6) {
13267
+ //move right
13268
+ if (area.shape == 'circle') {
13269
+ this.is_drawing = this.DM_SQUARE_RESIZE_RIGHT;
13270
+ this.statusMessage(this.strings.SQUARE_RESIZE_RIGHT);
13271
+ }
13272
+ else if (area.shape == 'rect') {
13273
+ this.is_drawing = this.DM_RECTANGLE_RESIZE_RIGHT;
13274
+ this.statusMessage(this.strings.RECTANGLE_RESIZE_RIGHT);
13275
+ }
13276
+ }
13277
+ else if (xdiff > 6 && ydiff < 6) {
13278
+ //move top
13279
+ if (area.shape == 'circle') {
13280
+ this.is_drawing = this.DM_SQUARE_RESIZE_TOP;
13281
+ this.statusMessage(this.strings.SQUARE_RESIZE_TOP);
13282
+ }
13283
+ else if (area.shape == 'rect') {
13284
+ this.is_drawing = this.DM_RECTANGLE_RESIZE_TOP;
13285
+ this.statusMessage(this.strings.RECTANGLE_RESIZE_TOP);
13286
+ }
13287
+ }
13288
+ else if (ydiff > parseInt(area.style.height, 10) - 6 && xdiff > 6) {
13289
+ //move bottom
13290
+ if (area.shape == 'circle') {
13291
+ this.is_drawing = this.DM_SQUARE_RESIZE_BOTTOM;
13292
+ this.statusMessage(this.strings.SQUARE_RESIZE_BOTTOM);
13293
+ }
13294
+ else if (area.shape == 'rect') {
13295
+ this.is_drawing = this.DM_RECTANGLE_RESIZE_BOTTOM;
13296
+ this.statusMessage(this.strings.RECTANGLE_RESIZE_BOTTOM);
13297
+ }
13298
+ }
13299
+ else /*if (xdiff < 10 && ydiff < 10 ) */ {
13300
+ //move all
13301
+ if (area.shape == 'circle') {
13302
+ this.is_drawing = this.DM_SQUARE_MOVE;
13303
+ this.statusMessage(this.strings.SQUARE_MOVE);
13304
+ this.memory[this.currentid].rdownx = xdiff;
13305
+ this.memory[this.currentid].rdowny = ydiff;
13306
+ }
13307
+ else if (area.shape == 'rect') {
13308
+ this.is_drawing = this.DM_RECTANGLE_MOVE;
13309
+ this.statusMessage(this.strings.RECTANGLE_MOVE);
13310
+ this.memory[this.currentid].rdownx = xdiff;
13311
+ this.memory[this.currentid].rdowny = ydiff;
13312
+ }
13313
+ else if (area.shape == 'poly') {
13314
+ if (area.xpoints) {
13315
+ for (var i = 0, le = area.xpoints.length; i < le; i++) {
13316
+ this.memory[this.currentid].xpoints[i] = area.xpoints[i];
13317
+ this.memory[this.currentid].ypoints[i] = area.ypoints[i];
13318
+ }
13319
+ }
13320
+ if (area.shape == 'poly') {
13321
+ this.is_drawing = this.DM_POLYGON_MOVE;
13322
+ this.statusMessage(this.strings.POLYGON_MOVE);
13323
+ }
13324
+ this.memory[this.currentid].rdownx = xdiff;
13325
+ this.memory[this.currentid].rdowny = ydiff;
13326
+ }
13327
+ }
13328
+ //common memory settings (preparing to move or resize)
13329
+ this.memory[this.currentid].width = parseInt(area.style.width, 10);
13330
+ this.memory[this.currentid].height = parseInt(area.style.height, 10);
13331
+ this.memory[this.currentid].top = parseInt(area.style.top, 10);
13332
+ this.memory[this.currentid].left = parseInt(area.style.left, 10);
13333
+ this._setBorder(area, 'DRAW');
13334
+ this._setopacity(area, this.config.CL_DRAW_BG, this.config.draw_opacity);
13335
+ }
13336
+ else {
13337
+ //if drawing and not ie, have to propagate to image event
13338
+ this.img_mousemove(e);
13339
+ }
13340
+ };
13341
+ /**
13342
+ * EVENT HANDLER: Handles event of mouseup on imgmap areas.
13343
+ * Basically clears draggedId.
13344
+ * @author adam
13345
+ * @param e The event object
13346
+ */
13347
+ this.area_mouseup = function (e) {
13348
+ if (!this.is_drawing) {
13349
+ var obj = (this.isMSIE) ? window.event.srcElement : e.currentTarget;
13350
+ if (obj.tagName == 'DIV') {
13351
+ //do this because of label
13352
+ obj = obj.parentNode;
13353
+ }
13354
+ if (obj.tagName == 'image' || obj.tagName == 'group' ||
13355
+ obj.tagName == 'shape' || obj.tagName == 'stroke') {
13356
+ //do this because of excanvas
13357
+ obj = obj.parentNode.parentNode;
13358
+ }
13359
+ if (this.areas[this.currentid] != obj) {
13360
+ //trying to draw on a different canvas,switch to this one
13361
+ if (typeof obj.aid == 'undefined') {
13362
+ this.log('Cannot identify target area', 1);
13363
+ return;
13364
+ }
13365
+ }
13366
+ this.draggedId = null;
13367
+ }
13368
+ else {
13369
+ //if drawing and not ie, have to propagate to image event
13370
+ this.img_mouseup(e);
13371
+ }
13372
+ };
13373
+ /**
13374
+ * EVENT HANDLER: Handles event of mouseover on imgmap areas.
13375
+ * Calls gradual highlight on the given area.
13376
+ * @author adam
13377
+ * @param e The event object
13378
+ */
13379
+ this.area_mouseover = function (e) {
13380
+ if (!this.is_drawing) {
13381
+ //identify source object
13382
+ var obj = (this.isMSIE) ? window.event.srcElement : e.currentTarget;
13383
+ if (obj.tagName == 'DIV') {
13384
+ //do this because of label
13385
+ obj = obj.parentNode;
13386
+ }
13387
+ if (obj.tagName == 'image' || obj.tagName == 'group' ||
13388
+ obj.tagName == 'shape' || obj.tagName == 'stroke') {
13389
+ //do this because of excanvas
13390
+ obj = obj.parentNode.parentNode;
13391
+ }
13392
+ this.highlightArea(obj.aid);
13393
+ }
13394
+ };
13395
+ /**
13396
+ * EVENT HANDLER: Handles event of mouseout on imgmap areas.
13397
+ * Calls gradient blur on the given area.
13398
+ * @author adam
13399
+ * @param e The event object
13400
+ */
13401
+ this.area_mouseout = function (e) {
13402
+ if (!this.is_drawing) {
13403
+ if (!e)
13404
+ e = window.event;
13405
+ if (this.isMSIE) {
13406
+ // When moving to a child, ignore this mouseout event
13407
+ if (e.toElement && e.srcElement == e.toElement.parentNode)
13408
+ return;
13409
+ }
13410
+ //identify source object
13411
+ var obj = (this.isMSIE) ? e.srcElement : e.currentTarget;
13412
+ var tagName = obj.tagName.toLowerCase();
13413
+ if (tagName == 'div') {
13414
+ //do this because of label
13415
+ obj = obj.parentNode;
13416
+ }
13417
+ if (tagName == 'image' || tagName == 'group' ||
13418
+ tagName == 'shape' || tagName == 'stroke') {
13419
+ //do this because of excanvas
13420
+ obj = obj.parentNode.parentNode;
13421
+ }
13422
+ // Only blur the area if it isn't the current one
13423
+ if (this.currentid != obj.aid)
13424
+ this.blurArea(obj.aid);
13425
+ }
13426
+ };
13427
+ /**
13428
+ * EVENT HANDLER: Handles event of mousedown on imgmap areas.
13429
+ * Sets the variables draggedid, selectedid and currentid to the given area.
13430
+ * @author adam
13431
+ * @param e The event object
13432
+ */
13433
+ this.area_mousedown = function (e) {
13434
+ if (!this.is_drawing) {
13435
+ var obj = (this.isMSIE) ? window.event.srcElement : e.currentTarget;
13436
+ if (obj.tagName == 'DIV') {
13437
+ //do this because of label
13438
+ obj = obj.parentNode;
13439
+ }
13440
+ if (obj.tagName == 'image' || obj.tagName == 'group' ||
13441
+ obj.tagName == 'shape' || obj.tagName == 'stroke') {
13442
+ //do this because of excanvas
13443
+ obj = obj.parentNode.parentNode;
13444
+ }
13445
+ if (this.areas[this.currentid] != obj) {
13446
+ //trying to draw on a different canvas, switch to this one
13447
+ if (typeof obj.aid == 'undefined') {
13448
+ this.log('Cannot identify target area', 1);
13449
+ return;
13450
+ }
13451
+ this.blurArea(this.currentid);
13452
+ this.currentid = obj.aid;
13453
+ this.highlightArea(obj.aid);
13454
+ }
13455
+ this.draggedId = this.currentid;
13456
+ this.selectedId = this.currentid;
13457
+ this.fireEvent('onSelectArea', this.areas[this.currentid]);
13458
+ //stop event propagation to document level
13459
+ if (this.isMSIE) {
13460
+ window.event.cancelBubble = true;
13461
+ }
13462
+ else {
13463
+ e.stopPropagation();
13464
+ }
13465
+ }
13466
+ else {
13467
+ //if drawing and not ie, have to propagate to image event
13468
+ this.img_mousedown(e);
13469
+ }
13470
+ };
13471
+ /**
13472
+ * EVENT HANDLER: Handles event 'keydown' on document.
13473
+ * Handles SHIFT hold while drawing.
13474
+ * Note: Safari doesn't generate keyboard events for modifiers:
13475
+ * @url http://bugs.webkit.org/show_bug.cgi?id=11696
13476
+ * @author adam
13477
+ * @param e The event object
13478
+ */
13479
+ this.doc_keydown = function (e) {
13480
+ if (e.keyCode == 46 || e.key == "Delete") {
13481
+ //delete key pressed
13482
+ if (this.selectedId !== null && !this.is_drawing) {
13483
+ this.removeArea(this.selectedId);
13484
+ }
13485
+ }
13486
+ else if (e.keyCode == 16 || e.key == "Shift") {
13487
+ //shift key pressed
13488
+ if (this.is_drawing == this.DM_RECTANGLE_DRAW) {
13489
+ this.is_drawing = this.DM_SQUARE_DRAW;
13490
+ this.statusMessage(this.strings.SQUARE_DRAW);
13491
+ }
13492
+ }
13493
+ };
13494
+ /**
13495
+ * EVENT HANDLER: Handles event 'keyup' on document.
13496
+ * Handles SHIFT release while drawing.
13497
+ * @author adam
13498
+ * @param e The event object
13499
+ */
13500
+ this.doc_keyup = function (e) {
13501
+ if (e.keyCode == 16 || e.key == "Shift") {
13502
+ //shift key released
13503
+ if (this.is_drawing == this.DM_SQUARE_DRAW && this.areas[this.currentid].shape == 'rect') {
13504
+ //not for circle!
13505
+ this.is_drawing = this.DM_RECTANGLE_DRAW;
13506
+ this.statusMessage(this.strings.RECTANGLE_DRAW);
13507
+ }
13508
+ }
13509
+ };
13510
+ /**
13511
+ * EVENT HANDLER: Handles event 'mousedown' on document.
13512
+ * @author adam
13513
+ * @param e The event object
13514
+ */
13515
+ this.doc_mousedown = function (e) {
13516
+ if (!this.is_drawing) {
13517
+ this.selectedId = null;
13518
+ }
13519
+ };
13520
+ /**
13521
+ * Get the real position of the element.
13522
+ * Deal with browser differences when trying to get the position of an area.
13523
+ * @param element The element you want the position of.
13524
+ * @return An object with x and y members.
13525
+ */
13526
+ this._getPos = function (element) {
13527
+ var bounding = element.getBoundingClientRect();
13528
+ return { x: bounding.left, y: bounding.top };
13529
+ };
13530
+ /**
13531
+ * Gets the last (visible and editable) area.
13532
+ * @author Adam Maschek (adam.maschek(at)gmail.com)
13533
+ * @date 2006-06-15 16:34:51
13534
+ * @returns The last area object or null.
13535
+ */
13536
+ this._getLastArea = function () {
13537
+ for (var i = this.areas.length - 1; i >= 0; i--) {
13538
+ if (this.areas[i]) {
13539
+ return this.areas[i];
13540
+ }
13541
+ }
13542
+ return null;
13543
+ };
13544
+ /**
13545
+ * Parses cssText to single style declarations.
13546
+ * @author adam
13547
+ * @date 25-09-2007 18:19:51
13548
+ * @param obj The DOM object to apply styles on.
13549
+ * @param cssText The css declarations to apply.
13550
+ */
13551
+ this.assignCSS = function (obj, cssText) {
13552
+ var parts = cssText.split(';');
13553
+ for (var i = 0; i < parts.length; i++) {
13554
+ var p = parts[i].split(':');
13555
+ //we need to camelcase by - signs
13556
+ var pp = trim(p[0]).split('-');
13557
+ var prop = pp[0];
13558
+ for (var j = 1; j < pp.length; j++) {
13559
+ //replace first letters to uppercase
13560
+ prop += pp[j].replace(/^\w/, pp[j].substring(0, 1).toUpperCase());
13561
+ }
13562
+ obj.style[trim(prop)] = trim(p[1]);
13563
+ }
13564
+ };
13565
+ /**
13566
+ * To fire callback hooks on custom events, passing them the object of the event.
13567
+ * @author adam
13568
+ * @date 13-10-2007 15:24:49
13569
+ * @param evt The type of event
13570
+ * @param obj The object of the event. (can be an id, a string, an object, whatever is most relevant)
13571
+ */
13572
+ this.fireEvent = function (evt, obj) {
13573
+ if (typeof this.config.custom_callbacks[evt] == 'function') {
13574
+ return this.config.custom_callbacks[evt](obj);
13575
+ }
13576
+ };
13577
+ /**
13578
+ * To set area dimensions.
13579
+ * This is needed to achieve the same result in all browsers.
13580
+ * @author adam
13581
+ * @date 10-12-2007 22:29:41
13582
+ * @param id The id of the area (canvas) to resize.
13583
+ * @param w The desired width in pixels.
13584
+ * @param h The desired height in pixels.
13585
+ */
13586
+ this.setAreaSize = function (id, w, h) {
13587
+ if (id === null) {
13588
+ id = this.currentid;
13589
+ }
13590
+ var area = this.areas[id];
13591
+ if (w !== null) {
13592
+ area.width = w;
13593
+ area.style.width = (w) + 'px';
13594
+ area.setAttribute('width', w);
13595
+ }
13596
+ if (h !== null) {
13597
+ area.height = h;
13598
+ area.style.height = (h) + 'px';
13599
+ area.setAttribute('height', h);
13600
+ }
13601
+ };
13602
+ /**
13603
+ * Disable selection on a given object.
13604
+ * This is especially useful in Safari, where dragging around areas
13605
+ * keeps selecting all sorts of things.
13606
+ * @author Bret Taylor
13607
+ * @url http://ajaxcookbook.org/disable-text-selection/
13608
+ * @date 27-07-2008 1:57:45
13609
+ * @param element The DOM element on which you want to disable selection.
13610
+ */
13611
+ this.disableSelection = function (element) {
13612
+ if (typeof element == 'undefined' || !element) {
13613
+ return false;
13614
+ }
13615
+ if (typeof element.onselectstart != "undefined") {
13616
+ element.onselectstart = function () {
13617
+ return false;
13618
+ };
13619
+ }
13620
+ if (typeof element.unselectable != "undefined") {
13621
+ element.unselectable = "on";
13622
+ }
13623
+ if (typeof element.style.MozUserSelect != "undefined") {
13624
+ element.style.MozUserSelect = "none";
13625
+ }
13626
+ };
13627
+ this.config = {
13628
+ custom_callbacks: {},
13629
+ //default color values
13630
+ CL_DRAW_SHAPE: '#d00',
13631
+ CL_DRAW_BG: '#fff',
13632
+ CL_NORM_SHAPE: '#d00',
13633
+ CL_NORM_BG: '#fff',
13634
+ CL_HIGHLIGHT_SHAPE: '#d00',
13635
+ CL_HIGHLIGHT_BG: '#fff',
13636
+ CL_KNOB: '#555',
13637
+ bounding_box: true,
13638
+ label: '%n',
13639
+ label_class: 'imgmap_label',
13640
+ label_style: 'font: bold 10px Arial',
13641
+ hint: '#%n %h',
13642
+ draw_opacity: '35',
13643
+ norm_opacity: '50',
13644
+ highlight_opacity: '70',
13645
+ cursor_default: 'crosshair' //the css cursor while hovering over the image
13646
+ };
13647
+ //browser sniff
13648
+ const navigator = window.navigator;
13649
+ const userAgent = window.navigator.userAgent;
13650
+ this.isMSIE = (navigator.appName == "Microsoft Internet Explorer");
13651
+ this.isSafari = userAgent.indexOf('Safari') != -1;
13652
+ this.setup(options);
13653
+ }
13654
+ }
13655
+ /**
13656
+ * Trims a string.
13657
+ * Changed not to extend String but use own function for better compatibility.
13658
+ * @param str The string to trim.
13659
+ */
13660
+ function trim(str) {
13661
+ return str.replace(/^\s+|\s+$/g, '');
13662
+ }
13663
+ ;
13664
+
13665
+ function invalidURLValidator(regex) {
13666
+ return (control) => {
13667
+ const invalid = regex.test(control.value);
13668
+ return invalid ? { invalidURL: { value: 'control.value' } } : null;
13669
+ };
13670
+ }
13671
+
13672
+ class QMSCKEditorImageMapComponent extends QMSCKEditorBaseComponent {
13673
+ constructor(renderer, cdr, dialog, translate, linkService, dialogRef, data, iconRegistry, sanitizer) {
13674
+ super();
13675
+ this.renderer = renderer;
13676
+ this.cdr = cdr;
13677
+ this.dialog = dialog;
13678
+ this.translate = translate;
13679
+ this.linkService = linkService;
13680
+ this.dialogRef = dialogRef;
13681
+ this.data = data;
13682
+ this.linkTypes = [];
13683
+ this.targets = [];
13684
+ this.protocols = [];
13685
+ this.modes = [];
13686
+ this.zoomTypes = [];
13687
+ this.url = '';
13688
+ this.processedUrl = '';
13689
+ this.selectedMode = ImageModeName.Rectangle;
13690
+ this.selectedLinkType = LinkType.url;
13691
+ this.selectedTarget = TargetTypeName.new;
13692
+ this.selectedProtocol = ProtocolTypeName.http;
13693
+ this.selectedZoom = 1.0;
13694
+ this.protocolRegex = /^(http|https|ftp|news):\/\/(?=.)/i;
13695
+ this.javascriptLinkRegex = /javascript\:/i;
13696
+ this.documentId = 0;
13697
+ //anchorTitle = '';
13698
+ this.anchorText = '';
13699
+ //anchorByName = '';
13700
+ this.advisoryTitle = '';
13701
+ this.isUrlProcessing = false;
13702
+ this.naturalImageWidth = 0;
13703
+ this.naturalImageHeight = 0;
13704
+ this.currentAreaId = -1;
13705
+ this.showImageMapInformation = false;
13706
+ this.anchorDocuments = [];
13707
+ //documentAnchors: IAnchor[];
13708
+ this.imageListeners = [];
13709
+ this.imageMapData = data;
13710
+ this.naturalImageHeight = this.imageMapData.imageHeight;
13711
+ this.naturalImageWidth = this.imageMapData.imageWidth;
13712
+ this.initFormControl();
13713
+ this.initSvgIcons(iconRegistry, sanitizer);
13714
+ }
13715
+ initDefaultValues() {
13716
+ this.selectedLinkType = LinkType.url;
13717
+ this.selectedTarget = TargetTypeName.new;
13718
+ this.selectedProtocol = ProtocolTypeName.http;
13719
+ this.url = '';
13720
+ this.processedUrl = '';
13721
+ this.advisoryTitle = '';
13722
+ this.anchorText = '';
13723
+ }
13724
+ initSvgIcons(iconRegistry, sanitizer) {
13725
+ iconRegistry.addSvgIconLiteral('vector-pointer', sanitizer.bypassSecurityTrustHtml(IconSvg.VECTOR_POINTER));
13726
+ iconRegistry.addSvgIconLiteral('vector-circle', sanitizer.bypassSecurityTrustHtml(IconSvg.VECTOR_CIRCLE));
13727
+ iconRegistry.addSvgIconLiteral('vector-rectangle', sanitizer.bypassSecurityTrustHtml(IconSvg.VECTOR_RECTANGLE));
13728
+ iconRegistry.addSvgIconLiteral('vector-polygon', sanitizer.bypassSecurityTrustHtml(IconSvg.VECTOR_POLYGON));
13729
+ iconRegistry.addSvgIconLiteral('vector-remove', sanitizer.bypassSecurityTrustHtml(IconSvg.VECTOR_REMOVE));
13730
+ }
13731
+ initFormControl() {
13732
+ const valiationControls = {
13733
+ targetList: new FormControl(),
13734
+ protocolList: new FormControl(),
13735
+ anchorTextList: new FormControl(),
13736
+ modeList: new FormControl(),
13737
+ zoomList: new FormControl(),
13738
+ linkTypeList: new FormControl()
13739
+ };
13740
+ if (this.imageMapData.linkJavaScriptLinksAllowed == true) {
13741
+ valiationControls['url'] = new FormControl('', [Validators.required]);
13742
+ }
13743
+ else {
13744
+ valiationControls['url'] = new FormControl('', [Validators.required, invalidURLValidator(this.javascriptLinkRegex)]);
13745
+ }
13746
+ this.imageMapFormGroup = new FormGroup(valiationControls);
13747
+ }
13748
+ initLinkType() {
13749
+ if (this.linkTypes) {
13750
+ this.linkTypes.push({ id: LinkType.url, name: this.LANG.QMSCKEDITOR.LINK_URL });
13751
+ this.linkTypes.push({
13752
+ id: LinkType.anchorText,
13753
+ name: this.LANG.QMSCKEDITOR.LINK_ANCHOR_IN_TEXT
13754
+ });
13755
+ }
13756
+ }
13757
+ initTarget() {
13758
+ if (this.targets) {
13759
+ this.targets.push({ id: TargetTypeName.new, name: this.LANG.QMSCKEDITOR.TARTGET_NEW });
13760
+ this.targets.push({ id: TargetTypeName.same, name: this.LANG.QMSCKEDITOR.TARGET_SAME });
13761
+ }
13762
+ }
13763
+ initProtocol() {
13764
+ if (this.protocols) {
13765
+ this.protocols.push({ id: ProtocolTypeName.http, name: this.LANG.QMSCKEDITOR.PROTOCOL_HTTP });
13766
+ this.protocols.push({ id: ProtocolTypeName.https, name: this.LANG.QMSCKEDITOR.PROTOCOL_HTTPS });
13767
+ this.protocols.push({ id: ProtocolTypeName.ftp, name: this.LANG.QMSCKEDITOR.PROTOCOL_FTP });
13768
+ this.protocols.push({ id: ProtocolTypeName.news, name: this.LANG.QMSCKEDITOR.PROTOCOL_NEW });
13769
+ this.protocols.push({ id: ProtocolTypeName.other, name: this.LANG.QMSCKEDITOR.PROTOCOL_OTHER });
13770
+ }
13771
+ }
13772
+ initModes() {
13773
+ if (this.modes) {
13774
+ this.modes.push({ id: ImageModeName.Pointer, name: this.LANG.QMSCKEDITOR.IMAGE_MODE_POINTER, icon: "vector-pointer" });
13775
+ this.modes.push({ id: ImageModeName.Rectangle, name: this.LANG.QMSCKEDITOR.IMAGE_MODE_RECTANGLE, icon: "vector-rectangle" });
13776
+ this.modes.push({ id: ImageModeName.Circle, name: this.LANG.QMSCKEDITOR.IMAGE_MODE_CIRCLE, icon: "vector-circle" });
13777
+ this.modes.push({ id: ImageModeName.Polygon, name: this.LANG.QMSCKEDITOR.IMAGE_MODE_POLYGON, icon: "vector-polygon" });
13778
+ this.modes.push({ id: ImageModeName.Remove, name: this.LANG.QMSCKEDITOR.IMAGE_MODE_REMOVE, icon: "vector-remove" });
13779
+ }
13780
+ }
13781
+ initZoomTypes() {
13782
+ if (this.zoomTypes) {
13783
+ this.zoomTypes.push({ id: 0.25, name: "25%" });
13784
+ this.zoomTypes.push({ id: 0.5, name: "50%" });
13785
+ this.zoomTypes.push({ id: 1.0, name: "100%" });
13786
+ this.zoomTypes.push({ id: 2.0, name: "200%" });
13787
+ this.zoomTypes.push({ id: 3.0, name: "300%" });
13788
+ }
13789
+ }
13790
+ initAnchor() {
13791
+ this.anchors = [];
13792
+ this.anchors = [{ value: 0, viewValue: '', anchorValue: LinkAnchor.Blank }];
13793
+ }
13794
+ ngOnInit() {
13795
+ this.translate.getLanguageSubject$.pipe(takeUntil(this.ngUnsubcribe)).subscribe((res) => {
13796
+ if (res) {
13797
+ this.LANG = this.translate.getObjectLang(res);
13798
+ }
13799
+ });
13800
+ this.initLinkType();
13801
+ this.initTarget();
13802
+ this.initProtocol();
13803
+ this.initModes();
13804
+ this.initZoomTypes();
13805
+ }
13806
+ ngOnDestroy() {
13807
+ super.ngOnDestroy();
13808
+ if (this.imageListeners && this.imageListeners.length > 0) {
13809
+ this.imageListeners.forEach(listener => {
13810
+ listener();
13811
+ });
13812
+ }
13813
+ }
13814
+ onImageLoad() {
13815
+ this.naturalImageHeight = this.naturalImageHeight != 0 ? this.naturalImageHeight : this.myImageRef.nativeElement.naturalHeight;
13816
+ this.naturalImageWidth = this.naturalImageWidth != 0 ? this.naturalImageWidth : this.myImageRef.nativeElement.naturalWidth;
13817
+ this.setImageSize();
13818
+ this.myImageMap.setMapJson({
13819
+ name: this.imageMapData.name,
13820
+ areas: this.imageMapData.areas
13821
+ });
13822
+ if (this.imageMapData.areas && this.imageMapData.areas.length > 0) {
13823
+ this.myImageMap.blurArea(this.myImageMap.currentid);
13824
+ this.myImageMap.currentid = 0;
13825
+ this.myImageMap.selectedId = 0;
13826
+ this.onSelectArea(this.myImageMap.areas[0]);
13827
+ this.myImageMap.highlightArea(0);
13828
+ }
13829
+ }
13830
+ ngAfterViewInit() {
13831
+ if (this.myImageRef) {
13832
+ this.imageListeners.push(this.renderer.listen(this.myImageRef.nativeElement, 'load', () => {
13833
+ this.onImageLoad();
13834
+ }));
13835
+ }
13836
+ // Avoid drag&drop of the image
13837
+ this.myImageMap = new QMSCKEditorImageMapLib({
13838
+ custom_callbacks: {
13839
+ "onAddArea": this.onAddArea.bind(this),
13840
+ 'onSelectArea': this.onSelectArea.bind(this),
13841
+ 'onRemoveArea': this.onRemoveArea.bind(this),
13842
+ 'onStatusMessage': this.onStatusMessage.bind(this)
13843
+ },
13844
+ imageElement: this.myImageRef.nativeElement,
13845
+ bounding_box: false,
13846
+ CL_DRAW_SHAPE: '#F00',
13847
+ CL_NORM_SHAPE: '#AAA',
13848
+ CL_HIGHLIGHT_SHAPE: '#F00',
13849
+ strings: {
13850
+ "POLYGON_DRAW": this.LANG.QMSCKEDITOR.POLYGON_DRAW,
13851
+ "RECTANGLE_DRAW": this.LANG.QMSCKEDITOR.RECTANGLE_DRAW,
13852
+ "SQUARE_DRAW": this.LANG.QMSCKEDITOR.SQUARE_DRAW,
13853
+ 'READY': '',
13854
+ 'RECTANGLE_MOVE': '',
13855
+ 'RECTANGLE_RESIZE_TOP': '',
13856
+ 'RECTANGLE_RESIZE_RIGHT': '',
13857
+ 'RECTANGLE_RESIZE_BOTTOM': '',
13858
+ 'RECTANGLE_RESIZE_LEFT': '',
13859
+ 'SQUARE_MOVE': '',
13860
+ 'SQUARE_RESIZE_TOP': '',
13861
+ 'SQUARE_RESIZE_RIGHT': '',
13862
+ 'SQUARE_RESIZE_BOTTOM': '',
13863
+ 'SQUARE_RESIZE_LEFT': '',
13864
+ 'POLYGON_MOVE': ''
13865
+ }
13866
+ });
13867
+ }
13868
+ parseLinkUrl(url, defaultProtocolName) {
13869
+ const protocol = this.protocolRegex.exec(url);
13870
+ if (protocol) {
13871
+ this.processedUrl = url.substr(protocol[0].length);
13872
+ this.url = this.processedUrl;
13873
+ this.selectedProtocol = protocol[0].toLowerCase();
13874
+ }
13875
+ else if (this.javascriptLinkRegex.test(url) && !this.imageMapData.linkJavaScriptLinksAllowed) {
13876
+ this.selectedProtocol = ProtocolTypeName.http;
13877
+ this.processedUrl = '';
13878
+ this.url = this.processedUrl;
13879
+ }
13880
+ else {
13881
+ this.processedUrl = url;
13882
+ this.url = this.processedUrl;
13883
+ if (!!this.selectedProtocol) {
13884
+ this.selectedProtocol = defaultProtocolName || ProtocolTypeName.http;
13885
+ }
13886
+ }
13887
+ }
13888
+ onSelectArea(area) {
13889
+ this.currentAreaId = area.aid;
13890
+ this.showImageMapInformation = true;
13891
+ if (this.selectedMode == ImageModeName.Remove) {
13892
+ this.myImageMap.removeArea(this.currentAreaId);
13893
+ }
13894
+ else {
13895
+ if (area.ahref.match(/^#(.*)$/)) {
13896
+ this.anchorText = area.ahref.slice(1);
13897
+ this.selectedLinkType = LinkType.anchorText;
13898
+ }
13899
+ else {
13900
+ this.selectedLinkType = LinkType.url;
13901
+ this.parseLinkUrl(area.ahref);
13902
+ }
13903
+ this.selectedTarget = area.atarget;
13904
+ this.advisoryTitle = area.aalt;
13905
+ this.cdr.detectChanges();
13906
+ }
13907
+ }
13908
+ onRemoveArea() {
13909
+ this.currentAreaId = -1;
13910
+ this.showImageMapInformation = false;
13911
+ }
13912
+ removeMap() {
13913
+ this.currentAreaId = -1;
13914
+ this.showImageMapInformation = false;
13915
+ this.myImageMap.removeAllAreas();
13916
+ }
13917
+ onStatusMessage(text) {
13918
+ if (this.myStatusRef) {
13919
+ this.myStatusRef.nativeElement.innerHTML = text || '';
13920
+ }
13921
+ }
13922
+ onUrlKeyup() {
13923
+ this.isUrlProcessing = true;
13924
+ if (this.url != this.processedUrl) {
13925
+ this.parseLinkUrl(this.url);
13926
+ this.updateAreaValues();
13927
+ }
13928
+ this.isUrlProcessing = false;
13929
+ }
13930
+ onUrlChange() {
13931
+ if (!this.isUrlProcessing) {
13932
+ this.onUrlKeyup();
13933
+ }
13934
+ }
13935
+ onAnchorTextChange() {
13936
+ this.updateAreaValues();
13937
+ }
13938
+ onProtocolChange() {
13939
+ this.updateAreaValues();
13940
+ }
13941
+ onTargetChange() {
13942
+ this.updateAreaValues();
13943
+ }
13944
+ onAddArea(id) {
13945
+ this.currentAreaId = id;
13946
+ this.showImageMapInformation = true;
13947
+ this.initDefaultValues();
13948
+ this.updateAreaValues();
13949
+ }
13950
+ updateAreaValues() {
13951
+ if (this.currentAreaId > -1) {
13952
+ var ahref = this.buildUrlWithProtocol();
13953
+ if (this.selectedLinkType == LinkType.anchorText) {
13954
+ this.myImageMap.areas[this.currentAreaId].atarget = TargetTypeName.same;
13955
+ this.myImageMap.areas[this.currentAreaId].aalt = this.anchorText;
13956
+ }
13957
+ else {
13958
+ this.myImageMap.areas[this.currentAreaId].atarget = this.selectedTarget || TargetTypeName.new;
13959
+ this.myImageMap.areas[this.currentAreaId].aalt = this.advisoryTitle;
13960
+ }
13961
+ this.myImageMap.areas[this.currentAreaId].ahref = ahref;
13962
+ }
13963
+ }
13964
+ buildUrlWithProtocol() {
13965
+ if (this.selectedLinkType == LinkType.anchorText) {
13966
+ return '#' + (this.anchorText || '');
13967
+ }
13968
+ if (!!this.processedUrl) {
13969
+ return this.selectedProtocol + this.processedUrl;
13970
+ }
13971
+ return '';
13972
+ }
13973
+ ngAfterViewChecked() {
13974
+ this.cdr.detectChanges();
13975
+ }
13976
+ onCloseDialog() {
13977
+ this.dialogRef.close();
13978
+ }
13979
+ onModeChange(e) {
13980
+ this.selectedMode = e.value;
13981
+ if (this.selectedMode == ImageModeName.Pointer || this.selectedMode == ImageModeName.Remove) {
13982
+ this.myImageMap.is_drawing = 0;
13983
+ this.myImageMap.nextShape = '';
13984
+ this.myImageRef.nativeElement.style.cursor = 'default';
13985
+ }
13986
+ else {
13987
+ this.myImageMap.nextShape = this.selectedMode;
13988
+ this.myImageRef.nativeElement.style.cursor = 'crosshair';
13989
+ }
13990
+ }
13991
+ onZoomChange() {
13992
+ this.setImageSize();
13993
+ if (this.myImageMap) {
13994
+ this.myImageMap.scaleAllAreas(this.selectedZoom);
13995
+ }
13996
+ }
13997
+ onLinkTypeChange() {
13998
+ if (this.selectedLinkType === LinkType.anchorText) {
13999
+ this.getEditorAnchor();
14000
+ }
14001
+ this.updateAreaValues();
14002
+ }
14003
+ getEditorAnchor() {
14004
+ this.anchorDocuments = [];
14005
+ if (this.imageMapData.editorContent) {
14006
+ this.anchorDocuments.push({
14007
+ id: 0,
14008
+ entityId: 0,
14009
+ documentId: 0,
14010
+ documentTypeId: 0,
14011
+ richText: this.imageMapData.editorContent
14012
+ });
14013
+ }
14014
+ this.setAnchorDocument(this.anchorDocuments);
14015
+ this.editorAnchors = this.anchors;
14016
+ }
14017
+ setImageSize() {
14018
+ if (this.myImageRef) {
14019
+ const width = this.naturalImageWidth * this.selectedZoom;
14020
+ const height = this.naturalImageHeight * this.selectedZoom;
14021
+ this.myImageRef.nativeElement.setAttribute("width", `${width}px;`);
14022
+ this.myImageRef.nativeElement.setAttribute("height", `${height}px;`);
14023
+ this.myImageRef.nativeElement.style.width = `${width}px`;
14024
+ this.myImageRef.nativeElement.style.height = `${height}px`;
14025
+ this.myImageRef.nativeElement.style.cursor = this.selectedMode == ImageModeName.Pointer || this.selectedMode == ImageModeName.Remove ? 'default' : 'crosshair';
14026
+ }
14027
+ }
14028
+ eHandbook(isOnlyDocument, isAnchorDocument) {
14029
+ const data = new QMSCKEditorRelation();
14030
+ data.isOnlyDocument = isOnlyDocument;
14031
+ data.isEnableFolder = !isOnlyDocument;
14032
+ const dialogTemplate = this.dialog.open(QMSCKEditorRelatedComponent, {
14033
+ width: '650px',
14034
+ height: '650px',
14035
+ data,
14036
+ disableClose: true
14037
+ });
14038
+ dialogTemplate
14039
+ .afterClosed()
14040
+ .pipe(takeUntil(this.ngUnsubcribe))
14041
+ .subscribe((result) => {
14042
+ if (result) {
14043
+ if (isAnchorDocument) {
14044
+ this.documentId = result.id;
14045
+ //this.anchorTitle = `${result.title}(${result.id})`;
14046
+ this.getAnchorDocument(result.id);
14047
+ }
14048
+ else {
14049
+ this.parseLinkUrl(result.url);
14050
+ this.selectedProtocol = ProtocolTypeName.other;
14051
+ if (!this.advisoryTitle) {
14052
+ this.advisoryTitle = result.title;
14053
+ }
14054
+ }
14055
+ this.updateAreaValues();
14056
+ }
14057
+ });
14058
+ }
14059
+ getAnchorDocument(documentId) {
14060
+ this.linkService
14061
+ .getAnchorDocumentList(documentId)
14062
+ .pipe(takeUntil(this.ngUnsubcribe))
14063
+ .subscribe((res) => {
14064
+ if (res) {
14065
+ this.anchorDocuments = res;
14066
+ this.setAnchorDocument(this.anchorDocuments);
14067
+ //this.documentAnchors = this.anchors;
14068
+ }
14069
+ else {
14070
+ this.anchorDocuments = [];
14071
+ this.setAnchorDocument(this.anchorDocuments);
14072
+ //this.documentAnchors = this.anchors;
14073
+ }
14074
+ });
14075
+ }
14076
+ setAnchorDocument(anchorDocument) {
14077
+ this.initAnchor();
14078
+ let id = 3;
14079
+ if (anchorDocument) {
14080
+ anchorDocument.forEach((e) => {
14081
+ const div = document.createElement('div');
14082
+ div.innerHTML = e.richText;
14083
+ const domContent = div;
14084
+ const aTags = domContent.getElementsByTagName('a');
14085
+ if (aTags) {
14086
+ // tslint:disable-next-line:prefer-for-of
14087
+ for (let i = 0; i < aTags.length; i++) {
14088
+ const tag = aTags[i];
14089
+ if (tag.name) {
14090
+ const index = this.anchors.findIndex((x) => {
14091
+ return x.anchorValue === tag.name;
14092
+ });
14093
+ if (index < 0) {
14094
+ this.anchors.push({
14095
+ value: id,
14096
+ viewValue: tag.name,
14097
+ anchorValue: tag.name
14098
+ });
14099
+ id += 1;
14100
+ }
14101
+ }
14102
+ }
14103
+ }
14104
+ });
14105
+ }
14106
+ // this.anchors.push({
14107
+ // value: 1,
14108
+ // viewValue: this.LANG.QMSCKEDITOR.ANCHOR_ATTACHMENT,
14109
+ // anchorValue: LinkAnchor.Attachment
14110
+ // });
14111
+ // this.anchors.push({
14112
+ // value: 2,
14113
+ // viewValue: this.LANG.QMSCKEDITOR.ANCHOR_RELATED_DOCUMENT,
14114
+ // anchorValue: LinkAnchor.Related
14115
+ // });
14116
+ }
14117
+ attachment() {
14118
+ const data = new QMSCKEditorParamter();
14119
+ data.module = this.imageMapData.module;
14120
+ data.entityId = this.imageMapData.entityId;
14121
+ const dialogTemplate = this.dialog.open(LinkAttachmentComponent, {
14122
+ width: '650px',
14123
+ height: '650px',
14124
+ data,
14125
+ disableClose: true
14126
+ });
14127
+ dialogTemplate
14128
+ .afterClosed()
14129
+ .pipe(takeUntil(this.ngUnsubcribe))
14130
+ .subscribe((result) => {
14131
+ if (result) {
14132
+ this.parseLinkUrl(result.url);
14133
+ this.selectedProtocol = ProtocolTypeName.other;
14134
+ if (!this.advisoryTitle) {
14135
+ this.advisoryTitle = result.title;
14136
+ }
14137
+ this.updateAreaValues();
14138
+ }
14139
+ });
14140
+ }
14141
+ save() {
14142
+ const data = this.myImageMap.getMapJson();
14143
+ data.imageHeight = this.naturalImageHeight;
14144
+ data.imageWidth = this.naturalImageWidth;
14145
+ this.dialogRef.close(data);
14146
+ }
14147
+ cancel() {
14148
+ this.dialogRef.close();
14149
+ }
14150
+ }
14151
+ QMSCKEditorImageMapComponent.decorators = [
14152
+ { type: Component, args: [{
14153
+ selector: 'app-qmsck-imagemap',
14154
+ template: "<div id=\"qmsckeditor-imagemap\" class=\"qmsckeditor qmsckeditor__imagemap__container\">\r\n <div id=\"qmsckeditor-imagemap-header\">\r\n <span id=\"qmsckeditor-imagemap-header_001\" mat-icon-button class=\"qmsckeditor button__close\"\r\n (click)=\"onCloseDialog()\">\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n <div id=\"qmsckeditor-imagemap-header_002\" mat-dialog-content>\r\n <h2 id=\"qmsckeditor-imagemap_002_001\">\r\n {{ LANG.QMSCKEDITOR.IMAGE_MAP_PROPERTIES }}\r\n </h2>\r\n </div>\r\n </div>\r\n <div id=\"qmsckeditor-imagemap-content\">\r\n <div id=\"qmsckeditor-imagemap-content_001\" class=\"col-12 mt-1 pl-2 pr-2\">\r\n <mat-expansion-panel id=\"qmsckeditor-imagemap-panel\" [expanded]=\"true\" (opened)=\"(true)\" (closed)=\"(false)\">\r\n <div id=\"qmsckeditor-imagemap-panel_001\">\r\n <div id=\"qmsckeditor-imagemap-panel_001_001\" class=\"qmsckeditor__imagemap__information\">\r\n <form [formGroup]=\"imageMapFormGroup\">\r\n <div class=\"row\">\r\n <div class=\"col-9\">\r\n <mat-button-toggle-group [(ngModel)]=\"selectedMode\" formControlName=\"modeList\"\r\n (change)=\"onModeChange($event)\">\r\n <mat-button-toggle *ngFor=\"let mode of modes\" [value]=\"mode.id\"\r\n [matTooltip]=\"mode.name\">\r\n <mat-icon color=\"red\" [svgIcon]=\"mode.icon\" aria-hidden=\"true\">\r\n </mat-icon>\r\n </mat-button-toggle>\r\n </mat-button-toggle-group>\r\n <span style=\"margin-left: 15px;\" #myStatus></span>\r\n </div>\r\n <div class=\"col-3\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-3 pb-1\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.ZOOM }}</mat-label>\r\n <mat-select [(ngModel)]=\"selectedZoom\" formControlName=\"zoomList\"\r\n (ngModelChange)=\"onZoomChange()\" disableOptionCentering>\r\n <mat-option *ngFor=\"let zoomType of zoomTypes\" [value]=\"zoomType.id\">\r\n {{ zoomType.name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n <div class=\"row\" [ngClass]=\"{'hidden': !showImageMapInformation}\">\r\n <div class=\"col-3\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-3 pb-1\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.LINK_TYPE }}</mat-label>\r\n <mat-select [(ngModel)]=\"selectedLinkType\" formControlName=\"linkTypeList\"\r\n (ngModelChange)=\"onLinkTypeChange()\" disableOptionCentering>\r\n <mat-option *ngFor=\"let link of linkTypes\" [value]=\"link.id\">\r\n {{ link.name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n <div class=\"col-3\" *ngIf=\"selectedLinkType === 0\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-3 pb-1\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.TARGET }}</mat-label>\r\n <mat-select [(ngModel)]=\"selectedTarget\" formControlName=\"targetList\"\r\n (ngModelChange)=\"onTargetChange()\" disableOptionCentering>\r\n <mat-option *ngFor=\"let target of targets\" [value]=\"target.id\">\r\n {{ target.name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n <div class=\"row\" [ngClass]=\"{'hidden': !showImageMapInformation}\"\r\n *ngIf=\"selectedLinkType === 1\">\r\n <div class=\"col-3\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.ANCHOR_BY_NAME }}</mat-label>\r\n <mat-select [(ngModel)]=\"anchorText\" formControlName=\"anchorTextList\"\r\n (ngModelChange)=\"onAnchorTextChange()\">\r\n <mat-option *ngFor=\"let editorAnchor of editorAnchors\"\r\n [value]=\"editorAnchor.anchorValue\" disableOptionCentering>\r\n {{ editorAnchor.viewValue }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n </div>\r\n <div class=\"row\" [ngClass]=\"{'hidden': !showImageMapInformation}\"\r\n *ngIf=\"selectedLinkType === 0\">\r\n <div class=\"col-3\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-3 pb-1\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.PROTOCOL }}</mat-label>\r\n <mat-select [(ngModel)]=\"selectedProtocol\" formControlName=\"protocolList\"\r\n (ngModelChange)=\"onProtocolChange()\" disableOptionCentering>\r\n <mat-option *ngFor=\"let protocol of protocols\" [value]=\"protocol.id\">\r\n {{ protocol.name }}\r\n </mat-option>\r\n </mat-select>\r\n </mat-form-field>\r\n </div>\r\n <div class=\"col-5\">\r\n <mat-form-field appearance=\"fill\" class=\"col-12 pl-3 pr-3 pb-1\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.LINK_URL }}</mat-label>\r\n <input matInput [(ngModel)]=\"url\" name=\"url\" formControlName=\"url\"\r\n (ngModelChange)=\"onUrlChange()\" (keyup)=\"onUrlKeyup()\" />\r\n <mat-error *ngIf=\"imageMapFormGroup.get('url').hasError('required')\">{{\r\n LANG.QMSCKEDITOR.REQUIRED_URL }}\r\n </mat-error>\r\n <mat-error *ngIf=\"imageMapFormGroup.get('url').hasError('invalidURL')\">{{\r\n LANG.QMSCKEDITOR.INVALID_URL }}</mat-error>\r\n </mat-form-field>\r\n </div>\r\n <div class=\"col-4\">\r\n <div class=\"row button__groups\">\r\n <div class=\"col-6\">\r\n <button class=\"save\" mat-stroked-button (click)=\"attachment()\">\r\n {{ LANG.QMSCKEDITOR.ATTACHMENT }}\r\n </button>\r\n </div>\r\n <div class=\"col-6\">\r\n <button class=\"save\" mat-stroked-button (click)=\"eHandbook(false, false)\">\r\n {{ LANG.QMSCKEDITOR.HANDBOOK }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </form>\r\n </div>\r\n <div id=\"qmsckeditor-imagemap-panel_001_002\" class=\"qmsckeditor__imagemap__map\">\r\n <img #myImage [src]=\"imageMapData.imageUrl\">\r\n </div>\r\n <div id=\"qmsckeditor-imagemap-panel_001_003\" class=\"qmsckeditor button__groups row mr-0 ml-0 mt-4\">\r\n <div class=\"col-4 pr-0\">\r\n <button class=\"save\" mat-flat-button (click)=\"removeMap()\">\r\n {{ LANG.QMSCKEDITOR.REMOVE_MAP }}\r\n </button>\r\n </div>\r\n <div class=\"col-4 pr-0\">\r\n <button class=\"save\" mat-flat-button (click)=\"save()\">\r\n {{ LANG.QMSCKEDITOR.SAVE }}\r\n </button>\r\n </div>\r\n <div class=\"col-4 pl-0\">\r\n <button class=\"cancel\" mat-flat-button (click)=\"cancel()\">\r\n {{ LANG.QMSCKEDITOR.CANCEL }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </mat-expansion-panel>\r\n </div>\r\n </div>\r\n</div>",
14155
+ styles: [".mt5{margin-top:5px!important}.mt10{margin-top:10px!important}.mt7{margin-top:7px!important}.mt15{margin-top:15px!important}.mt20{margin-top:20px!important}.mt30{margin-top:30px!important}.mt40{margin-top:40px!important}.ml2{margin-left:2px!important}.ml3{margin-left:3px!important}.ml5{margin-left:5px!important}.ml15{margin-left:15px!important}.ml10{margin-left:10px!important}.ml12{margin-left:12px!important}.ml16{margin-left:16px!important}.ml-auto{margin-left:auto!important}.ml-25{margin-left:-25px!important}.mr5{margin-right:5px!important}.mr12{margin-right:12px!important}.mr15{margin-right:15px!important}.mb5{margin-bottom:5px!important}.mb10{margin-bottom:10px!important}.mb15{margin-bottom:15px!important}.pt8{padding-top:8px!important}.pt10{padding-top:10px!important}.pt15{padding-top:15px!important}.pt16{padding-top:16px!important}.pl15{padding-left:15px!important}.pl0{padding-left:0!important}.pr0{padding-right:0!important}.pr15{padding-right:15px!important}.fs12{font-size:12px}.fs14{font-size:14px!important}.fs16{font-size:16px!important}.fs22{font-size:22px!important}.fw500{font-weight:500!important}.italic-text{font-style:italic}.display-flex{display:flex}.qmsckeditor{font-family:Roboto,Helvetica Neue,sans-serif;font-size:14px;font-weight:400}.qmsckeditor h2{font-size:20px;font-weight:400}.qmsckeditor .mat-dialog-content{padding:0}.qmsckeditor .mat-icon{color:#909497}.qmsckeditor__fullscreen{position:fixed;top:0;left:0;right:0;bottom:0;background:#fff;overflow-y:auto;max-height:100vh;overflow-x:hidden}.qmsckeditor__cursor{cursor:pointer}.qmsckeditor__notallowed{cursor:not-allowed}.qmsckeditor.button__close,.qmsckeditor.button__done{float:right;top:-24px;right:-24px;cursor:pointer}.qmsckeditor.button__done{margin-right:20px}.qmsckeditor.button__done .mat-icon{color:#28a745;font-weight:700}.qmsckeditor.button__groups button{min-height:40px;width:100%;border-radius:4px;border:1px solid #c5c5c5;font-family:Open Sans;font-weight:600;font-size:14px;letter-spacing:1px;line-height:16px}.qmsckeditor.button__groups .save{background:#f8f9f9}.qmsckeditor.button__groups .save:hover{background:#e5e7e9}.qmsckeditor.button__groups .save:disabled{cursor:not-allowed}.qmsckeditor.button__groups .cancel{background:#f8f9f9}.qmsckeditor.button__groups .cancel:hover{background:#e5e7e9}.qmsckeditor.button__groups .cancel:disabled{cursor:not-allowed}.qmsckeditor.button__groups .delete{background:#f8f9f9}.qmsckeditor.button__groups .delete:hover{background:#e5e7e9}.qmsckeditor.button__groups .delete:disabled{cursor:not-allowed}.qmsckeditor.confirm__button__groups button{min-height:36px;border-radius:4px;width:auto;border:1px solid #c5c5c5;font-family:Open Sans;font-weight:600;font-size:14px;letter-spacing:1px;line-height:16px;padding-left:15px;padding-right:15px}.qmsckeditor.confirm__button__groups .confirm{background:#f8f9f9}.qmsckeditor.confirm__button__groups .confirm:hover{background:#e5e7e9}.qmsckeditor.confirm__button__groups .cancel{background:#f8f9f9}.qmsckeditor.confirm__button__groups .cancel:hover{background:#e5e7e9}.qmsckeditor.template-content.height{min-height:420px;max-height:520px;overflow:auto}.qmsckeditor.template-content.title{margin-left:-9px}.qmsckeditor.link__content.height{min-height:400px;max-height:520px}.qmsckeditor.card{margin-bottom:10px;min-height:60px;box-shadow:none;border:1px solid #e5e5e5}.qmsckeditor.card .title{font-weight:700}.qmsckeditor.card .content{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.qmsckeditor.card .material-icons{font-size:20px}.qmsckeditor.tooltip-content.height{min-height:400px;max-height:470px;overflow:auto}.qmsckeditor.save__as__template.height{height:125px}.ck-content .page-break,.qmsckeditor__imagemap__container .mat-form-field{width:100%}.qmsckeditor__imagemap__container .qmsckeditor__imagemap__information{position:relative}.qmsckeditor__imagemap__container .qmsckeditor__imagemap__map{overflow:auto;width:800px;min-height:371px;position:relative;max-height:460px}.qmsckeditor__imagemap__container .mat-button-toggle-checked{border:1px solid #000!important}.qmsckeditor__imagemap__container .hidden{visibility:hidden}"]
14156
+ },] }
14157
+ ];
14158
+ QMSCKEditorImageMapComponent.ctorParameters = () => [
14159
+ { type: Renderer2 },
14160
+ { type: ChangeDetectorRef },
14161
+ { type: MatDialog },
14162
+ { type: TranslateLibraryService },
14163
+ { type: QMSCKEditorLinkService },
14164
+ { type: MatDialogRef },
14165
+ { type: QMSCKEditorImageMap, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] },
14166
+ { type: MatIconRegistry },
14167
+ { type: DomSanitizer }
14168
+ ];
14169
+ QMSCKEditorImageMapComponent.propDecorators = {
14170
+ myImageRef: [{ type: ViewChild, args: ['myImage',] }],
14171
+ myStatusRef: [{ type: ViewChild, args: ['myStatus',] }]
14172
+ };
14173
+
14174
+ class QMSCKEditorTooltip {
14175
+ constructor() {
14176
+ this.text = '';
14177
+ this.content = '';
14178
+ }
14179
+ }
14180
+
14181
+ class QMSCKEditorTooltipComponent extends QMSCKEditorBaseComponent {
14182
+ constructor(cdr, translate, dialogRef, data) {
14183
+ super();
14184
+ this.cdr = cdr;
14185
+ this.translate = translate;
14186
+ this.dialogRef = dialogRef;
14187
+ this.data = data;
14188
+ this.tooltipFormGroup = new FormGroup({
14189
+ title: new FormControl('', [Validators.required]),
14190
+ content: new FormControl('', [Validators.required])
14191
+ });
14192
+ this.tooltip = { text: data.text, content: data.content };
14193
+ this.editor = data.ckEditor;
14194
+ }
14195
+ ngOnInit() {
14196
+ this.translate.getLanguageSubject$.pipe(takeUntil(this.ngUnsubcribe)).subscribe((res) => {
14197
+ if (res) {
14198
+ this.LANG = this.translate.getObjectLang(res);
14199
+ }
14200
+ });
14201
+ this.editorConfig = CKEditorCommonFunctions.getCKEditorConfiguration(',heading,|,fontsize,fontfamily,fontColor,fontBackgroundColor,|,bold,italic,underline,strikethrough,|,alignment,|,bulletedList,numberedList,|,outdent,indent,|,subscript,superscript,|,undo,redo,|,specialCharacters,blockQuote,insertTable,|,link,anchor,|,timestamp,|,removeformat');
14202
+ }
14203
+ ngAfterViewChecked() {
14204
+ this.cdr.detectChanges();
14205
+ }
14206
+ onCloseDialog() {
14207
+ this.dialogRef.close();
14208
+ }
14209
+ getOutputContent(content) {
14210
+ this.tooltip.content = content;
14211
+ }
14212
+ onChanged({ editor }) {
14213
+ this.tooltip.content = editor.getData();
14214
+ }
14215
+ onBlur({ editor }) {
14216
+ this.tooltip.content = editor.getData();
14217
+ }
14218
+ onReady(editor) {
14219
+ if (this.tooltip.text) {
14220
+ editor.setData(this.tooltip.text);
14221
+ }
14222
+ editor.ui.getEditableElement().parentElement.insertBefore(editor.ui.view.toolbar.element, editor.ui.getEditableElement());
14223
+ }
14224
+ saveTooltip() {
14225
+ const tooltip = new QMSCKEditorTooltip();
14226
+ tooltip.content = this.tooltip.content;
14227
+ tooltip.text = this.tooltip.text;
14228
+ this.dialogRef.close(tooltip);
14229
+ }
14230
+ cancelTooltip() {
14231
+ this.dialogRef.close();
14232
+ }
14233
+ }
14234
+ QMSCKEditorTooltipComponent.decorators = [
14235
+ { type: Component, args: [{
14236
+ selector: 'app-qmsck-tooltip',
14237
+ template: "<div\r\n id=\"qmsckeditor-tooltip\"\r\n class=\"qmsckeditor qmsckeditor__tooltip__container\"\r\n>\r\n <div id=\"qmsckeditor-tooltip-header\">\r\n <span\r\n id=\"qmsckeditor-tooltip-header_001\"\r\n mat-icon-button\r\n class=\"qmsckeditor button__close\"\r\n (click)=\"onCloseDialog()\"\r\n >\r\n <mat-icon>close</mat-icon>\r\n </span>\r\n <div id=\"qmsckeditor-tooltip-header_002\" mat-dialog-content>\r\n <h2 id=\"qmsckeditor-tooltip_002_001\">\r\n {{ LANG.QMSCKEDITOR.INSERT_TOOLTIP }}\r\n </h2>\r\n </div>\r\n </div>\r\n <form [formGroup]=\"tooltipFormGroup\">\r\n <div\r\n id=\"qmsckeditor-tooltip-content\"\r\n class=\"qmsckeditor tooltip-content height\"\r\n >\r\n <div id=\"qmsckeditor-tooltip-content_001\" class=\"col-12 mt-1 pl-2 pr-2\">\r\n <mat-expansion-panel\r\n id=\"qmsckeditor-tooltip-panel\"\r\n [expanded]=\"true\"\r\n (opened)=\"(true)\"\r\n (closed)=\"(false)\"\r\n >\r\n <div id=\"qmsckeditor-tooltip-panel_001\">\r\n <div id=\"qmsckeditor-tooltip-panel_001_001\">\r\n <mat-form-field class=\"col-12 pl-0 pr-0\" appearance=\"fill\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.TITLE }}</mat-label>\r\n <input\r\n matInput\r\n [(ngModel)]=\"tooltip.text\"\r\n formControlName=\"title\"\r\n />\r\n </mat-form-field>\r\n </div>\r\n <div id=\"qmsckeditor-tooltip-panel_001_002\">\r\n <mat-label>{{ LANG.QMSCKEDITOR.CONTENT }}</mat-label>\r\n <div class=\"qmsckeditor_container col-12 pl-0 pr-0\">\r\n <ckeditor\r\n class=\"qms-ckeditor\"\r\n [(editor)]=\"editor\"\r\n [config]=\"editorConfig\"\r\n (ready)=\"onReady($event)\"\r\n [(ngModel)]=\"tooltip.content\"\r\n (change)=\"onChanged($event)\"\r\n (blur)=\"onBlur($event)\"\r\n formControlName=\"content\"\r\n >\r\n </ckeditor>\r\n </div>\r\n </div>\r\n <div\r\n id=\"qmsckeditor-tooltip-panel_001_003\"\r\n class=\"qmsckeditor button__groups row mr-0 ml-0 mt-4\"\r\n >\r\n <div class=\"col-6 pr-0\">\r\n <button\r\n class=\"save\"\r\n mat-flat-button\r\n (click)=\"saveTooltip()\"\r\n [disabled]=\"tooltipFormGroup.invalid\"\r\n >\r\n {{ LANG.QMSCKEDITOR.SAVE }}\r\n </button>\r\n </div>\r\n <div class=\"col-6 pl-0\">\r\n <button\r\n class=\"cancel\"\r\n mat-flat-button\r\n (click)=\"cancelTooltip()\"\r\n >\r\n {{ LANG.QMSCKEDITOR.CANCEL }}\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n </mat-expansion-panel>\r\n </div>\r\n </div>\r\n </form>\r\n</div>\r\n",
14238
+ styles: [".mt5{margin-top:5px!important}.mt10{margin-top:10px!important}.mt7{margin-top:7px!important}.mt15{margin-top:15px!important}.mt20{margin-top:20px!important}.mt30{margin-top:30px!important}.mt40{margin-top:40px!important}.ml2{margin-left:2px!important}.ml3{margin-left:3px!important}.ml5{margin-left:5px!important}.ml15{margin-left:15px!important}.ml10{margin-left:10px!important}.ml12{margin-left:12px!important}.ml16{margin-left:16px!important}.ml-auto{margin-left:auto!important}.ml-25{margin-left:-25px!important}.mr5{margin-right:5px!important}.mr12{margin-right:12px!important}.mr15{margin-right:15px!important}.mb5{margin-bottom:5px!important}.mb10{margin-bottom:10px!important}.mb15{margin-bottom:15px!important}.pt8{padding-top:8px!important}.pt10{padding-top:10px!important}.pt15{padding-top:15px!important}.pt16{padding-top:16px!important}.pl15{padding-left:15px!important}.pl0{padding-left:0!important}.pr0{padding-right:0!important}.pr15{padding-right:15px!important}.fs12{font-size:12px}.fs14{font-size:14px!important}.fs16{font-size:16px!important}.fs22{font-size:22px!important}.fw500{font-weight:500!important}.italic-text{font-style:italic}.display-flex{display:flex}.qmsckeditor{font-family:Roboto,Helvetica Neue,sans-serif;font-size:14px;font-weight:400}.qmsckeditor h2{font-size:20px;font-weight:400}.qmsckeditor .mat-dialog-content{padding:0}.qmsckeditor .mat-icon{color:#909497}.qmsckeditor__fullscreen{position:fixed;top:0;left:0;right:0;bottom:0;background:#fff;overflow-y:auto;max-height:100vh;overflow-x:hidden}.qmsckeditor__cursor{cursor:pointer}.qmsckeditor__notallowed{cursor:not-allowed}.qmsckeditor.button__close,.qmsckeditor.button__done{float:right;top:-24px;right:-24px;cursor:pointer}.qmsckeditor.button__done{margin-right:20px}.qmsckeditor.button__done .mat-icon{color:#28a745;font-weight:700}.qmsckeditor.button__groups button{min-height:40px;width:100%;border-radius:4px;border:1px solid #c5c5c5;font-family:Open Sans;font-weight:600;font-size:14px;letter-spacing:1px;line-height:16px}.qmsckeditor.button__groups .save{background:#f8f9f9}.qmsckeditor.button__groups .save:hover{background:#e5e7e9}.qmsckeditor.button__groups .save:disabled{cursor:not-allowed}.qmsckeditor.button__groups .cancel{background:#f8f9f9}.qmsckeditor.button__groups .cancel:hover{background:#e5e7e9}.qmsckeditor.button__groups .cancel:disabled{cursor:not-allowed}.qmsckeditor.button__groups .delete{background:#f8f9f9}.qmsckeditor.button__groups .delete:hover{background:#e5e7e9}.qmsckeditor.button__groups .delete:disabled{cursor:not-allowed}.qmsckeditor.confirm__button__groups button{min-height:36px;border-radius:4px;width:auto;border:1px solid #c5c5c5;font-family:Open Sans;font-weight:600;font-size:14px;letter-spacing:1px;line-height:16px;padding-left:15px;padding-right:15px}.qmsckeditor.confirm__button__groups .confirm{background:#f8f9f9}.qmsckeditor.confirm__button__groups .confirm:hover{background:#e5e7e9}.qmsckeditor.confirm__button__groups .cancel{background:#f8f9f9}.qmsckeditor.confirm__button__groups .cancel:hover{background:#e5e7e9}.qmsckeditor.template-content.height{min-height:420px;max-height:520px;overflow:auto}.qmsckeditor.template-content.title{margin-left:-9px}.qmsckeditor.link__content.height{min-height:400px;max-height:520px}.qmsckeditor.card{margin-bottom:10px;min-height:60px;box-shadow:none;border:1px solid #e5e5e5}.qmsckeditor.card .title{font-weight:700}.qmsckeditor.card .content{text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.qmsckeditor.card .material-icons{font-size:20px}.qmsckeditor.tooltip-content.height{min-height:400px;max-height:470px;overflow:auto}.qmsckeditor.save__as__template.height{height:125px}.ck-content .page-break,.qmsckeditor__tooltip__container .mat-form-field{width:100%}.qmsckeditor__tooltip__container textarea.mat-input-element{min-height:150px}"]
14239
+ },] }
14240
+ ];
14241
+ QMSCKEditorTooltipComponent.ctorParameters = () => [
14242
+ { type: ChangeDetectorRef },
14243
+ { type: TranslateLibraryService },
14244
+ { type: MatDialogRef },
14245
+ { type: QMSCKEditorTooltip, decorators: [{ type: Inject, args: [MAT_DIALOG_DATA,] }] }
14246
+ ];
14247
+
14248
+ class QMSCKEditorComponent extends QMSCKEditorBaseComponent {
14249
+ /**
14250
+ * Constructor
14251
+ */
14252
+ constructor(dialog, globalService, qmsCKEditorFullscreenComponent, renderer, elRef) {
14253
+ super();
14254
+ this.dialog = dialog;
14255
+ this.globalService = globalService;
14256
+ this.qmsCKEditorFullscreenComponent = qmsCKEditorFullscreenComponent;
14257
+ this.renderer = renderer;
14258
+ this.elRef = elRef;
14259
+ this.required = false;
14260
+ this.qmsckContentOutput = new EventEmitter();
14261
+ this.ckEditorEventConst = CKEditorEventConst;
14262
+ }
14263
+ onMessage(event) {
14264
+ switch (event.data.eventName) {
14265
+ case this.ckEditorEventConst.QMSCK_FULLSCREEN_PLUGIN_MSG:
14266
+ this.fullscreenEventHandling();
14267
+ break;
14268
+ case this.ckEditorEventConst.QMSCK_TEMPLATE_PLUGIN_MSG:
14269
+ this.templateEventHandling();
14270
+ break;
14271
+ case this.ckEditorEventConst.QMSCK_LOAD_TEMPLATE_PLUGIN_MSG:
14272
+ this.loadTemplateEventHandling();
14273
+ break;
14274
+ case this.ckEditorEventConst.QMSCK_LINK_PLUGIN_MSG:
14275
+ this.linkEventHandling(event.data.value);
14276
+ break;
14277
+ case this.ckEditorEventConst.QMSCK_TOOLTIP_PLUGIN_MSG:
14278
+ this.tooltipEventHandling(event.data.value);
14279
+ break;
14280
+ case this.ckEditorEventConst.QMSCK_IMAGEMAP_PLUGIN_MSG:
14281
+ this.imageMapEventHandling(event.data.value);
14282
+ break;
14283
+ case this.ckEditorEventConst.QMSCK_BPMN_PLUGIN_MSG:
14284
+ this.bpmnEventHandling(event.data.value);
14285
+ break;
14286
+ default:
14287
+ break;
14288
+ }
14289
+ }
14290
+ ngOnInit() {
14291
+ this.name = 'CKEditor custom build';
14292
+ this.ckEditor = this.qmsckPlugin.pluginObject;
14293
+ this.ckeditorConfig = CKEditorCommonFunctions.getCKEditorConfiguration(this.qmsckPlugin.itemToolbar);
14294
+ this.globalService.setApiUrl(this.qmsckData.apiUrl);
14295
+ if (this.isEnabledCustomizingMathtypeService()) {
14296
+ this.customizeMathTypeService();
14297
+ }
14298
+ if (this.isEnabledCustomizingTimestampFormat()) {
14299
+ this.customizeTimestampFormat();
14300
+ }
14301
+ }
14302
+ registerOnChange(fn) {
14303
+ this.onChange = fn;
14304
+ }
14305
+ registerOnTouched(fn) {
14306
+ this.onTouched = fn;
14307
+ }
14308
+ ngAfterViewInit() {
14309
+ if (this.isDisabled) {
14310
+ this.renderer.addClass(this.elRef.nativeElement, 'ck-disabled');
14311
+ }
14312
+ }
14313
+ isEnabledCustomizingTimestampFormat() {
14314
+ const pattern = /(timestamp)/gmi;
14315
+ return !!this.qmsckData.timestampFormat
14316
+ && this.qmsckData.timestampFormat !== ''
14317
+ && !!this.qmsckPlugin.itemToolbar
14318
+ && this.qmsckPlugin.itemToolbar.search(pattern) > -1;
14319
+ }
14320
+ customizeTimestampFormat() {
14321
+ const timestampConfig = {
14322
+ timestampConfig: {
14323
+ datetimeFormat: this.qmsckData.timestampFormat
14324
+ }
14325
+ };
14326
+ this.ckEditor.defaultConfig = Object.assign(this.ckEditor.defaultConfig || {}, timestampConfig);
14327
+ }
14328
+ isEnabledCustomizingMathtypeService() {
14329
+ const pattern = /(MathType)|(ChemType)/gmi;
14330
+ return !!this.qmsckData.mathtypeServiceUrl
14331
+ && this.qmsckData.mathtypeServiceUrl !== ''
14332
+ && !!this.qmsckPlugin.itemToolbar
14333
+ && this.qmsckPlugin.itemToolbar.search(pattern) > -1;
14334
+ }
14335
+ customizeMathTypeService() {
14336
+ const mathTypeConfig = {
14337
+ mathTypeParameters: {
14338
+ serviceProviderProperties: {
14339
+ URI: this.qmsckData.mathtypeServiceUrl,
14340
+ server: 'aspx'
14341
+ }
14342
+ }
14343
+ };
14344
+ this.ckEditor.defaultConfig = Object.assign(this.ckEditor.defaultConfig || {}, mathTypeConfig);
14345
+ }
14346
+ onChanged({ editor }) {
14347
+ this.qmsckContentOutput.emit(this.qmsckContentInput);
14348
+ }
14349
+ onBlur({ editor }) {
14350
+ this.qmsckContentOutput.emit(this.qmsckContentInput);
14351
+ }
14352
+ validate(c) {
14353
+ if (!this.required) {
14354
+ return null;
14355
+ }
14356
+ return (this.qmsckContentInput && !this.required) ? null : {
14357
+ type: {
14358
+ valid: false,
14359
+ actual: c.value
14360
+ }
14361
+ };
14362
+ }
14363
+ /**
14364
+ * onReady
14365
+ */
14366
+ onReady(editor) {
14367
+ this.editorInstance = editor;
14368
+ if (this.qmsckContentInput) {
14369
+ editor.setData(this.qmsckContentInput);
14370
+ }
14371
+ this.initEditor(editor);
14372
+ }
14373
+ initEditor(editor) {
14374
+ editor.ui
14375
+ .getEditableElement()
14376
+ .parentElement.insertBefore(editor.ui.view.toolbar.element, editor.ui.getEditableElement());
14377
+ editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
14378
+ return new UploadAdapter(loader);
14379
+ };
14380
+ // Apped Wordcount to CKeditor
14381
+ editor.plugins.get('WordCount').on('update', (evt, stats) => {
14382
+ // Prints the current content statistics.
14383
+ const wordsBox = document.querySelector('.wordcount-content');
14384
+ wordsBox.textContent = `Words: ${stats.words} / Characters: ${stats.characters}`;
14385
+ });
14386
+ }
14387
+ /**
14388
+ * Full screen - Restore down
14389
+ */
14390
+ fullscreenEventHandling() {
14391
+ const ck = window.document.getElementById('qmsckeditor');
14392
+ if (ck) {
14393
+ if (!ck.classList.contains('qmsckeditor__fullscreen')) {
14394
+ this.qmsCKEditorFullscreenComponent.showFullScreen();
14395
+ }
14396
+ else {
14397
+ this.qmsCKEditorFullscreenComponent.hideFullScreen();
14398
+ }
14399
+ }
14400
+ }
14401
+ /**
14402
+ * Add template - Load template
14403
+ */
14404
+ templateEventHandling() {
14405
+ const data = new QMSCKEditorTemplate();
14406
+ data.id = 0;
14407
+ data.content = this.qmsckContentInput;
14408
+ data.edit = false;
14409
+ const dialogTemplate = this.dialog.open(QMSCKEditorTemplateComponent, {
11865
14410
  width: '650px',
11866
14411
  height: '520px',
11867
14412
  data,
@@ -11952,8 +14497,38 @@ class QMSCKEditorComponent extends QMSCKEditorBaseComponent {
11952
14497
  });
11953
14498
  }
11954
14499
  /**
11955
- * Business Process Model and Notation
11956
- */
14500
+ * ImageMap mapping
14501
+ */
14502
+ imageMapEventHandling(value) {
14503
+ let data = new QMSCKEditorImageMap();
14504
+ data.name = value.name;
14505
+ data.areas = value.areas;
14506
+ data.imageUrl = value.imageUrl;
14507
+ data.imageWidth = value.imageWidth;
14508
+ data.imageHeight = value.imageHeight;
14509
+ data.module = this.qmsckData.module;
14510
+ data.entityId = this.qmsckData.entityId;
14511
+ data.editorContent = this.qmsckContentInput;
14512
+ data.linkJavaScriptLinksAllowed = this.qmsckData.linkJavaScriptLinksAllowed;
14513
+ const dialogTemplate = this.dialog.open(QMSCKEditorImageMapComponent, {
14514
+ data,
14515
+ disableClose: true
14516
+ });
14517
+ dialogTemplate
14518
+ .afterClosed()
14519
+ .pipe(takeUntil(this.ngUnsubcribe))
14520
+ .subscribe((result) => {
14521
+ if (result) {
14522
+ const evt = new CustomEvent(this.ckEditorEventConst.QMSCK_IMAGEMAP_PLUGIN_RESP, {
14523
+ detail: result
14524
+ });
14525
+ window.dispatchEvent(evt);
14526
+ }
14527
+ });
14528
+ }
14529
+ /*
14530
+ Business Process Model and Notation
14531
+ */
11957
14532
  bpmnEventHandling(id) {
11958
14533
  const dialogTemplate = this.dialog.open(QMSCKEditorBpmnComponent, {
11959
14534
  width: '89vw',
@@ -11968,12 +14543,10 @@ class QMSCKEditorComponent extends QMSCKEditorBaseComponent {
11968
14543
  .pipe(takeUntil(this.ngUnsubcribe))
11969
14544
  .subscribe((result) => {
11970
14545
  if (result) {
11971
- if (result) {
11972
- const evt = new CustomEvent(this.ckEditorEventConst.QMSCK_BPMN_PLUGIN_RESP, {
11973
- detail: result
11974
- });
11975
- window.dispatchEvent(evt);
11976
- }
14546
+ const evt = new CustomEvent(this.ckEditorEventConst.QMSCK_BPMN_PLUGIN_RESP, {
14547
+ detail: result
14548
+ });
14549
+ window.dispatchEvent(evt);
11977
14550
  }
11978
14551
  });
11979
14552
  }
@@ -12036,6 +14609,7 @@ QMSCKEditorModule.decorators = [
12036
14609
  QMSCKEditorRelatedComponent,
12037
14610
  LinkAttachmentComponent,
12038
14611
  QMSCKEditorTooltipComponent,
14612
+ QMSCKEditorImageMapComponent,
12039
14613
  QMSCKEditorBpmnComponent,
12040
14614
  SaveTemplateComponent
12041
14615
  ],
@@ -12055,6 +14629,10 @@ QMSCKEditorModule.decorators = [
12055
14629
  MatSnackBarModule,
12056
14630
  MatSelectModule,
12057
14631
  MatButtonModule,
14632
+ MatButtonToggleModule,
14633
+ MatProgressSpinnerModule,
14634
+ MatTooltipModule,
14635
+ MatRadioModule,
12058
14636
  MatTreeModule,
12059
14637
  MatAutocompleteModule,
12060
14638
  ScrollingModule,
@@ -12076,14 +14654,6 @@ class QMSCKEditorData {
12076
14654
  }
12077
14655
 
12078
14656
  class QMSCKEdtiorInputData {
12079
- constructor() {
12080
- this.apiUrl = '';
12081
- this.module = 0;
12082
- this.entityId = '';
12083
- this.documentId = 0;
12084
- this.mathtypeServiceUrl = '';
12085
- this.timestampFormat = '';
12086
- }
12087
14657
  }
12088
14658
 
12089
14659
  class QMSCKEditorLinkAnchorDocument {
@@ -12577,5 +15147,5 @@ class QMSSnackbarConfig extends MatSnackBarConfig {
12577
15147
  * Generated bundle index. Do not edit.
12578
15148
  */
12579
15149
 
12580
- export { AutocompleteOffDirective, BREADCRUMB_DROPDOWN_ICON, BUTTON_TOGGLE_DEFAULT_OPTIONS, BUTTON_TOGGLE_GROUP, BUTTON_TOGGLE_GROUP_VALUE_ACCESSOR, BannerType, BpmnService, BreadcrumbNode, ButtonToggleChange, CHECKLIST_ICON, CKEditorEventConst, CKEditorModule, ConfirmDialog, DEPARTMENT_FOLDER_ICON, DEPARTMENT_FOLDER_OUTLINED_ICON, DEVIATION_ICON, DOCUMENT_DEPARTMENT_ICON, DOCUMENT_ENTERPRISE_ICON, DOCUMENT_ICON, DOCUMENT_LOCAL_ICON, DOCUMENT_REGIONAL_ICON, DateFormatPipe, ENTERPRISE_FOLDER_ICON, ENTERPRISE_FOLDER_OUTLINED_ICON, FileErrorType, FlowChartConst, FlowchartViewMode, IconModel, KEYBOARD_DOWN_ICON, KEYBOARD_UP_ICON, LOCAL_FOLDER_ICON, LOCAL_FOLDER_OUTLINED_ICON, LinkAnchor, LinkType, MarginDirective, NORMAL_FOLDER_ICON, NORMAL_FOLDER_OUTLINED_ICON, PROCESS_AREA_ICON, PROCESS_AREA_OUTLINED_ICON, PROCESS_ICON, PopupData, ProtocolType, QMSAnchor, QMSAppIconModule, QMSAttachmentListDirective, QMSBreadcrumb, QMSBreadcrumbDirectionIconDirective, QMSBreadcrumbItemDirective, QMSBreadcrumbModule, QMSButton, QMSButtonIcon, QMSButtonModule, QMSButtonToggle, QMSButtonToggleGroup, QMSCKEditorBaseComponent, QMSCKEditorBaseService, QMSCKEditorBpmn, QMSCKEditorBpmnApiService, QMSCKEditorBpmnComponent, QMSCKEditorBpmnTemplate, QMSCKEditorComponent, QMSCKEditorConfirmComponent, QMSCKEditorData, QMSCKEditorDialogData, QMSCKEditorDocumentType, QMSCKEditorFullscreenComponent, QMSCKEditorGlobalService, QMSCKEditorInjector, QMSCKEditorLinkAnchorDocument, QMSCKEditorLinkComponent, QMSCKEditorLinkService, QMSCKEditorLoadTemplateComponent, QMSCKEditorModule, QMSCKEditorPlugin, QMSCKEditorRelatedComponent, QMSCKEditorRelation, QMSCKEditorTemplate, QMSCKEditorTemplateService, QMSCKEditorToastService, QMSCKEditorTreeComponent, QMSCKEdtiorInputData, QMSChipBodyDirective, QMSChipInputChipListDirective, QMSChipInputDirective, QMSChipInputSelectDropWDownDirective, QMSChipInputSelectFieldDirective, QMSChipInputSelectTriggerDirective, QMSComment, QMSConfirmDialog, QMSDialogConfig, QMSDrawerContentDirective, QMSDrawerDirective, QMSDrawerHeaderActionDirective, QMSDrawerHeaderDirective, QMSDropdownMenuItem, QMSEditFileNameDialog, QMSEditFileNameDialogModule, QMSFileAttachment, QMSFileUploadDirective, QMSFileUploadDisplayDirective, QMSFileUploadMultipleDirective, QMSFileUploadMultipleDisplayDirective, QMSFileUploadMultipleSelectorDirective, QMSFileUploadSelectorDirective, QMSFormDialog, QMSFormFieldDatePickerDirective, QMSFormFieldDirective, QMSFormFieldTextareaDirective, QMSGroupOptionDirective, QMSIconRegistryService, QMSInputChipDirective, QMSInputClearDirective, QMSList, QMSListExpansion, QMSListExpansionHeader, QMSListHeader, QMSListItem, QMSListLeadingIcon, QMSListLine, QMSListModule, QMSRangeSliderDirective, QMSRangeSliderLockUpDirective, QMSRelatedGlobalService, QMSRelatedModule, QMSRichText, QMSRichTextModule, QMSScrolableAttachmentListDirective, QMSScrollbarDirective, QMSSearchFieldDirective, QMSSnackbarConfig, QMSSuffixDirective, QMSSuffixFieldDirective, QMSTabGroupAdvancedDirective, QMSTabGroupDirective, QMSTabLabelDirective, QMSTableAction, QMSTableActionBlock, QMSTableModule, QMSTextBlockDirective, QMSTextBlockLine, QMSToolTipComponent, QMSToolTipRendererDirective, QMSTooltipImageDirective, QMSTooltipModule, QMSUploadFileErrorDialog, QMSUploadFileErrorDialogModule, QMSUploadingFileGuard, QmsAngularComponent, QmsAngularModule, QmsAngularService, QmsAppBarComponent, QmsAppBarModule, QmsBannerComponent, QmsBannerConfirmButton, QmsBannerConfirmButtonClick, QmsBannerConfirmComponent, QmsBannerConfirmModule, QmsBannerContent, QmsBannerLoadingComponent, QmsBannerLoadingModule, QmsBannerModule, QmsStepperComponent, QmsStepperModule, REGIONAL_FOLDER_ICON, REGIONAL_FOLDER_OUTLINED_ICON, RISK_ICON, RelatedContentComponent, RelatedItemType, RelatedListComponent, RelatedPopupComponent, Result, RiskAnalysis, RiskAnalysisComponent, RiskDanger, RiskListComponent, RiskResult, RiskResultComponent, SaveTemplateComponent, ScrollToSelectedDirective, SharedModule, SideNav, SideNavItem, SidenavComponent, StepModel, TargetType, TestOnlyComponent, TranslateLibraryService, TreeComponent, TreeConfig, TreeModel, TreeNode$1 as TreeNode, UploadErrorData, en, mixinColor, no, notExceedSize, requiredFileType, ɵ1, SharedMaterialModule as ɵa, QMSCKEditorTemplateComponent as ɵb, QMSCKEditorTreeService as ɵc, LinkAttachmentComponent as ɵd, QMSCKEditorTooltipComponent as ɵe, QMSCKEditorTooltip as ɵf };
15150
+ export { AutocompleteOffDirective, BREADCRUMB_DROPDOWN_ICON, BUTTON_TOGGLE_DEFAULT_OPTIONS, BUTTON_TOGGLE_GROUP, BUTTON_TOGGLE_GROUP_VALUE_ACCESSOR, BannerType, BpmnService, BreadcrumbNode, ButtonToggleChange, CHECKLIST_ICON, CKEditorEventConst, CKEditorModule, ConfirmDialog, DEPARTMENT_FOLDER_ICON, DEPARTMENT_FOLDER_OUTLINED_ICON, DEVIATION_ICON, DOCUMENT_DEPARTMENT_ICON, DOCUMENT_ENTERPRISE_ICON, DOCUMENT_ICON, DOCUMENT_LOCAL_ICON, DOCUMENT_REGIONAL_ICON, DateFormatPipe, ENTERPRISE_FOLDER_ICON, ENTERPRISE_FOLDER_OUTLINED_ICON, FileErrorType, FlowChartConst, FlowchartViewMode, IconModel, KEYBOARD_DOWN_ICON, KEYBOARD_UP_ICON, LOCAL_FOLDER_ICON, LOCAL_FOLDER_OUTLINED_ICON, LinkAnchor, LinkType, MarginDirective, NORMAL_FOLDER_ICON, NORMAL_FOLDER_OUTLINED_ICON, PROCESS_AREA_ICON, PROCESS_AREA_OUTLINED_ICON, PROCESS_ICON, PopupData, ProtocolType, ProtocolTypeName, QMSAnchor, QMSAppIconModule, QMSAttachmentListDirective, QMSBreadcrumb, QMSBreadcrumbDirectionIconDirective, QMSBreadcrumbItemDirective, QMSBreadcrumbModule, QMSButton, QMSButtonIcon, QMSButtonModule, QMSButtonToggle, QMSButtonToggleGroup, QMSCKEditorBaseComponent, QMSCKEditorBaseService, QMSCKEditorBpmn, QMSCKEditorBpmnApiService, QMSCKEditorBpmnComponent, QMSCKEditorBpmnTemplate, QMSCKEditorComponent, QMSCKEditorConfirmComponent, QMSCKEditorData, QMSCKEditorDialogData, QMSCKEditorDocumentType, QMSCKEditorFullscreenComponent, QMSCKEditorGlobalService, QMSCKEditorInjector, QMSCKEditorLinkAnchorDocument, QMSCKEditorLinkComponent, QMSCKEditorLinkService, QMSCKEditorLoadTemplateComponent, QMSCKEditorModule, QMSCKEditorPlugin, QMSCKEditorRelatedComponent, QMSCKEditorRelation, QMSCKEditorTemplate, QMSCKEditorTemplateService, QMSCKEditorToastService, QMSCKEditorTreeComponent, QMSCKEdtiorInputData, QMSChipBodyDirective, QMSChipInputChipListDirective, QMSChipInputDirective, QMSChipInputSelectDropWDownDirective, QMSChipInputSelectFieldDirective, QMSChipInputSelectTriggerDirective, QMSComment, QMSConfirmDialog, QMSDialogConfig, QMSDrawerContentDirective, QMSDrawerDirective, QMSDrawerHeaderActionDirective, QMSDrawerHeaderDirective, QMSDropdownMenuItem, QMSEditFileNameDialog, QMSEditFileNameDialogModule, QMSFileAttachment, QMSFileUploadDirective, QMSFileUploadDisplayDirective, QMSFileUploadMultipleDirective, QMSFileUploadMultipleDisplayDirective, QMSFileUploadMultipleSelectorDirective, QMSFileUploadSelectorDirective, QMSFormDialog, QMSFormFieldDatePickerDirective, QMSFormFieldDirective, QMSFormFieldTextareaDirective, QMSGroupOptionDirective, QMSIconRegistryService, QMSInputChipDirective, QMSInputClearDirective, QMSList, QMSListExpansion, QMSListExpansionHeader, QMSListHeader, QMSListItem, QMSListLeadingIcon, QMSListLine, QMSListModule, QMSRangeSliderDirective, QMSRangeSliderLockUpDirective, QMSRelatedGlobalService, QMSRelatedModule, QMSRichText, QMSRichTextModule, QMSScrolableAttachmentListDirective, QMSScrollbarDirective, QMSSearchFieldDirective, QMSSnackbarConfig, QMSSuffixDirective, QMSSuffixFieldDirective, QMSTabGroupAdvancedDirective, QMSTabGroupDirective, QMSTabLabelDirective, QMSTableAction, QMSTableActionBlock, QMSTableModule, QMSTextBlockDirective, QMSTextBlockLine, QMSToolTipComponent, QMSToolTipRendererDirective, QMSTooltipImageDirective, QMSTooltipModule, QMSUploadFileErrorDialog, QMSUploadFileErrorDialogModule, QMSUploadingFileGuard, QmsAngularComponent, QmsAngularModule, QmsAngularService, QmsAppBarComponent, QmsAppBarModule, QmsBannerComponent, QmsBannerConfirmButton, QmsBannerConfirmButtonClick, QmsBannerConfirmComponent, QmsBannerConfirmModule, QmsBannerContent, QmsBannerLoadingComponent, QmsBannerLoadingModule, QmsBannerModule, QmsStepperComponent, QmsStepperModule, REGIONAL_FOLDER_ICON, REGIONAL_FOLDER_OUTLINED_ICON, RISK_ICON, RelatedContentComponent, RelatedItemType, RelatedListComponent, RelatedPopupComponent, Result, RiskAnalysis, RiskAnalysisComponent, RiskDanger, RiskListComponent, RiskResult, RiskResultComponent, SaveTemplateComponent, ScrollToSelectedDirective, SharedModule, SideNav, SideNavItem, SidenavComponent, StepModel, TargetType, TargetTypeName, TestOnlyComponent, TranslateLibraryService, TreeComponent, TreeConfig, TreeModel, TreeNode$1 as TreeNode, UploadErrorData, en, mixinColor, no, notExceedSize, requiredFileType, ɵ1, SharedMaterialModule as ɵa, QMSCKEditorTemplateComponent as ɵb, QMSCKEditorTreeService as ɵc, LinkAttachmentComponent as ɵd, QMSCKEditorTooltipComponent as ɵe, QMSCKEditorTooltip as ɵf, QMSCKEditorImageMapComponent as ɵg, QMSCKEditorImageMap as ɵh };
12581
15151
  //# sourceMappingURL=qms-angular.js.map