ng2-ckeditor.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. import { __decorate, __metadata } from 'tslib';
  2. import { EventEmitter, Output, Input, Directive, ContentChildren, QueryList, NgZone, ViewChild, Component, forwardRef, NgModule } from '@angular/core';
  3. import { CommonModule } from '@angular/common';
  4. import { NG_VALUE_ACCESSOR } from '@angular/forms';
  5. /**
  6. * CKGroup component
  7. * Usage :
  8. * <ckeditor [(ngModel)]="data" [config]="{...}" debounce="500">
  9. * <ckbutton [name]="'SaveButton'" [command]="'saveCommand'" (click)="save($event)"
  10. * [icon]="'/save.png'" [toolbar]="'customGroup,1'" [label]="'Save'">
  11. * </ckbutton>
  12. * </ckeditor>
  13. */
  14. var CKButtonDirective = /** @class */ (function () {
  15. function CKButtonDirective() {
  16. this.click = new EventEmitter();
  17. }
  18. CKButtonDirective.prototype.initialize = function (editor) {
  19. var _this = this;
  20. editor.instance.addCommand(this.command, {
  21. exec: function (evt) {
  22. _this.click.emit(evt);
  23. },
  24. });
  25. editor.instance.ui.addButton(this.name, {
  26. label: this.label,
  27. command: this.command,
  28. toolbar: this.toolbar,
  29. icon: this.icon,
  30. });
  31. };
  32. CKButtonDirective.prototype.ngOnInit = function () {
  33. if (!this.name)
  34. throw new Error('Attribute "name" is required on <ckbutton>');
  35. if (!this.command)
  36. throw new Error('Attribute "command" is required on <ckbutton>');
  37. };
  38. __decorate([
  39. Output(),
  40. __metadata("design:type", Object)
  41. ], CKButtonDirective.prototype, "click", void 0);
  42. __decorate([
  43. Input(),
  44. __metadata("design:type", String)
  45. ], CKButtonDirective.prototype, "label", void 0);
  46. __decorate([
  47. Input(),
  48. __metadata("design:type", String)
  49. ], CKButtonDirective.prototype, "command", void 0);
  50. __decorate([
  51. Input(),
  52. __metadata("design:type", String)
  53. ], CKButtonDirective.prototype, "toolbar", void 0);
  54. __decorate([
  55. Input(),
  56. __metadata("design:type", String)
  57. ], CKButtonDirective.prototype, "name", void 0);
  58. __decorate([
  59. Input(),
  60. __metadata("design:type", String)
  61. ], CKButtonDirective.prototype, "icon", void 0);
  62. CKButtonDirective = __decorate([
  63. Directive({
  64. selector: 'ckbutton',
  65. })
  66. ], CKButtonDirective);
  67. return CKButtonDirective;
  68. }());
  69. /**
  70. * CKGroup component
  71. * Usage :
  72. * <ckeditor [(ngModel)]="data" [config]="{...}" debounce="500">
  73. * <ckgroup [name]="'exampleGroup2'" [previous]="'1'" [subgroupOf]="'exampleGroup1'">
  74. * .
  75. * .
  76. * </ckgroup>
  77. * </ckeditor>
  78. */
  79. var CKGroupDirective = /** @class */ (function () {
  80. function CKGroupDirective() {
  81. }
  82. CKGroupDirective.prototype.ngAfterContentInit = function () {
  83. var _this = this;
  84. // Reconfigure each button's toolbar property within ckgroup to hold its parent's name
  85. this.toolbarButtons.forEach(function (button) { return (button.toolbar = _this.name); });
  86. };
  87. CKGroupDirective.prototype.initialize = function (editor) {
  88. editor.instance.ui.addToolbarGroup(this.name, this.previous, this.subgroupOf);
  89. // Initialize each button within ckgroup
  90. this.toolbarButtons.forEach(function (button) {
  91. button.initialize(editor);
  92. });
  93. };
  94. __decorate([
  95. Input(),
  96. __metadata("design:type", String)
  97. ], CKGroupDirective.prototype, "name", void 0);
  98. __decorate([
  99. Input(),
  100. __metadata("design:type", Object)
  101. ], CKGroupDirective.prototype, "previous", void 0);
  102. __decorate([
  103. Input(),
  104. __metadata("design:type", String)
  105. ], CKGroupDirective.prototype, "subgroupOf", void 0);
  106. __decorate([
  107. ContentChildren(CKButtonDirective),
  108. __metadata("design:type", QueryList)
  109. ], CKGroupDirective.prototype, "toolbarButtons", void 0);
  110. CKGroupDirective = __decorate([
  111. Directive({
  112. selector: 'ckgroup',
  113. })
  114. ], CKGroupDirective);
  115. return CKGroupDirective;
  116. }());
  117. /**
  118. * CKEditor component
  119. * Usage :
  120. * <ckeditor [(ngModel)]="data" [config]="{...}" debounce="500"></ckeditor>
  121. */
  122. var CKEditorComponent = /** @class */ (function () {
  123. /**
  124. * Constructor
  125. */
  126. function CKEditorComponent(zone) {
  127. this.zone = zone;
  128. this.change = new EventEmitter();
  129. this.editorChange = new EventEmitter();
  130. this.ready = new EventEmitter();
  131. this.blur = new EventEmitter();
  132. this.focus = new EventEmitter();
  133. this.contentDom = new EventEmitter();
  134. this.fileUploadRequest = new EventEmitter();
  135. this.fileUploadResponse = new EventEmitter();
  136. this.paste = new EventEmitter();
  137. this.drop = new EventEmitter();
  138. this._value = '';
  139. }
  140. CKEditorComponent_1 = CKEditorComponent;
  141. Object.defineProperty(CKEditorComponent.prototype, "value", {
  142. get: function () {
  143. return this._value;
  144. },
  145. set: function (v) {
  146. if (v !== this._value) {
  147. this._value = v;
  148. this.onChange(v);
  149. }
  150. },
  151. enumerable: true,
  152. configurable: true
  153. });
  154. CKEditorComponent.prototype.ngOnChanges = function (changes) {
  155. if (changes.readonly && this.instance) {
  156. this.instance.setReadOnly(changes.readonly.currentValue);
  157. }
  158. };
  159. /**
  160. * On component destroy
  161. */
  162. CKEditorComponent.prototype.ngOnDestroy = function () {
  163. if (this.instance) {
  164. this.instance.removeAllListeners();
  165. CKEDITOR.instances[this.instance.name].destroy();
  166. this.instance.destroy();
  167. this.instance = null;
  168. }
  169. };
  170. /**
  171. * On component view init
  172. */
  173. CKEditorComponent.prototype.ngAfterViewInit = function () {
  174. this.ckeditorInit(this.config || {});
  175. };
  176. /**
  177. * On component view checked
  178. */
  179. CKEditorComponent.prototype.ngAfterViewChecked = function () {
  180. this.ckeditorInit(this.config || {});
  181. };
  182. /**
  183. * Value update process
  184. */
  185. CKEditorComponent.prototype.updateValue = function (value) {
  186. var _this = this;
  187. this.zone.run(function () {
  188. _this.value = value;
  189. _this.onChange(value);
  190. _this.onTouched();
  191. _this.change.emit(value);
  192. });
  193. };
  194. /**
  195. * CKEditor init
  196. */
  197. CKEditorComponent.prototype.ckeditorInit = function (config) {
  198. var _this = this;
  199. if (typeof CKEDITOR === 'undefined') {
  200. console.warn('CKEditor 4.x is missing (http://ckeditor.com/)');
  201. }
  202. else {
  203. // Check textarea exists
  204. if (this.instance || !this.documentContains(this.host.nativeElement)) {
  205. return;
  206. }
  207. if (this.readonly) {
  208. config.readOnly = this.readonly;
  209. }
  210. // CKEditor replace textarea
  211. this.instance = CKEDITOR.replace(this.host.nativeElement, config);
  212. // Set initial value
  213. this.instance.setData(this.value);
  214. // listen for instanceReady event
  215. this.instance.on('instanceReady', function (evt) {
  216. // if value has changed while instance loading
  217. // update instance with current component value
  218. if (_this.instance.getData() !== _this.value) {
  219. _this.instance.setData(_this.value);
  220. }
  221. // send the evt to the EventEmitter
  222. _this.ready.emit(evt);
  223. });
  224. // CKEditor change event
  225. this.instance.on('change', function (evt) {
  226. _this.onTouched();
  227. var value = _this.instance.getData();
  228. if (_this.value !== value) {
  229. // Debounce update
  230. if (_this.debounce) {
  231. if (_this.debounceTimeout)
  232. clearTimeout(_this.debounceTimeout);
  233. _this.debounceTimeout = setTimeout(function () {
  234. _this.updateValue(value);
  235. _this.debounceTimeout = null;
  236. }, parseInt(_this.debounce));
  237. // Live update
  238. }
  239. else {
  240. _this.updateValue(value);
  241. }
  242. }
  243. // Original ckeditor event dispatch
  244. _this.editorChange.emit(evt);
  245. });
  246. // CKEditor blur event
  247. this.instance.on('blur', function (evt) {
  248. _this.blur.emit(evt);
  249. });
  250. // CKEditor focus event
  251. this.instance.on('focus', function (evt) {
  252. _this.focus.emit(evt);
  253. });
  254. // CKEditor contentDom event
  255. this.instance.on('contentDom', function (evt) {
  256. _this.contentDom.emit(evt);
  257. });
  258. // CKEditor fileUploadRequest event
  259. this.instance.on('fileUploadRequest', function (evt) {
  260. _this.fileUploadRequest.emit(evt);
  261. });
  262. // CKEditor fileUploadResponse event
  263. this.instance.on('fileUploadResponse', function (evt) {
  264. _this.fileUploadResponse.emit(evt);
  265. });
  266. // CKEditor paste event
  267. this.instance.on('paste', function (evt) {
  268. _this.paste.emit(evt);
  269. });
  270. // CKEditor drop event
  271. this.instance.on('drop', function (evt) {
  272. _this.drop.emit(evt);
  273. });
  274. // Add Toolbar Groups to Editor. This will also add Buttons within groups.
  275. this.toolbarGroups.forEach(function (group) {
  276. group.initialize(_this);
  277. });
  278. // Add Toolbar Buttons to Editor.
  279. this.toolbarButtons.forEach(function (button) {
  280. button.initialize(_this);
  281. });
  282. }
  283. };
  284. /**
  285. * Implements ControlValueAccessor
  286. */
  287. CKEditorComponent.prototype.writeValue = function (value) {
  288. this._value = value;
  289. if (this.instance)
  290. this.instance.setData(value);
  291. };
  292. CKEditorComponent.prototype.onChange = function (_) { };
  293. CKEditorComponent.prototype.onTouched = function () { };
  294. CKEditorComponent.prototype.registerOnChange = function (fn) {
  295. this.onChange = fn;
  296. };
  297. CKEditorComponent.prototype.registerOnTouched = function (fn) {
  298. this.onTouched = fn;
  299. };
  300. CKEditorComponent.prototype.documentContains = function (node) {
  301. return document.contains ? document.contains(node) : document.body.contains(node);
  302. };
  303. var CKEditorComponent_1;
  304. CKEditorComponent.ctorParameters = function () { return [
  305. { type: NgZone }
  306. ]; };
  307. __decorate([
  308. Input(),
  309. __metadata("design:type", Object)
  310. ], CKEditorComponent.prototype, "config", void 0);
  311. __decorate([
  312. Input(),
  313. __metadata("design:type", Boolean)
  314. ], CKEditorComponent.prototype, "readonly", void 0);
  315. __decorate([
  316. Input(),
  317. __metadata("design:type", String)
  318. ], CKEditorComponent.prototype, "debounce", void 0);
  319. __decorate([
  320. Output(),
  321. __metadata("design:type", Object)
  322. ], CKEditorComponent.prototype, "change", void 0);
  323. __decorate([
  324. Output(),
  325. __metadata("design:type", Object)
  326. ], CKEditorComponent.prototype, "editorChange", void 0);
  327. __decorate([
  328. Output(),
  329. __metadata("design:type", Object)
  330. ], CKEditorComponent.prototype, "ready", void 0);
  331. __decorate([
  332. Output(),
  333. __metadata("design:type", Object)
  334. ], CKEditorComponent.prototype, "blur", void 0);
  335. __decorate([
  336. Output(),
  337. __metadata("design:type", Object)
  338. ], CKEditorComponent.prototype, "focus", void 0);
  339. __decorate([
  340. Output(),
  341. __metadata("design:type", Object)
  342. ], CKEditorComponent.prototype, "contentDom", void 0);
  343. __decorate([
  344. Output(),
  345. __metadata("design:type", Object)
  346. ], CKEditorComponent.prototype, "fileUploadRequest", void 0);
  347. __decorate([
  348. Output(),
  349. __metadata("design:type", Object)
  350. ], CKEditorComponent.prototype, "fileUploadResponse", void 0);
  351. __decorate([
  352. Output(),
  353. __metadata("design:type", Object)
  354. ], CKEditorComponent.prototype, "paste", void 0);
  355. __decorate([
  356. Output(),
  357. __metadata("design:type", Object)
  358. ], CKEditorComponent.prototype, "drop", void 0);
  359. __decorate([
  360. ViewChild('host', { static: false }),
  361. __metadata("design:type", Object)
  362. ], CKEditorComponent.prototype, "host", void 0);
  363. __decorate([
  364. ContentChildren(CKButtonDirective),
  365. __metadata("design:type", QueryList)
  366. ], CKEditorComponent.prototype, "toolbarButtons", void 0);
  367. __decorate([
  368. ContentChildren(CKGroupDirective),
  369. __metadata("design:type", QueryList)
  370. ], CKEditorComponent.prototype, "toolbarGroups", void 0);
  371. __decorate([
  372. Input(),
  373. __metadata("design:type", Object),
  374. __metadata("design:paramtypes", [Object])
  375. ], CKEditorComponent.prototype, "value", null);
  376. CKEditorComponent = CKEditorComponent_1 = __decorate([
  377. Component({
  378. selector: 'ckeditor',
  379. providers: [
  380. {
  381. provide: NG_VALUE_ACCESSOR,
  382. useExisting: forwardRef(function () { return CKEditorComponent_1; }),
  383. multi: true,
  384. },
  385. ],
  386. template: "\n <textarea #host></textarea>\n "
  387. }),
  388. __metadata("design:paramtypes", [NgZone])
  389. ], CKEditorComponent);
  390. return CKEditorComponent;
  391. }());
  392. /**
  393. * CKEditorModule
  394. */
  395. var CKEditorModule = /** @class */ (function () {
  396. function CKEditorModule() {
  397. }
  398. CKEditorModule = __decorate([
  399. NgModule({
  400. imports: [CommonModule],
  401. declarations: [CKEditorComponent, CKButtonDirective, CKGroupDirective],
  402. exports: [CKEditorComponent, CKButtonDirective, CKGroupDirective],
  403. })
  404. ], CKEditorModule);
  405. return CKEditorModule;
  406. }());
  407. /**
  408. * Generated bundle index. Do not edit.
  409. */
  410. export { CKEditorModule, CKEditorComponent as ɵa, CKButtonDirective as ɵb, CKGroupDirective as ɵc };
  411. //# sourceMappingURL=ng2-ckeditor.js.map