Browse Source

Move ComponentTextView to TS

ts-components
Artur Arseniev 4 years ago
parent
commit
37c7c2e42e
  1. 2
      src/dom_components/model/types.ts
  2. 72
      src/dom_components/view/ComponentTextView.ts
  3. 3
      src/editor/model/Editor.ts
  4. 2
      src/rich_text_editor/index.ts
  5. 1
      src/rich_text_editor/model/RichTextEditor.ts

2
src/dom_components/model/types.ts

@ -201,7 +201,7 @@ export interface ComponentModelProperties extends ComponentProperties {
[key: string]: any; [key: string]: any;
} }
type ComponentAddType = Component | ComponentDefinitionDefined | ComponentDefinitionDefined | string; type ComponentAddType = Component | ComponentDefinition | ComponentDefinitionDefined | string;
export type ComponentAdd = ComponentAddType | ComponentAddType[]; export type ComponentAdd = ComponentAddType | ComponentAddType[];

72
src/dom_components/view/ComponentTextView.js → src/dom_components/view/ComponentTextView.ts

@ -1,10 +1,19 @@
import { on, off, getModel } from 'utils/mixins';
import ComponentView from './ComponentView';
import { bindAll } from 'underscore'; import { bindAll } from 'underscore';
import { ObjectAny } from '../../common';
const compProt = ComponentView.prototype; import RichTextEditorModule from '../../rich_text_editor';
import RichTextEditor from '../../rich_text_editor/model/RichTextEditor';
import { getModel, off, on } from '../../utils/mixins';
import Component from '../model/Component';
import ComponentText from '../model/ComponentText';
import { ComponentDefinition } from '../model/types';
import ComponentView from './ComponentView';
export default class ComponentTextView extends ComponentView { export default class ComponentTextView extends ComponentView {
rte?: RichTextEditorModule;
rteEnabled?: boolean;
activeRte?: RichTextEditor;
lastContent?: string;
events() { events() {
return { return {
dblclick: 'onActive', dblclick: 'onActive',
@ -12,18 +21,18 @@ export default class ComponentTextView extends ComponentView {
}; };
} }
initialize(o) { initialize(props: any) {
compProt.initialize.apply(this, arguments); super.initialize(props);
bindAll(this, 'disableEditing', 'onDisable'); bindAll(this, 'disableEditing', 'onDisable');
const model = this.model; const model = this.model;
const em = this.em; const em = this.em;
this.listenTo(model, 'focus', this.onActive); this.listenTo(model, 'focus', this.onActive);
this.listenTo(model, 'change:content', this.updateContentText); this.listenTo(model, 'change:content', this.updateContentText);
this.listenTo(model, 'sync:content', this.syncContent); this.listenTo(model, 'sync:content', this.syncContent);
this.rte = em && em.get('RichTextEditor'); this.rte = em?.RichTextEditor;
} }
updateContentText(m, v, opts = {}) { updateContentText(m: any, v: any, opts: { fromDisable?: boolean } = {}) {
!opts.fromDisable && this.disableEditing(); !opts.fromDisable && this.disableEditing();
} }
@ -60,7 +69,7 @@ export default class ComponentTextView extends ComponentView {
* Enable element content editing * Enable element content editing
* @private * @private
* */ * */
async onActive(ev) { async onActive(ev: Event) {
const { rte, em } = this; const { rte, em } = this;
const { result, delegate } = this.canActivate(); const { result, delegate } = this.canActivate();
@ -80,13 +89,13 @@ export default class ComponentTextView extends ComponentView {
if (rte) { if (rte) {
try { try {
this.activeRte = await rte.enable(this, this.activeRte, { event: ev }); this.activeRte = await rte.enable(this, this.activeRte!, { event: ev });
} catch (err) { } catch (err) {
em.logError(err); em.logError(err as any);
} }
} }
this.toggleEvents(1); this.toggleEvents(true);
} }
onDisable() { onDisable() {
@ -107,7 +116,7 @@ export default class ComponentTextView extends ComponentView {
try { try {
await rte.disable(this, activeRte); await rte.disable(this, activeRte);
} catch (err) { } catch (err) {
em.logError(err); em.logError(err as any);
} }
if (editable && this.getContent() !== this.lastContent) { if (editable && this.getContent() !== this.lastContent) {
@ -125,33 +134,32 @@ export default class ComponentTextView extends ComponentView {
*/ */
getContent() { getContent() {
const { activeRte } = this; const { activeRte } = this;
const canGetRteContent = activeRte && typeof activeRte.getContent === 'function';
return canGetRteContent ? activeRte.getContent() : this.getChildrenContainer().innerHTML; return typeof activeRte?.getContent === 'function' ? activeRte.getContent() : this.getChildrenContainer().innerHTML;
} }
/** /**
* Merge content from the DOM to the model * Merge content from the DOM to the model
*/ */
syncContent(opts = {}) { syncContent(opts: ObjectAny = {}) {
const { model, rte, rteEnabled } = this; const { model, rte, rteEnabled } = this;
if (!rteEnabled && !opts.force) return; if (!rteEnabled && !opts.force) return;
const content = this.getContent(); const content = this.getContent();
const comps = model.components(); const comps = model.components();
const contentOpt = { fromDisable: 1, ...opts }; const contentOpt: ObjectAny = { fromDisable: 1, ...opts };
model.set('content', '', contentOpt); model.set('content', '', contentOpt);
// If there is a custom RTE the content is just baked staticly // If there is a custom RTE the content is just baked staticly
// inside 'content' // inside 'content'
if (rte.customRte) { if (rte?.customRte) {
comps.length && comps.reset(null, opts); comps.length && comps.reset(undefined, opts);
model.set('content', content, contentOpt); model.set('content', content, contentOpt);
} else { } else {
comps.resetFromString(content, opts); comps.resetFromString(content, opts);
} }
} }
insertComponent(content, opts = {}) { insertComponent(content: ComponentDefinition, opts = {}) {
const { model, el } = this; const { model, el } = this;
const doc = el.ownerDocument; const doc = el.ownerDocument;
const selection = doc.getSelection(); const selection = doc.getSelection();
@ -160,15 +168,15 @@ export default class ComponentTextView extends ComponentView {
const range = selection.getRangeAt(0); const range = selection.getRangeAt(0);
const textNode = range.startContainer; const textNode = range.startContainer;
const offset = range.startOffset; const offset = range.startOffset;
const textModel = getModel(textNode); const textModel = getModel(textNode) as ComponentText;
const newCmps = []; const newCmps: (ComponentDefinition | Component)[] = [];
if (textModel && textModel.is?.('textnode')) { if (textModel && textModel.is?.('textnode')) {
const cmps = textModel.collection; const cmps = textModel.collection;
cmps.forEach(cmp => { cmps.forEach(cmp => {
if (cmp === textModel) { if (cmp === textModel) {
const type = 'textnode'; const type = 'textnode';
const cnt = cmp.get('content'); const cnt = cmp.get('content') || '';
newCmps.push({ type, content: cnt.slice(0, offset) }); newCmps.push({ type, content: cnt.slice(0, offset) });
newCmps.push(content); newCmps.push(content);
newCmps.push({ type, content: cnt.slice(offset) }); newCmps.push({ type, content: cnt.slice(offset) });
@ -206,7 +214,7 @@ export default class ComponentTextView extends ComponentView {
* @param {Event} * @param {Event}
* @private * @private
* */ * */
disablePropagation(e) { disablePropagation(e: Event) {
e.stopPropagation(); e.stopPropagation();
} }
@ -214,11 +222,11 @@ export default class ComponentTextView extends ComponentView {
* Enable/Disable events * Enable/Disable events
* @param {Boolean} enable * @param {Boolean} enable
*/ */
toggleEvents(enable) { toggleEvents(enable?: boolean) {
const { em, model, $el } = this; const { em, model, $el } = this;
const mixins = { on, off }; const mixins = { on, off };
const method = enable ? 'on' : 'off'; const method = enable ? 'on' : 'off';
em.setEditing(enable ? this : 0); em.setEditing(enable ? this : false);
this.rteEnabled = !!enable; this.rteEnabled = !!enable;
// The ownerDocument is from the frame // The ownerDocument is from the frame
@ -231,8 +239,9 @@ export default class ComponentTextView extends ComponentView {
model.trigger(`rte:${enable ? 'enable' : 'disable'}`); model.trigger(`rte:${enable ? 'enable' : 'disable'}`);
} }
// Avoid closing edit mode on component click // @ts-ignore Avoid closing edit mode on component click
$el && $el.off('mousedown', this.disablePropagation); $el?.off('mousedown', this.disablePropagation);
// @ts-ignore
$el && $el[method]('mousedown', this.disablePropagation); $el && $el[method]('mousedown', this.disablePropagation);
// Fixes #2210 but use this also as a replacement // Fixes #2210 but use this also as a replacement
@ -243,8 +252,11 @@ export default class ComponentTextView extends ComponentView {
while (el) { while (el) {
el.draggable = enable ? !1 : !0; el.draggable = enable ? !1 : !0;
// Note: el.parentNode is sometimes null here // Note: el.parentNode is sometimes null here
el = el.parentNode; el = el.parentNode as HTMLElement;
el && el.tagName == 'BODY' && (el = 0); if (el && el.tagName == 'BODY') {
// @ts-ignore
el = 0;
}
} }
} }
} }

3
src/editor/model/Editor.ts

@ -36,6 +36,7 @@ import StyleManager from '../../style_manager';
import CssRule from '../../css_composer/model/CssRule'; import CssRule from '../../css_composer/model/CssRule';
import { HTMLGeneratorBuildOptions } from '../../code_manager/model/HtmlGenerator'; import { HTMLGeneratorBuildOptions } from '../../code_manager/model/HtmlGenerator';
import { CssGeneratorBuildOptions } from '../../code_manager/model/CssGenerator'; import { CssGeneratorBuildOptions } from '../../code_manager/model/CssGenerator';
import ComponentView from '../../dom_components/view/ComponentView';
export interface ProjectData { export interface ProjectData {
[key: string]: any; [key: string]: any;
@ -1027,7 +1028,7 @@ export default class EditorModel extends Model {
return (res && res.model) || undefined; return (res && res.model) || undefined;
} }
setEditing(value: boolean) { setEditing(value: boolean | ComponentView) {
this.set('editing', value); this.set('editing', value);
return this; return this;
} }

2
src/rich_text_editor/index.ts

@ -327,7 +327,7 @@ export default class RichTextEditorModule extends Module<RichTextEditorConfig &
* @param {Object} rte The instance of already defined RTE * @param {Object} rte The instance of already defined RTE
* @private * @private
* */ * */
disable(view: ComponentView, rte: RichTextEditor) { disable(view: ComponentView, rte?: RichTextEditor) {
const { em } = this; const { em } = this;
const customRte = this.customRte; const customRte = this.customRte;
// @ts-ignore // @ts-ignore

1
src/rich_text_editor/model/RichTextEditor.ts

@ -118,6 +118,7 @@ export default class RichTextEditor {
el!: HTMLElement; el!: HTMLElement;
doc!: Document; doc!: Document;
enabled?: boolean; enabled?: boolean;
getContent?: () => string;
constructor(em: EditorModel, el: HTMLElement & { _rte?: RichTextEditor }, settings: RichTextEditorOptions = {}) { constructor(em: EditorModel, el: HTMLElement & { _rte?: RichTextEditor }, settings: RichTextEditorOptions = {}) {
this.em = em; this.em = em;

Loading…
Cancel
Save