feat: save full image when cropping rectangle

This commit is contained in:
Michal Szczepanski 2023-04-23 07:10:32 +02:00
parent a9d79dde46
commit a55ca90ae6
5 changed files with 86 additions and 13 deletions

View File

@ -11,4 +11,18 @@ Browser extension nobody wants and nobody needs
npm run dev
```
### Website
[https://pinmenote.com](https://pinmenote.com) - subscribe to premium to move project further
### Known issues
#### Shadow root
Open shadow root is not always displayed or parsed correctly - but at least it matches mht quality.
#### Youtube
Youtube use polymer dom with ```<!--css-build:shady-->```.
It is some polymer polyfil for shadow root that messes with css.
#### Twitter
Use style ```transform: translateY(4620.5px); position: absolute;``` for single tweets
(todo remove those style attributes from tweet when saving element)

View File

@ -48,7 +48,7 @@ export class WordNlp {
ch = word.charAt(i).toLowerCase();
flatPart += ch;
if (flatPart.length % 2 === 0) {
await this.saveStorage(flatPart, id);
break;
}
}
await this.saveStorage(flatPart, id);
@ -56,6 +56,7 @@ export class WordNlp {
await this.saveWord(word);
}
fnConsoleLog('indexed', Array.from(this.flatSet), 'count', this.flatSet.size, 'in', Date.now() - a);
this.flatSet.clear();
};
static removeFlat = async (words: string[], id: number): Promise<void> => {
@ -67,7 +68,7 @@ export class WordNlp {
ch = word.charAt(i).toLowerCase();
flatPart += ch;
if (flatPart.length % 2 === 0) {
await this.removeStorage(flatPart, id);
break;
}
}
await this.removeStorage(flatPart, id);

View File

@ -19,6 +19,7 @@ import { ICommand } from '../../../common/model/shared/common.dto';
import { ObjUrlDto } from '../../../common/model/obj/obj.dto';
import { ScreenshotFactory } from '../../../common/factory/screenshot.factory';
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>> {
@ -32,6 +33,9 @@ export class SnapshotCreateCommand implements ICommand<Promise<ObjSnapshotDto>>
const res = await new SnapshotContentSaveCommand(this.element).execute();
contentId = res.id;
words = res.words;
} else if (this.element instanceof HTMLImageElement) {
// TODO save image
contentId = await new SnapshotSaveImageCommand(this.element).execute();
}
const screenshot = await ScreenshotFactory.takeScreenshot(rect, this.url);
return {

View File

@ -0,0 +1,45 @@
/*
* 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 { BrowserStorageWrapper } from '../../../common/service/browser.storage.wrapper';
import { HtmlImgFactory } from '../../factory/html/html-img.factory';
import { ICommand } from '../../../common/model/shared/common.dto';
import { ObjNextContentIdCommand } from '../../../common/command/obj/content/obj-next-content-id.command';
import { ObjSnapshotContentDto } from '../../../common/model/obj/obj-snapshot.dto';
import { ObjectStoreKeys } from '../../../common/keys/object.store.keys';
export class SnapshotSaveImageCommand implements ICommand<Promise<number>> {
constructor(private element: HTMLElement) {}
async execute(): Promise<number> {
const id = await new ObjNextContentIdCommand().execute();
const key = `${ObjectStoreKeys.CONTENT_ID}:${id}`;
const value = await HtmlImgFactory.computeImgValue(this.element as HTMLImageElement);
await BrowserStorageWrapper.set<ObjSnapshotContentDto>(key, {
id,
html: `<img src="${value}" />`,
htmlAttr: '',
css: {
css: []
},
video: [],
content: []
});
return id;
}
}

View File

@ -60,11 +60,14 @@ export const HtmlPreviewComponent: FunctionComponent = () => {
async (event, key, value) => {
setIsPreLoading(true);
setIsLoading(true);
if (value.canvas) {
renderCanvas(value);
} else {
const c = await new ObjGetSnapshotContentCommand(value.contentId).execute();
let c: ObjSnapshotData | undefined = undefined;
if (value.contentId > 0) {
c = await new ObjGetSnapshotContentCommand(value.contentId).execute();
setContent(c);
}
if (value.canvas) {
renderCanvas(value, c);
} else {
await renderSnapshot(value, c);
}
}
@ -75,8 +78,8 @@ export const HtmlPreviewComponent: FunctionComponent = () => {
};
});
const renderCanvas = (s: ObjSnapshotDto) => {
renderHeader(s, 0);
const renderCanvas = (s: ObjSnapshotDto, c?: ObjSnapshotData) => {
renderHeader(s, c?.size);
if (!htmlRef.current) return;
if (!containerRef.current) return;
@ -86,8 +89,14 @@ export const HtmlPreviewComponent: FunctionComponent = () => {
iframe.height = '100%';
htmlRef.current.appendChild(iframe);
if (!iframe.contentWindow) return;
let html = `<body>`;
if (c) {
html += `${c.snapshot.html}`;
} else {
html += `<img src="${s.screenshot || ''}" alt="screenshot" />`;
}
const html = `<body><img src="${s.screenshot || ''}" alt="screenshot" /></body>`;
html += `</body>`;
const doc = iframe.contentWindow.document;
doc.write(html);
doc.close();
@ -96,9 +105,9 @@ export const HtmlPreviewComponent: FunctionComponent = () => {
setIsLoading(false);
};
const renderSnapshot = async (s: ObjSnapshotDto, c: ObjSnapshotData): Promise<void> => {
fnConsoleLog('SHOW HTML !!!', s, c, c.snapshot.css.css.length);
renderHeader(s, c.size);
const renderSnapshot = async (s: ObjSnapshotDto, c?: ObjSnapshotData): Promise<void> => {
fnConsoleLog('SHOW HTML !!!', s, c, c?.snapshot.css.css.length);
renderHeader(s, c?.size);
if (!htmlRef.current) return;
if (!containerRef.current) return;
if (!c) return;
@ -134,7 +143,7 @@ export const HtmlPreviewComponent: FunctionComponent = () => {
setIsLoading(false);
};
const renderHeader = (s: ObjSnapshotDto, size: number): void => {
const renderHeader = (s: ObjSnapshotDto, size?: number): void => {
if (sizeRef.current) {
sizeRef.current.innerHTML = `${fnByteToMb(size)} MB`;
}