@social-mail/social-mail-client 1.8.332 → 1.8.334
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/site-editor/editor/HtmlPageEditor.d.ts +1 -1
- package/dist/site-editor/editor/HtmlPageEditor.d.ts.map +1 -1
- package/dist/site-editor/editor/HtmlPageEditor.js.map +1 -1
- package/dist/site-editor/editor/ui/SelectionUI.d.ts.map +1 -1
- package/dist/site-editor/editor/ui/SelectionUI.js +52 -21
- package/dist/site-editor/editor/ui/SelectionUI.js.map +1 -1
- package/dist/site-editor/tools/ToolService.d.ts +21 -0
- package/dist/site-editor/tools/ToolService.d.ts.map +1 -0
- package/dist/site-editor/tools/ToolService.js +35 -0
- package/dist/site-editor/tools/ToolService.js.map +1 -0
- package/dist/site-editor/tools/basic/BasicShapes.d.ts +5 -4
- package/dist/site-editor/tools/basic/BasicShapes.d.ts.map +1 -1
- package/dist/site-editor/tools/basic/BasicShapes.js +23 -41
- package/dist/site-editor/tools/basic/BasicShapes.js.map +1 -1
- package/dist/site-editor/tools/designs/Designs.d.ts +5 -4
- package/dist/site-editor/tools/designs/Designs.d.ts.map +1 -1
- package/dist/site-editor/tools/designs/Designs.js +23 -41
- package/dist/site-editor/tools/designs/Designs.js.map +1 -1
- package/dist/site-editor-app/SiteEditorApp.pack.js +137 -104
- package/dist/site-editor-app/SiteEditorApp.pack.js.map +1 -1
- package/dist/site-editor-app/SiteEditorApp.pack.min.js +1 -1
- package/dist/site-editor-app/SiteEditorApp.pack.min.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/site-editor/editor/HtmlPageEditor.tsx +2 -1
- package/src/site-editor/editor/ui/SelectionUI.tsx +75 -32
- package/src/site-editor/tools/ToolService.ts +32 -0
- package/src/site-editor/tools/basic/BasicShapes.tsx +15 -38
- package/src/site-editor/tools/designs/Designs.tsx +15 -38
package/package.json
CHANGED
|
@@ -95,6 +95,8 @@ export default class HtmlPageEditor extends AtomControl {
|
|
|
95
95
|
|
|
96
96
|
public maxWidth = desktopWidth;
|
|
97
97
|
|
|
98
|
+
public contentEditor: HTMLIFrameElement;
|
|
99
|
+
|
|
98
100
|
|
|
99
101
|
public get modifiedDocument() {
|
|
100
102
|
if (!this.undoRedo.changed) {
|
|
@@ -231,7 +233,6 @@ export default class HtmlPageEditor extends AtomControl {
|
|
|
231
233
|
private lastInit: Promise<void>;
|
|
232
234
|
private initCT: CancelToken;
|
|
233
235
|
|
|
234
|
-
private contentEditor: HTMLIFrameElement;
|
|
235
236
|
|
|
236
237
|
|
|
237
238
|
private readonly dropTarget: SelectedElement = new SelectedElement(this);
|
|
@@ -43,6 +43,9 @@ const setCapture = (editor: HtmlPageEditor, element: HTMLElement, e: PointerEven
|
|
|
43
43
|
const selectedElement = selection.element;
|
|
44
44
|
const selectedParent = selectedElement.parentElement;
|
|
45
45
|
|
|
46
|
+
const frameDocument = selectedElement.ownerDocument;
|
|
47
|
+
const frame = editor.contentEditor;
|
|
48
|
+
|
|
46
49
|
|
|
47
50
|
const insetAttribute = `${prefix}-inset`;
|
|
48
51
|
const widthAttribute = `${prefix}-width`;
|
|
@@ -52,15 +55,10 @@ const setCapture = (editor: HtmlPageEditor, element: HTMLElement, e: PointerEven
|
|
|
52
55
|
const oldHeight = selectedElement.getAttribute(heightAttribute);
|
|
53
56
|
const oldInset = selectedElement.getAttribute(insetAttribute);
|
|
54
57
|
|
|
55
|
-
let newInset;
|
|
56
|
-
let newHeight;
|
|
57
|
-
let newWidth;
|
|
58
|
-
|
|
59
58
|
const records = [] as MutationRecord[];
|
|
60
59
|
|
|
61
60
|
|
|
62
61
|
const style = selectedElement.ownerDocument.defaultView.getComputedStyle(selectedElement);
|
|
63
|
-
const { left = "0", top = "0", right = "0", bottom = "0" } = style;
|
|
64
62
|
const width = selectedParent.offsetWidth;
|
|
65
63
|
const height = selectedParent.offsetHeight;
|
|
66
64
|
|
|
@@ -70,39 +68,51 @@ const setCapture = (editor: HtmlPageEditor, element: HTMLElement, e: PointerEven
|
|
|
70
68
|
|
|
71
69
|
const d = undoRedo.beginPause();
|
|
72
70
|
|
|
71
|
+
const left = parseFloat(style.left || "0");
|
|
72
|
+
const top = parseFloat(style.top || "0");
|
|
73
|
+
const bottom = parseFloat(style.bottom || "0");
|
|
74
|
+
const right = parseFloat(style.right || "0");
|
|
75
|
+
|
|
76
|
+
let moved = false;
|
|
77
|
+
|
|
78
|
+
let changed = false;
|
|
79
|
+
|
|
73
80
|
const captureMove = (evt: PointerEvent) => {
|
|
74
81
|
const dx = evt.clientX - sx;
|
|
75
82
|
const dy = evt.clientY - sy;
|
|
83
|
+
if (dx === 0 && dy === 0) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
76
86
|
const ri = {
|
|
77
|
-
left
|
|
78
|
-
top
|
|
79
|
-
right
|
|
80
|
-
bottom
|
|
87
|
+
left,
|
|
88
|
+
top,
|
|
89
|
+
right,
|
|
90
|
+
bottom,
|
|
81
91
|
sx,
|
|
82
92
|
sy,
|
|
83
93
|
dx,
|
|
84
94
|
dy
|
|
85
95
|
};
|
|
96
|
+
changed = true;
|
|
86
97
|
const r = fx(ri);
|
|
87
|
-
|
|
88
|
-
selectedElement.setAttribute(insetAttribute,
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
100
|
-
newWidth = ps(width + widthDiff, width) + "%";
|
|
101
|
-
selectedElement.setAttribute(widthAttribute, newWidth);
|
|
102
|
-
newHeight = ps(height + heightDiff, height) + "%";
|
|
103
|
-
selectedElement.setAttribute(heightAttribute, newHeight);
|
|
98
|
+
const inset = `${ps(r.top, height)}% ${ps(r.right, width)}% ${ps(r.bottom, height)}% ${ps(r.left, width)}%`;
|
|
99
|
+
selectedElement.setAttribute(insetAttribute, inset);
|
|
100
|
+
|
|
101
|
+
if (!r.move) {
|
|
102
|
+
moved = true;
|
|
103
|
+
let widthDiff = -r.left;
|
|
104
|
+
let heightDiff = -r.top;
|
|
105
|
+
if (ri.bottom === r.bottom) {
|
|
106
|
+
heightDiff -= r.bottom;
|
|
107
|
+
}
|
|
108
|
+
if (ri.right === r.right) {
|
|
109
|
+
widthDiff -= r.right;
|
|
104
110
|
}
|
|
105
|
-
|
|
111
|
+
const newWidth = ps(width + widthDiff, width) + "%";
|
|
112
|
+
selectedElement.setAttribute(widthAttribute, newWidth);
|
|
113
|
+
const newHeight = ps(height + heightDiff, height) + "%";
|
|
114
|
+
selectedElement.setAttribute(heightAttribute, newHeight);
|
|
115
|
+
}
|
|
106
116
|
|
|
107
117
|
setTimeout(() => {
|
|
108
118
|
selection.updateRect();
|
|
@@ -112,13 +122,47 @@ const setCapture = (editor: HtmlPageEditor, element: HTMLElement, e: PointerEven
|
|
|
112
122
|
|
|
113
123
|
element.addEventListener("pointermove", captureMove);
|
|
114
124
|
element.setPointerCapture(e.pointerId);
|
|
115
|
-
const release = (e1) => {
|
|
125
|
+
const release = (e1: PointerEvent) => {
|
|
116
126
|
element.releasePointerCapture(e.pointerId);
|
|
117
127
|
element.removeEventListener("pointermove", captureMove);
|
|
118
128
|
element.removeEventListener("pointerup", release);
|
|
119
129
|
captureMove(e1);
|
|
120
130
|
d.resume();
|
|
121
131
|
|
|
132
|
+
if (!changed) {
|
|
133
|
+
|
|
134
|
+
// try to select an element...
|
|
135
|
+
const frameRect = frame.getBoundingClientRect();
|
|
136
|
+
let { clientX, clientY } = e1;
|
|
137
|
+
clientX -= frameRect.left;
|
|
138
|
+
clientY -= frameRect.top;
|
|
139
|
+
|
|
140
|
+
const elementAtPoint = frameDocument.elementFromPoint(clientX, clientY);
|
|
141
|
+
if (!elementAtPoint) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (elementAtPoint === selectedElement) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const body = frameDocument.body;
|
|
150
|
+
|
|
151
|
+
let start = elementAtPoint;
|
|
152
|
+
while(start) {
|
|
153
|
+
if (start === selectedParent) {
|
|
154
|
+
// we need to select different child
|
|
155
|
+
editor.selection.update(elementAtPoint as any);
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
start = start.parentElement;
|
|
159
|
+
if (start === body) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
122
166
|
// push records...
|
|
123
167
|
records.push({
|
|
124
168
|
type: "attributes",
|
|
@@ -128,7 +172,7 @@ const setCapture = (editor: HtmlPageEditor, element: HTMLElement, e: PointerEven
|
|
|
128
172
|
attributeNamespace: "",
|
|
129
173
|
} as MutationRecord);
|
|
130
174
|
|
|
131
|
-
if (
|
|
175
|
+
if (moved) {
|
|
132
176
|
records.push({
|
|
133
177
|
type: "attributes",
|
|
134
178
|
oldValue: oldWidth,
|
|
@@ -136,8 +180,6 @@ const setCapture = (editor: HtmlPageEditor, element: HTMLElement, e: PointerEven
|
|
|
136
180
|
attributeName: widthAttribute,
|
|
137
181
|
attributeNamespace: "",
|
|
138
182
|
} as MutationRecord);
|
|
139
|
-
}
|
|
140
|
-
if (newHeight) {
|
|
141
183
|
records.push({
|
|
142
184
|
type: "attributes",
|
|
143
185
|
oldValue: oldHeight,
|
|
@@ -222,7 +264,8 @@ const eventPointerDown = (editor: HtmlPageEditor, e: PointerEvent) => {
|
|
|
222
264
|
|
|
223
265
|
export function SelectionUI() {
|
|
224
266
|
return <selected-element data-element="selection"
|
|
225
|
-
data-edit={BindEditor.oneWay((e) => /
|
|
267
|
+
data-edit={BindEditor.oneWay((e) => /relative/i.test(e.selection.parentStyle.position)
|
|
268
|
+
&& /absolute|fixed/i.test(e.selection.currentStyle.position) ? "1" : null)}
|
|
226
269
|
event-pointerdown={BindEditor.event(eventPointerDown as any)}
|
|
227
270
|
style-left={BindEditor.oneWay((e) => e.selection.left)}
|
|
228
271
|
style-top={BindEditor.oneWay((e) => e.selection.top)}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import DISingleton from "@web-atoms/core/dist/di/DISingleton";
|
|
2
|
+
import FetchBuilder from "@web-atoms/core/dist/services/FetchBuilder";
|
|
3
|
+
import IPagedList from "@web-atoms/entity/dist/models/IPagedList";
|
|
4
|
+
|
|
5
|
+
export interface ISiteTemplate {
|
|
6
|
+
id: any;
|
|
7
|
+
tags: string[];
|
|
8
|
+
name: string;
|
|
9
|
+
host: string;
|
|
10
|
+
preview: string;
|
|
11
|
+
previewMobile: string;
|
|
12
|
+
template: string;
|
|
13
|
+
url: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@DISingleton()
|
|
17
|
+
export default class ToolService {
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
designs({ search, tags, start = 0, size = 50, cancelToken }) {
|
|
21
|
+
return FetchBuilder.get(`https://tools.esocialmail.com/social-mail/site/list/designs`)
|
|
22
|
+
.queries({
|
|
23
|
+
search,
|
|
24
|
+
tags,
|
|
25
|
+
start,
|
|
26
|
+
size
|
|
27
|
+
})
|
|
28
|
+
.cancelToken(cancelToken)
|
|
29
|
+
.asJson<IPagedList<ISiteTemplate>>();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
}
|
|
@@ -1,59 +1,33 @@
|
|
|
1
1
|
import FetchBuilder from "@web-atoms/core/dist/services/FetchBuilder";
|
|
2
2
|
import { CacheTTL } from "../../../common/cache/CacheTTL";
|
|
3
3
|
import { packageVersion } from "../../../common/PackageInfo";
|
|
4
|
-
import { Sql } from "../../../common/Sql";
|
|
5
|
-
import { ChannelEmail, IChannelEmail } from "../../../model/model";
|
|
6
4
|
import ToolSection, { IToolItem } from "../section/ToolSection";
|
|
5
|
+
import ToolService, { ISiteTemplate } from "../ToolService";
|
|
6
|
+
import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
|
|
7
7
|
|
|
8
8
|
const cacheVersion = packageVersion;
|
|
9
9
|
const cacheSeconds = CacheTTL.seconds.oneDay;
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
export default class BasicShapes extends ToolSection<
|
|
12
|
+
export default class BasicShapes extends ToolSection<ISiteTemplate> {
|
|
13
|
+
|
|
14
|
+
@InjectProperty
|
|
15
|
+
tools: ToolService;
|
|
13
16
|
|
|
14
17
|
get headerName() {
|
|
15
18
|
return "Shapes";
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
async searchItems({ start, search, cancelToken }) {
|
|
19
|
-
|
|
20
|
-
const shape = "shape";
|
|
21
|
-
let q = this.entityService.query(ChannelEmail, "libraryEmails")
|
|
22
|
-
.where({ contentTypes, shape }, (p) => (x) => x.email.attachments.some((e) =>
|
|
23
|
-
Sql.text.iLikeAny(e.contentType, p.contentTypes)
|
|
24
|
-
&& e.email.emailTags.some((t) => t.tag.parent.lowerCaseName === p.shape)
|
|
25
|
-
))
|
|
26
|
-
;
|
|
27
|
-
if(search) {
|
|
28
|
-
search += "%";
|
|
29
|
-
q = q.where({ search }, (p) => (x) => Sql.text.iLike(x.email.subject, p.search));
|
|
30
|
-
}
|
|
31
|
-
return q
|
|
32
|
-
.include((x) => [x.email.attachments, x.email.emailTags.forEach((t) => t.tag)])
|
|
33
|
-
.toPagedList({
|
|
34
|
-
start,
|
|
35
|
-
cancelToken,
|
|
36
|
-
size: 25,
|
|
37
|
-
cacheSeconds,
|
|
38
|
-
cacheVersion
|
|
39
|
-
});
|
|
22
|
+
return this.tools.designs({ search, tags: "Shape", start, cancelToken, size: 50 });
|
|
40
23
|
}
|
|
41
24
|
|
|
42
|
-
asToolItem(x:
|
|
43
|
-
|
|
44
|
-
const { email, emailID: id } = x;
|
|
45
|
-
const { attachments: files, subject: title } = email;
|
|
25
|
+
asToolItem(x: ISiteTemplate): IToolItem {
|
|
46
26
|
|
|
47
|
-
const
|
|
48
|
-
const { src, href } = this.getFileType("template.", ... files);
|
|
27
|
+
const { id, preview, name: title, template: templateUrl } = x;
|
|
49
28
|
|
|
50
29
|
const template = async () => {
|
|
51
|
-
|
|
52
|
-
const img = document.createElement("img");
|
|
53
|
-
img.src = src;
|
|
54
|
-
return img;
|
|
55
|
-
}
|
|
56
|
-
const text = await FetchBuilder.get(href).asText();
|
|
30
|
+
const text = await FetchBuilder.get(templateUrl).asText();
|
|
57
31
|
const parser = new DOMParser();
|
|
58
32
|
const d = parser.parseFromString(text, "text/html");
|
|
59
33
|
const t = d.body.querySelector("template");
|
|
@@ -64,10 +38,13 @@ export default class BasicShapes extends ToolSection<IChannelEmail> {
|
|
|
64
38
|
|
|
65
39
|
return {
|
|
66
40
|
title,
|
|
67
|
-
files,
|
|
41
|
+
files: [],
|
|
68
42
|
id,
|
|
69
43
|
copyAssets: true,
|
|
70
|
-
preview
|
|
44
|
+
preview: {
|
|
45
|
+
src: preview,
|
|
46
|
+
href: void 0
|
|
47
|
+
},
|
|
71
48
|
template
|
|
72
49
|
};
|
|
73
50
|
}
|
|
@@ -1,59 +1,33 @@
|
|
|
1
1
|
import FetchBuilder from "@web-atoms/core/dist/services/FetchBuilder";
|
|
2
2
|
import { CacheTTL } from "../../../common/cache/CacheTTL";
|
|
3
3
|
import { packageVersion } from "../../../common/PackageInfo";
|
|
4
|
-
import { Sql } from "../../../common/Sql";
|
|
5
|
-
import { ChannelEmail, IChannelEmail } from "../../../model/model";
|
|
6
4
|
import ToolSection, { IToolItem } from "../section/ToolSection";
|
|
5
|
+
import InjectProperty from "@web-atoms/core/dist/core/InjectProperty";
|
|
6
|
+
import ToolService, { ISiteTemplate } from "../ToolService";
|
|
7
7
|
|
|
8
8
|
const cacheVersion = packageVersion;
|
|
9
9
|
const cacheSeconds = CacheTTL.seconds.oneDay;
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
export default class Designs extends ToolSection<
|
|
12
|
+
export default class Designs extends ToolSection<ISiteTemplate> {
|
|
13
|
+
|
|
14
|
+
@InjectProperty
|
|
15
|
+
tools: ToolService;
|
|
13
16
|
|
|
14
17
|
get headerName() {
|
|
15
18
|
return "Designs";
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
async searchItems({ start, search, cancelToken }) {
|
|
19
|
-
|
|
20
|
-
const shape = "design";
|
|
21
|
-
let q = this.entityService.query(ChannelEmail, "libraryEmails")
|
|
22
|
-
.where({ contentTypes, shape }, (p) => (x) => x.email.attachments.some((e) =>
|
|
23
|
-
Sql.text.iLikeAny(e.contentType, p.contentTypes)
|
|
24
|
-
&& e.email.emailTags.some((t) => t.tag.lowerCaseName === p.shape)
|
|
25
|
-
))
|
|
26
|
-
;
|
|
27
|
-
if(search) {
|
|
28
|
-
search += "%";
|
|
29
|
-
q = q.where({ search }, (p) => (x) => Sql.text.iLike(x.email.subject, p.search));
|
|
30
|
-
}
|
|
31
|
-
return q
|
|
32
|
-
.include((x) => [x.email.attachments, x.email.emailTags.forEach((t) => t.tag)])
|
|
33
|
-
.toPagedList({
|
|
34
|
-
start,
|
|
35
|
-
cancelToken,
|
|
36
|
-
size: 25,
|
|
37
|
-
cacheSeconds,
|
|
38
|
-
cacheVersion
|
|
39
|
-
});
|
|
22
|
+
return this.tools.designs({ search, tags: "Shape", start, cancelToken, size: 50 });
|
|
40
23
|
}
|
|
41
24
|
|
|
42
|
-
asToolItem(x:
|
|
43
|
-
|
|
44
|
-
const { email, emailID: id } = x;
|
|
45
|
-
const { attachments: files, subject: title } = email;
|
|
25
|
+
asToolItem(x: ISiteTemplate): IToolItem {
|
|
46
26
|
|
|
47
|
-
const
|
|
48
|
-
const { src, href } = this.getFileType("template.", ... files);
|
|
27
|
+
const { id, preview, name: title, template: templateUrl } = x;
|
|
49
28
|
|
|
50
29
|
const template = async () => {
|
|
51
|
-
|
|
52
|
-
const img = document.createElement("img");
|
|
53
|
-
img.src = src;
|
|
54
|
-
return img;
|
|
55
|
-
}
|
|
56
|
-
const text = await FetchBuilder.get(href).asText();
|
|
30
|
+
const text = await FetchBuilder.get(templateUrl).asText();
|
|
57
31
|
const parser = new DOMParser();
|
|
58
32
|
const d = parser.parseFromString(text, "text/html");
|
|
59
33
|
const t = d.body.querySelector("template");
|
|
@@ -64,10 +38,13 @@ export default class Designs extends ToolSection<IChannelEmail> {
|
|
|
64
38
|
|
|
65
39
|
return {
|
|
66
40
|
title,
|
|
67
|
-
files,
|
|
41
|
+
files: [],
|
|
68
42
|
id,
|
|
69
43
|
copyAssets: true,
|
|
70
|
-
preview
|
|
44
|
+
preview: {
|
|
45
|
+
src: preview,
|
|
46
|
+
href: void 0
|
|
47
|
+
},
|
|
71
48
|
template
|
|
72
49
|
};
|
|
73
50
|
}
|