Add suppport for UL; fix file uploader redirects
This commit is contained in:
parent
665fdc91a8
commit
6a7618f971
@ -13,6 +13,22 @@ import { ComponentsModule } from './components/components.module';
|
|||||||
import { TreeModule } from 'angular-tree-component';
|
import { TreeModule } from 'angular-tree-component';
|
||||||
import {AgGridModule} from 'ag-grid-angular';
|
import {AgGridModule} from 'ag-grid-angular';
|
||||||
import {MonacoEditorModule} from 'ngx-monaco-editor';
|
import {MonacoEditorModule} from 'ngx-monaco-editor';
|
||||||
|
import { APP_BASE_HREF, PlatformLocation } from '@angular/common';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is used internal to get a string instance of the `<base href="" />` value from `index.html`.
|
||||||
|
* This is an exported function, instead of a private function or inline lambda, to prevent this error:
|
||||||
|
*
|
||||||
|
* `Error encountered resolving symbol values statically.`
|
||||||
|
* `Function calls are not supported.`
|
||||||
|
* `Consider replacing the function or lambda with a reference to an exported function.`
|
||||||
|
*
|
||||||
|
* @param platformLocation an Angular service used to interact with a browser's URL
|
||||||
|
* @return a string instance of the `<base href="" />` value from `index.html`
|
||||||
|
*/
|
||||||
|
export function getBaseHref(platformLocation: PlatformLocation): string {
|
||||||
|
return platformLocation.getBaseHrefFromDOM();
|
||||||
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [AppComponent],
|
declarations: [AppComponent],
|
||||||
@ -30,7 +46,12 @@ import {MonacoEditorModule} from 'ngx-monaco-editor';
|
|||||||
providers: [
|
providers: [
|
||||||
StatusBar,
|
StatusBar,
|
||||||
SplashScreen,
|
SplashScreen,
|
||||||
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
|
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
|
||||||
|
{
|
||||||
|
provide: APP_BASE_HREF,
|
||||||
|
useFactory: getBaseHref,
|
||||||
|
deps: [PlatformLocation]
|
||||||
|
}
|
||||||
],
|
],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<div class="new-uploads" style="margin: 20px;">
|
<div class="new-uploads" style="margin: 20px;">
|
||||||
<form #uploadForm [action]="getApiSubmit()" enctype="multipart/form-data" method="post">
|
<form #uploadForm [action]="getApiSubmit()" enctype="multipart/form-data" method="post">
|
||||||
<input style="margin-top: 10px;" type="file" id="file" name="uploaded_file">
|
<input style="margin-top: 10px;" type="file" id="file" name="uploaded_file">
|
||||||
|
<input type="hidden" name="redirectTo" [value]="getReturnUrl()">
|
||||||
<ion-button (click)="onSubmitClick()" type="submit" fill="outline" class="ion-margin-start">Upload</ion-button>
|
<ion-button (click)="onSubmitClick()" type="submit" fill="outline" class="ion-margin-start">Upload</ion-button>
|
||||||
<ion-button (click)="onDestroyClick()" type="submit" fill="outline" class="ion-margin-start" color="danger">Drop Files</ion-button>
|
<ion-button (click)="onDestroyClick()" type="submit" fill="outline" class="ion-margin-start" color="danger">Drop Files</ion-button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
div.files-wrapper {
|
div.files-wrapper {
|
||||||
border: 2px solid #8c8c8c;
|
border: 2px solid #8c8c8c;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
|
margin-top: 15px;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild} from '@angular/core';
|
import {Component, ElementRef, EventEmitter, Inject, Input, OnInit, Output, ViewChild} from '@angular/core';
|
||||||
import HostRecord from '../../../structures/HostRecord';
|
import HostRecord from '../../../structures/HostRecord';
|
||||||
import {ApiService} from '../../../service/api.service';
|
import {ApiService} from '../../../service/api.service';
|
||||||
import {AlertController} from '@ionic/angular';
|
import {AlertController} from '@ionic/angular';
|
||||||
import {Observable} from 'rxjs';
|
import {Observable} from 'rxjs';
|
||||||
|
import { APP_BASE_HREF } from '@angular/common';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'editor-files',
|
selector: 'editor-files',
|
||||||
@ -23,6 +24,7 @@ export class FilesComponent implements OnInit {
|
|||||||
constructor(
|
constructor(
|
||||||
protected api: ApiService,
|
protected api: ApiService,
|
||||||
protected alerts: AlertController,
|
protected alerts: AlertController,
|
||||||
|
@Inject(APP_BASE_HREF) private baseHref: string
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -39,6 +41,10 @@ export class FilesComponent implements OnInit {
|
|||||||
this.uploadForm.nativeElement.submit();
|
this.uploadForm.nativeElement.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getReturnUrl() {
|
||||||
|
return `${this.baseHref}editor;id=${this.hostRecord.PageId}`;
|
||||||
|
}
|
||||||
|
|
||||||
downloadFile(fileRecord) {
|
downloadFile(fileRecord) {
|
||||||
// tslint:disable-next-line:max-line-length
|
// tslint:disable-next-line:max-line-length
|
||||||
window.open(this.api._build_url(`files/${this.hostRecord.PageId}/${this.hostRecord.UUID}/get/${this.hostRecord.Value.Value}/${fileRecord._id}`), '_blank');
|
window.open(this.api._build_url(`files/${this.hostRecord.PageId}/${this.hostRecord.UUID}/get/${this.hostRecord.Value.Value}/${fileRecord._id}`), '_blank');
|
||||||
|
@ -15,14 +15,17 @@
|
|||||||
class="host-host ion-padding"
|
class="host-host ion-padding"
|
||||||
>
|
>
|
||||||
<li
|
<li
|
||||||
contenteditable="true"
|
|
||||||
*ngFor="let line of listLines; let i = index"
|
|
||||||
#liItems
|
#liItems
|
||||||
(keyup)="onLIKeyUp($event, i)"
|
contenteditable="true"
|
||||||
(blur)="listLines[i]=liItems.innerHTML"
|
(keyup)="onUlKeyUp($event, i)"
|
||||||
|
(keydown)="onUlKeyDown($event, i)"
|
||||||
|
*ngFor="let line of listLines; let i = index"
|
||||||
[innerHTML]="listLines[i]"
|
[innerHTML]="listLines[i]"
|
||||||
></li>
|
></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<div *ngIf="record.type === 'page_sep'" class="hr-wrapper">
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
*ngIf="record.type === 'database_ref'"
|
*ngIf="record.type === 'database_ref'"
|
||||||
class="db-wrapper"
|
class="db-wrapper"
|
||||||
|
@ -33,3 +33,32 @@
|
|||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hr-wrapper {
|
||||||
|
margin: 50px 100px;
|
||||||
|
|
||||||
|
& hr {
|
||||||
|
background: #ccc;
|
||||||
|
height: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-indentation-level-num-1 {
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-indentation-level-num-2 {
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-indentation-level-num-3 {
|
||||||
|
margin-left: 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-indentation-level-num-4 {
|
||||||
|
margin-left: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-indentation-level-num-5 {
|
||||||
|
margin-left: 75px;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild, ViewChildren} from '@angular/core';
|
import {Component, ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, ViewChild, ViewChildren} from '@angular/core';
|
||||||
import HostRecord from '../../../structures/HostRecord';
|
import HostRecord from '../../../structures/HostRecord';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -19,7 +19,18 @@ export class HostComponent implements OnInit {
|
|||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
ngOnInit() {}
|
ngOnInit() {
|
||||||
|
if ( this.record.type === 'ul' ) {
|
||||||
|
const values = JSON.parse(this.record.value);
|
||||||
|
values.forEach(group => this.listLines.push(group.value));
|
||||||
|
setTimeout(() => {
|
||||||
|
values.forEach((group, i) => {
|
||||||
|
const el = this.liItems.toArray()[i].nativeElement;
|
||||||
|
el.className += ` node-indentation-level-num-${group.indentationLevel}`;
|
||||||
|
});
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onRecordChange($event) {
|
onRecordChange($event) {
|
||||||
this.recordChange.emit($event);
|
this.recordChange.emit($event);
|
||||||
@ -27,13 +38,13 @@ export class HostComponent implements OnInit {
|
|||||||
|
|
||||||
onKeyUp($event) {
|
onKeyUp($event) {
|
||||||
const innerText = this.hostContainer.nativeElement.innerText.trim()
|
const innerText = this.hostContainer.nativeElement.innerText.trim()
|
||||||
if ( $event.code === 'Enter'
|
if ( $event.code === 'Enter' && this.record.isNorm() && !$event.shiftKey
|
||||||
&& ( this.record.type !== 'block_code'
|
&& ( this.record.type !== 'block_code'
|
||||||
|| (innerText.endsWith('```') && (innerText.match(/`/g) || []).length >= 6)
|
|| (innerText.endsWith('```') && (innerText.match(/`/g) || []).length >= 6) // TODO don't add new if cursor in block
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
this.newHostRequested.emit(this);
|
|
||||||
this.hostContainer.nativeElement.innerText = this.hostContainer.nativeElement.innerText.trim();
|
this.hostContainer.nativeElement.innerText = this.hostContainer.nativeElement.innerText.trim();
|
||||||
|
this.newHostRequested.emit(this);
|
||||||
} else if ( $event.code === 'Backspace' && !this.hostContainer.nativeElement.innerText.trim() ) {
|
} else if ( $event.code === 'Backspace' && !this.hostContainer.nativeElement.innerText.trim() ) {
|
||||||
this.destroyHostRequested.emit(this);
|
this.destroyHostRequested.emit(this);
|
||||||
}
|
}
|
||||||
@ -50,60 +61,119 @@ export class HostComponent implements OnInit {
|
|||||||
this.record.type = 'block_code';
|
this.record.type = 'block_code';
|
||||||
} else if ( innerText.startsWith('http') ) {
|
} else if ( innerText.startsWith('http') ) {
|
||||||
this.record.type = 'click_link';
|
this.record.type = 'click_link';
|
||||||
} else if ( false && innerText.startsWith('-') || innerText.startsWith(' -') ) {
|
} else if ( innerText === '---' ) {
|
||||||
// this.record.type = 'ul';
|
this.record.type = 'page_sep';
|
||||||
|
} else if ( innerText.startsWith('-') || innerText.startsWith(' -') ) {
|
||||||
|
this.record.type = 'ul';
|
||||||
this.listLines = [this.record.value];
|
this.listLines = [this.record.value];
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const item = this.liItems.toArray()[0].nativeElement;
|
this.focusStart(this.liItems.toArray()[0].nativeElement);
|
||||||
const s = window.getSelection();
|
|
||||||
const r = document.createRange();
|
|
||||||
r.setStart(item, 0);
|
|
||||||
r.setEnd(item, 0);
|
|
||||||
s.removeAllRanges();
|
|
||||||
s.addRange(r);
|
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onUlKeyDown($event, index) {
|
||||||
|
if ( $event.code === 'Tab' ) {
|
||||||
|
$event.preventDefault();
|
||||||
|
const elem = this.liItems.toArray()[index];
|
||||||
|
let currentLevel = 0;
|
||||||
|
|
||||||
|
elem.nativeElement.className.split(' ').some(x => {
|
||||||
|
if ( x.startsWith('node-indentation-level-num-') ) {
|
||||||
|
currentLevel = Number(x.replace('node-indentation-level-num-', ''));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const newLevel = $event.shiftKey ? currentLevel - 1 : currentLevel + 1;
|
||||||
|
if ( newLevel <= 5 && newLevel >= 0 ) {
|
||||||
|
const existing = elem.nativeElement.className.split(' ').filter(x => !x.startsWith('node-indentation-level-num-'));
|
||||||
|
existing.push(`node-indentation-level-num-${newLevel}`);
|
||||||
|
|
||||||
|
elem.nativeElement.className = existing.join(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onUlKeyUp($event, i) {
|
||||||
|
if ( $event.code === 'Enter' && !$event.shiftKey ) {
|
||||||
|
const e = this.liItems.toArray()[i].nativeElement;
|
||||||
|
e.innerText = e.innerText.trim();
|
||||||
|
if ( this.liItems.toArray()[i].nativeElement.innerText.trim() === '' ) {
|
||||||
|
this.newHostRequested.emit(this);
|
||||||
|
} else {
|
||||||
|
this.listLines.push('');
|
||||||
|
setTimeout(() => {
|
||||||
|
this.focusStart(this.liItems.toArray()[i + 1].nativeElement);
|
||||||
|
|
||||||
|
let newLevel = 0;
|
||||||
|
this.liItems.toArray()[i].nativeElement.className.split(' ').some(x => {
|
||||||
|
if ( x.startsWith('node-indentation-level-num-') ) {
|
||||||
|
newLevel = Number(x.replace('node-indentation-level-num-', ''));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const classes = this.liItems.toArray()[i + 1].nativeElement.className
|
||||||
|
.split(' ')
|
||||||
|
.filter(x => !x.startsWith('node-indentation-level-num-'));
|
||||||
|
classes.push(`node-indentation-level-num-${newLevel}`);
|
||||||
|
this.liItems.toArray()[i + 1].nativeElement.className = classes.join(' ');
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
} else if ( $event.code === 'Backspace' && this.liItems.toArray()[i].nativeElement.innerText.trim() === '' ) {
|
||||||
|
const newLines = [];
|
||||||
|
this.liItems.toArray().forEach((elem, index) => {
|
||||||
|
if ( index !== i ) {
|
||||||
|
newLines.push(elem.innerText ? elem.innerText.trim() : '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.listLines = newLines;
|
||||||
|
|
||||||
|
if ( i === 0 && this.listLines.length === 0 ) {
|
||||||
|
this.destroyHostRequested.emit(this);
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.focusEnd(this.liItems.toArray()[i - 1].nativeElement);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
} else if ( $event.code === 'ArrowDown' ) {
|
||||||
|
const liArr = this.liItems.toArray();
|
||||||
|
if ( liArr.length > i + 1 ) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.focusStart(this.liItems.toArray()[i + 1].nativeElement);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
} else if ( $event.code === 'ArrowUp' ) {
|
||||||
|
if ( i !== 0 ) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.focusStart(this.liItems.toArray()[i - 1].nativeElement);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const recordValue = this.liItems.toArray().map(item => {
|
||||||
|
const elem = item.nativeElement;
|
||||||
|
const value = elem.innerText.trim();
|
||||||
|
let indentationLevel = 0;
|
||||||
|
elem.className.split(' ').some(x => {
|
||||||
|
if ( x.startsWith('node-indentation-level-num-') ) {
|
||||||
|
indentationLevel = x.replace('node-indentation-level-num-', '');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return {value, indentationLevel};
|
||||||
|
});
|
||||||
|
|
||||||
|
this.record.value = JSON.stringify(recordValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onRequestDelete($event) {
|
onRequestDelete($event) {
|
||||||
this.destroyHostRequested.emit(this);
|
this.destroyHostRequested.emit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
onLIKeyUp($event, i) {
|
|
||||||
if ( $event.code === 'Enter' ) {
|
|
||||||
/*const newListLines = [];
|
|
||||||
this.liItems.forEach((li, index) => {
|
|
||||||
newListLines.push(li.nativeElement.innerText.trim());
|
|
||||||
if ( index === i ) {
|
|
||||||
newListLines.push('');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.listLines = newListLines;*/
|
|
||||||
// this.listLines[i] = this.liItems[i].innerText.trim()
|
|
||||||
// const newLines = []
|
|
||||||
// this.listLines.forEach((rec, x) => {
|
|
||||||
// newLines.push(rec.trim());
|
|
||||||
// if ( i === x ) {
|
|
||||||
// newLines.push('');
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
|
|
||||||
// this.listLines = newLines;
|
|
||||||
|
|
||||||
// setTimeout(() => {
|
|
||||||
// const item = this.liItems.toArray()[i + 1].nativeElement;
|
|
||||||
// const s = window.getSelection();
|
|
||||||
// const r = document.createRange();
|
|
||||||
// r.setStart(item, 0);
|
|
||||||
// r.setEnd(item, 0);
|
|
||||||
// s.removeAllRanges();
|
|
||||||
// s.addRange(r);
|
|
||||||
// }, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onRequestParentSave($event) {
|
onRequestParentSave($event) {
|
||||||
this.saveHostRequested.emit(this);
|
this.saveHostRequested.emit(this);
|
||||||
}
|
}
|
||||||
@ -114,4 +184,48 @@ export class HostComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
takeFocus(fromTop = true) {
|
||||||
|
if ( this.record.type === 'ul' ) {
|
||||||
|
if ( fromTop ) {
|
||||||
|
this.focusStart(this.liItems.toArray()[0].nativeElement);
|
||||||
|
} else {
|
||||||
|
this.focusEnd(this.liItems.toArray().reverse()[0].nativeElement);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ( fromTop ) {
|
||||||
|
this.focusStart(this.hostContainer.nativeElement);
|
||||||
|
} else {
|
||||||
|
this.focusEnd(this.hostContainer.nativeElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO return an observable here, probably
|
||||||
|
focusEnd(item) {
|
||||||
|
const s = window.getSelection();
|
||||||
|
const r = document.createRange();
|
||||||
|
r.setStart(item, 0);
|
||||||
|
r.setEnd(item, 0);
|
||||||
|
s.removeAllRanges();
|
||||||
|
s.addRange(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO return an observable here, probably
|
||||||
|
focusStart(item) {
|
||||||
|
const s = window.getSelection();
|
||||||
|
const r = document.createRange();
|
||||||
|
r.setStart(item, 0);
|
||||||
|
r.setEnd(item, 0);
|
||||||
|
s.removeAllRanges();
|
||||||
|
s.addRange(r);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
const r2 = document.createRange();
|
||||||
|
r2.selectNodeContents(item);
|
||||||
|
r2.collapse(false);
|
||||||
|
const s2 = window.getSelection();
|
||||||
|
s2.removeAllRanges();
|
||||||
|
s2.addRange(r2);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
<ion-icon slot="start" name="alert"></ion-icon>
|
<ion-icon slot="start" name="alert"></ion-icon>
|
||||||
<ion-label>Heading 4</ion-label>
|
<ion-label>Heading 4</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
<ion-item button (click)="onSelect('ul')">
|
||||||
|
<ion-icon slot="start" name="list"></ion-icon>
|
||||||
|
<ion-label>Unordered List</ion-label>
|
||||||
|
</ion-item>
|
||||||
<ion-item button (click)="onSelect('block_code')">
|
<ion-item button (click)="onSelect('block_code')">
|
||||||
<ion-icon slot="start" name="information"></ion-icon>
|
<ion-icon slot="start" name="information"></ion-icon>
|
||||||
<ion-label>Monospace Block</ion-label>
|
<ion-label>Monospace Block</ion-label>
|
||||||
@ -39,4 +43,8 @@
|
|||||||
<ion-icon slot="start" name="document"></ion-icon>
|
<ion-icon slot="start" name="document"></ion-icon>
|
||||||
<ion-label>Upload Files</ion-label>
|
<ion-label>Upload Files</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
<ion-item button (click)="onSelect('page_sep')">
|
||||||
|
<ion-icon slot="start" name="remove"></ion-icon>
|
||||||
|
<ion-label>Horizontal Row</ion-label>
|
||||||
|
</ion-item>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<ng-container>
|
<ng-container>
|
||||||
<div class="editor-root ion-padding">
|
<div class="editor-root ion-padding" style="padding: 30px 80px;">
|
||||||
<div class="host-container ion-padding">
|
<div class="host-container ion-padding">
|
||||||
<editor-host #editorHosts *ngFor="let record of hostRecords; let i = index" [record]="hostRecords[i]" (recordChange)="onHostRecordChange($event, i)"
|
<editor-host #editorHosts *ngFor="let record of hostRecords; let i = index" [record]="hostRecords[i]" (recordChange)="onHostRecordChange($event, i)"
|
||||||
(newHostRequested)="onNewHostRequested($event)" (destroyHostRequested)="onDestroyHostRequested($event)"
|
(newHostRequested)="onNewHostRequested($event)" (destroyHostRequested)="onDestroyHostRequested($event)"
|
||||||
@ -24,7 +24,7 @@
|
|||||||
</editor-host>
|
</editor-host>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="editor-buttons">
|
<div class="editor-buttons" style="margin-bottom: 50px;">
|
||||||
<ion-button (click)="onAddClick($event)" class="ion-padding ion-margin-start" fill="outline" color="medium">Add Node</ion-button>
|
<ion-button (click)="onAddClick($event)" class="ion-padding ion-margin-start" fill="outline" color="medium">Add Node</ion-button>
|
||||||
<ion-button (click)="onSaveClick()" class="ion-padding" fill="outline" color="medium">Save</ion-button>
|
<ion-button (click)="onSaveClick()" class="ion-padding" fill="outline" color="medium">Save</ion-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -62,16 +62,15 @@ export class EditorPage implements OnInit {
|
|||||||
const hostRec = new HostRecord(defValue);
|
const hostRec = new HostRecord(defValue);
|
||||||
hostRec.type = arg.data;
|
hostRec.type = arg.data;
|
||||||
hostRec.PageId = this.pageRecord.UUID;
|
hostRec.PageId = this.pageRecord.UUID;
|
||||||
|
|
||||||
|
if ( hostRec.type === 'ul' ) {
|
||||||
|
hostRec.value = JSON.stringify([{value: '', indentationLevel: 0}]);
|
||||||
|
}
|
||||||
|
|
||||||
this.hostRecords.push(hostRec);
|
this.hostRecords.push(hostRec);
|
||||||
if ( hostRec.isNorm() ) {
|
if ( hostRec.isNorm() ) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const host = this.editorHosts.toArray().reverse()[0].hostContainer.nativeElement;
|
this.editorHosts.toArray().reverse()[0].takeFocus();
|
||||||
const s = window.getSelection();
|
|
||||||
const r = document.createRange();
|
|
||||||
r.setStart(host, defValue.length);
|
|
||||||
r.setEnd(host, defValue.length);
|
|
||||||
s.removeAllRanges();
|
|
||||||
s.addRange(r);
|
|
||||||
}, 0);
|
}, 0);
|
||||||
} else {
|
} else {
|
||||||
this.onSaveClick();
|
this.onSaveClick();
|
||||||
@ -96,6 +95,8 @@ export class EditorPage implements OnInit {
|
|||||||
return '```';
|
return '```';
|
||||||
} else if ( type === 'click_link' ) {
|
} else if ( type === 'click_link' ) {
|
||||||
return 'https://';
|
return 'https://';
|
||||||
|
} else if ( type === 'page_sep' ) {
|
||||||
|
return '---';
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@ -115,15 +116,8 @@ export class EditorPage implements OnInit {
|
|||||||
this.hostRecords = newHosts;
|
this.hostRecords = newHosts;
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const host = this.editorHosts.toArray()[insertAfter + 1].hostContainer.nativeElement;
|
this.editorHosts.toArray()[insertAfter + 1].takeFocus();
|
||||||
const s = window.getSelection();
|
|
||||||
const r = document.createRange();
|
|
||||||
r.setStart(host, 0);
|
|
||||||
r.setEnd(host, 0);
|
|
||||||
s.removeAllRanges();
|
|
||||||
s.addRange(r);
|
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDestroyHostRequested($event) {
|
onDestroyHostRequested($event) {
|
||||||
@ -148,14 +142,10 @@ export class EditorPage implements OnInit {
|
|||||||
focusIndex = removedIndex - 1;
|
focusIndex = removedIndex - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log({removedIndex, focusIndex, edHArr: this.editorHosts.toArray()});
|
||||||
|
|
||||||
if ( focusIndex >= 0 ) {
|
if ( focusIndex >= 0 ) {
|
||||||
const host = this.editorHosts.toArray()[focusIndex].hostContainer.nativeElement;
|
this.editorHosts.toArray()[focusIndex].takeFocus(false);
|
||||||
const s = window.getSelection();
|
|
||||||
const r = document.createRange();
|
|
||||||
r.setStart(host, 0);
|
|
||||||
r.setEnd(host, 0);
|
|
||||||
s.removeAllRanges();
|
|
||||||
s.addRange(r);
|
|
||||||
}
|
}
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
@ -167,7 +157,6 @@ export class EditorPage implements OnInit {
|
|||||||
index = i;
|
index = i;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
export default class HostRecord {
|
export default class HostRecord {
|
||||||
public value = '';
|
public value = '';
|
||||||
public type: 'paragraph'|'header1'|'header2'|'header3'|'header4'|'block_code'|'click_link'|'database_ref'|'ul'|'code_ref'|'file_ref' = 'paragraph';
|
public type: 'paragraph'
|
||||||
|
|'header1'|'header2'|'header3'|'header4'
|
||||||
|
|'block_code'|'click_link'|'database_ref'
|
||||||
|
|'ul'|'code_ref'|'file_ref'|'page_sep' = 'paragraph';
|
||||||
|
|
||||||
public CreatedAt: string;
|
public CreatedAt: string;
|
||||||
public PageId: string;
|
public PageId: string;
|
||||||
@ -13,7 +16,7 @@ export default class HostRecord {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public isNorm() {
|
public isNorm() {
|
||||||
return ['paragraph', 'header1', 'header2', 'header3', 'header4', 'block_code', 'click_link'].includes(this.type);
|
return ['paragraph', 'header1', 'header2', 'header3', 'header4', 'block_code', 'click_link', 'page_sep'].includes(this.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
load(data: any) {
|
load(data: any) {
|
||||||
|
Loading…
Reference in New Issue
Block a user