MOBILE-3053 rte: Highlight toolbar styles

main
Albert Gasset 2019-06-19 15:37:03 +02:00
parent 51086fa848
commit 0943b0c431
2 changed files with 56 additions and 16 deletions

View File

@ -10,52 +10,52 @@
<ion-slides [slidesPerView]="numToolbarButtons" (ionSlideDidChange)="updateToolbarArrows()"> <ion-slides [slidesPerView]="numToolbarButtons" (ionSlideDidChange)="updateToolbarArrows()">
<!-- https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand --> <!-- https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand -->
<ion-slide> <ion-slide>
<button [disabled]="!rteEnabled" (click)="buttonAction($event, 'bold')"> <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.b" (click)="buttonAction($event, 'bold')">
<core-icon name="fa-bold"></core-icon> <core-icon name="fa-bold"></core-icon>
</button> </button>
</ion-slide> </ion-slide>
<ion-slide> <ion-slide>
<button [disabled]="!rteEnabled" (click)="buttonAction($event, 'italic')"> <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.i" (click)="buttonAction($event, 'italic')">
<core-icon name="fa-italic"></core-icon> <core-icon name="fa-italic"></core-icon>
</button> </button>
</ion-slide> </ion-slide>
<ion-slide> <ion-slide>
<button [disabled]="!rteEnabled" (click)="buttonAction($event, 'underline')"> <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.u" (click)="buttonAction($event, 'underline')">
<core-icon name="fa-underline"></core-icon> <core-icon name="fa-underline"></core-icon>
</button> </button>
</ion-slide> </ion-slide>
<ion-slide> <ion-slide>
<button [disabled]="!rteEnabled" (click)="buttonAction($event, 'strikeThrough')"> <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.strike" (click)="buttonAction($event, 'strikeThrough')">
<core-icon name="fa-strikethrough"></core-icon> <core-icon name="fa-strikethrough"></core-icon>
</button> </button>
</ion-slide> </ion-slide>
<ion-slide> <ion-slide>
<button [disabled]="!rteEnabled" (click)="buttonAction($event, 'formatBlock|<p>')"> <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.p" (click)="buttonAction($event, 'formatBlock|<p>')">
<core-icon name="fa-paragraph"></core-icon> <core-icon name="fa-paragraph"></core-icon>
</button> </button>
</ion-slide> </ion-slide>
<ion-slide> <ion-slide>
<button [disabled]="!rteEnabled" (click)="buttonAction($event, 'formatBlock|<h1>')"> <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.h1" (click)="buttonAction($event, 'formatBlock|<h1>')">
<core-icon name="fa-header"></core-icon>1 <core-icon name="fa-header"></core-icon>1
</button> </button>
</ion-slide> </ion-slide>
<ion-slide> <ion-slide>
<button [disabled]="!rteEnabled" (click)="buttonAction($event, 'formatBlock|<h2>')"> <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.h2" (click)="buttonAction($event, 'formatBlock|<h2>')">
<core-icon name="fa-header"></core-icon>2 <core-icon name="fa-header"></core-icon>2
</button> </button>
</ion-slide> </ion-slide>
<ion-slide> <ion-slide>
<button [disabled]="!rteEnabled" (click)="buttonAction($event, 'formatBlock|<h3>')"> <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.h3" (click)="buttonAction($event, 'formatBlock|<h3>')">
<core-icon name="fa-header"></core-icon>3 <core-icon name="fa-header"></core-icon>3
</button> </button>
</ion-slide> </ion-slide>
<ion-slide> <ion-slide>
<button [disabled]="!rteEnabled"(click)="buttonAction($event, 'insertUnorderedList')"> <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.ul" (click)="buttonAction($event, 'insertUnorderedList')">
<core-icon name="fa-list-ul"></core-icon> <core-icon name="fa-list-ul"></core-icon>
</button> </button>
</ion-slide> </ion-slide>
<ion-slide> <ion-slide>
<button [disabled]="!rteEnabled" (click)="buttonAction($event, 'insertOrderedList')"> <button [disabled]="!rteEnabled" [attr.aria-pressed]="toolbarStyles.ol" (click)="buttonAction($event, 'insertOrderedList')">
<core-icon name="fa-list-ol"></core-icon> <core-icon name="fa-list-ol"></core-icon>
</button> </button>
</ion-slide> </ion-slide>

