feat: show and manage pins on page snapshot
This commit is contained in:
parent
0830cdf945
commit
99368bf2e9
@ -17,11 +17,12 @@
|
||||
import { BrowserStorageWrapper } from '../../service/browser.storage.wrapper';
|
||||
import { ICommand } from '../../model/shared/common.dto';
|
||||
import { ObjDto } from '../../model/obj/obj.dto';
|
||||
import { ObjPinDto } from '../../model/obj/obj-pin.dto';
|
||||
import { ObjectStoreKeys } from '../../keys/object.store.keys';
|
||||
|
||||
export class ObjPinGetCommand<T> implements ICommand<Promise<ObjDto<T>>> {
|
||||
export class ObjPinGetCommand implements ICommand<Promise<ObjDto<ObjPinDto>>> {
|
||||
constructor(private id: number) {}
|
||||
async execute(): Promise<ObjDto<T>> {
|
||||
return await BrowserStorageWrapper.get<ObjDto<T>>(`${ObjectStoreKeys.PIN_ID}:${this.id}`);
|
||||
async execute(): Promise<ObjDto<ObjPinDto>> {
|
||||
return await BrowserStorageWrapper.get<ObjDto<ObjPinDto>>(`${ObjectStoreKeys.PIN_ID}:${this.id}`);
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ export class ObjGetHrefCommand implements ICommand<Promise<ObjDto<ObjPageDataDto
|
||||
const out: ObjDto<ObjPageDataDto>[] = [];
|
||||
const pinIds = (await LinkHrefOriginStore.pinIds(this.data.href)).reverse();
|
||||
for (const id of pinIds) {
|
||||
const obj = await new ObjPinGetCommand<ObjPageDataDto>(id).execute();
|
||||
const obj = await new ObjPinGetCommand(id).execute();
|
||||
out.push(obj);
|
||||
}
|
||||
const ids = (await LinkHrefOriginStore.hrefIds(this.data.href)).reverse();
|
||||
|
@ -30,7 +30,7 @@ export class PinGetHrefCommand implements ICommand<Promise<ObjDto<ObjPinDto>[]>>
|
||||
const out: ObjDto<ObjPinDto>[] = [];
|
||||
|
||||
for (const id of pinIds) {
|
||||
const obj = await new ObjPinGetCommand<ObjPinDto>(id).execute();
|
||||
const obj = await new ObjPinGetCommand(id).execute();
|
||||
// TODO revisit visible flag in pin.manager.ts in content scripts
|
||||
if (!obj.local?.visible) continue;
|
||||
out.push(obj);
|
||||
|
@ -14,7 +14,8 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { applyStylesToElement } from '../../../common/style.utils';
|
||||
import { PinDocument } from '../model/pin-view.model';
|
||||
import { applyStylesToElement } from '../../../style.utils';
|
||||
|
||||
const elStyles = {
|
||||
'background-color': '#ffffff',
|
||||
@ -26,8 +27,9 @@ const elStyles = {
|
||||
};
|
||||
|
||||
export class ContentButton {
|
||||
private readonly btn = document.createElement('button');
|
||||
constructor(private html: string, private clickCallback: () => void) {
|
||||
private readonly btn: HTMLButtonElement;
|
||||
constructor(private doc: PinDocument, private html: string, private clickCallback: () => void) {
|
||||
this.btn = doc.document.createElement('button');
|
||||
this.btn.innerHTML = html;
|
||||
this.btn.addEventListener('click', clickCallback);
|
||||
}
|
@ -14,12 +14,12 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../../model/html.model';
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../model/pin-view.model';
|
||||
import { PinEditManager } from '../pin-edit.manager';
|
||||
import { PinModel } from '../pin.model';
|
||||
import { PinEditModel } from '../model/pin-edit.model';
|
||||
import { ShowCommentButton } from './buttons/show-comment.button';
|
||||
import { VideoTimeComponent } from './video-time/video-time.component';
|
||||
import { applyStylesToElement } from '../../../common/style.utils';
|
||||
import { applyStylesToElement } from '../../../style.utils';
|
||||
|
||||
const elStyles = {
|
||||
height: '20px',
|
||||
@ -30,14 +30,15 @@ const elStyles = {
|
||||
};
|
||||
|
||||
export class BottomBarComponent implements HtmlComponent<HTMLElement>, HtmlComponentFocusable {
|
||||
private el = document.createElement('div');
|
||||
private el: HTMLDivElement;
|
||||
|
||||
private videoTime: VideoTimeComponent;
|
||||
private addComment: ShowCommentButton;
|
||||
|
||||
constructor(edit: PinEditManager, private model: PinModel) {
|
||||
constructor(edit: PinEditManager, private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.videoTime = new VideoTimeComponent(model);
|
||||
this.addComment = new ShowCommentButton(edit);
|
||||
this.addComment = new ShowCommentButton(edit, model);
|
||||
}
|
||||
|
||||
render(): HTMLDivElement {
|
@ -14,9 +14,10 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditManager } from '../../pin-edit.manager';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
|
||||
const elStyles = {
|
||||
color: '#000000',
|
||||
@ -28,11 +29,13 @@ const elStyles = {
|
||||
};
|
||||
|
||||
export class ShowCommentButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private visible = false;
|
||||
|
||||
constructor(private edit: PinEditManager) {}
|
||||
constructor(private edit: PinEditManager, model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
cleanup(): void {
|
||||
this.el.removeEventListener('click', this.handleClick);
|
@ -14,11 +14,11 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ObjVideoDataDto } from '../../../../common/model/obj/obj-snapshot.dto';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { XpathFactory } from '../../../../common/factory/xpath.factory';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { fnVideoSecondsTime } from '../../../../common/fn/fn-date-format';
|
||||
import { ObjVideoDataDto } from '../../../../model/obj/obj-snapshot.dto';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { XpathFactory } from '../../../../factory/xpath.factory';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { fnVideoSecondsTime } from '../../../../fn/fn-date-format';
|
||||
|
||||
const elStyles = {
|
||||
display: 'flex',
|
||||
@ -35,10 +35,11 @@ const titleStyle = {
|
||||
};
|
||||
|
||||
export class VideoTimeComponent {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
private readonly video?: ObjVideoDataDto;
|
||||
|
||||
constructor(private model: PinModel) {
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
if (model.video) {
|
||||
this.video = model.video[0];
|
||||
}
|
||||
@ -47,16 +48,16 @@ export class VideoTimeComponent {
|
||||
renderVideo = () => {
|
||||
if (!this.video) return;
|
||||
this.el.innerHTML = '';
|
||||
const title = document.createElement('div');
|
||||
const title = this.model.doc.document.createElement('div');
|
||||
applyStylesToElement(title, titleStyle);
|
||||
title.innerText = 'video';
|
||||
this.el.appendChild(title);
|
||||
const from = document.createElement('div');
|
||||
const from = this.model.doc.document.createElement('div');
|
||||
from.innerText = fnVideoSecondsTime(this.video.currentTime);
|
||||
|
||||
this.el.appendChild(from);
|
||||
|
||||
const between = document.createElement('div');
|
||||
const between = this.model.doc.document.createElement('div');
|
||||
between.innerText = '-';
|
||||
this.el.appendChild(between);
|
||||
};
|
||||
@ -75,7 +76,7 @@ export class VideoTimeComponent {
|
||||
|
||||
private handleNavigateClick = () => {
|
||||
if (!this.video) return;
|
||||
const value = XpathFactory.newXPathResult(this.video.xpath);
|
||||
const value = XpathFactory.newXPathResult(document, this.video.xpath);
|
||||
const node = value.singleNodeValue as HTMLVideoElement;
|
||||
if (!node) return;
|
||||
node.currentTime = this.video.currentTime;
|
@ -16,10 +16,10 @@
|
||||
*/
|
||||
import { DownloadCsvButton } from './download-buttons/download-csv.button';
|
||||
import { DownloadImageButton } from './download-buttons/download-image.button';
|
||||
import { HtmlComponent } from '../../model/html.model';
|
||||
import { HtmlComponent } from '../model/pin-view.model';
|
||||
import { PinEditManager } from '../pin-edit.manager';
|
||||
import { PinModel } from '../pin.model';
|
||||
import { applyStylesToElement } from '../../../common/style.utils';
|
||||
import { PinEditModel } from '../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../style.utils';
|
||||
|
||||
const downloadBarStyles = {
|
||||
top: '-24px',
|
||||
@ -34,14 +34,15 @@ const downloadBarStyles = {
|
||||
};
|
||||
|
||||
export class DownloadBarComponent implements HtmlComponent<HTMLElement> {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private visible = false;
|
||||
|
||||
private imageButton: DownloadImageButton;
|
||||
private csvButton: DownloadCsvButton;
|
||||
|
||||
constructor(edit: PinEditManager, private model: PinModel) {
|
||||
constructor(edit: PinEditManager, private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.imageButton = new DownloadImageButton(edit, model);
|
||||
this.csvButton = new DownloadCsvButton(model);
|
||||
}
|
@ -14,11 +14,11 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { BusDownloadMessage, BusMessageType } from '../../../../common/model/bus.model';
|
||||
import { BrowserApi } from '../../../../common/service/browser.api.wrapper';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { fnUid } from '../../../../common/fn/fn-uid';
|
||||
import { BusDownloadMessage, BusMessageType } from '../../../../model/bus.model';
|
||||
import { BrowserApi } from '../../../../service/browser.api.wrapper';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { fnUid } from '../../../../fn/fn-uid';
|
||||
|
||||
const elStyles = {
|
||||
'margin-right': '10px',
|
||||
@ -28,9 +28,11 @@ const elStyles = {
|
||||
};
|
||||
|
||||
export class DownloadCsvButton {
|
||||
constructor(private model: PinModel) {}
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private readonly el = document.createElement('div');
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.innerText = 'csv';
|
@ -14,16 +14,15 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { BusDownloadMessage, BusMessageType } from '../../../../common/model/bus.model';
|
||||
import { BrowserApi } from '../../../../common/service/browser.api.wrapper';
|
||||
import { ContentSettingsStore } from '../../../store/content-settings.store';
|
||||
import { ObjRectangleDto } from '../../../../common/model/obj/obj-utils.dto';
|
||||
import { BusDownloadMessage, BusMessageType } from '../../../../model/bus.model';
|
||||
import { BrowserApi } from '../../../../service/browser.api.wrapper';
|
||||
import { ObjRectangleDto } from '../../../../model/obj/obj-utils.dto';
|
||||
import { PinEditManager } from '../../pin-edit.manager';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { ScreenshotFactory } from '../../../../common/factory/screenshot.factory';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { fnB64toBlob } from '../../../../common/fn/fn-b64-to-blob';
|
||||
import { fnUid } from '../../../../common/fn/fn-uid';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { ScreenshotFactory } from '../../../../factory/screenshot.factory';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { fnB64toBlob } from '../../../../fn/fn-b64-to-blob';
|
||||
import { fnUid } from '../../../../fn/fn-uid';
|
||||
|
||||
const elStyles = {
|
||||
'margin-right': '10px',
|
||||
@ -32,9 +31,11 @@ const elStyles = {
|
||||
};
|
||||
|
||||
export class DownloadImageButton {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
constructor(private edit: PinEditManager, private model: PinModel) {}
|
||||
constructor(private edit: PinEditManager, private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.innerText = 'image';
|
||||
@ -62,20 +63,20 @@ export class DownloadImageButton {
|
||||
if (this.model.canvas) {
|
||||
rect = this.model.canvas.rect;
|
||||
}
|
||||
const screenshot = await ScreenshotFactory.takeScreenshot(rect);
|
||||
const screenshot = await ScreenshotFactory.takeScreenshot(this.model.doc, rect);
|
||||
await this.downloadScreenshot(screenshot);
|
||||
|
||||
this.edit.showScreenshot();
|
||||
|
||||
this.model.ref.style.border = ContentSettingsStore.borderStyle;
|
||||
this.model.ref.style.borderRadius = ContentSettingsStore.borderRadius;
|
||||
this.model.ref.style.border = this.model.doc.settings.borderStyle;
|
||||
this.model.ref.style.borderRadius = this.model.doc.settings.borderRadius;
|
||||
}, 0);
|
||||
};
|
||||
|
||||
private downloadScreenshot = async (screenshot: string): Promise<void> => {
|
||||
let url = '';
|
||||
let filename = '';
|
||||
if (ContentSettingsStore.screenshotFormat == 'jpeg') {
|
||||
if (this.model.doc.settings.screenshotFormat == 'jpeg') {
|
||||
url = window.URL.createObjectURL(fnB64toBlob(screenshot, 'image/jpeg'));
|
||||
filename = `${fnUid()}.jpg`;
|
||||
} else {
|
@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../../model/html.model';
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../model/pin-view.model';
|
||||
import { ContentButton } from '../base/content-button';
|
||||
import { DrawBrushSizeButton } from './draw-buttons/draw-brush-size.button';
|
||||
import { DrawColorPickerButton } from './draw-buttons/draw-color-picker.button';
|
||||
@ -24,10 +24,10 @@ import { DrawLineButton } from './draw-buttons/draw-line.button';
|
||||
import { DrawPencilButton } from './draw-buttons/draw-pencil.button';
|
||||
import { DrawRedoButton } from './draw-buttons/draw-redo.button';
|
||||
import { DrawTestButton } from './draw-buttons/draw-test.button';
|
||||
import { DrawToolDto } from '../../../common/model/obj/obj-draw.dto';
|
||||
import { DrawToolDto } from '../../../model/obj/obj-draw.dto';
|
||||
import { DrawUndoButton } from './draw-buttons/draw-undo.button';
|
||||
import { PinModel } from '../pin.model';
|
||||
import { applyStylesToElement } from '../../../common/style.utils';
|
||||
import { PinEditModel } from '../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../style.utils';
|
||||
|
||||
const drawBarStyles = {
|
||||
top: '-24px',
|
||||
@ -44,7 +44,7 @@ const iconStyles = {
|
||||
};
|
||||
|
||||
export class DrawBarComponent implements HtmlComponent<HTMLElement>, HtmlComponentFocusable {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private visible = false;
|
||||
|
||||
@ -63,17 +63,18 @@ export class DrawBarComponent implements HtmlComponent<HTMLElement>, HtmlCompone
|
||||
|
||||
private readonly saveButton: ContentButton;
|
||||
|
||||
constructor(private model: PinModel) {
|
||||
this.pencil = new DrawPencilButton(this);
|
||||
this.line = new DrawLineButton(this);
|
||||
this.fill = new DrawFillButton(this);
|
||||
this.erase = new DrawEraseButton(this);
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.pencil = new DrawPencilButton(this, model);
|
||||
this.line = new DrawLineButton(this, model);
|
||||
this.fill = new DrawFillButton(this, model);
|
||||
this.erase = new DrawEraseButton(this, model);
|
||||
|
||||
this.colorPicker = new DrawColorPickerButton(model);
|
||||
this.sizeButton = new DrawBrushSizeButton(model);
|
||||
|
||||
this.undoButton = new DrawUndoButton(this);
|
||||
this.redoButton = new DrawRedoButton(this);
|
||||
this.undoButton = new DrawUndoButton(this, model);
|
||||
this.redoButton = new DrawRedoButton(this, model);
|
||||
|
||||
// TODO move logic to model
|
||||
this.model.draw.setUndoButton(this.undoButton);
|
||||
@ -81,7 +82,7 @@ export class DrawBarComponent implements HtmlComponent<HTMLElement>, HtmlCompone
|
||||
|
||||
this.drawTest = new DrawTestButton(model);
|
||||
|
||||
this.saveButton = new ContentButton('save', this.handleSaveClick);
|
||||
this.saveButton = new ContentButton(model.doc, 'save', this.handleSaveClick);
|
||||
}
|
||||
|
||||
handleSaveClick = async (): Promise<void> => {
|
@ -14,20 +14,21 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../../../model/html.model';
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../../model/pin-view.model';
|
||||
import { DrawBrushSize } from './draw-brush-size';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class DrawBrushSizeButton implements HtmlComponent<HTMLElement>, HtmlComponentFocusable {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private visible = false;
|
||||
|
||||
private sizeInput: DrawBrushSize;
|
||||
|
||||
constructor(private model: PinModel) {
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.sizeInput = new DrawBrushSize(model);
|
||||
}
|
||||
|
@ -14,9 +14,9 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
|
||||
const elStyles = {
|
||||
width: '75px',
|
||||
@ -37,11 +37,13 @@ const inputStyles = {
|
||||
};
|
||||
|
||||
export class DrawBrushSize implements HtmlComponent<HTMLElement> {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
private readonly input: HTMLInputElement;
|
||||
|
||||
private input = document.createElement('input');
|
||||
|
||||
constructor(private model: PinModel) {}
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.input = model.doc.document.createElement('input');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
applyStylesToElement(this.el, elStyles);
|
@ -14,21 +14,22 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../../../model/html.model';
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../../model/pin-view.model';
|
||||
import { DrawColorPicker } from './draw-color-picker';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class DrawColorPickerButton implements HtmlComponent<HTMLElement>, HtmlComponentFocusable {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private picker: DrawColorPicker;
|
||||
|
||||
private visible = false;
|
||||
|
||||
constructor(private model: PinModel) {
|
||||
this.picker = new DrawColorPicker(model.rect, this);
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.picker = new DrawColorPicker(model, this);
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
@ -16,9 +16,9 @@
|
||||
*/
|
||||
import { ColorUtils, RGBColor } from './draw-color.utils';
|
||||
import { DrawColorPickerButton } from './draw-color-picker.button';
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { ObjRectangleDto } from '../../../../common/model/obj/obj-utils.dto';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
|
||||
const saturationStyles = {
|
||||
background: 'linear-gradient(to right, #FFFFFF, #FF0000)',
|
||||
@ -94,22 +94,30 @@ const colorInputStyles = {
|
||||
};
|
||||
|
||||
export class DrawColorPicker implements HtmlComponent<HTMLElement> {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly saturation = document.createElement('div');
|
||||
private readonly saturationSelector = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
private readonly saturation: HTMLDivElement;
|
||||
private readonly saturationSelector: HTMLDivElement;
|
||||
private saturationMove = false;
|
||||
|
||||
private readonly brightness = document.createElement('div');
|
||||
private readonly brightness: HTMLDivElement;
|
||||
|
||||
private readonly hue = document.createElement('div');
|
||||
private readonly hueSelector = document.createElement('div');
|
||||
private readonly hue: HTMLDivElement;
|
||||
private readonly hueSelector: HTMLDivElement;
|
||||
private hueMove = false;
|
||||
|
||||
private colorInput = document.createElement('input');
|
||||
private readonly colorInput: HTMLInputElement;
|
||||
|
||||
private color: RGBColor = { r: 255, g: 0, b: 0 };
|
||||
|
||||
constructor(private rect: ObjRectangleDto, private colorDisplay: DrawColorPickerButton) {}
|
||||
constructor(private model: PinEditModel, private colorDisplay: DrawColorPickerButton) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.saturation = model.doc.document.createElement('div');
|
||||
this.saturationSelector = model.doc.document.createElement('div');
|
||||
this.brightness = model.doc.document.createElement('div');
|
||||
this.hue = model.doc.document.createElement('div');
|
||||
this.hueSelector = model.doc.document.createElement('div');
|
||||
this.colorInput = model.doc.document.createElement('input');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
applyStylesToElement(this.saturation, saturationStyles);
|
@ -15,17 +15,20 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { DrawBarComponent } from '../draw-bar.component';
|
||||
import { DrawToolDto } from '../../../../common/model/obj/obj-draw.dto';
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { DrawToolDto } from '../../../../model/obj/obj-draw.dto';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class DrawEraseButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private selected = false;
|
||||
|
||||
constructor(private drawBar: DrawBarComponent) {}
|
||||
constructor(private drawBar: DrawBarComponent, model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
const stroke = this.selected ? '#ff0000' : '#000000';
|
@ -15,17 +15,20 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { DrawBarComponent } from '../draw-bar.component';
|
||||
import { DrawToolDto } from '../../../../common/model/obj/obj-draw.dto';
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { DrawToolDto } from '../../../../model/obj/obj-draw.dto';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class DrawFillButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private selected = false;
|
||||
|
||||
constructor(private drawBar: DrawBarComponent) {}
|
||||
constructor(private drawBar: DrawBarComponent, model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
const fill = this.selected ? '#ff0000' : '#000000';
|
@ -15,17 +15,20 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { DrawBarComponent } from '../draw-bar.component';
|
||||
import { DrawToolDto } from '../../../../common/model/obj/obj-draw.dto';
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { DrawToolDto } from '../../../../model/obj/obj-draw.dto';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class DrawLineButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private selected = false;
|
||||
|
||||
constructor(private drawBar: DrawBarComponent) {}
|
||||
constructor(private drawBar: DrawBarComponent, model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
const stroke = this.selected ? '#ff0000' : '#000000';
|
@ -15,17 +15,20 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { DrawBarComponent } from '../draw-bar.component';
|
||||
import { DrawToolDto } from '../../../../common/model/obj/obj-draw.dto';
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { DrawToolDto } from '../../../../model/obj/obj-draw.dto';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class DrawPencilButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el;
|
||||
|
||||
private selected = false;
|
||||
|
||||
constructor(private drawBar: DrawBarComponent) {}
|
||||
constructor(private drawBar: DrawBarComponent, model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
const fill = this.selected ? '#ff0000' : '#000000';
|
@ -15,16 +15,19 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { DrawBarComponent } from '../draw-bar.component';
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class DrawRedoButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private canRedo = false;
|
||||
|
||||
constructor(private drawBar: DrawBarComponent) {}
|
||||
constructor(private drawBar: DrawBarComponent, model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
const fill = this.canRedo ? '#ff0000' : '#000000';
|
@ -14,15 +14,17 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class DrawTestButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
constructor(private model: PinModel) {}
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.innerText = 'test';
|
@ -15,16 +15,19 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { DrawBarComponent } from '../draw-bar.component';
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class DrawUndoButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private canUndo = false;
|
||||
|
||||
constructor(private drawBar: DrawBarComponent) {}
|
||||
constructor(private drawBar: DrawBarComponent, model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
const fill = this.canUndo ? '#ff0000' : '#000000';
|
@ -14,19 +14,20 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../model/html.model';
|
||||
import { HtmlComponent, HtmlComponentFocusable } from './model/pin-view.model';
|
||||
import { DrawAreaComponent } from './draw/draw-area.component';
|
||||
import { ObjRectangleDto } from '../../common/model/obj/obj-utils.dto';
|
||||
import { PinModel } from './pin.model';
|
||||
import { applyStylesToElement } from '../../common/style.utils';
|
||||
import { ObjRectangleDto } from '../../model/obj/obj-utils.dto';
|
||||
import { PinEditModel } from './model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../style.utils';
|
||||
|
||||
export class DrawContainerComponent implements HtmlComponent<HTMLElement>, HtmlComponentFocusable {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
readonly drawArea: DrawAreaComponent;
|
||||
private rect: ObjRectangleDto;
|
||||
|
||||
constructor(private model: PinModel) {
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.rect = model.rect;
|
||||
this.drawArea = new DrawAreaComponent(model);
|
||||
|
@ -14,15 +14,15 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { DrawToolDto, ObjDrawDataDto } from '../../../common/model/obj/obj-draw.dto';
|
||||
import { DrawToolDto, ObjDrawDataDto } from '../../../model/obj/obj-draw.dto';
|
||||
import { EraserDraw } from './tool/eraser.draw';
|
||||
import { FillDraw } from './tool/fill.draw';
|
||||
import { LineDraw } from './tool/line.draw';
|
||||
import { ObjPointDto } from '../../../common/model/obj/obj-utils.dto';
|
||||
import { ObjPointDto } from '../../../model/obj/obj-utils.dto';
|
||||
import { PencilDraw } from './tool/pencil.draw';
|
||||
import { PinModel } from '../pin.model';
|
||||
import { applyStylesToElement } from '../../../common/style.utils';
|
||||
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
||||
import { PinEditModel } from '../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../style.utils';
|
||||
import { fnConsoleLog } from '../../../fn/fn-console';
|
||||
|
||||
const canvasStyles = {
|
||||
position: 'absolute',
|
||||
@ -31,8 +31,8 @@ const canvasStyles = {
|
||||
};
|
||||
|
||||
export class DrawAreaComponent {
|
||||
readonly rasterCanvas: HTMLCanvasElement = document.createElement('canvas');
|
||||
readonly drawCanvas: HTMLCanvasElement = document.createElement('canvas');
|
||||
readonly rasterCanvas: HTMLCanvasElement;
|
||||
readonly drawCanvas: HTMLCanvasElement;
|
||||
private readonly drawCtx: CanvasRenderingContext2D | null;
|
||||
private readonly rasterCtx: CanvasRenderingContext2D | null;
|
||||
|
||||
@ -41,7 +41,9 @@ export class DrawAreaComponent {
|
||||
private readonly drawData: ObjDrawDataDto[] = [];
|
||||
private drawRedoData: ObjDrawDataDto[] = [];
|
||||
|
||||
constructor(private model: PinModel) {
|
||||
constructor(private model: PinEditModel) {
|
||||
this.rasterCanvas = model.doc.document.createElement('canvas');
|
||||
this.drawCanvas = model.doc.document.createElement('canvas');
|
||||
this.drawCtx = this.drawCanvas.getContext('2d');
|
||||
this.rasterCtx = this.rasterCanvas.getContext('2d');
|
||||
if (!model.drawData) {
|
@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ObjPointDto } from '../../../../common/model/obj/obj-utils.dto';
|
||||
import { ObjPointDto } from '../../../../model/obj/obj-utils.dto';
|
||||
|
||||
export class EraserDraw {
|
||||
private static points: ObjPointDto[];
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ColorUtils, RGBColor } from '../../draw-bar/draw-buttons/draw-color.utils';
|
||||
import { ObjPointDto } from '../../../../common/model/obj/obj-utils.dto';
|
||||
import { ObjPointDto } from '../../../../model/obj/obj-utils.dto';
|
||||
|
||||
export class FillDraw {
|
||||
static fill(from: ObjPointDto, color: string, ctx: CanvasRenderingContext2D): ObjPointDto[] {
|
@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ObjPointDto } from '../../../../common/model/obj/obj-utils.dto';
|
||||
import { ObjPointDto } from '../../../../model/obj/obj-utils.dto';
|
||||
|
||||
export class LineDraw {
|
||||
private static color: string;
|
@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ObjPointDto } from '../../../../common/model/obj/obj-utils.dto';
|
||||
import { ObjPointDto } from '../../../../model/obj/obj-utils.dto';
|
||||
|
||||
export class PencilDraw {
|
||||
private static points: ObjPointDto[] = [];
|
@ -14,9 +14,9 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../../model/html.model';
|
||||
import { HtmlPrettifyFactory } from '../../factory/html-prettify.factory';
|
||||
import { applyStylesToElement } from '../../../common/style.utils';
|
||||
import { HtmlComponent, HtmlComponentFocusable, PinDocument } from '../model/pin-view.model';
|
||||
import { HtmlPrettifyFactory } from '../../../factory/html-prettify.factory';
|
||||
import { applyStylesToElement } from '../../../style.utils';
|
||||
|
||||
const elStyle = {
|
||||
'margin-top': '48px',
|
||||
@ -45,19 +45,24 @@ const btnStyle = {
|
||||
};
|
||||
|
||||
export class HtmlEditComponent implements HtmlComponent<HTMLElement>, HtmlComponentFocusable {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private text = document.createElement('textarea');
|
||||
private action = document.createElement('div');
|
||||
private saveButton = document.createElement('button');
|
||||
private rollbackButton = document.createElement('button');
|
||||
private text: HTMLTextAreaElement;
|
||||
private action: HTMLDivElement;
|
||||
private saveButton: HTMLButtonElement;
|
||||
private rollbackButton: HTMLButtonElement;
|
||||
|
||||
public originalHtml: string;
|
||||
private htmlValue = '';
|
||||
|
||||
constructor(private ref: HTMLElement) {
|
||||
constructor(private ref: HTMLElement, doc: PinDocument) {
|
||||
// TODO fix parent icon click
|
||||
this.originalHtml = ref.innerHTML;
|
||||
this.el = doc.document.createElement('div');
|
||||
this.text = doc.document.createElement('textarea');
|
||||
this.action = doc.document.createElement('div');
|
||||
this.saveButton = doc.document.createElement('button');
|
||||
this.rollbackButton = doc.document.createElement('button');
|
||||
}
|
||||
|
||||
get value(): string | undefined {
|
@ -14,14 +14,14 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { DrawToolDto, ObjDrawDataDto, ObjDrawDto } from '../../common/model/obj/obj-draw.dto';
|
||||
import { DrawAreaComponent } from './draw/draw-area.component';
|
||||
import { DrawRedoButton } from './draw-bar/draw-buttons/draw-redo.button';
|
||||
import { DrawUndoButton } from './draw-bar/draw-buttons/draw-undo.button';
|
||||
import { ObjDrawListDto } from '../../common/model/obj/obj-pin.dto';
|
||||
import { PinModel } from './pin.model';
|
||||
import { PinUpdateCommand } from '../../common/command/pin/pin-update.command';
|
||||
import { fnSha256 } from '../../common/fn/fn-sha256';
|
||||
import { DrawToolDto, ObjDrawDataDto, ObjDrawDto } from '../../../model/obj/obj-draw.dto';
|
||||
import { DrawAreaComponent } from '../draw/draw-area.component';
|
||||
import { DrawRedoButton } from '../draw-bar/draw-buttons/draw-redo.button';
|
||||
import { DrawUndoButton } from '../draw-bar/draw-buttons/draw-undo.button';
|
||||
import { ObjDrawListDto } from '../../../model/obj/obj-pin.dto';
|
||||
import { PinEditModel } from './pin-edit.model';
|
||||
import { PinUpdateCommand } from '../../../command/pin/pin-update.command';
|
||||
import { fnSha256 } from '../../../fn/fn-sha256';
|
||||
|
||||
export class DrawModel {
|
||||
tool = DrawToolDto.Pencil;
|
||||
@ -76,7 +76,7 @@ export class DrawModel {
|
||||
this.draw.data[0].data = data;
|
||||
}
|
||||
|
||||
async saveDraw(model: PinModel) {
|
||||
async saveDraw(model: PinEditModel) {
|
||||
this.draw.data[0].hash = fnSha256(JSON.stringify(this.draw.data[0].data));
|
||||
await new PinUpdateCommand(model.object).execute();
|
||||
}
|
@ -14,16 +14,18 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ObjCanvasDto, ObjVideoDataDto } from '../../common/model/obj/obj-snapshot.dto';
|
||||
import { ObjCommentListDto, ObjPinDto, PinBorderDataDto } from '../../common/model/obj/obj-pin.dto';
|
||||
import { ObjDto, ObjLocalDto, ObjUrlDto } from '../../common/model/obj/obj.dto';
|
||||
import { ObjCanvasDto, ObjVideoDataDto } from '../../../model/obj/obj-snapshot.dto';
|
||||
import { ObjCommentListDto, ObjPinDto, PinBorderDataDto } from '../../../model/obj/obj-pin.dto';
|
||||
import { ObjDto, ObjLocalDto, ObjUrlDto } from '../../../model/obj/obj.dto';
|
||||
import { DrawModel } from './draw.model';
|
||||
import { ObjDrawDto } from '../../common/model/obj/obj-draw.dto';
|
||||
import { ObjRectangleDto } from '../../common/model/obj/obj-utils.dto';
|
||||
import { PinMouseManager } from './pin-mouse.manager';
|
||||
import { PinPointFactory } from '../factory/pin-point.factory';
|
||||
import { ObjDrawDto } from '../../../model/obj/obj-draw.dto';
|
||||
import { ObjRectangleDto } from '../../../model/obj/obj-utils.dto';
|
||||
import { PinComponent } from '../pin.component';
|
||||
import { PinDocument } from './pin-view.model';
|
||||
import { PinMouseManager } from '../pin-mouse.manager';
|
||||
import { PinPointFactory } from '../../../factory/pin-point.factory';
|
||||
|
||||
export class PinModel {
|
||||
export class PinEditModel {
|
||||
private readonly obj: ObjDto<ObjPinDto>;
|
||||
private refValue: HTMLElement;
|
||||
private rectValue: ObjRectangleDto;
|
||||
@ -34,9 +36,9 @@ export class PinModel {
|
||||
constructor(
|
||||
object: ObjDto<ObjPinDto>,
|
||||
refValue: HTMLElement,
|
||||
readonly top: HTMLDivElement,
|
||||
readonly bottom: HTMLDivElement,
|
||||
private mouseManager: PinMouseManager
|
||||
private component: PinComponent,
|
||||
private mouseManager: PinMouseManager,
|
||||
readonly doc: PinDocument
|
||||
) {
|
||||
this.obj = object;
|
||||
this.refValue = refValue;
|
||||
@ -44,6 +46,14 @@ export class PinModel {
|
||||
this.draw = new DrawModel(this.obj.data.draw);
|
||||
}
|
||||
|
||||
get top(): HTMLDivElement {
|
||||
return this.component.top;
|
||||
}
|
||||
|
||||
get bottom(): HTMLDivElement {
|
||||
return this.component.bottom;
|
||||
}
|
||||
|
||||
get rect(): ObjRectangleDto {
|
||||
return this.rectValue;
|
||||
}
|
||||
@ -103,4 +113,8 @@ export class PinModel {
|
||||
get object(): ObjDto<ObjPinDto> {
|
||||
return this.obj;
|
||||
}
|
||||
|
||||
remove() {
|
||||
this.component.cleanup();
|
||||
}
|
||||
}
|
42
src/common/components/pin/model/pin-view.model.ts
Normal file
42
src/common/components/pin/model/pin-view.model.ts
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* This file is part of the pinmenote-extension distribution (https://github.com/pinmenote/pinmenote-extension).
|
||||
* Copyright (c) 2023 Michal Szczepanski.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { PinEditModel } from './pin-edit.model';
|
||||
import { SettingsConfig } from '../../../environment';
|
||||
|
||||
export interface PinDocument {
|
||||
document: Document;
|
||||
window: Window;
|
||||
settings: SettingsConfig;
|
||||
}
|
||||
|
||||
export interface HtmlComponentFocusable {
|
||||
focusin(): void;
|
||||
focusout(): void;
|
||||
}
|
||||
|
||||
export interface PageComponent {
|
||||
model: PinEditModel; // TODO REMOVE here
|
||||
focus(goto: boolean): void;
|
||||
cleanup(): void;
|
||||
resize(): void;
|
||||
render(): any;
|
||||
isHidden(): boolean;
|
||||
}
|
||||
|
||||
export interface HtmlComponent<T> {
|
||||
render(): T;
|
||||
}
|
@ -14,18 +14,20 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { PinUpdateCommand } from '../../../../common/command/pin/pin-update.command';
|
||||
import { XpathFactory } from '../../../../common/factory/xpath.factory';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { PinUpdateCommand } from '../../../../command/pin/pin-update.command';
|
||||
import { XpathFactory } from '../../../../factory/xpath.factory';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { fnConsoleLog } from '../../../../fn/fn-console';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class EditBarParentButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
constructor(private model: PinModel, private resizeCallback: () => void) {}
|
||||
constructor(private model: PinEditModel, private resizeCallback: () => void) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" height="24" viewBox="0 0 24 24" width="24">
|
@ -14,21 +14,17 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ObjDto, ObjTypeDto } from '../../../../common/model/obj/obj.dto';
|
||||
import { BrowserStorageWrapper } from '../../../../common/service/browser.storage.wrapper';
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { LinkHrefOriginStore } from '../../../../common/store/link-href-origin.store';
|
||||
import { ObjPageDto } from '../../../../common/model/obj/obj-pin.dto';
|
||||
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { PinStore } from '../../../store/pin.store';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class EditBarSnapshotButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
constructor(private model: PinModel) {}
|
||||
constructor(model: PinEditModel, private editCallback: () => void) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="#777777" height="24" viewBox="0 0 24 24" width="24">
|
||||
@ -54,21 +50,8 @@ export class EditBarSnapshotButton implements HtmlComponent<HTMLElement> {
|
||||
this.el.removeEventListener('click', this.handleClick);
|
||||
}
|
||||
|
||||
private handleClick = async () => {
|
||||
private handleClick = () => {
|
||||
this.el.removeEventListener('click', this.handleClick);
|
||||
const o = this.model.object;
|
||||
const obj: ObjDto<ObjPageDto> = {
|
||||
...o,
|
||||
data: { snapshot: o.data.snapshot, draw: { data: [] }, comments: { data: [] } }
|
||||
};
|
||||
obj.type = ObjTypeDto.PageElementSnapshot;
|
||||
|
||||
await LinkHrefOriginStore.pinDel(obj.data.snapshot.url, obj.id);
|
||||
|
||||
const key = `${ObjectStoreKeys.OBJECT_ID}:${obj.id}`;
|
||||
await BrowserStorageWrapper.set(key, obj);
|
||||
|
||||
// Remove from store
|
||||
PinStore.delByUid(this.model.object.id);
|
||||
this.editCallback();
|
||||
};
|
||||
}
|
@ -14,11 +14,11 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../../model/html.model';
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../model/pin-view.model';
|
||||
import { EditBarParentButton } from './edit-bar-buttons/edit-bar-parent.button';
|
||||
import { EditBarSnapshotButton } from './edit-bar-buttons/edit-bar-snapshot.button';
|
||||
import { PinModel } from '../pin.model';
|
||||
import { applyStylesToElement } from '../../../common/style.utils';
|
||||
import { PinEditModel } from '../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../style.utils';
|
||||
|
||||
const editBarStyles = {
|
||||
top: '-24px',
|
||||
@ -31,16 +31,17 @@ const editBarStyles = {
|
||||
};
|
||||
|
||||
export class PinEditBarComponent implements HtmlComponent<HTMLElement>, HtmlComponentFocusable {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly el;
|
||||
|
||||
private visible = false;
|
||||
|
||||
private parentButton: EditBarParentButton;
|
||||
private snapshotButton: EditBarSnapshotButton;
|
||||
private readonly snapshotButton?: EditBarSnapshotButton;
|
||||
|
||||
constructor(private model: PinModel, resizeCallback: () => void) {
|
||||
constructor(private model: PinEditModel, resizeCallback: () => void, editCallback?: () => void) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.parentButton = new EditBarParentButton(model, resizeCallback);
|
||||
this.snapshotButton = new EditBarSnapshotButton(model);
|
||||
if (editCallback) this.snapshotButton = new EditBarSnapshotButton(model, editCallback);
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
@ -49,7 +50,7 @@ export class PinEditBarComponent implements HtmlComponent<HTMLElement>, HtmlComp
|
||||
|
||||
this.adjustTop();
|
||||
|
||||
this.el.appendChild(this.snapshotButton.render());
|
||||
if (this.snapshotButton) this.el.appendChild(this.snapshotButton.render());
|
||||
this.el.appendChild(this.parentButton.render());
|
||||
|
||||
return this.el;
|
||||
@ -57,7 +58,7 @@ export class PinEditBarComponent implements HtmlComponent<HTMLElement>, HtmlComp
|
||||
|
||||
cleanup(): void {
|
||||
this.parentButton.cleanup();
|
||||
this.snapshotButton.cleanup();
|
||||
if (this.snapshotButton) this.snapshotButton.cleanup();
|
||||
}
|
||||
|
||||
focusin(): void {
|
@ -15,7 +15,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { PinComponent } from './pin.component';
|
||||
import { fnConsoleLog } from '../../common/fn/fn-console';
|
||||
import { fnConsoleLog } from '../../fn/fn-console';
|
||||
|
||||
enum VisibleState {
|
||||
None = 1,
|
0
src/content-script/components/pin-mouse.manager.ts → src/common/components/pin/pin-mouse.manager.ts
0
src/content-script/components/pin-mouse.manager.ts → src/common/components/pin/pin-mouse.manager.ts
@ -14,31 +14,30 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent, PageComponent } from '../model/html.model';
|
||||
import { HtmlComponent, PageComponent, PinDocument } from './model/pin-view.model';
|
||||
import { BottomBarComponent } from './bottom-bar/bottom-bar.component';
|
||||
import { ContentSettingsStore } from '../store/content-settings.store';
|
||||
import { DownloadBarComponent } from './download-bar/download-bar.component';
|
||||
import { DrawBarComponent } from './draw-bar/draw-bar.component';
|
||||
import { DrawContainerComponent } from './draw-container.component';
|
||||
import { DrawToolDto } from '../../common/model/obj/obj-draw.dto';
|
||||
import { ObjDto } from '../../common/model/obj/obj.dto';
|
||||
import { ObjPinDto } from '../../common/model/obj/obj-pin.dto';
|
||||
import { DrawToolDto } from '../../model/obj/obj-draw.dto';
|
||||
import { ObjDto } from '../../model/obj/obj.dto';
|
||||
import { ObjPinDto } from '../../model/obj/obj-pin.dto';
|
||||
import { PinEditBarComponent } from './pin-edit-bar/pin-edit-bar.component';
|
||||
import { PinEditManager } from './pin-edit.manager';
|
||||
import { PinModel } from './pin.model';
|
||||
import { PinEditModel } from './model/pin-edit.model';
|
||||
import { PinMouseManager } from './pin-mouse.manager';
|
||||
import { PinPointFactory } from '../factory/pin-point.factory';
|
||||
import { PinPointFactory } from '../../factory/pin-point.factory';
|
||||
import { TextContainerComponent } from './text/text-container.component';
|
||||
import { TopBarComponent } from './top-bar/top-bar.component';
|
||||
import { applyStylesToElement } from '../../common/style.utils';
|
||||
import { isElementHiddenFn } from '../fn/is-element-hidden.fn';
|
||||
import { applyStylesToElement } from '../../style.utils';
|
||||
import { fnIsElementHidden } from '../../fn/fn-is-element-hidden';
|
||||
import { fnScrollToElement } from '../../fn/fn-scroll-to-element';
|
||||
import { pinStyles } from './styles/pin.styles';
|
||||
import { scrollToElementFn } from '../fn/scroll-to-element.fn';
|
||||
|
||||
export class PinComponent implements HtmlComponent<void>, PageComponent {
|
||||
readonly top = document.createElement('div');
|
||||
readonly bottom = document.createElement('div');
|
||||
readonly border = document.createElement('div');
|
||||
readonly top: HTMLDivElement;
|
||||
readonly bottom: HTMLDivElement;
|
||||
readonly border: HTMLDivElement;
|
||||
|
||||
private readonly mouseManager: PinMouseManager;
|
||||
|
||||
@ -55,11 +54,14 @@ export class PinComponent implements HtmlComponent<void>, PageComponent {
|
||||
|
||||
readonly edit: PinEditManager;
|
||||
|
||||
readonly model: PinModel;
|
||||
readonly model: PinEditModel;
|
||||
|
||||
constructor(ref: HTMLElement, object: ObjDto<ObjPinDto>) {
|
||||
constructor(ref: HTMLElement, object: ObjDto<ObjPinDto>, private doc: PinDocument, toSnapshotHandler?: () => void) {
|
||||
this.top = this.doc.document.createElement('div');
|
||||
this.bottom = this.doc.document.createElement('div');
|
||||
this.border = this.doc.document.createElement('div');
|
||||
this.mouseManager = new PinMouseManager(this.top, this.bottom, this.handleMouseOver, this.handleMouseOut);
|
||||
this.model = new PinModel(object, ref, this.top, this.bottom, this.mouseManager);
|
||||
this.model = new PinEditModel(object, ref, this, this.mouseManager, doc);
|
||||
this.edit = new PinEditManager(this);
|
||||
|
||||
this.topBar = new TopBarComponent(this.edit, this.model);
|
||||
@ -71,11 +73,11 @@ export class PinComponent implements HtmlComponent<void>, PageComponent {
|
||||
|
||||
this.downloadBar = new DownloadBarComponent(this.edit, this.model);
|
||||
|
||||
this.editBar = new PinEditBarComponent(this.model, this.resize);
|
||||
this.editBar = new PinEditBarComponent(this.model, this.resize, toSnapshotHandler);
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
scrollToElementFn(this.model.ref, this.model.ref.getBoundingClientRect().height / 2);
|
||||
fnScrollToElement(this.model.ref, this.model.ref.getBoundingClientRect().height / 2);
|
||||
this.handleMouseOver();
|
||||
}
|
||||
|
||||
@ -117,8 +119,8 @@ export class PinComponent implements HtmlComponent<void>, PageComponent {
|
||||
// Pin Edit
|
||||
this.top.appendChild(this.editBar.render());
|
||||
|
||||
document.body.appendChild(this.top);
|
||||
document.body.appendChild(this.bottom);
|
||||
this.doc.document.body.appendChild(this.top);
|
||||
this.doc.document.body.appendChild(this.bottom);
|
||||
this.mouseManager.start(this.model.ref);
|
||||
this.handleMouseOut();
|
||||
|
||||
@ -130,11 +132,11 @@ export class PinComponent implements HtmlComponent<void>, PageComponent {
|
||||
this.border.style.pointerEvents = 'none';
|
||||
this.border.style.top = `${this.model.rect.y}px`;
|
||||
this.border.style.left = `${this.model.rect.x}px`;
|
||||
this.border.style.border = ContentSettingsStore.newElementStyle;
|
||||
document.body.appendChild(this.border);
|
||||
this.border.style.border = this.doc.settings.newElementStyle;
|
||||
this.doc.document.body.appendChild(this.border);
|
||||
} else {
|
||||
this.model.ref.style.border = ContentSettingsStore.borderStyle;
|
||||
this.model.ref.style.borderRadius = ContentSettingsStore.borderRadius;
|
||||
this.model.ref.style.border = this.doc.settings.borderStyle;
|
||||
this.model.ref.style.borderRadius = this.doc.settings.borderRadius;
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,7 +180,7 @@ export class PinComponent implements HtmlComponent<void>, PageComponent {
|
||||
private timeoutId = -1;
|
||||
|
||||
private handleMouseOver = () => {
|
||||
window.clearTimeout(this.timeoutId);
|
||||
this.doc.window.clearTimeout(this.timeoutId);
|
||||
|
||||
if (!this.edit.isScreenshot) this.topBar.focusin();
|
||||
if (!this.edit.isScreenshot) this.bottomBar.focusin();
|
||||
@ -186,29 +188,29 @@ export class PinComponent implements HtmlComponent<void>, PageComponent {
|
||||
this.drawBar.focusin();
|
||||
this.downloadBar.focusin();
|
||||
this.editBar.focusin();
|
||||
if (ContentSettingsStore.borderStyle === ContentSettingsStore.borderNone) {
|
||||
this.model.ref.style.border = ContentSettingsStore.newElementStyle;
|
||||
if (this.doc.settings.borderStyle === 'none') {
|
||||
this.model.ref.style.border = this.doc.settings.newElementStyle;
|
||||
}
|
||||
if (!this.model.canvas) this.timeoutId = window.setTimeout(this.handleMouseOut, 3000);
|
||||
if (!this.model.canvas) this.timeoutId = this.doc.window.setTimeout(this.handleMouseOut, 3000);
|
||||
};
|
||||
|
||||
private handleMouseOut = () => {
|
||||
window.clearTimeout(this.timeoutId);
|
||||
this.doc.window.clearTimeout(this.timeoutId);
|
||||
if (this.model.canvas) return;
|
||||
this.timeoutId = window.setTimeout(() => {
|
||||
this.timeoutId = this.doc.window.setTimeout(() => {
|
||||
this.topBar.focusout();
|
||||
this.bottomBar.focusout();
|
||||
this.drawBar.focusout();
|
||||
this.downloadBar.focusout();
|
||||
this.editBar.focusout();
|
||||
if (ContentSettingsStore.borderStyle === ContentSettingsStore.borderNone) {
|
||||
this.model.ref.style.border = ContentSettingsStore.borderNone;
|
||||
if (this.doc.settings.borderStyle === 'none') {
|
||||
this.model.ref.style.border = 'none';
|
||||
}
|
||||
this.model.ref.style.border = ContentSettingsStore.borderStyle;
|
||||
this.model.ref.style.border = this.doc.settings.borderStyle;
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
isHidden(): boolean {
|
||||
return isElementHiddenFn(this.model.ref);
|
||||
return fnIsElementHidden(this.model.ref);
|
||||
}
|
||||
}
|
0
src/content-script/components/styles/pin.styles.ts → src/common/components/pin/styles/pin.styles.ts
0
src/content-script/components/styles/pin.styles.ts → src/common/components/pin/styles/pin.styles.ts
@ -16,13 +16,14 @@
|
||||
*/
|
||||
import { Command } from 'prosemirror-state';
|
||||
import { EditorView } from 'prosemirror-view';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { editorBarButtonStyles } from './editor-bar-button.styles';
|
||||
import { schema } from 'prosemirror-markdown';
|
||||
import { toggleMark } from 'prosemirror-commands';
|
||||
|
||||
export class TextBoldButton {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
private boldCommand?: Command;
|
||||
|
||||
private clicked = false;
|
||||
@ -30,6 +31,10 @@ export class TextBoldButton {
|
||||
|
||||
private editor?: EditorView;
|
||||
|
||||
constructor(model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
setEditor(editor: EditorView | undefined): void {
|
||||
this.editor = editor;
|
||||
}
|
@ -16,23 +16,28 @@
|
||||
*/
|
||||
import { Command } from 'prosemirror-state';
|
||||
import { EditorView } from 'prosemirror-view';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { editorBarButtonStyles } from './editor-bar-button.styles';
|
||||
import { schema } from 'prosemirror-markdown';
|
||||
import { wrapInList } from 'prosemirror-schema-list';
|
||||
|
||||
export class TextBulletListButton {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
private listCommand?: Command;
|
||||
|
||||
private editor?: EditorView;
|
||||
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
setEditor(editor: EditorView | undefined): void {
|
||||
this.editor = editor;
|
||||
}
|
||||
|
||||
render(): HTMLDivElement {
|
||||
const li = document.createElement('li');
|
||||
const li = this.model.doc.document.createElement('li');
|
||||
li.style.paddingLeft = '5px';
|
||||
li.style.paddingBottom = '10px';
|
||||
this.el.appendChild(li);
|
@ -16,13 +16,14 @@
|
||||
*/
|
||||
import { Command } from 'prosemirror-state';
|
||||
import { EditorView } from 'prosemirror-view';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { editorBarButtonStyles } from './editor-bar-button.styles';
|
||||
import { schema } from 'prosemirror-markdown';
|
||||
import { toggleMark } from 'prosemirror-commands';
|
||||
|
||||
export class TextItalicButton {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
private italicCommand?: Command;
|
||||
|
||||
private clicked = false;
|
||||
@ -30,6 +31,10 @@ export class TextItalicButton {
|
||||
|
||||
private editor?: EditorView;
|
||||
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
setEditor(editor: EditorView | undefined): void {
|
||||
this.editor = editor;
|
||||
}
|
@ -16,17 +16,22 @@
|
||||
*/
|
||||
import { Command } from 'prosemirror-state';
|
||||
import { EditorView } from 'prosemirror-view';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { editorBarButtonStyles } from './editor-bar-button.styles';
|
||||
import { schema } from 'prosemirror-markdown';
|
||||
import { wrapInList } from 'prosemirror-schema-list';
|
||||
|
||||
export class TextNumericListButton {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
private listCommand?: Command;
|
||||
|
||||
private editor?: EditorView;
|
||||
|
||||
constructor(model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
setEditor(editor: EditorView | undefined): void {
|
||||
this.editor = editor;
|
||||
}
|
@ -16,14 +16,15 @@
|
||||
*/
|
||||
import { EditorState } from 'prosemirror-state';
|
||||
import { EditorView } from 'prosemirror-view';
|
||||
import { HtmlComponent } from '../../model/html.model';
|
||||
import { ObjRectangleDto } from '../../../common/model/obj/obj-utils.dto';
|
||||
import { HtmlComponent } from '../model/pin-view.model';
|
||||
import { ObjRectangleDto } from '../../../model/obj/obj-utils.dto';
|
||||
import { PinEditModel } from '../model/pin-edit.model';
|
||||
import { TextBoldButton } from './text-bar-buttons/text-bold.button';
|
||||
import { TextBulletListButton } from './text-bar-buttons/text-bullet-list.button';
|
||||
import { TextItalicButton } from './text-bar-buttons/text-italic.button';
|
||||
import { TextNumericListButton } from './text-bar-buttons/text-numeric-list.button';
|
||||
import { applyStylesToElement } from '../../../common/style.utils';
|
||||
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
||||
import { applyStylesToElement } from '../../../style.utils';
|
||||
import { fnConsoleLog } from '../../../fn/fn-console';
|
||||
|
||||
const elStyles = {
|
||||
display: 'flex',
|
||||
@ -35,7 +36,7 @@ const elStyles = {
|
||||
};
|
||||
|
||||
export class TextBarComponent implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private bold: TextBoldButton;
|
||||
private italic: TextItalicButton;
|
||||
@ -49,11 +50,12 @@ export class TextBarComponent implements HtmlComponent<HTMLElement> {
|
||||
|
||||
private editor?: EditorView;
|
||||
|
||||
constructor() {
|
||||
this.bold = new TextBoldButton();
|
||||
this.italic = new TextItalicButton();
|
||||
this.bulletList = new TextBulletListButton();
|
||||
this.numericList = new TextNumericListButton();
|
||||
constructor(model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.bold = new TextBoldButton(model);
|
||||
this.italic = new TextItalicButton(model);
|
||||
this.bulletList = new TextBulletListButton(model);
|
||||
this.numericList = new TextNumericListButton(model);
|
||||
}
|
||||
|
||||
setEditor(editor: EditorView | undefined): void {
|
@ -16,7 +16,8 @@
|
||||
*/
|
||||
import { CommentEditButton } from './comment-edit.button';
|
||||
import { CommentRemoveButton } from './comment-remove.button';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
|
||||
const elStyles = {
|
||||
margin: '10px',
|
||||
@ -25,12 +26,14 @@ const elStyles = {
|
||||
};
|
||||
|
||||
export class CommentActionBar {
|
||||
private el = document.createElement('div');
|
||||
constructor(private removeCallback: () => void, private editCallback: () => void) {}
|
||||
private readonly el: HTMLDivElement;
|
||||
constructor(private model: PinEditModel, private removeCallback: () => void, private editCallback: () => void) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
const r = new CommentRemoveButton(this.removeCallback);
|
||||
const e = new CommentEditButton(this.editCallback);
|
||||
const r = new CommentRemoveButton(this.model, this.removeCallback);
|
||||
const e = new CommentEditButton(this.model, this.editCallback);
|
||||
this.el.appendChild(e.render());
|
||||
this.el.appendChild(r.render());
|
||||
applyStylesToElement(this.el, elStyles);
|
@ -14,12 +14,16 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
|
||||
export class CommentEditButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
constructor(private editCallback: () => void) {}
|
||||
constructor(model: PinEditModel, private editCallback: () => void) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" height="16" viewBox="0 0 24 24" width="16">
|
@ -14,13 +14,16 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ObjCommentDto } from '../../../../common/model/obj/obj-pin.dto';
|
||||
import { fnDateFormat } from '../../../../common/fn/fn-date-format';
|
||||
import { ObjCommentDto } from '../../../../model/obj/obj-pin.dto';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { fnDateFormat } from '../../../../fn/fn-date-format';
|
||||
|
||||
export class CommentFooterComponent {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
constructor(private comment: ObjCommentDto) {}
|
||||
constructor(private model: PinEditModel, private comment: ObjCommentDto) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.style.fontSize = '0.7em';
|
@ -14,12 +14,16 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
|
||||
export class CommentRemoveButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
constructor(private removeCallback: () => void) {}
|
||||
constructor(model: PinEditModel, private removeCallback: () => void) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" height="16" viewBox="0 0 24 24" width="16">
|
@ -16,15 +16,15 @@
|
||||
*/
|
||||
import { CommentActionBar } from './comment-action-bar';
|
||||
import { CommentFooterComponent } from './comment-footer.component';
|
||||
import { HashtagFindCommand } from '../../../../common/command/obj/hashtag/hashtag-find.command';
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { ObjCommentDto } from '../../../../common/model/obj/obj-pin.dto';
|
||||
import { ObjRemoveHashtagsCommand } from '../../../../common/command/obj/hashtag/obj-remove-hashtags.command';
|
||||
import { ObjUpdateHashtagsCommand } from '../../../../common/command/obj/hashtag/obj-update-hashtags.command';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { PinUpdateCommand } from '../../../../common/command/pin/pin-update.command';
|
||||
import { HashtagFindCommand } from '../../../../command/obj/hashtag/hashtag-find.command';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { ObjCommentDto } from '../../../../model/obj/obj-pin.dto';
|
||||
import { ObjRemoveHashtagsCommand } from '../../../../command/obj/hashtag/obj-remove-hashtags.command';
|
||||
import { ObjUpdateHashtagsCommand } from '../../../../command/obj/hashtag/obj-update-hashtags.command';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { PinUpdateCommand } from '../../../../command/pin/pin-update.command';
|
||||
import { TextCommentEditorComponent } from '../text-comment-editor.component';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { marked } from 'marked';
|
||||
|
||||
const viewStyles = {
|
||||
@ -37,17 +37,18 @@ const viewStyles = {
|
||||
};
|
||||
|
||||
export class CommentComponent implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
private view?: HTMLDivElement;
|
||||
private footer: CommentFooterComponent;
|
||||
|
||||
constructor(
|
||||
private model: PinModel,
|
||||
private model: PinEditModel,
|
||||
private comment: ObjCommentDto,
|
||||
private index: number,
|
||||
private renderCallback: () => void
|
||||
) {
|
||||
this.footer = new CommentFooterComponent(comment);
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.footer = new CommentFooterComponent(model, comment);
|
||||
}
|
||||
render(): HTMLElement {
|
||||
this.renderRead();
|
||||
@ -56,8 +57,8 @@ export class CommentComponent implements HtmlComponent<HTMLElement> {
|
||||
|
||||
renderRead = () => {
|
||||
this.renderView();
|
||||
const comment = document.createElement('div');
|
||||
const value = document.createElement('div');
|
||||
const comment = this.model.doc.document.createElement('div');
|
||||
const value = this.model.doc.document.createElement('div');
|
||||
value.innerHTML = marked(this.comment.value);
|
||||
comment.appendChild(value);
|
||||
comment.appendChild(this.footer.render());
|
||||
@ -65,20 +66,20 @@ export class CommentComponent implements HtmlComponent<HTMLElement> {
|
||||
comment.style.marginBottom = '5px';
|
||||
if (!this.view) return;
|
||||
this.view.appendChild(comment);
|
||||
const actionBar = new CommentActionBar(this.removeCallback, this.editCallback);
|
||||
const actionBar = new CommentActionBar(this.model, this.removeCallback, this.editCallback);
|
||||
this.view.appendChild(actionBar.render());
|
||||
this.el.appendChild(this.view);
|
||||
};
|
||||
|
||||
renderView = () => {
|
||||
this.view?.remove();
|
||||
this.view = document.createElement('div');
|
||||
this.view = this.model.doc.document.createElement('div');
|
||||
applyStylesToElement(this.view, viewStyles);
|
||||
};
|
||||
|
||||
editCallback = () => {
|
||||
this.renderView();
|
||||
const comment = document.createElement('div');
|
||||
const comment = this.model.doc.document.createElement('div');
|
||||
const txt = new TextCommentEditorComponent(
|
||||
this.model,
|
||||
'Save',
|
@ -15,28 +15,29 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ContentButton } from '../base/content-button';
|
||||
import { HtmlComponent } from '../../model/html.model';
|
||||
import { PinModel } from '../pin.model';
|
||||
import { HtmlComponent } from '../model/pin-view.model';
|
||||
import { PinEditModel } from '../model/pin-edit.model';
|
||||
import { TextEditorComponent } from './text-editor.component';
|
||||
|
||||
export class TextCommentEditorComponent implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private textEditor: TextEditorComponent;
|
||||
private readonly saveButton: ContentButton;
|
||||
private readonly cancelButton?: ContentButton;
|
||||
|
||||
constructor(
|
||||
model: PinModel,
|
||||
model: PinEditModel,
|
||||
saveLabel: string,
|
||||
private saveCallback: (value: string) => void,
|
||||
cancelLabel?: string,
|
||||
cancelCallback?: () => void,
|
||||
initialValue = ''
|
||||
) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.textEditor = new TextEditorComponent(initialValue, model);
|
||||
this.saveButton = new ContentButton(saveLabel, this.handleSaveClick);
|
||||
if (cancelLabel && cancelCallback) this.cancelButton = new ContentButton(cancelLabel, cancelCallback);
|
||||
this.saveButton = new ContentButton(model.doc, saveLabel, this.handleSaveClick);
|
||||
if (cancelLabel && cancelCallback) this.cancelButton = new ContentButton(model.doc, cancelLabel, cancelCallback);
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
@ -15,18 +15,20 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { CommentComponent } from './comment/comment.component';
|
||||
import { HtmlComponent } from '../../model/html.model';
|
||||
import { PinModel } from '../pin.model';
|
||||
import { applyStylesToElement } from '../../../common/style.utils';
|
||||
import { HtmlComponent } from '../model/pin-view.model';
|
||||
import { PinEditModel } from '../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../style.utils';
|
||||
|
||||
const elStyles = {
|
||||
'background-color': '#ffffff'
|
||||
};
|
||||
|
||||
export class TextCommentListComponent implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
constructor(private model: PinModel) {}
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
applyStylesToElement(this.el, elStyles);
|
@ -14,14 +14,14 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../model/html.model';
|
||||
import { ObjAddHashtagsCommand } from '../../../common/command/obj/hashtag/obj-add-hashtags.command';
|
||||
import { PinModel } from '../pin.model';
|
||||
import { PinUpdateCommand } from '../../../common/command/pin/pin-update.command';
|
||||
import { HtmlComponent } from '../model/pin-view.model';
|
||||
import { ObjAddHashtagsCommand } from '../../../command/obj/hashtag/obj-add-hashtags.command';
|
||||
import { PinEditModel } from '../model/pin-edit.model';
|
||||
import { PinUpdateCommand } from '../../../command/pin/pin-update.command';
|
||||
import { TextCommentEditorComponent } from './text-comment-editor.component';
|
||||
import { TextCommentListComponent } from './text-comment-list.component';
|
||||
import { applyStylesToElement } from '../../../common/style.utils';
|
||||
import { fnSha256 } from '../../../common/fn/fn-sha256';
|
||||
import { applyStylesToElement } from '../../../style.utils';
|
||||
import { fnSha256 } from '../../../fn/fn-sha256';
|
||||
|
||||
const elStyles = {
|
||||
'min-height': '40px',
|
||||
@ -29,12 +29,13 @@ const elStyles = {
|
||||
};
|
||||
|
||||
export class TextContainerComponent implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private add: TextCommentEditorComponent;
|
||||
private comments: TextCommentListComponent;
|
||||
|
||||
constructor(private model: PinModel) {
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.add = new TextCommentEditorComponent(model, 'Add', this.addCommentCallback);
|
||||
this.comments = new TextCommentListComponent(model);
|
||||
}
|
@ -15,17 +15,19 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { EditorView } from 'prosemirror-view';
|
||||
import { HtmlComponent } from '../../model/html.model';
|
||||
import { PinModel } from '../pin.model';
|
||||
import { createTextEditorState } from '../../../common/components/text-editor/text.editor.state';
|
||||
import { HtmlComponent } from '../model/pin-view.model';
|
||||
import { PinEditModel } from '../model/pin-edit.model';
|
||||
import { createTextEditorState } from '../../text-editor/text.editor.state';
|
||||
import { defaultMarkdownSerializer } from 'prosemirror-markdown';
|
||||
|
||||
export class TextEditorComponent implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private editorView?: EditorView;
|
||||
|
||||
constructor(private initialValue: string, private model: PinModel) {}
|
||||
constructor(private initialValue: string, private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
get value(): string {
|
||||
if (!this.editorView) return '';
|
@ -14,16 +14,18 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import MathMLToLaTeX from '../../../../vendor/mathml-to-latex/src/index';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { fnConsoleLog } from '../../../../common/fn/fn-console';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import MathMLToLaTeX from '../../../../../vendor/mathml-to-latex/src';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { fnConsoleLog } from '../../../../fn/fn-console';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class ActionCopyButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
constructor(private model: PinModel) {}
|
||||
private readonly el: HTMLDivElement;
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" height="24" viewBox="0 0 24 24" width="24">
|
@ -14,18 +14,21 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditManager } from '../../pin-edit.manager';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class ActionDownloadButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private visible = false;
|
||||
private fillColor = '#000000';
|
||||
|
||||
constructor(private edit: PinEditManager) {}
|
||||
constructor(private edit: PinEditManager, model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="${this.fillColor}" enable-background="new 0 0 24 24" height="24" viewBox="0 0 24 24" width="24">
|
@ -14,19 +14,20 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditManager } from '../../pin-edit.manager';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { PinUpdateCommand } from '../../../../common/command/pin/pin-update.command';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { PinUpdateCommand } from '../../../../command/pin/pin-update.command';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class ActionDrawVisibleButton implements HtmlComponent<HTMLElement> {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private fillColor: string;
|
||||
|
||||
constructor(private edit: PinEditManager, private model: PinModel) {
|
||||
constructor(private edit: PinEditManager, private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.fillColor = model.local.drawVisible ? '#ff0000' : '#000000';
|
||||
}
|
||||
|
@ -14,19 +14,22 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditManager } from '../../pin-edit.manager';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class ActionDrawButton implements HtmlComponent<HTMLElement> {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private visible = false;
|
||||
|
||||
private fillColor = '#000000';
|
||||
|
||||
constructor(private edit: PinEditManager) {}
|
||||
constructor(private edit: PinEditManager, model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="${this.fillColor}" height="24" viewBox="0 0 24 24" width="24">
|
@ -14,18 +14,21 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditManager } from '../../pin-edit.manager';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class ActionPinEditButton implements HtmlComponent<HTMLElement> {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly el;
|
||||
|
||||
private visible = false;
|
||||
private fillColor = '#000000';
|
||||
|
||||
constructor(private edit: PinEditManager) {}
|
||||
constructor(private edit: PinEditManager, model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render() {
|
||||
this.el.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="${this.fillColor}" height="24" viewBox="0 0 24 24" width="24">
|
@ -14,16 +14,17 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../../model/html.model';
|
||||
import { PinModel } from '../../pin.model';
|
||||
import { PinRemoveCommand } from '../../../../common/command/pin/pin-remove.command';
|
||||
import { PinStore } from '../../../store/pin.store';
|
||||
import { applyStylesToElement } from '../../../../common/style.utils';
|
||||
import { HtmlComponent } from '../../model/pin-view.model';
|
||||
import { PinEditModel } from '../../model/pin-edit.model';
|
||||
import { PinRemoveCommand } from '../../../../command/pin/pin-remove.command';
|
||||
import { applyStylesToElement } from '../../../../style.utils';
|
||||
import { iconButtonStyles } from '../../styles/icon-button.styles';
|
||||
|
||||
export class ActionRemoveButton implements HtmlComponent<HTMLElement> {
|
||||
private el = document.createElement('div');
|
||||
constructor(private model: PinModel) {}
|
||||
private readonly el: HTMLDivElement;
|
||||
constructor(private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
}
|
||||
|
||||
render(): HTMLElement {
|
||||
this.el.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" height="24" viewBox="0 0 24 24" width="24">
|
||||
@ -41,6 +42,7 @@ export class ActionRemoveButton implements HtmlComponent<HTMLElement> {
|
||||
private handleClick = async () => {
|
||||
this.el.removeEventListener('click', this.handleClick);
|
||||
await new PinRemoveCommand(this.model.id, this.model.url).execute();
|
||||
PinStore.delByUid(this.model.id);
|
||||
this.model.remove();
|
||||
// PinStore.delByUid(this.model.id);
|
||||
};
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../../model/html.model';
|
||||
import { HtmlComponent, HtmlComponentFocusable } from '../model/pin-view.model';
|
||||
import { ActionCopyButton } from './action-buttons/action-copy.button';
|
||||
import { ActionDownloadButton } from './action-buttons/action-download.button';
|
||||
import { ActionDrawButton } from './action-buttons/action-draw.button';
|
||||
@ -22,8 +22,8 @@ import { ActionDrawVisibleButton } from './action-buttons/action-draw-visible.bu
|
||||
import { ActionPinEditButton } from './action-buttons/action-pin-edit.button';
|
||||
import { ActionRemoveButton } from './action-buttons/action-remove.button';
|
||||
import { PinEditManager } from '../pin-edit.manager';
|
||||
import { PinModel } from '../pin.model';
|
||||
import { applyStylesToElement } from '../../../common/style.utils';
|
||||
import { PinEditModel } from '../model/pin-edit.model';
|
||||
import { applyStylesToElement } from '../../../style.utils';
|
||||
|
||||
const topBarStyles = {
|
||||
height: '24px',
|
||||
@ -68,7 +68,7 @@ const drawVisibleIconStyles = {
|
||||
};
|
||||
|
||||
export class TopBarComponent implements HtmlComponent<HTMLElement>, HtmlComponentFocusable {
|
||||
private readonly el = document.createElement('div');
|
||||
private readonly el: HTMLDivElement;
|
||||
|
||||
private readonly editIcon: ActionPinEditButton;
|
||||
private readonly removeIcon: ActionRemoveButton;
|
||||
@ -80,13 +80,14 @@ export class TopBarComponent implements HtmlComponent<HTMLElement>, HtmlComponen
|
||||
|
||||
private topMargin = '-24px';
|
||||
|
||||
constructor(edit: PinEditManager, private model: PinModel) {
|
||||
this.editIcon = new ActionPinEditButton(edit);
|
||||
constructor(edit: PinEditManager, private model: PinEditModel) {
|
||||
this.el = model.doc.document.createElement('div');
|
||||
this.editIcon = new ActionPinEditButton(edit, model);
|
||||
this.removeIcon = new ActionRemoveButton(model);
|
||||
this.copyIcon = new ActionCopyButton(model);
|
||||
this.downloadIcon = new ActionDownloadButton(edit);
|
||||
this.downloadIcon = new ActionDownloadButton(edit, model);
|
||||
|
||||
this.drawIcon = new ActionDrawButton(edit);
|
||||
this.drawIcon = new ActionDrawButton(edit, model);
|
||||
this.drawVisibleIcon = new ActionDrawVisibleButton(edit, model);
|
||||
}
|
||||
|
@ -14,26 +14,26 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ContentSettingsStore } from '../../content-script/store/content-settings.store';
|
||||
import { ObjRectangleDto } from '../model/obj/obj-utils.dto';
|
||||
import { PinDocument } from '../components/pin/model/pin-view.model';
|
||||
|
||||
export class ImageResizeFactory {
|
||||
static resize = (size: ObjRectangleDto, b64image: string): Promise<string> => {
|
||||
static resize = (doc: PinDocument, size: ObjRectangleDto, b64image: string): Promise<string> => {
|
||||
const rect = {
|
||||
x: size.x,
|
||||
y: size.y,
|
||||
width: size.width,
|
||||
height: Math.min(size.height, window.innerHeight - size.y)
|
||||
height: Math.min(size.height, doc.window.innerHeight - size.y)
|
||||
};
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const img = new Image();
|
||||
img.onload = () => {
|
||||
try {
|
||||
const can = document.createElement('canvas');
|
||||
const can = doc.document.createElement('canvas');
|
||||
can.width = rect.width;
|
||||
can.height = rect.height;
|
||||
const wr = img.naturalWidth / window.innerWidth;
|
||||
const hr = img.naturalHeight / window.innerHeight;
|
||||
const wr = img.naturalWidth / doc.window.innerWidth;
|
||||
const hr = img.naturalHeight / doc.window.innerHeight;
|
||||
const ctx = can.getContext('2d');
|
||||
ctx?.drawImage(
|
||||
img,
|
||||
@ -46,10 +46,7 @@ export class ImageResizeFactory {
|
||||
rect.width,
|
||||
rect.height
|
||||
);
|
||||
b64image = can.toDataURL(
|
||||
`image/${ContentSettingsStore.screenshotFormat}`,
|
||||
ContentSettingsStore.screenshotQuality
|
||||
);
|
||||
b64image = can.toDataURL(`image/${doc.settings.screenshotFormat}`, doc.settings.screenshotQuality);
|
||||
} finally {
|
||||
window.URL.revokeObjectURL(b64image);
|
||||
img.onerror = null;
|
||||
|
@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ObjRectangleDto } from '../../common/model/obj/obj-utils.dto';
|
||||
import { ObjRectangleDto } from '../model/obj/obj-utils.dto';
|
||||
|
||||
export class PinPointFactory {
|
||||
static calculateRect(ref: HTMLElement): ObjRectangleDto {
|
@ -19,18 +19,19 @@ import { BusMessageType } from '../model/bus.model';
|
||||
import { ImageResizeFactory } from './image-resize.factory';
|
||||
import { ObjRectangleDto } from '../model/obj/obj-utils.dto';
|
||||
import { ObjUrlDto } from '../model/obj/obj.dto';
|
||||
import { PinDocument } from '../components/pin/model/pin-view.model';
|
||||
import { TinyEventDispatcher } from '../service/tiny.event.dispatcher';
|
||||
import { fnConsoleLog } from '../fn/fn-console';
|
||||
|
||||
export class ScreenshotFactory {
|
||||
static takeScreenshot = async (rect?: ObjRectangleDto, url?: ObjUrlDto): Promise<string> => {
|
||||
static takeScreenshot = async (doc: PinDocument, rect?: ObjRectangleDto, url?: ObjUrlDto): Promise<string> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Crop screenshot function
|
||||
TinyEventDispatcher.addListener<string>(
|
||||
BusMessageType.CONTENT_TAKE_SCREENSHOT,
|
||||
async (event: string, key: string, screenshot: string) => {
|
||||
TinyEventDispatcher.removeListener(event, key);
|
||||
if (rect) screenshot = await ImageResizeFactory.resize(rect, screenshot);
|
||||
if (rect) screenshot = await ImageResizeFactory.resize(doc, rect, screenshot);
|
||||
resolve(screenshot);
|
||||
}
|
||||
);
|
||||
|
@ -80,7 +80,7 @@ export class XpathFactory {
|
||||
return subtree;
|
||||
}
|
||||
|
||||
static newXPathResult(path: string): XPathResult {
|
||||
static newXPathResult(document: Document, path: string): XPathResult {
|
||||
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE);
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
export const isElementHiddenFn = (el: HTMLElement): boolean => {
|
||||
export const fnIsElementHidden = (el: HTMLElement): boolean => {
|
||||
const style = window.getComputedStyle(el);
|
||||
return style.display === 'none' || el.offsetParent === null; // !document.body.contains(el);
|
||||
};
|
@ -14,13 +14,13 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { PinVideoDataDto } from '../../common/model/obj/obj-pin.dto';
|
||||
import { XpathFactory } from '../../common/factory/xpath.factory';
|
||||
import { ObjVideoDataDto } from '../model/obj/obj-snapshot.dto';
|
||||
import { XpathFactory } from '../factory/xpath.factory';
|
||||
|
||||
export const resolveVideoTimeFn = (videoTime?: PinVideoDataDto[]): void => {
|
||||
export const fnResolveVideoTime = (videoTime?: ObjVideoDataDto[]): void => {
|
||||
if (!videoTime) return;
|
||||
for (const video of videoTime) {
|
||||
const value = XpathFactory.newXPathResult(video.xpath);
|
||||
const value = XpathFactory.newXPathResult(document, video.xpath);
|
||||
const node = value.singleNodeValue as HTMLVideoElement;
|
||||
if (!node) continue;
|
||||
node.currentTime = video.currentTime;
|
@ -14,7 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
export const scrollToElementFn = (view?: HTMLElement, offset?: number): number => {
|
||||
export const fnScrollToElement = (view?: HTMLElement, offset?: number): number => {
|
||||
if (!view) return -1;
|
||||
const rect = view.getBoundingClientRect();
|
||||
// TODO fix scroll
|
@ -15,8 +15,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ICommand } from '../../../common/model/shared/common.dto';
|
||||
import { ObjDto } from '../../../common/model/obj/obj.dto';
|
||||
import { ObjPinDto } from '../../../common/model/obj/obj-pin.dto';
|
||||
import { ObjTypeDto } from '../../../common/model/obj/obj.dto';
|
||||
import { PinAddXpathCommand } from './pin-add-xpath.command';
|
||||
import { PinPendingStore } from '../../store/pin-pending.store';
|
||||
@ -43,7 +41,7 @@ export class InvalidatePinsCommand implements ICommand<Promise<void>> {
|
||||
for (const pin of pinList) {
|
||||
switch (pin.type) {
|
||||
case ObjTypeDto.PageElementPin:
|
||||
if (new PinAddXpathCommand(pin as ObjDto<ObjPinDto>).execute()) {
|
||||
if (new PinAddXpathCommand(pin).execute()) {
|
||||
PinPendingStore.remove(pin.id);
|
||||
}
|
||||
break;
|
||||
|
@ -21,16 +21,16 @@ import { PinComponentAddCommand } from './pin-component-add.command';
|
||||
import { PinPendingStore } from '../../store/pin-pending.store';
|
||||
import { XpathFactory } from '../../../common/factory/xpath.factory';
|
||||
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
||||
import { isElementHiddenFn } from '../../fn/is-element-hidden.fn';
|
||||
import { fnIsElementHidden } from '../../../common/fn/fn-is-element-hidden';
|
||||
|
||||
export class PinAddXpathCommand implements ICommand<boolean> {
|
||||
constructor(private data: ObjDto<ObjPinDto>) {}
|
||||
execute(): boolean {
|
||||
const pin = this.data.data;
|
||||
const value = XpathFactory.newXPathResult(pin.xpath);
|
||||
const value = XpathFactory.newXPathResult(document, pin.xpath);
|
||||
fnConsoleLog('PinAddXpathCommand->xpath', pin.xpath, 'singleNodeValue', value.singleNodeValue);
|
||||
const node = value.singleNodeValue as HTMLElement;
|
||||
if (!this.data.local?.visible || !node || isElementHiddenFn(node)) {
|
||||
if (!this.data.local?.visible || !node || fnIsElementHidden(node)) {
|
||||
// will be created on invalidate
|
||||
PinPendingStore.add(this.data);
|
||||
return false;
|
||||
|
@ -19,6 +19,7 @@ import { BrowserApi } from '../../../common/service/browser.api.wrapper';
|
||||
import { BrowserStorageWrapper } from '../../../common/service/browser.storage.wrapper';
|
||||
import { BusMessageType } from '../../../common/model/bus.model';
|
||||
import { ContentPageSnapshotAddCommand } from '../snapshot/content-page-snapshot-add.command';
|
||||
import { ContentSettingsStore } from '../../store/content-settings.store';
|
||||
import { ICommand } from '../../../common/model/shared/common.dto';
|
||||
import { LinkHrefOriginStore } from '../../../common/store/link-href-origin.store';
|
||||
import { ObjNextIdCommand } from '../../../common/command/obj/id/obj-next-id.command';
|
||||
@ -58,7 +59,7 @@ export class PinAddCommand implements ICommand<Promise<ObjDto<ObjPinDto>>> {
|
||||
|
||||
const hasSnapshot = await LinkHrefOriginStore.hasPageSnapshot(this.pin.url.href);
|
||||
if (!hasSnapshot) {
|
||||
await new ContentPageSnapshotAddCommand(this.pin.url).execute();
|
||||
await new ContentPageSnapshotAddCommand(ContentSettingsStore.settings, this.pin.url).execute();
|
||||
}
|
||||
|
||||
// Send stop - iframe loads own content scripts
|
||||
|
@ -14,17 +14,22 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { HtmlComponent } from '../../model/html.model';
|
||||
import { ContentSettingsStore } from '../../store/content-settings.store';
|
||||
import { HtmlComponent } from '../../../common/components/pin/model/pin-view.model';
|
||||
import { ICommand } from '../../../common/model/shared/common.dto';
|
||||
import { ObjDto } from '../../../common/model/obj/obj.dto';
|
||||
import { ObjPinDto } from '../../../common/model/obj/obj-pin.dto';
|
||||
import { PinComponent } from '../../components/pin.component';
|
||||
import { PinComponent } from '../../../common/components/pin/pin.component';
|
||||
import { PinStore } from '../../store/pin.store';
|
||||
|
||||
export class PinComponentAddCommand implements ICommand<HtmlComponent<HTMLElement> | undefined> {
|
||||
constructor(private ref: HTMLElement, private dto: ObjDto<ObjPinDto>, private focus = false) {}
|
||||
execute(): HtmlComponent<HTMLElement> | undefined {
|
||||
const pinComponent = new PinComponent(this.ref, this.dto);
|
||||
const pinComponent = new PinComponent(this.ref, this.dto, {
|
||||
document,
|
||||
window,
|
||||
settings: ContentSettingsStore.settings
|
||||
});
|
||||
pinComponent.render();
|
||||
if (this.focus) pinComponent.focus();
|
||||
|
||||
|
@ -21,13 +21,22 @@ import { ICommand } from '../../../common/model/shared/common.dto';
|
||||
import { ObjSnapshotDto } from '../../../common/model/obj/obj-snapshot.dto';
|
||||
import { PageSnapshotAddCommand } from '../../../common/command/snapshot/page-snapshot-add.command';
|
||||
import { ScreenshotFactory } from '../../../common/factory/screenshot.factory';
|
||||
import { SettingsConfig } from '../../../common/environment';
|
||||
import { SnapshotContentSaveCommand } from './snapshot-content-save.command';
|
||||
|
||||
export class ContentPageSnapshotAddCommand implements ICommand<Promise<void>> {
|
||||
constructor(private url: ObjUrlDto) {}
|
||||
constructor(private settings: SettingsConfig, private url: ObjUrlDto) {}
|
||||
|
||||
async execute(): Promise<void> {
|
||||
const screenshot = await ScreenshotFactory.takeScreenshot(undefined, this.url);
|
||||
const screenshot = await ScreenshotFactory.takeScreenshot(
|
||||
{
|
||||
document,
|
||||
window,
|
||||
settings: this.settings
|
||||
},
|
||||
undefined,
|
||||
this.url
|
||||
);
|
||||
|
||||
const res = await new SnapshotContentSaveCommand(document.body, [], false).execute();
|
||||
|
||||
|
@ -18,12 +18,14 @@ import { ObjCanvasDto, ObjSnapshotDto } from '../../../common/model/obj/obj-snap
|
||||
import { ICommand } from '../../../common/model/shared/common.dto';
|
||||
import { ObjUrlDto } from '../../../common/model/obj/obj.dto';
|
||||
import { ScreenshotFactory } from '../../../common/factory/screenshot.factory';
|
||||
import { SettingsConfig } from '../../../common/environment';
|
||||
import { SnapshotContentSaveCommand } from './snapshot-content-save.command';
|
||||
import { SnapshotSaveImageCommand } from './snapshot-save-image.command';
|
||||
import { XpathFactory } from '../../../common/factory/xpath.factory';
|
||||
|
||||
export class SnapshotCreateCommand implements ICommand<Promise<ObjSnapshotDto>> {
|
||||
constructor(
|
||||
private settings: SettingsConfig,
|
||||
private url: ObjUrlDto,
|
||||
private element: HTMLElement,
|
||||
private skipElements: string[],
|
||||
@ -41,7 +43,11 @@ export class SnapshotCreateCommand implements ICommand<Promise<ObjSnapshotDto>>
|
||||
} else if (this.element instanceof HTMLImageElement) {
|
||||
contentId = await new SnapshotSaveImageCommand(this.element).execute();
|
||||
}
|
||||
const screenshot = await ScreenshotFactory.takeScreenshot(rect, this.url);
|
||||
const screenshot = await ScreenshotFactory.takeScreenshot(
|
||||
{ settings: this.settings, document, window },
|
||||
rect,
|
||||
this.url
|
||||
);
|
||||
const title = this.element.innerText.substring(0, 100) || document.title;
|
||||
return {
|
||||
title,
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { BrowserGlobalSender, BusMessage, BusMessageType } from '../common/model/bus.model';
|
||||
import { BrowserApi } from '../common/service/browser.api.wrapper';
|
||||
import { ContentPageSnapshotAddCommand } from './command/snapshot/content-page-snapshot-add.command';
|
||||
import { ContentSettingsStore } from './store/content-settings.store';
|
||||
import { DocumentMediator } from './mediator/document.mediator';
|
||||
import { ExtensionPopupInitData } from '../common/model/obj-request.model';
|
||||
import { IFrameMessageHandler } from './iframe-message.handler';
|
||||
@ -63,7 +64,7 @@ export class ContentMessageHandler {
|
||||
});
|
||||
switch (msg.type) {
|
||||
case BusMessageType.POPUP_PAGE_SNAPSHOT_ADD:
|
||||
if (!this.iframe) await new ContentPageSnapshotAddCommand(msg.data).execute();
|
||||
if (!this.iframe) await new ContentPageSnapshotAddCommand(ContentSettingsStore.settings, msg.data).execute();
|
||||
break;
|
||||
case BusMessageType.IFRAME_INDEX:
|
||||
case BusMessageType.IFRAME_PING:
|
||||
|
@ -15,6 +15,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ObjPinDto, PinBorderDataDto } from '../../common/model/obj/obj-pin.dto';
|
||||
import { ContentSettingsStore } from '../store/content-settings.store';
|
||||
import { ObjCanvasDto } from '../../common/model/obj/obj-snapshot.dto';
|
||||
import { ObjRectangleDto } from '../../common/model/obj/obj-utils.dto';
|
||||
import { ObjUrlDto } from '../../common/model/obj/obj.dto';
|
||||
@ -30,7 +31,15 @@ export class PinFactory {
|
||||
canvas?: ObjCanvasDto
|
||||
): Promise<ObjPinDto> => {
|
||||
const rect = canvas ? canvas.rect : XpathFactory.computeRect(ref);
|
||||
const screenshot = await ScreenshotFactory.takeScreenshot(rect, url);
|
||||
const screenshot = await ScreenshotFactory.takeScreenshot(
|
||||
{
|
||||
settings: ContentSettingsStore.settings,
|
||||
document,
|
||||
window
|
||||
},
|
||||
rect,
|
||||
url
|
||||
);
|
||||
const xpath = XpathFactory.newXPathString(ref);
|
||||
return {
|
||||
xpath,
|
||||
|
@ -17,6 +17,7 @@
|
||||
import { BrowserApi } from '../../common/service/browser.api.wrapper';
|
||||
import { BusMessageType } from '../../common/model/bus.model';
|
||||
import { CIRCLE_PRELOADER_SVG } from './capture.preloader';
|
||||
import { ContentSettingsStore } from '../store/content-settings.store';
|
||||
import { IFrameIndexMessage } from '../../common/model/iframe-message.model';
|
||||
import { IFrameStore } from '../store/iframe.store';
|
||||
import { ObjCanvasDto } from '../../common/model/obj/obj-snapshot.dto';
|
||||
@ -34,7 +35,7 @@ import { applyStylesToElement } from '../../common/style.utils';
|
||||
import { fnConsoleLog } from '../../common/fn/fn-console';
|
||||
import { fnSleep } from '../../common/fn/fn-sleep';
|
||||
import { fnUid } from '../../common/fn/fn-uid';
|
||||
import { pinStyles } from '../components/styles/pin.styles';
|
||||
import { pinStyles } from '../../common/components/pin/styles/pin.styles';
|
||||
|
||||
export class DocumentMediator {
|
||||
static type?: ObjTypeDto;
|
||||
@ -294,7 +295,13 @@ export class DocumentMediator {
|
||||
const skipUid = this.showPreloader();
|
||||
|
||||
const url = UrlFactory.newUrl();
|
||||
const dto = await new SnapshotCreateCommand(url, element, [skipUid], canvas).execute();
|
||||
const dto = await new SnapshotCreateCommand(
|
||||
ContentSettingsStore.settings,
|
||||
url,
|
||||
element,
|
||||
[skipUid],
|
||||
canvas
|
||||
).execute();
|
||||
await new PageSnapshotAddCommand(dto, ObjTypeDto.PageElementSnapshot).execute();
|
||||
await BrowserApi.sendRuntimeMessage({ type: BusMessageType.POPUP_PAGE_ELEMENT_SNAPSHOT_ADD });
|
||||
}
|
||||
|
@ -15,27 +15,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ObjContentDto } from '../../common/model/obj/obj-content.dto';
|
||||
import { PinModel } from '../components/pin.model';
|
||||
|
||||
export interface HtmlIntermediateData {
|
||||
html: string;
|
||||
content: ObjContentDto[];
|
||||
}
|
||||
|
||||
export interface HtmlComponentFocusable {
|
||||
focusin(): void;
|
||||
focusout(): void;
|
||||
}
|
||||
|
||||
export interface PageComponent {
|
||||
model: PinModel; // TODO REMOVE here
|
||||
focus(goto: boolean): void;
|
||||
cleanup(): void;
|
||||
resize(): void;
|
||||
render(): any;
|
||||
isHidden(): boolean;
|
||||
}
|
||||
|
||||
export interface HtmlComponent<T> {
|
||||
render(): T;
|
||||
}
|
||||
|
@ -14,39 +14,38 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { SettingsConfig, environmentConfig } from '../../common/environment';
|
||||
import { BrowserStorageWrapper } from '../../common/service/browser.storage.wrapper';
|
||||
import { ObjectStoreKeys } from '../../common/keys/object.store.keys';
|
||||
import { SettingsConfig } from '../../common/environment';
|
||||
|
||||
export class ContentSettingsStore {
|
||||
private static settings: SettingsConfig;
|
||||
static readonly borderNone = 'none';
|
||||
private static settingsData: SettingsConfig;
|
||||
|
||||
static get borderStyle(): string {
|
||||
return this.settings.borderStyle;
|
||||
static get settings(): SettingsConfig {
|
||||
return this.settingsData;
|
||||
}
|
||||
|
||||
static get newElementStyle(): string {
|
||||
return environmentConfig.settings.newElementStyle;
|
||||
return this.settingsData.newElementStyle;
|
||||
}
|
||||
|
||||
static get borderRadius(): string {
|
||||
return this.settings.borderRadius;
|
||||
return this.settingsData.borderRadius;
|
||||
}
|
||||
|
||||
static get screenshotQuality(): number {
|
||||
return this.settings.screenshotQuality;
|
||||
return this.settingsData.screenshotQuality;
|
||||
}
|
||||
|
||||
static get screenshotFormat(): string {
|
||||
return this.settings.screenshotFormat;
|
||||
return this.settingsData.screenshotFormat;
|
||||
}
|
||||
|
||||
static get skipCssImageSize(): number {
|
||||
return this.settings.skipCssImageSizeMB;
|
||||
return this.settingsData.skipCssImageSizeMB;
|
||||
}
|
||||
|
||||
static initSettings = async (): Promise<void> => {
|
||||
this.settings = await BrowserStorageWrapper.get<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY);
|
||||
this.settingsData = await BrowserStorageWrapper.get<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY);
|
||||
};
|
||||
}
|
||||
|
@ -15,16 +15,17 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ObjDto } from '../../common/model/obj/obj.dto';
|
||||
import { ObjPinDto } from '../../common/model/obj/obj-pin.dto';
|
||||
|
||||
export class PinPendingStore {
|
||||
// Map of pending pins
|
||||
private static pendingPins: { [id: number]: ObjDto } = {};
|
||||
private static pendingPins: { [id: number]: ObjDto<ObjPinDto> } = {};
|
||||
|
||||
static get values(): ObjDto[] {
|
||||
static get values(): ObjDto<ObjPinDto>[] {
|
||||
return Object.values(PinPendingStore.pendingPins);
|
||||
}
|
||||
|
||||
static add(pin: ObjDto): void {
|
||||
static add(pin: ObjDto<ObjPinDto>): void {
|
||||
this.pendingPins[pin.id] = pin;
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
import { ObjDto } from '../../common/model/obj/obj.dto';
|
||||
import { ObjPinDto } from '../../common/model/obj/obj-pin.dto';
|
||||
import { PageComponent } from '../model/html.model';
|
||||
import { PageComponent } from '../../common/components/pin/model/pin-view.model';
|
||||
import { fnConsoleLog } from '../../common/fn/fn-console';
|
||||
|
||||
export class PinStore {
|
||||
|
@ -27,7 +27,7 @@ export const MainFooterButton: FunctionComponent = () => {
|
||||
variant="outlined"
|
||||
onClick={() => BrowserApi.openOptionsPage()}
|
||||
>
|
||||
Go to pin board
|
||||
Go on board
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
|
@ -15,7 +15,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import React, { FunctionComponent, useState } from 'react';
|
||||
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
|
||||
import { BrowserApi } from '../../../common/service/browser.api.wrapper';
|
||||
import { BusMessageType } from '../../../common/model/bus.model';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
@ -26,7 +25,6 @@ import { ObjDto } from '../../../common/model/obj/obj.dto';
|
||||
import { ObjPinDto } from '../../../common/model/obj/obj-pin.dto';
|
||||
import { PinListExpandComponent } from './pin-list-expand.component';
|
||||
import { PinUpdateCommand } from '../../../common/command/pin/pin-update.command';
|
||||
import { PopupActiveTabStore } from '../../store/popup-active-tab.store';
|
||||
import PushPinIcon from '@mui/icons-material/PushPin';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import VisibilityIcon from '@mui/icons-material/Visibility';
|
||||
@ -40,20 +38,6 @@ interface PinListElementProps {
|
||||
export const PinListElement: FunctionComponent<PinListElementProps> = (props) => {
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
const [isVisible, setIsVisible] = useState(props.obj.local?.visible);
|
||||
const handleNavigate = async (data: ObjDto<ObjPinDto>): Promise<void> => {
|
||||
if (!isVisible) {
|
||||
data.local.visible = true;
|
||||
await new PinUpdateCommand(data).execute();
|
||||
setIsVisible(true);
|
||||
}
|
||||
|
||||
if (PopupActiveTabStore.url?.href !== data.data.url.href) {
|
||||
await BrowserApi.setActiveTabUrl(data.data.url.href);
|
||||
} else {
|
||||
await BrowserApi.sendTabMessage<ObjDto<ObjPinDto>>({ type: BusMessageType.CONTENT_PIN_NAVIGATE, data });
|
||||
}
|
||||
window.close();
|
||||
};
|
||||
|
||||
const handlePinVisible = async (data: ObjDto<ObjPinDto>): Promise<void> => {
|
||||
data.local.visible = !data.local.visible;
|
||||
@ -116,9 +100,6 @@ export const PinListElement: FunctionComponent<PinListElementProps> = (props) =>
|
||||
}}
|
||||
>
|
||||
{visibleIcon}
|
||||
<IconButton title="Go to page" size="small" onClick={() => handleNavigate(props.obj)}>
|
||||
<ArrowForwardIcon sx={{ fontSize: '12px' }} />
|
||||
</IconButton>
|
||||
<IconButton title="Remove pin" size="small" onClick={() => handlePinRemove(props.obj)}>
|
||||
<DeleteIcon sx={{ fontSize: '12px' }} />
|
||||
</IconButton>
|
||||
|
@ -24,7 +24,6 @@ import {
|
||||
ObjGetSnapshotContentCommand,
|
||||
ObjSnapshotData
|
||||
} from '../../../common/command/obj/content/obj-get-snapshot-content.command';
|
||||
import { ObjPageDto, ObjPinDto } from '../../../common/model/obj/obj-pin.dto';
|
||||
import React, { FunctionComponent, useEffect, useRef, useState } from 'react';
|
||||
import { BrowserApi } from '../../../common/service/browser.api.wrapper';
|
||||
import CircularProgress from '@mui/material/CircularProgress';
|
||||
@ -32,9 +31,14 @@ import ClearIcon from '@mui/icons-material/Clear';
|
||||
import DownloadIcon from '@mui/icons-material/Download';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import { IframeHtmlFactory } from '../../../common/factory/iframe-html.factory';
|
||||
import { LinkHrefOriginStore } from '../../../common/store/link-href-origin.store';
|
||||
import { ObjGetCommand } from '../../../common/command/obj/obj-get.command';
|
||||
import { ObjPageDto } from '../../../common/model/obj/obj-pin.dto';
|
||||
import { ObjPinGetCommand } from '../../../common/command/obj/obj-pin-get.command';
|
||||
import { ObjSnapshotDto } from '../../../common/model/obj/obj-snapshot.dto';
|
||||
import { ObjTypeDto } from '../../../common/model/obj/obj.dto';
|
||||
import { PinComponent } from '../../../common/components/pin/pin.component';
|
||||
import { SettingsStore } from '../../store/settings.store';
|
||||
import { XpathFactory } from '../../../common/factory/xpath.factory';
|
||||
import { fnConsoleLog } from '../../../common/fn/fn-console';
|
||||
import { fnParse5 } from '../../../common/fn/fn-parse5';
|
||||
@ -93,10 +97,6 @@ export const HtmlPreviewComponent: FunctionComponent<Props> = (props) => {
|
||||
const dom = fnParse5(c.snapshot.html);
|
||||
fnConsoleLog('DOM !!!', dom, 'in', Date.now() - a);
|
||||
fnConsoleLog('obj', obj, 'snapshot', c);
|
||||
if (obj.type === ObjTypeDto.PageElementPin) {
|
||||
const pin = obj.data as ObjPinDto;
|
||||
fnConsoleLog('XPATH SUBTREE', XpathFactory.evaluateTree(pin.xpath, dom));
|
||||
}
|
||||
setSnapshotData(c);
|
||||
}
|
||||
if (obj.data.snapshot.canvas) {
|
||||
@ -104,9 +104,39 @@ export const HtmlPreviewComponent: FunctionComponent<Props> = (props) => {
|
||||
} else {
|
||||
await renderSnapshot(obj.data.snapshot, c);
|
||||
}
|
||||
if (obj.type === ObjTypeDto.PageSnapshot) {
|
||||
const pinIds = await LinkHrefOriginStore.pinIds(obj.data.snapshot.url.href);
|
||||
await renderPins(pinIds);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const renderPins = async (ids: number[]) => {
|
||||
if (!htmlRef.current?.lastElementChild) return;
|
||||
|
||||
const el = htmlRef.current?.lastElementChild as HTMLIFrameElement;
|
||||
if (!el.contentDocument || !el.contentWindow) return;
|
||||
|
||||
await SettingsStore.fetchData();
|
||||
if (!SettingsStore.settings) return;
|
||||
|
||||
fnConsoleLog('PIN IDS !!!!', ids, 'iframe', el);
|
||||
|
||||
for (const id of ids) {
|
||||
const pin = await new ObjPinGetCommand(id).execute();
|
||||
const value = XpathFactory.newXPathResult(el.contentDocument, pin.data.xpath);
|
||||
const node = value.singleNodeValue as HTMLElement;
|
||||
if (!node) continue;
|
||||
const pinComponent = new PinComponent(node, pin, {
|
||||
settings: SettingsStore.settings,
|
||||
document: el.contentDocument,
|
||||
window: el.contentWindow
|
||||
});
|
||||
pinComponent.render();
|
||||
fnConsoleLog('PIN !!!', id, pin, value);
|
||||
}
|
||||
};
|
||||
|
||||
const renderCanvas = (s: ObjSnapshotDto, c?: ObjSnapshotData) => {
|
||||
renderHeader(s, c?.size);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user