fix: cleanup url, shadow with children slots
This commit is contained in:
parent
b09b03edb0
commit
ee53b501bf
4
.env
4
.env
@ -1,6 +1,4 @@
|
||||
VERSION=1
|
||||
API_URL='https://pinmenote.com'
|
||||
SHORT_URL='https://pmn.cl'
|
||||
WEB_URL='https://pinmenote.com'
|
||||
WEB_URL=https://pinmenote.com
|
||||
IS_PRODUCTION=true
|
||||
OBJ_LIST_LIMIT=1000
|
@ -16,14 +16,20 @@
|
||||
*/
|
||||
import { BrowserStorageWrapper } from '../../../service/browser.storage.wrapper';
|
||||
import { ICommand } from '../../../model/shared/common.dto';
|
||||
import { ObjRemoveHashtagsCommand } from '../hashtag/obj-remove-hashtags.command';
|
||||
import { ObjSnapshotDto } from '../../../model/obj/obj-snapshot.dto';
|
||||
import { ObjectStoreKeys } from '../../../keys/object.store.keys';
|
||||
import { WordNlp } from '../../../text/nlp/word.nlp';
|
||||
|
||||
export class ObjRemoveSnapshotContentCommand implements ICommand<Promise<void>> {
|
||||
constructor(private snapshot: ObjSnapshotDto) {}
|
||||
constructor(private snapshot: ObjSnapshotDto, private id: number) {}
|
||||
async execute(): Promise<void> {
|
||||
const key = `${ObjectStoreKeys.CONTENT_ID}:${this.snapshot.contentId}`;
|
||||
|
||||
await WordNlp.removeFlat(this.snapshot.words, this.id);
|
||||
|
||||
await new ObjRemoveHashtagsCommand(this.id, this.snapshot.hashtags).execute();
|
||||
|
||||
await BrowserStorageWrapper.remove(key);
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import { ObjAddIdCommand } from '../obj/id/obj-add-id.command';
|
||||
import { ObjNextIdCommand } from '../obj/id/obj-next-id.command';
|
||||
import { ObjPagePinDto } from '../../model/obj/obj-pin.dto';
|
||||
import { ObjectStoreKeys } from '../../keys/object.store.keys';
|
||||
import { WordNlp } from '../../text/nlp/word.nlp';
|
||||
import { fnConsoleLog } from '../../fn/console.fn';
|
||||
|
||||
export class PinAddCommand implements ICommand<Promise<ObjDto<ObjPagePinDto>>> {
|
||||
@ -47,10 +48,11 @@ export class PinAddCommand implements ICommand<Promise<ObjDto<ObjPagePinDto>>> {
|
||||
},
|
||||
encryption: {
|
||||
encrypted: false
|
||||
},
|
||||
hashtags: []
|
||||
}
|
||||
};
|
||||
|
||||
await WordNlp.indexFlat(this.pin.snapshot.words, id);
|
||||
|
||||
const key = `${ObjectStoreKeys.OBJECT_ID}:${id}`;
|
||||
|
||||
await BrowserStorageWrapper.set(key, dto);
|
||||
|
@ -19,7 +19,6 @@ import { ICommand } from '../../model/shared/common.dto';
|
||||
import { LinkHrefOriginStore } from '../../store/link-href-origin.store';
|
||||
import { ObjDto } from '../../model/obj/obj.dto';
|
||||
import { ObjPagePinDto } from '../../model/obj/obj-pin.dto';
|
||||
import { ObjRemoveHashtagsCommand } from '../obj/hashtag/obj-remove-hashtags.command';
|
||||
import { ObjRemoveIdCommand } from '../obj/id/obj-remove-id.command';
|
||||
import { ObjRemoveSnapshotContentCommand } from '../obj/content/obj-remove-snapshot-content.command';
|
||||
import { ObjectStoreKeys } from '../../keys/object.store.keys';
|
||||
@ -34,8 +33,6 @@ export class PinRemoveCommand implements ICommand<void> {
|
||||
|
||||
await new ObjRemoveIdCommand(this.obj.id, new Date(this.obj.createdAt)).execute();
|
||||
|
||||
await new ObjRemoveHashtagsCommand(this.obj.id, this.obj.hashtags).execute();
|
||||
|
||||
await new ObjRemoveSnapshotContentCommand(this.obj.data.snapshot).execute();
|
||||
await new ObjRemoveSnapshotContentCommand(this.obj.data.snapshot, this.obj.id).execute();
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import { environmentConfig } from '../../../environment';
|
||||
|
||||
export class TokenStorageGetCommand implements ICommand<Promise<AccessTokenDto | undefined>> {
|
||||
async execute(): Promise<AccessTokenDto | undefined> {
|
||||
const key = `${ObjectStoreKeys.ACCESS_TOKEN}:${environmentConfig.url.api}`;
|
||||
const key = `${ObjectStoreKeys.ACCESS_TOKEN}:${environmentConfig.defaultServer}`;
|
||||
return await BrowserStorageWrapper.get<AccessTokenDto | undefined>(key);
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import { environmentConfig } from '../../../environment';
|
||||
|
||||
export class TokenStorageRemoveCommand implements ICommand<Promise<void>> {
|
||||
async execute(): Promise<void> {
|
||||
const key = `${ObjectStoreKeys.ACCESS_TOKEN}:${environmentConfig.url.api}`;
|
||||
const key = `${ObjectStoreKeys.ACCESS_TOKEN}:${environmentConfig.defaultServer}`;
|
||||
await BrowserStorageWrapper.remove(key);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import { environmentConfig } from '../../../environment';
|
||||
export class TokenStorageSetCommand implements ICommand<Promise<void>> {
|
||||
constructor(private value: AccessTokenDto) {}
|
||||
async execute(): Promise<void> {
|
||||
const key = `${ObjectStoreKeys.ACCESS_TOKEN}:${environmentConfig.url.api}`;
|
||||
const key = `${ObjectStoreKeys.ACCESS_TOKEN}:${environmentConfig.defaultServer}`;
|
||||
await BrowserStorageWrapper.set(key, this.value);
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import { ObjAddIdCommand } from '../obj/id/obj-add-id.command';
|
||||
import { ObjNextIdCommand } from '../obj/id/obj-next-id.command';
|
||||
import { ObjSnapshotDto } from '../../model/obj/obj-snapshot.dto';
|
||||
import { ObjectStoreKeys } from '../../keys/object.store.keys';
|
||||
import { WordNlp } from '../../text/nlp/word.nlp';
|
||||
|
||||
export class PageElementSnapshotAddCommand implements ICommand<Promise<void>> {
|
||||
constructor(private dto: ObjSnapshotDto) {}
|
||||
@ -41,10 +42,11 @@ export class PageElementSnapshotAddCommand implements ICommand<Promise<void>> {
|
||||
},
|
||||
encryption: {
|
||||
encrypted: false
|
||||
},
|
||||
hashtags: []
|
||||
}
|
||||
};
|
||||
|
||||
await WordNlp.indexFlat(this.dto.words, id);
|
||||
|
||||
const key = `${ObjectStoreKeys.OBJECT_ID}:${id}`;
|
||||
await BrowserStorageWrapper.set(key, dto);
|
||||
|
||||
|
@ -18,6 +18,7 @@ import { BrowserStorageWrapper } from '../../service/browser.storage.wrapper';
|
||||
import { ICommand } from '../../model/shared/common.dto';
|
||||
import { ObjDto } from '../../model/obj/obj.dto';
|
||||
import { ObjRemoveIdCommand } from '../obj/id/obj-remove-id.command';
|
||||
import { ObjRemoveSnapshotContentCommand } from '../obj/content/obj-remove-snapshot-content.command';
|
||||
import { ObjSnapshotDto } from '../../model/obj/obj-snapshot.dto';
|
||||
import { ObjectStoreKeys } from '../../keys/object.store.keys';
|
||||
|
||||
@ -29,5 +30,7 @@ export class PageElementSnapshotRemoveCommand implements ICommand<Promise<void>>
|
||||
await BrowserStorageWrapper.remove(key);
|
||||
|
||||
await new ObjRemoveIdCommand(this.obj.id, new Date(this.obj.createdAt)).execute();
|
||||
|
||||
await new ObjRemoveSnapshotContentCommand(this.obj.data, this.obj.id).execute();
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import { ObjAddIdCommand } from '../obj/id/obj-add-id.command';
|
||||
import { ObjNextIdCommand } from '../obj/id/obj-next-id.command';
|
||||
import { ObjSnapshotDto } from '../../model/obj/obj-snapshot.dto';
|
||||
import { ObjectStoreKeys } from '../../keys/object.store.keys';
|
||||
import { WordNlp } from '../../text/nlp/word.nlp';
|
||||
|
||||
export class PageSnapshotAddCommand implements ICommand<Promise<void>> {
|
||||
constructor(private dto: ObjSnapshotDto) {}
|
||||
@ -41,9 +42,9 @@ export class PageSnapshotAddCommand implements ICommand<Promise<void>> {
|
||||
},
|
||||
encryption: {
|
||||
encrypted: false
|
||||
},
|
||||
hashtags: []
|
||||
}
|
||||
};
|
||||
await WordNlp.indexFlat(this.dto.words, id);
|
||||
|
||||
const key = `${ObjectStoreKeys.OBJECT_ID}:${id}`;
|
||||
await BrowserStorageWrapper.set(key, dto);
|
||||
|
@ -31,6 +31,6 @@ export class PageSnapshotRemoveCommand implements ICommand<Promise<void>> {
|
||||
|
||||
await new ObjRemoveIdCommand(this.obj.id, new Date(this.obj.createdAt)).execute();
|
||||
|
||||
await new ObjRemoveSnapshotContentCommand(this.obj.data).execute();
|
||||
await new ObjRemoveSnapshotContentCommand(this.obj.data, this.obj.id).execute();
|
||||
}
|
||||
}
|
||||
|
@ -28,15 +28,9 @@ export interface SettingsConfig {
|
||||
videoDisplayTime: number;
|
||||
}
|
||||
|
||||
export interface UrlConfig {
|
||||
short: string;
|
||||
web: string;
|
||||
api: string;
|
||||
}
|
||||
|
||||
interface EnvironmentConfig {
|
||||
showAckMessage: boolean;
|
||||
url: UrlConfig;
|
||||
defaultServer: string;
|
||||
isProduction: boolean;
|
||||
settings: SettingsConfig;
|
||||
objListLimit: number;
|
||||
@ -44,11 +38,7 @@ interface EnvironmentConfig {
|
||||
|
||||
export const environmentConfig: EnvironmentConfig = {
|
||||
showAckMessage: false,
|
||||
url: {
|
||||
api: process.env.API_URL || 'https://pinmenote.com',
|
||||
web: process.env.WEB_URL || 'https://pinmenote.com',
|
||||
short: process.env.SHORT_URL || 'https://pmn.cl'
|
||||
},
|
||||
defaultServer: process.env.WEB_URL || 'https://pinmenote.com',
|
||||
isProduction: process.env.IS_PRODUCTION === 'true',
|
||||
settings: {
|
||||
version: parseInt(process.env.VERSION || '1'),
|
||||
|
@ -33,10 +33,14 @@ export class ObjectStoreKeys {
|
||||
static readonly OBJECT_LINK = 'o:link';
|
||||
|
||||
// INDEX
|
||||
static readonly SEARCH_INDEX = 'i';
|
||||
static readonly SEARCH_INDEX = 's:i';
|
||||
static readonly SEARCH_WORD = 's:w';
|
||||
|
||||
static readonly ACCESS_TOKEN = 'accessToken';
|
||||
|
||||
// SYNC
|
||||
static readonly SYNC_TIME = 'sync';
|
||||
|
||||
// SETTINGS
|
||||
static readonly CONTENT_SETTINGS_KEY = 'content-settings';
|
||||
}
|
||||
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* This file is part of the pinmenote-extension distribution (https://github.com/pinmenote/pinmenote-extension).
|
||||
* Copyright (c) 2022 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/>.
|
||||
*/
|
||||
export class SettingsKeys {
|
||||
static readonly CONTENT_SETTINGS_KEY = 'content-settings';
|
||||
}
|
@ -27,6 +27,8 @@ export interface ObjCanvasDto {
|
||||
export interface ObjSnapshotDto {
|
||||
url: ObjUrlDto;
|
||||
title: string;
|
||||
words: string[];
|
||||
hashtags: string[];
|
||||
screenshot?: string;
|
||||
contentId: number;
|
||||
canvas?: ObjCanvasDto;
|
||||
|
@ -55,6 +55,5 @@ export interface ObjDto<T = ObjDataDto> {
|
||||
createdAt: number;
|
||||
local: ObjLocalDto;
|
||||
encryption: ObjEncryptionDto;
|
||||
hashtags: string[];
|
||||
data: T;
|
||||
}
|
||||
|
@ -15,13 +15,16 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import * as LanguageDetect from 'languagedetect';
|
||||
import { fnConsoleLog } from '../fn/console.fn';
|
||||
|
||||
export class DetectLanguage {
|
||||
private static lang = new LanguageDetect();
|
||||
|
||||
static detect(sample: string): string {
|
||||
this.lang.setLanguageType('iso2');
|
||||
const languages = this.lang.detect(sample);
|
||||
const samp = sample.length < 1000 ? sample : sample.substring(0, 1000);
|
||||
const languages = this.lang.detect(samp);
|
||||
fnConsoleLog('DetectLanguage', languages[0]);
|
||||
return languages[0][0];
|
||||
}
|
||||
}
|
||||
|
@ -53,13 +53,53 @@ export class WordNlp {
|
||||
}
|
||||
await this.saveStorage(flatPart, id);
|
||||
flatPart = '';
|
||||
await this.saveWord(word);
|
||||
}
|
||||
fnConsoleLog('indexed', Array.from(this.flatSet), 'count', this.flatSet.size, 'in', Date.now() - a);
|
||||
};
|
||||
|
||||
static removeFlat = async (words: string[], id: number): Promise<void> => {
|
||||
const a = Date.now();
|
||||
let ch = '';
|
||||
let flatPart = '';
|
||||
for (const word of words) {
|
||||
for (let i = 0; i < word.length; i++) {
|
||||
ch = word.charAt(i).toLowerCase();
|
||||
flatPart += ch;
|
||||
if (flatPart.length % 2 === 0) {
|
||||
await this.removeStorage(flatPart, id);
|
||||
}
|
||||
}
|
||||
await this.removeStorage(flatPart, id);
|
||||
flatPart = '';
|
||||
}
|
||||
fnConsoleLog('removed', Array.from(this.flatSet), 'count', this.flatSet.size, 'in', Date.now() - a);
|
||||
};
|
||||
|
||||
private static removeStorage = async (value: string, id: number) => {
|
||||
if (this.flatSet.has(value)) return;
|
||||
this.flatSet.add(value);
|
||||
|
||||
const key = `${ObjectStoreKeys.SEARCH_INDEX}:${value}`;
|
||||
const arr = await BrowserStorageWrapper.get<number[]>(key);
|
||||
if (!arr) return;
|
||||
|
||||
const idx = arr.indexOf(id);
|
||||
if (idx === -1) return;
|
||||
|
||||
arr.splice(idx, 1);
|
||||
if (arr.length === 0) {
|
||||
await BrowserStorageWrapper.remove(key);
|
||||
await this.removeWord(value);
|
||||
} else {
|
||||
await BrowserStorageWrapper.set<number[]>(key, arr);
|
||||
}
|
||||
};
|
||||
|
||||
private static saveStorage = async (value: string, id: number) => {
|
||||
// skip existing
|
||||
if (this.flatSet.has(value)) return;
|
||||
this.flatSet.add(value);
|
||||
|
||||
const key = `${ObjectStoreKeys.SEARCH_INDEX}:${value}`;
|
||||
let arr = await BrowserStorageWrapper.get<number[]>(key);
|
||||
@ -69,6 +109,36 @@ export class WordNlp {
|
||||
arr = [id];
|
||||
}
|
||||
await BrowserStorageWrapper.set<number[]>(key, arr);
|
||||
this.flatSet.add(value);
|
||||
};
|
||||
|
||||
private static saveWord = async (word: string) => {
|
||||
if (word.length < 3) return;
|
||||
const start = word.substring(0, 2);
|
||||
const key = `${ObjectStoreKeys.SEARCH_WORD}:${start}`;
|
||||
let arr = await BrowserStorageWrapper.get<string[]>(key);
|
||||
if (arr) {
|
||||
const idx = arr.indexOf(word);
|
||||
if (idx === -1) arr.push(word);
|
||||
} else {
|
||||
arr = [word];
|
||||
}
|
||||
await BrowserStorageWrapper.set<string[]>(key, arr);
|
||||
};
|
||||
|
||||
private static removeWord = async (word: string) => {
|
||||
const start = word.substring(0, 2);
|
||||
const key = `${ObjectStoreKeys.SEARCH_WORD}:${start}`;
|
||||
const arr = await BrowserStorageWrapper.get<string[]>(key);
|
||||
if (!arr) return;
|
||||
|
||||
const idx = arr.indexOf(word);
|
||||
if (idx === -1) return;
|
||||
|
||||
arr.splice(idx, 1);
|
||||
if (arr.length === 0) {
|
||||
await BrowserStorageWrapper.remove(key);
|
||||
} else {
|
||||
await BrowserStorageWrapper.set<string[]>(key, arr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -33,13 +33,15 @@ export class ContentPageSnapshotAddCommand implements ICommand<Promise<void>> {
|
||||
}
|
||||
const screenshot = await ScreenshotFactory.takeScreenshot(undefined, this.url);
|
||||
|
||||
const contentId = await new SnapshotContentSaveCommand(document.body).execute();
|
||||
const res = await new SnapshotContentSaveCommand(document.body).execute();
|
||||
|
||||
const dto: ObjSnapshotDto = {
|
||||
title: document.title,
|
||||
url: this.url,
|
||||
screenshot,
|
||||
contentId
|
||||
contentId: res.id,
|
||||
words: res.words,
|
||||
hashtags: []
|
||||
};
|
||||
await new PageSnapshotAddCommand(dto).execute();
|
||||
|
||||
|
@ -22,12 +22,16 @@ 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';
|
||||
import { WordNlp } from '../../../common/text/nlp/word.nlp';
|
||||
import { fnConsoleLog } from '../../../common/fn/console.fn';
|
||||
|
||||
export class SnapshotContentSaveCommand implements ICommand<Promise<number>> {
|
||||
interface SnapshotResult {
|
||||
id: number;
|
||||
words: string[];
|
||||
}
|
||||
|
||||
export class SnapshotContentSaveCommand implements ICommand<Promise<SnapshotResult>> {
|
||||
constructor(private element: HTMLElement) {}
|
||||
async execute(): Promise<number> {
|
||||
async execute(): Promise<SnapshotResult> {
|
||||
const id = await new ObjNextContentIdCommand().execute();
|
||||
const key = `${ObjectStoreKeys.CONTENT_ID}:${id}`;
|
||||
|
||||
@ -39,9 +43,8 @@ export class SnapshotContentSaveCommand implements ICommand<Promise<number>> {
|
||||
fnConsoleLog('HTML DONE');
|
||||
const css = await CssFactory.computeCssContent(urlCache);
|
||||
fnConsoleLog('CSS DONE');
|
||||
const tagList = AutoTagMediator.computeTags(this.element);
|
||||
const words = AutoTagMediator.computeTags(this.element);
|
||||
fnConsoleLog('SOCIAL TAGS DONE');
|
||||
await WordNlp.indexFlat(tagList, id);
|
||||
fnConsoleLog('SKIPPED', urlCache);
|
||||
fnConsoleLog('END');
|
||||
|
||||
@ -54,6 +57,6 @@ export class SnapshotContentSaveCommand implements ICommand<Promise<number>> {
|
||||
content: htmlContent.content
|
||||
});
|
||||
|
||||
return id;
|
||||
return { id, words };
|
||||
}
|
||||
}
|
||||
|
@ -28,12 +28,17 @@ export class SnapshotCreateCommand implements ICommand<Promise<ObjSnapshotDto>>
|
||||
const rect = this.canvas ? this.canvas.rect : XpathFactory.computeRect(this.element);
|
||||
const screenshot = await ScreenshotFactory.takeScreenshot(rect, this.url);
|
||||
let contentId = -1;
|
||||
let words: string[] = [];
|
||||
if (!this.canvas) {
|
||||
contentId = await new SnapshotContentSaveCommand(this.element).execute();
|
||||
const res = await new SnapshotContentSaveCommand(this.element).execute();
|
||||
contentId = res.id;
|
||||
words = res.words;
|
||||
}
|
||||
return {
|
||||
title: document.title,
|
||||
url: this.url,
|
||||
words,
|
||||
hashtags: [],
|
||||
canvas: this.canvas,
|
||||
screenshot,
|
||||
contentId
|
||||
|
@ -68,10 +68,11 @@ export class HtmlFactory {
|
||||
skipUrlCache?: Set<string>
|
||||
): Promise<HtmlIntermediateData> => {
|
||||
if (!skipTagCache) skipTagCache = new Set<string>();
|
||||
|
||||
const tagName = ref.tagName.toLowerCase();
|
||||
|
||||
if (!HtmlConstraints.KNOWN_ELEMENTS.includes(tagName) && !skipTagCache.has(tagName)) {
|
||||
const shadow = BrowserApi.shadowRoot(ref);
|
||||
// fnConsoleLog('NOT KNOWN ELEMENT', tagName, 'SHADOW', shadow);
|
||||
// Go with shadow
|
||||
if (shadow) {
|
||||
return ShadowFactory.computeShadow(tagName, ref, shadow, skipUrlCache);
|
||||
@ -79,6 +80,7 @@ export class HtmlFactory {
|
||||
skipTagCache.add(tagName);
|
||||
}
|
||||
}
|
||||
|
||||
let html = `<${tagName} `;
|
||||
const video: ObjVideoDataDto[] = [];
|
||||
const content: ObjContentDto[] = [];
|
||||
@ -168,11 +170,26 @@ export class HtmlFactory {
|
||||
skipUrlCache?: Set<string>
|
||||
): Promise<HtmlIntermediateData> => {
|
||||
if (!ref.firstElementChild) return HtmlAttrFactory.EMPTY_RESULT;
|
||||
|
||||
const children = Array.from(ref.children);
|
||||
const images = children.filter((c) => c.tagName.toLowerCase() === 'img');
|
||||
const sources = children.filter((c) => c.tagName.toLowerCase() === 'source');
|
||||
const isSource = sources.length > 0;
|
||||
|
||||
const content: ObjContentDto[] = [];
|
||||
let html = `<picture `;
|
||||
html += await HtmlAttrFactory.computeAttrValues('picture', Array.from(ref.attributes));
|
||||
html = html.substring(0, html.length - 1) + '>';
|
||||
const child = ref.firstElementChild;
|
||||
const attrs = Array.from(ref.attributes);
|
||||
if (isSource && attrs.filter((attr) => attr.nodeName === 'style').length === 0) {
|
||||
const rect = ref.getBoundingClientRect();
|
||||
html += ` style="width:${rect.width}px;height:${rect.height}px" `;
|
||||
}
|
||||
html += await HtmlAttrFactory.computeAttrValues('picture', attrs);
|
||||
html = html.substring(0, html.length - 1);
|
||||
|
||||
// Source must be converted to img - we lose size information that's why we need to put style with those attributes
|
||||
html += '>';
|
||||
|
||||
const child = sources.length > 0 ? sources[0] : images[0];
|
||||
const childTag = child.tagName.toLowerCase();
|
||||
const value = await HtmlImgFactory.computeImgValue(child as HTMLImageElement, skipUrlCache);
|
||||
const uid = fnUid();
|
||||
|
@ -33,11 +33,28 @@ export class ShadowFactory {
|
||||
shadow: ShadowRoot,
|
||||
skipUrlCache?: Set<string>
|
||||
): Promise<HtmlIntermediateData> => {
|
||||
fnConsoleLog('COMPUTE SHADOW !!!');
|
||||
fnConsoleLog('COMPUTE SHADOW !!!', tagName, ref);
|
||||
const uid = fnUid();
|
||||
let html = `<${tagName} data-pin-id="${uid}" `;
|
||||
html += await HtmlAttrFactory.computeAttrValues(tagName, Array.from(ref.attributes));
|
||||
html = html.substring(0, html.length - 1) + '>';
|
||||
|
||||
const nodes = Array.from(ref.childNodes);
|
||||
for (const node of nodes) {
|
||||
if (node.nodeType === Node.TEXT_NODE) {
|
||||
const nre = new RegExp(String.fromCharCode(160), 'g');
|
||||
let txt = node.textContent ? node.textContent.replace(nre, ' ') : '';
|
||||
txt = txt.replace('<', '<').replace('>', '>');
|
||||
html += txt;
|
||||
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
html += await this.computeShadowChild(node as Element);
|
||||
} else if (node.nodeType === Node.COMMENT_NODE) {
|
||||
html += '<!---->';
|
||||
} else {
|
||||
fnConsoleLog('PROBLEM fnComputeHtmlContent !!!', node.nodeType);
|
||||
}
|
||||
}
|
||||
|
||||
html += `</${tagName}>`;
|
||||
const shadowHtml = await this.computeShadowHtml(shadow, skipUrlCache);
|
||||
return {
|
||||
@ -77,6 +94,11 @@ export class ShadowFactory {
|
||||
|
||||
private static computeShadowChild = async (ref: Element, skipUrlCache?: Set<string>): Promise<string> => {
|
||||
const tagName = ref.tagName.toLowerCase();
|
||||
|
||||
let htmlPrefilled = false;
|
||||
|
||||
let html = `<${tagName} `;
|
||||
|
||||
if (tagName === 'link') {
|
||||
const uri = ref.getAttribute('href');
|
||||
if (uri) {
|
||||
@ -96,22 +118,23 @@ export class ShadowFactory {
|
||||
return pic.html;
|
||||
} else if (!HtmlConstraints.KNOWN_ELEMENTS.includes(tagName)) {
|
||||
const shadow = BrowserApi.shadowRoot(ref);
|
||||
|
||||
if (shadow) {
|
||||
let html = `<${tagName} `;
|
||||
html += await HtmlAttrFactory.computeAttrValues(tagName, Array.from(ref.attributes));
|
||||
html = html.substring(0, html.length - 1) + '>';
|
||||
html += await this.computeShadowHtml(shadow, skipUrlCache);
|
||||
html += `</${tagName}>`;
|
||||
return html;
|
||||
htmlPrefilled = true;
|
||||
}
|
||||
}
|
||||
let html = `<${tagName} `;
|
||||
html += await HtmlAttrFactory.computeAttrValues(tagName, Array.from(ref.attributes));
|
||||
if (tagName === 'img') {
|
||||
const value = await HtmlImgFactory.computeImgValue(ref as HTMLImageElement, skipUrlCache);
|
||||
html += `src="${value}" `;
|
||||
|
||||
if (!htmlPrefilled) {
|
||||
html += await HtmlAttrFactory.computeAttrValues(tagName, Array.from(ref.attributes));
|
||||
if (tagName === 'img') {
|
||||
const value = await HtmlImgFactory.computeImgValue(ref as HTMLImageElement, skipUrlCache);
|
||||
html += `src="${value}" `;
|
||||
}
|
||||
html = html.substring(0, html.length - 1) + '>';
|
||||
}
|
||||
html = html.substring(0, html.length - 1) + '>';
|
||||
|
||||
const nodes = Array.from(ref.childNodes);
|
||||
for (const node of nodes) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
import { SettingsConfig, environmentConfig } from '../../common/environment';
|
||||
import { BrowserStorageWrapper } from '../../common/service/browser.storage.wrapper';
|
||||
import { SettingsKeys } from '../../common/keys/settings.keys';
|
||||
import { ObjectStoreKeys } from '../../common/keys/object.store.keys';
|
||||
|
||||
export class ContentSettingsStore {
|
||||
private static settings: SettingsConfig;
|
||||
@ -43,6 +43,6 @@ export class ContentSettingsStore {
|
||||
}
|
||||
|
||||
static initSettings = async (): Promise<void> => {
|
||||
this.settings = await BrowserStorageWrapper.get<SettingsConfig>(SettingsKeys.CONTENT_SETTINGS_KEY);
|
||||
this.settings = await BrowserStorageWrapper.get<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY);
|
||||
};
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ const inputContainerStyle = {
|
||||
};
|
||||
|
||||
function getWebsiteUrl(uri: string): string {
|
||||
return `${environmentConfig.url.web}${uri}`;
|
||||
return `${environmentConfig.defaultServer}${uri}`;
|
||||
}
|
||||
|
||||
interface LoginComponentProps {
|
||||
|
@ -38,7 +38,7 @@ const inputContainerStyle = {
|
||||
};
|
||||
|
||||
function getWebsiteUrl(uri: string): string {
|
||||
return `${environmentConfig.url.web}${uri}`;
|
||||
return `${environmentConfig.defaultServer}${uri}`;
|
||||
}
|
||||
|
||||
interface Verify2faComponentProps {
|
||||
|
@ -34,7 +34,7 @@ import { fnUid } from '../common/fn/uid.fn';
|
||||
* this prevents crashing extension on some web pages with infinite iframe loop (thank you fb)
|
||||
*/
|
||||
export class IframeScript {
|
||||
private href: string;
|
||||
private readonly href: string;
|
||||
private timeoutId = 0;
|
||||
private type?: ObjTypeDto;
|
||||
private uid?: string;
|
||||
@ -45,8 +45,6 @@ export class IframeScript {
|
||||
|
||||
ContentMessageHandler.start(this.href);
|
||||
|
||||
fnConsoleLog('IframeScript->constructor', this.href, window.top);
|
||||
|
||||
document.addEventListener('visibilitychange', this.handleVisibilityChange);
|
||||
|
||||
TinyEventDispatcher.addListener<number[]>(BusMessageType.CNT_SETTINGS, this.handlePinSettings);
|
||||
|
@ -206,7 +206,7 @@ export const HtmlPreviewComponent: FunctionComponent = () => {
|
||||
};
|
||||
|
||||
const renderShadow = (el: Element, content: ObjShadowContentDto) => {
|
||||
el.innerHTML = content.html;
|
||||
el.innerHTML = content.html + el.innerHTML;
|
||||
renderTemplate(el);
|
||||
};
|
||||
|
||||
|
@ -18,8 +18,8 @@ import React, { CSSProperties, ChangeEvent, FunctionComponent, useEffect, useSta
|
||||
import { BrowserStorageWrapper } from '../../../../common/service/browser.storage.wrapper';
|
||||
import { DEFAULT_BORDER_RADIUS } from '../../../../common/components/colors';
|
||||
import Input from '@mui/material/Input';
|
||||
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
||||
import { SettingsConfig } from '../../../../common/environment';
|
||||
import { SettingsKeys } from '../../../../common/keys/settings.keys';
|
||||
import { SettingsStore } from '../../../store/settings.store';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
@ -45,14 +45,14 @@ export const ContentSettingsComponent: FunctionComponent = () => {
|
||||
if (!SettingsStore.settings) return;
|
||||
setBorderRadius(e.target.value);
|
||||
SettingsStore.settings.borderRadius = e.target.value;
|
||||
await BrowserStorageWrapper.set<SettingsConfig>(SettingsKeys.CONTENT_SETTINGS_KEY, SettingsStore.settings);
|
||||
await BrowserStorageWrapper.set<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY, SettingsStore.settings);
|
||||
};
|
||||
|
||||
const handleBorderStyleChange = async (e: ChangeEvent<HTMLInputElement>): Promise<void> => {
|
||||
if (!SettingsStore.settings) return;
|
||||
setBorderStyle(e.target.value);
|
||||
SettingsStore.settings.borderStyle = e.target.value;
|
||||
await BrowserStorageWrapper.set<SettingsConfig>(SettingsKeys.CONTENT_SETTINGS_KEY, SettingsStore.settings);
|
||||
await BrowserStorageWrapper.set<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY, SettingsStore.settings);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -19,9 +19,9 @@ import { ScreenshotFormat, SettingsConfig } from '../../../../common/environment
|
||||
import { BrowserStorageWrapper } from '../../../../common/service/browser.storage.wrapper';
|
||||
import Input from '@mui/material/Input';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import { ObjectStoreKeys } from '../../../../common/keys/object.store.keys';
|
||||
import Select from '@mui/material/Select';
|
||||
import { SelectChangeEvent } from '@mui/material/Select';
|
||||
import { SettingsKeys } from '../../../../common/keys/settings.keys';
|
||||
import { SettingsStore } from '../../../store/settings.store';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
@ -49,7 +49,7 @@ export const ScreenshotSettingsComponent: FunctionComponent = () => {
|
||||
setScreenshotQuality(value);
|
||||
if (value > 0 && value <= 100) {
|
||||
SettingsStore.settings.screenshotQuality = value;
|
||||
await BrowserStorageWrapper.set<SettingsConfig>(SettingsKeys.CONTENT_SETTINGS_KEY, SettingsStore.settings);
|
||||
await BrowserStorageWrapper.set<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY, SettingsStore.settings);
|
||||
}
|
||||
};
|
||||
|
||||
@ -57,7 +57,7 @@ export const ScreenshotSettingsComponent: FunctionComponent = () => {
|
||||
if (!SettingsStore.settings) return;
|
||||
setScreenshotFormat(e.target.value);
|
||||
SettingsStore.settings.screenshotFormat = e.target.value as ScreenshotFormat;
|
||||
await BrowserStorageWrapper.set<SettingsConfig>(SettingsKeys.CONTENT_SETTINGS_KEY, SettingsStore.settings);
|
||||
await BrowserStorageWrapper.set<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY, SettingsStore.settings);
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -15,13 +15,13 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { BrowserStorageWrapper } from '../../common/service/browser.storage.wrapper';
|
||||
import { ObjectStoreKeys } from '../../common/keys/object.store.keys';
|
||||
import { SettingsConfig } from '../../common/environment';
|
||||
import { SettingsKeys } from '../../common/keys/settings.keys';
|
||||
|
||||
export class SettingsStore {
|
||||
static settings?: SettingsConfig;
|
||||
|
||||
static fetchData = async (): Promise<void> => {
|
||||
this.settings = await BrowserStorageWrapper.get<SettingsConfig>(SettingsKeys.CONTENT_SETTINGS_KEY);
|
||||
this.settings = await BrowserStorageWrapper.get<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY);
|
||||
};
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ export class ApiHelper {
|
||||
}
|
||||
|
||||
static get apiUrl(): string {
|
||||
return environmentConfig.url.api;
|
||||
return environmentConfig.defaultServer;
|
||||
}
|
||||
|
||||
static async getStoreUrl(): Promise<string> {
|
||||
|
@ -18,8 +18,8 @@ import { BrowserApi } from '../../../common/service/browser.api.wrapper';
|
||||
import { BrowserStorageWrapper } from '../../../common/service/browser.storage.wrapper';
|
||||
import { BusMessageType } from '../../../common/model/bus.model';
|
||||
import { ICommand } from '../../../common/model/shared/common.dto';
|
||||
import { ObjectStoreKeys } from '../../../common/keys/object.store.keys';
|
||||
import { SettingsConfig } from '../../../common/environment';
|
||||
import { SettingsKeys } from '../../../common/keys/settings.keys';
|
||||
import { fnConsoleLog } from '../../../common/fn/console.fn';
|
||||
|
||||
export class ContentTakeScreenshotCommand implements ICommand<void> {
|
||||
@ -27,7 +27,7 @@ export class ContentTakeScreenshotCommand implements ICommand<void> {
|
||||
async execute(): Promise<void> {
|
||||
try {
|
||||
fnConsoleLog('ContentTakeScreenshotCommand->execute', this.url);
|
||||
const settings = await BrowserStorageWrapper.get<SettingsConfig>(SettingsKeys.CONTENT_SETTINGS_KEY);
|
||||
const settings = await BrowserStorageWrapper.get<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY);
|
||||
const data = await BrowserApi.tabs.captureVisibleTab({
|
||||
format: settings.screenshotFormat,
|
||||
quality: settings.screenshotQuality
|
||||
|
@ -18,12 +18,12 @@ import { BrowserApi } from '../../../common/service/browser.api.wrapper';
|
||||
import { BrowserStorageWrapper } from '../../../common/service/browser.storage.wrapper';
|
||||
import { BusMessageType } from '../../../common/model/bus.model';
|
||||
import { ICommand } from '../../../common/model/shared/common.dto';
|
||||
import { ObjectStoreKeys } from '../../../common/keys/object.store.keys';
|
||||
import { SettingsConfig } from '../../../common/environment';
|
||||
import { SettingsKeys } from '../../../common/keys/settings.keys';
|
||||
|
||||
export class PopupTakeScreenshotCommand implements ICommand<Promise<void>> {
|
||||
async execute(): Promise<void> {
|
||||
const settings = await BrowserStorageWrapper.get<SettingsConfig>(SettingsKeys.CONTENT_SETTINGS_KEY);
|
||||
const settings = await BrowserStorageWrapper.get<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY);
|
||||
const data = await BrowserApi.tabs.captureVisibleTab({
|
||||
format: settings.screenshotFormat,
|
||||
quality: settings.screenshotQuality
|
||||
|
@ -18,15 +18,15 @@ import { SettingsConfig, environmentConfig } from '../../../common/environment';
|
||||
import { BrowserStorageWrapper } from '../../../common/service/browser.storage.wrapper';
|
||||
import { CryptoGenerateKeyPairCommand } from '../../../common/command/crypto/crypto-generate-key-pair.command';
|
||||
import { ICommand } from '../../../common/model/shared/common.dto';
|
||||
import { SettingsKeys } from '../../../common/keys/settings.keys';
|
||||
import { ObjectStoreKeys } from '../../../common/keys/object.store.keys';
|
||||
import { fnConsoleLog } from '../../../common/fn/console.fn';
|
||||
|
||||
export class SwInitSettingsCommand implements ICommand<Promise<void>> {
|
||||
async execute(): Promise<void> {
|
||||
const settings = await BrowserStorageWrapper.get<SettingsConfig>(SettingsKeys.CONTENT_SETTINGS_KEY);
|
||||
const settings = await BrowserStorageWrapper.get<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY);
|
||||
if (!settings) {
|
||||
fnConsoleLog('Settings Initialize');
|
||||
await BrowserStorageWrapper.set<SettingsConfig>(SettingsKeys.CONTENT_SETTINGS_KEY, environmentConfig.settings);
|
||||
await BrowserStorageWrapper.set<SettingsConfig>(ObjectStoreKeys.CONTENT_SETTINGS_KEY, environmentConfig.settings);
|
||||
await new CryptoGenerateKeyPairCommand().execute();
|
||||
} else if (settings.version !== environmentConfig.settings.version) {
|
||||
fnConsoleLog('Settings Migrate placeholder');
|
||||
|
Loading…
Reference in New Issue
Block a user