View File

@ -59,7 +59,6 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
protected element: HTMLDivElement; protected element: HTMLDivElement;
protected editorElement: HTMLDivElement; protected editorElement: HTMLDivElement;
protected resizeFunction;
protected kbHeight = 0; // Last known keyboard height. protected kbHeight = 0; // Last known keyboard height.
protected minHeight = 200; // Minimum height of the editor. protected minHeight = 200; // Minimum height of the editor.
@ -79,7 +78,18 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
toolbarArrows = false; toolbarArrows = false;
toolbarPrevHidden = true; toolbarPrevHidden = true;
toolbarNextHidden = false; toolbarNextHidden = false;
toolbarStyles = {
b: 'false',
i: 'false',
u: 'false',
strike: 'false',
p: 'false',
h1: 'false',
h2: 'false',
h3: 'false',
ul: 'false',
ol: 'false',
};
protected isCurrentView = true; protected isCurrentView = true;
protected toolbarButtonWidth = 40; protected toolbarButtonWidth = 40;
protected toolbarArrowWidth = 28; protected toolbarArrowWidth = 28;
@ -119,8 +129,8 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
// Use paragraph on enter. // Use paragraph on enter.
document.execCommand('DefaultParagraphSeparator', false, 'p'); document.execCommand('DefaultParagraphSeparator', false, 'p');
this.resizeFunction = this.maximizeEditorSize.bind(this); window.addEventListener('resize', this.maximizeEditorSize);
window.addEventListener('resize', this.resizeFunction); document.addEventListener('selectionchange', this.updateToolbarStyles);
let i = 0; let i = 0;
this.initHeightInterval = setInterval(() => { this.initHeightInterval = setInterval(() => {
@ -145,7 +155,7 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
* *
* @return {Promise<number>} Resolved with calculated editor size. * @return {Promise<number>} Resolved with calculated editor size.
*/ */
protected maximizeEditorSize(): Promise<number> { protected maximizeEditorSize = (): Promise<number> => {
this.content.resize(); this.content.resize();
const deferred = this.utils.promiseDefer(); const deferred = this.utils.promiseDefer();
@ -617,6 +627,35 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
this.toolbarNextHidden = currentIndex + this.numToolbarButtons >= this.toolbarSlides.length(); this.toolbarNextHidden = currentIndex + this.numToolbarButtons >= this.toolbarSlides.length();
} }
/**
* Update highlighted toolbar styles.
*/
updateToolbarStyles = (): void => {
const node = document.getSelection().focusNode;
if (!node) {
return;
}
let element = node.nodeType == 1 ? node as HTMLElement : node.parentElement;
const styles = {};
while (element != null && element !== this.editorElement) {
const tagName = element.tagName.toLowerCase();
if (this.toolbarStyles[tagName]) {
styles[tagName] = 'true';
}
element = element.parentElement;
}
for (const tagName in this.toolbarStyles) {
this.toolbarStyles[tagName] = 'false';
}
if (element === this.editorElement) {
Object.assign(this.toolbarStyles, styles);
}
}
/** /**
* User entered the page that contains the component. * User entered the page that contains the component.
*/ */
@ -638,7 +677,8 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
*/ */
ngOnDestroy(): void { ngOnDestroy(): void {
this.valueChangeSubscription && this.valueChangeSubscription.unsubscribe(); this.valueChangeSubscription && this.valueChangeSubscription.unsubscribe();
window.removeEventListener('resize', this.resizeFunction); window.removeEventListener('resize', this.maximizeEditorSize);
document.removeEventListener('selectionchange', this.updateToolbarStyles);
clearInterval(this.initHeightInterval); clearInterval(this.initHeightInterval);
this.keyboardObs && this.keyboardObs.off(); this.keyboardObs && this.keyboardObs.off();
} }