@concretecms/bedrock 1.3.7 → 1.4.0
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/.eslintrc.yml +2 -0
- package/assets/account/js/frontend/components/AvatarCropper.vue +159 -0
- package/assets/account/js/frontend.js +1 -1
- package/assets/account/scss/frontend/_frontend.scss +2 -0
- package/assets/account/scss/frontend/avatar/_avatar-cropper.scss +82 -0
- package/assets/account/scss/frontend/avatar/_avatar.scss +6 -0
- package/assets/bedrock/scss/_frontend.scss +0 -1
- package/assets/calendar/js/backend/duration.js +13 -13
- package/assets/calendar/js/vendor/fullcalendar.js +1 -0
- package/assets/cms/components/Announcement/Action/ExternalLinkAction.vue +25 -0
- package/assets/cms/components/Announcement/Action/GuideAction.vue +36 -0
- package/assets/cms/components/Announcement/Action/VideoAction.vue +31 -0
- package/assets/cms/components/Announcement/Broadcast.vue +63 -0
- package/assets/cms/components/Announcement/Button/ExternalLinkButton.vue +26 -0
- package/assets/cms/components/Announcement/Header/Header.vue +33 -0
- package/assets/cms/components/Announcement/Item/Item.vue +50 -0
- package/assets/cms/components/Announcement/Modal/Modal.vue +77 -0
- package/assets/cms/components/Announcement/Slide/CollectSiteInformationSlide.vue +61 -0
- package/assets/cms/components/Announcement/Slide/FeatureSlide.vue +81 -0
- package/assets/cms/components/Announcement/Slide/WelcomeSlide.vue +87 -0
- package/assets/cms/components/Help/Modal.vue +48 -0
- package/assets/cms/components/Image/ThumbnailEditor.vue +117 -0
- package/assets/cms/components/RunningProcessList.vue +6 -1
- package/assets/cms/components/customizer/FontFamilyPageCustomizerWidget.vue +27 -7
- package/assets/cms/components/file-manager/Chooser/FileManager.vue +0 -1
- package/assets/cms/components/file-manager/Chooser/FolderBookmark.vue +0 -1
- package/assets/cms/components/file-manager/Chooser.vue +1 -1
- package/assets/cms/components/form/ConcreteAjaxSelect.vue +173 -0
- package/assets/cms/components/form/ConcreteExpressEntrySelect.vue +74 -0
- package/assets/cms/components/form/ConcreteFileDirectoryInput.vue +28 -26
- package/assets/cms/components/form/ConcreteFileInput.vue +17 -5
- package/assets/cms/components/form/ConcreteGroupInput.vue +134 -0
- package/assets/cms/components/form/ConcreteLocaleSelect.vue +58 -0
- package/assets/cms/components/form/ConcreteOptionSelect.vue +92 -0
- package/assets/cms/components/form/ConcretePageSelect.vue +67 -0
- package/assets/cms/components/form/ConcreteSelect.vue +75 -0
- package/assets/cms/components/form/ConcreteThemeColorInput.vue +19 -14
- package/assets/cms/components/form/ConcreteUserInput.vue +24 -4
- package/assets/cms/components/form/ConcreteUserSelect.vue +126 -0
- package/assets/cms/components/form/IconSelector.vue +14 -5
- package/assets/cms/components/form/PasswordInput.vue +141 -24
- package/assets/cms/components/groups/Chooser.vue +6 -5
- package/assets/cms/components/index.js +24 -0
- package/assets/cms/components/toolbar/ConcreteToolbarSiteList.vue +62 -0
- package/assets/cms/components/user/Chooser/Search.vue +5 -0
- package/assets/cms/components/user/Chooser/Users.vue +6 -2
- package/assets/cms/components/user/Chooser.vue +9 -3
- package/assets/cms/js/ajax-request/base.js +13 -4
- package/assets/cms/js/alert.js +2 -1
- package/assets/cms/js/base.js +3 -10
- package/assets/cms/js/edit-mode/area.js +0 -35
- package/assets/cms/js/edit-mode/block.js +27 -0
- package/assets/cms/js/edit-mode/containerblock.js +33 -3
- package/assets/cms/js/edit-mode/editmode.js +12 -0
- package/assets/cms/js/edit-mode/layout.js +56 -0
- package/assets/cms/js/edit-mode/style-customizer/style-customizer.js +0 -1
- package/assets/cms/js/file-manager/uploader.js +30 -206
- package/assets/cms/js/help/help.js +11 -8
- package/assets/cms/js/in-context-menu.js +5 -0
- package/assets/cms/js/jquery-vue.js +22 -0
- package/assets/cms/js/legacy-dialog.js +74 -65
- package/assets/cms/js/modal.js +73 -0
- package/assets/cms/js/panels.js +8 -0
- package/assets/cms/js/search/base.js +0 -18
- package/assets/cms/js/search/field-selector.js +6 -14
- package/assets/cms/js/select-combo-box.js +2 -0
- package/assets/cms/js/sitemap/sitemap-selector.js +2 -2
- package/assets/cms/js/sitemap/sitemap.js +15 -20
- package/assets/cms/js/toolbar.js +25 -2
- package/assets/cms/js/tree.js +7 -7
- package/assets/cms/js/users/group-manager.js +55 -0
- package/assets/cms/js/users/user-manager.js +2 -1
- package/assets/cms/js/users.js +1 -0
- package/assets/cms/js/vue/Manager.js +6 -3
- package/assets/cms/scss/_base.scss +2 -8
- package/assets/cms/scss/_cards.scss +7 -0
- package/assets/cms/scss/_file-manager.scss +1 -0
- package/assets/cms/scss/_file-uploader.scss +13 -3
- package/assets/cms/scss/_help.scss +11 -2
- package/assets/cms/scss/_item-selector.scss +10 -0
- package/assets/cms/scss/_layouts.scss +16 -0
- package/assets/cms/scss/_page-areas.scss +517 -245
- package/assets/cms/scss/_popover.scss +5 -0
- package/assets/cms/scss/_select-combo-box.scss +18 -0
- package/assets/cms/scss/_toolbar.scss +5 -14
- package/assets/cms/scss/_transitions.scss +13 -0
- package/assets/cms/scss/_variables.scss +18 -7
- package/assets/cms/scss/bootstrap/_reboot-tags.scss +17 -32
- package/assets/cms/scss/bootstrap/_reboot.scss +17 -7
- package/assets/cms/scss/bootstrap/_root-modified.scss +41 -20
- package/assets/cms/scss/file-manager/_thumbnail-image-editor.scss +45 -0
- package/assets/cms/scss/panels/_help.scss +0 -10
- package/assets/staging/scss/frontend/_frontend.scss +12 -0
- package/assets/staging/scss/frontend.scss +4 -0
- package/package.json +9 -9
- package/assets/account/js/frontend/components/Avatar/Avatar.js +0 -270
- package/assets/account/js/frontend/components/Avatar/Avatar.scss +0 -17
- package/assets/account/js/frontend/components/Avatar/Avatar.vue +0 -18
- package/assets/account/js/frontend/components/Avatar/Cropper.js +0 -202
- package/assets/account/js/frontend/components/Avatar/Cropper.scss +0 -136
- package/assets/account/js/frontend/components/Avatar/Cropper.vue +0 -40
- package/assets/bedrock/scss/_theme-grid.scss +0 -7
- package/assets/cms/js/edit-mode/style-customizer/inline-toolbar.js +0 -279
- package/assets/cms/js/modifiable-ajax-bootstrap-select.js +0 -78
- package/assets/cms/js/modifiable-bootstrap-select.js +0 -112
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
import interact from 'interactjs'
|
|
2
|
-
|
|
3
|
-
export default {
|
|
4
|
-
|
|
5
|
-
// The properties available for our parent to edit
|
|
6
|
-
props: {
|
|
7
|
-
img: String,
|
|
8
|
-
imageHeight: Number,
|
|
9
|
-
imageWidth: Number,
|
|
10
|
-
cropperWidth: Number,
|
|
11
|
-
cropperHeight: Number,
|
|
12
|
-
shadow: Boolean
|
|
13
|
-
},
|
|
14
|
-
|
|
15
|
-
// Our state
|
|
16
|
-
data() {
|
|
17
|
-
return {
|
|
18
|
-
x: 0,
|
|
19
|
-
y: 0,
|
|
20
|
-
adjX: 0,
|
|
21
|
-
adjY: 0,
|
|
22
|
-
resizeHeight: 0,
|
|
23
|
-
resizeWidth: 0,
|
|
24
|
-
viewport: null,
|
|
25
|
-
outer: null
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Prepare to render by setting up our viewport
|
|
31
|
-
*/
|
|
32
|
-
beforeUpdate() {
|
|
33
|
-
if (this.viewport) {
|
|
34
|
-
this.viewport.x = this.x
|
|
35
|
-
this.viewport.y = this.y
|
|
36
|
-
this.viewport.adjX = this.adjX
|
|
37
|
-
this.viewport.adjY = this.adjY
|
|
38
|
-
this.viewport.resizeWidth = this.resizeWidth
|
|
39
|
-
this.viewport.resizeHeight = this.resizeHeight
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Once we are attached
|
|
45
|
-
*/
|
|
46
|
-
mounted() {
|
|
47
|
-
if (this.shadow === true) {
|
|
48
|
-
this.guessPosition()
|
|
49
|
-
this.setupResizing()
|
|
50
|
-
this.setupDragging()
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Emit an event
|
|
54
|
-
this.$emit('mount', this)
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
methods: {
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
*/
|
|
61
|
-
guessPosition() {
|
|
62
|
-
const adjustedHeight = this.adjustedDimensions(this.imageWidth, this.imageHeight)
|
|
63
|
-
let adjX = 0; let adjY = 0
|
|
64
|
-
|
|
65
|
-
this.resizeHeight = adjustedHeight.height
|
|
66
|
-
this.resizeWidth = adjustedHeight.width
|
|
67
|
-
|
|
68
|
-
if (this.resizeWidth > this.cropperWidth) {
|
|
69
|
-
adjX = -Math.round((this.resizeWidth - this.cropperWidth) / 2)
|
|
70
|
-
}
|
|
71
|
-
if (this.resizeHeight > this.cropperHeight) {
|
|
72
|
-
adjY = -Math.round((this.resizeHeight - this.cropperHeight) / 2)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const coords = this.adjustedCoordinates(adjX, adjY, this.resizeWidth, this.resizeHeight)
|
|
76
|
-
this.x += coords.x
|
|
77
|
-
this.y += coords.y
|
|
78
|
-
},
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Make the avatar resizable
|
|
82
|
-
*/
|
|
83
|
-
setupResizing() {
|
|
84
|
-
const me = this
|
|
85
|
-
this.interact = interact(this.$refs.image)
|
|
86
|
-
.resizable({
|
|
87
|
-
preserveAspectRatio: true,
|
|
88
|
-
edges: { left: true, right: true, bottom: true, top: true }
|
|
89
|
-
})
|
|
90
|
-
.on('resizemove', function (event) {
|
|
91
|
-
return me.handleResizeMove(event)
|
|
92
|
-
})
|
|
93
|
-
},
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Handle dimensions adjusting
|
|
97
|
-
* @param int width
|
|
98
|
-
* @param int height
|
|
99
|
-
*/
|
|
100
|
-
adjustedDimensions(width, height) {
|
|
101
|
-
let bestFactor = 1
|
|
102
|
-
const maxFactor = Math.sqrt(Math.min(width, height))
|
|
103
|
-
|
|
104
|
-
// Find the best factor to downsize by
|
|
105
|
-
for (let i = 2; i <= maxFactor; i++) {
|
|
106
|
-
if ((width / i) % 2 === 0 && (height / i) % 2 === 0) {
|
|
107
|
-
if ((width / i) > this.cropperWidth && (height / i) > this.cropperHeight) {
|
|
108
|
-
bestFactor = i
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return {
|
|
114
|
-
width: width / bestFactor,
|
|
115
|
-
height: height / bestFactor,
|
|
116
|
-
factor: bestFactor,
|
|
117
|
-
adjusted: bestFactor !== 1
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Handle coordinates adjusting
|
|
123
|
-
* @param int x
|
|
124
|
-
* @param int y
|
|
125
|
-
* @param int width
|
|
126
|
-
* @param int height
|
|
127
|
-
*/
|
|
128
|
-
adjustedCoordinates(x, y, width, height) {
|
|
129
|
-
const renderedX = this.x + x
|
|
130
|
-
const renderedY = this.y + y
|
|
131
|
-
const coords = {
|
|
132
|
-
min: {
|
|
133
|
-
x: -1 * (width - this.cropperWidth),
|
|
134
|
-
y: -1 * (height - this.cropperHeight)
|
|
135
|
-
},
|
|
136
|
-
max: {
|
|
137
|
-
x: 0,
|
|
138
|
-
y: 0
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
const adjustedX = Math.max(coords.min.x, Math.min(coords.max.x, renderedX)) - this.x
|
|
142
|
-
const adjustedY = Math.max(coords.min.y, Math.min(coords.max.y, renderedY)) - this.y
|
|
143
|
-
|
|
144
|
-
return {
|
|
145
|
-
x: adjustedX,
|
|
146
|
-
y: adjustedY,
|
|
147
|
-
adjusted: adjustedY !== y || adjustedX !== x
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Attach a parent Avatar if we're a shadow
|
|
153
|
-
* @param Avatar viewport
|
|
154
|
-
*/
|
|
155
|
-
setViewport(viewport) {
|
|
156
|
-
this.viewport = viewport
|
|
157
|
-
viewport.outer = this
|
|
158
|
-
viewport.setupDragging()
|
|
159
|
-
},
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Setup interactjs dragging
|
|
163
|
-
*/
|
|
164
|
-
setupDragging() {
|
|
165
|
-
const me = this
|
|
166
|
-
this.interact = interact(this.$refs.image)
|
|
167
|
-
.draggable({
|
|
168
|
-
intertia: false,
|
|
169
|
-
restrict: false,
|
|
170
|
-
|
|
171
|
-
// Send on move events to component
|
|
172
|
-
onmove: function (e) {
|
|
173
|
-
if (me.outer) {
|
|
174
|
-
return me.outer.handleDragMove(e)
|
|
175
|
-
}
|
|
176
|
-
return me.handleDragMove(e)
|
|
177
|
-
},
|
|
178
|
-
|
|
179
|
-
// Send onstart events to component
|
|
180
|
-
onstart: function (e) {
|
|
181
|
-
if (me.outer) {
|
|
182
|
-
return me.outer.handleDragStart(e)
|
|
183
|
-
}
|
|
184
|
-
return me.handleDragStart(e)
|
|
185
|
-
},
|
|
186
|
-
|
|
187
|
-
// Send onend events to component
|
|
188
|
-
onend: function (e) {
|
|
189
|
-
if (me.outer) {
|
|
190
|
-
return me.outer.handleDragEnd(e)
|
|
191
|
-
}
|
|
192
|
-
return me.handleDragEnd(e)
|
|
193
|
-
}
|
|
194
|
-
})
|
|
195
|
-
},
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Handle interactjs drag event
|
|
199
|
-
* @param event
|
|
200
|
-
*/
|
|
201
|
-
handleDragMove(event) {
|
|
202
|
-
const coords = this.adjustedCoordinates(
|
|
203
|
-
event.pageX - this.startEvent.pageX, event.pageY - this.startEvent.pageY,
|
|
204
|
-
this.resizeWidth, this.resizeHeight)
|
|
205
|
-
|
|
206
|
-
this.adjX = coords.x
|
|
207
|
-
this.adjY = coords.y
|
|
208
|
-
},
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Handle interactjs starting to drag
|
|
212
|
-
* @param Event event
|
|
213
|
-
*/
|
|
214
|
-
handleDragStart(event) {
|
|
215
|
-
this.startEvent = event
|
|
216
|
-
this.coords = {
|
|
217
|
-
min: {
|
|
218
|
-
x: -this.resizeWidth + this.cropperWidth,
|
|
219
|
-
y: -this.resizeHeight + this.cropperHeight
|
|
220
|
-
},
|
|
221
|
-
max: {
|
|
222
|
-
x: 0,
|
|
223
|
-
y: 0
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
},
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Handle interactjs stopping dragging
|
|
230
|
-
* @param event
|
|
231
|
-
*/
|
|
232
|
-
handleDragEnd(event) {
|
|
233
|
-
this.x += this.adjX
|
|
234
|
-
this.y += this.adjY
|
|
235
|
-
this.adjX = 0
|
|
236
|
-
this.adjY = 0
|
|
237
|
-
},
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* Handle resizing
|
|
241
|
-
* @param event
|
|
242
|
-
*/
|
|
243
|
-
handleResizeMove(event) {
|
|
244
|
-
const coordinates = this.adjustedCoordinates(
|
|
245
|
-
event.deltaRect.left, event.deltaRect.top,
|
|
246
|
-
event.rect.width, event.rect.height)
|
|
247
|
-
|
|
248
|
-
// Don't resize too small
|
|
249
|
-
if (event.rect.width < this.cropperWidth ||
|
|
250
|
-
event.rect.height < this.cropperHeight) {
|
|
251
|
-
// If the image is square
|
|
252
|
-
if (this.imageWidth === this.imageHeight) {
|
|
253
|
-
this.resizeWidth = this.cropperWidth
|
|
254
|
-
this.resizeHeight = this.cropperHeight
|
|
255
|
-
this.x = 0
|
|
256
|
-
this.y = 0
|
|
257
|
-
}
|
|
258
|
-
return
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
// update the element's style
|
|
262
|
-
this.resizeWidth = Math.max(event.rect.width, this.cropperWidth)
|
|
263
|
-
this.resizeHeight = Math.max(event.rect.height, this.cropperHeight)
|
|
264
|
-
|
|
265
|
-
// translate when resizing from top or left edges
|
|
266
|
-
this.x += coordinates.x
|
|
267
|
-
this.y += coordinates.y
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
img {
|
|
2
|
-
left: 0;
|
|
3
|
-
max-width: inherit;
|
|
4
|
-
min-width: inherit;
|
|
5
|
-
top: 0;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.shadow {
|
|
9
|
-
box-shadow: 0 0 10px black;
|
|
10
|
-
box-sizing: border-box;
|
|
11
|
-
left: 1px;
|
|
12
|
-
opacity: 0.3;
|
|
13
|
-
outline: solid 1px #333;
|
|
14
|
-
position: absolute;
|
|
15
|
-
top: 1px;
|
|
16
|
-
z-index: 1;
|
|
17
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<img ref='image'
|
|
4
|
-
:src="img"
|
|
5
|
-
:width="imageWidth" :height="imageHeight"
|
|
6
|
-
:class="{
|
|
7
|
-
shadow: shadow
|
|
8
|
-
}"
|
|
9
|
-
:style="{
|
|
10
|
-
width: resizeWidth + 'px',
|
|
11
|
-
height: resizeHeight + 'px',
|
|
12
|
-
transform: 'translate(' + (x + adjX) + 'px, ' + (y + adjY) + 'px)',
|
|
13
|
-
}"/>
|
|
14
|
-
</div>
|
|
15
|
-
</template>
|
|
16
|
-
|
|
17
|
-
<style src='./Avatar.scss' lang="scss" scoped></style>
|
|
18
|
-
<script src='./Avatar.js'></script>
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import Dropzone from 'dropzone'
|
|
2
|
-
import Avatar from './Avatar.vue'
|
|
3
|
-
|
|
4
|
-
// Disable dropzone discovery
|
|
5
|
-
Dropzone.autoDiscover = false
|
|
6
|
-
|
|
7
|
-
export default {
|
|
8
|
-
|
|
9
|
-
// Properties tied to our parent
|
|
10
|
-
props: {
|
|
11
|
-
width: Number,
|
|
12
|
-
height: Number,
|
|
13
|
-
uploadurl: String,
|
|
14
|
-
src: String,
|
|
15
|
-
cancelConfirmText: {
|
|
16
|
-
type: String,
|
|
17
|
-
default: 'Are you sure you want to quit?'
|
|
18
|
-
},
|
|
19
|
-
canceledText: {
|
|
20
|
-
type: String,
|
|
21
|
-
default: 'Upload canceled.'
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
// Our internal state
|
|
26
|
-
data: function () {
|
|
27
|
-
return {
|
|
28
|
-
img: null,
|
|
29
|
-
x: 10,
|
|
30
|
-
y: 5,
|
|
31
|
-
cropWidth: 0,
|
|
32
|
-
cropHeight: 0,
|
|
33
|
-
imageHeight: 0,
|
|
34
|
-
imageWidth: 0,
|
|
35
|
-
saving: false,
|
|
36
|
-
currentimage: null,
|
|
37
|
-
hasError: false,
|
|
38
|
-
errorMessage: ''
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Handle mounting to our element
|
|
44
|
-
*/
|
|
45
|
-
mounted() {
|
|
46
|
-
// Attach the current image
|
|
47
|
-
this.currentimage = this.src
|
|
48
|
-
|
|
49
|
-
// Setup Uploading
|
|
50
|
-
this.setupUploading()
|
|
51
|
-
},
|
|
52
|
-
methods: {
|
|
53
|
-
setError(error) {
|
|
54
|
-
this.hasError = true
|
|
55
|
-
this.errorMessage = error
|
|
56
|
-
},
|
|
57
|
-
clearError() {
|
|
58
|
-
this.hasError = false
|
|
59
|
-
this.errorMessage = ''
|
|
60
|
-
},
|
|
61
|
-
/**
|
|
62
|
-
* Setup dropzone for uploading
|
|
63
|
-
*/
|
|
64
|
-
setupUploading() {
|
|
65
|
-
if (this.dropzone) {
|
|
66
|
-
return
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const component = this
|
|
70
|
-
this.dropzone = new Dropzone(this.$refs.dropzone, {
|
|
71
|
-
url: this.uploadurl,
|
|
72
|
-
maxFiles: 1,
|
|
73
|
-
previewTemplate: '<span></span>',
|
|
74
|
-
transformFileSync: false,
|
|
75
|
-
|
|
76
|
-
// Accept uploaded files from user
|
|
77
|
-
accept(file, done) {
|
|
78
|
-
component.file = file
|
|
79
|
-
component.done = done
|
|
80
|
-
},
|
|
81
|
-
|
|
82
|
-
// Give the component a chance to finalize the file
|
|
83
|
-
transformFile(file, done) {
|
|
84
|
-
return component.finalize(file, done)
|
|
85
|
-
},
|
|
86
|
-
|
|
87
|
-
// Initialize dropzone
|
|
88
|
-
init() {
|
|
89
|
-
// Capture thumbnail details
|
|
90
|
-
this.on('thumbnail', function () {
|
|
91
|
-
component.img = component.file.dataURL
|
|
92
|
-
component.imageWidth = component.file.width
|
|
93
|
-
component.imageHeight = component.file.height
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
this.on('success', function(event, data) {
|
|
97
|
-
if (!component.hasError) {
|
|
98
|
-
component.currentimage = data.avatar
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
this.on('error', function (event, data) {
|
|
103
|
-
component.setError(typeof data === 'string' ? data : data.message)
|
|
104
|
-
component.currentimage = component.src
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
this.on('complete', function() {
|
|
108
|
-
component.saving = false
|
|
109
|
-
component.img = null
|
|
110
|
-
component.dropzone.destroy()
|
|
111
|
-
component.dropzone = null
|
|
112
|
-
|
|
113
|
-
setTimeout(function () {
|
|
114
|
-
component.setupUploading()
|
|
115
|
-
}, 0)
|
|
116
|
-
})
|
|
117
|
-
},
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Request full size thumbnails
|
|
121
|
-
* @param file
|
|
122
|
-
* @param int width
|
|
123
|
-
* @param int height
|
|
124
|
-
* @returns {{int srcWidth, int srcHeight, int trgWidth, int trgHeight}}
|
|
125
|
-
*/
|
|
126
|
-
resize(file, width, height) {
|
|
127
|
-
return {
|
|
128
|
-
srcWidth: file.width,
|
|
129
|
-
srcHeight: file.height,
|
|
130
|
-
trgWidth: file.width,
|
|
131
|
-
trgHeight: file.height
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
})
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Handle finalizing a user provided image.
|
|
139
|
-
* This is where we actually do the cropping and rendering.
|
|
140
|
-
*
|
|
141
|
-
* @param file
|
|
142
|
-
* @param bool done
|
|
143
|
-
* @returns {*}
|
|
144
|
-
*/
|
|
145
|
-
finalize(file, done) {
|
|
146
|
-
const canvas = document.createElement('canvas')
|
|
147
|
-
const ctx = canvas.getContext('2d')
|
|
148
|
-
const img = new Image()
|
|
149
|
-
|
|
150
|
-
img.src = file.dataURL
|
|
151
|
-
|
|
152
|
-
canvas.width = this.width
|
|
153
|
-
canvas.height = this.height
|
|
154
|
-
|
|
155
|
-
// Draw the image cropped
|
|
156
|
-
ctx.drawImage(
|
|
157
|
-
img, this.$refs.image.x, this.$refs.image.y,
|
|
158
|
-
this.$refs.image.resizeWidth, this.$refs.image.resizeHeight)
|
|
159
|
-
|
|
160
|
-
this.saving = true
|
|
161
|
-
// Complete the upload
|
|
162
|
-
const data = canvas.toDataURL()
|
|
163
|
-
const result = done(Dropzone.dataURItoBlob(data))
|
|
164
|
-
|
|
165
|
-
this.currentimage = data
|
|
166
|
-
return result
|
|
167
|
-
},
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Attach our shadow and our image together
|
|
171
|
-
*/
|
|
172
|
-
attachShadow() {
|
|
173
|
-
// Attach the shadow
|
|
174
|
-
this.$refs.shadow.setViewport(this.$refs.image)
|
|
175
|
-
},
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Handle checkmark click
|
|
179
|
-
*/
|
|
180
|
-
handleOkay() {
|
|
181
|
-
this.done.call(this.dropzone)
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Handle x mark click
|
|
186
|
-
*/
|
|
187
|
-
handleCancel() {
|
|
188
|
-
if (window.confirm(this.cancelConfirmText)) {
|
|
189
|
-
this.done.call(this.dropzone, this.canceledText)
|
|
190
|
-
this.img = null
|
|
191
|
-
this.saving = false
|
|
192
|
-
this.dropzone.destroy()
|
|
193
|
-
this.clearError()
|
|
194
|
-
this.dropzone = null
|
|
195
|
-
this.setupUploading()
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
},
|
|
199
|
-
components: {
|
|
200
|
-
Avatar
|
|
201
|
-
}
|
|
202
|
-
}
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
/* stylelint-disable property-no-vendor-prefix, property-no-unkown */
|
|
2
|
-
.ccm-avatar-creator-container {
|
|
3
|
-
position: relative;
|
|
4
|
-
|
|
5
|
-
.ccm-avatar-actions {
|
|
6
|
-
position: absolute;
|
|
7
|
-
z-index: 20000;
|
|
8
|
-
|
|
9
|
-
> a {
|
|
10
|
-
display: inline-block;
|
|
11
|
-
font-weight: 600;
|
|
12
|
-
opacity: 0.8;
|
|
13
|
-
text-align: center;
|
|
14
|
-
text-decoration: none;
|
|
15
|
-
transition: all 0.5s;
|
|
16
|
-
width: 50%;
|
|
17
|
-
|
|
18
|
-
&:hover {
|
|
19
|
-
opacity: 1;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
&::before {
|
|
23
|
-
font-family: 'Font Awesome 5 Free';
|
|
24
|
-
font-size: 16px;
|
|
25
|
-
text-align: center;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
&.ccm-avatar-cancel {
|
|
29
|
-
color: #ff4136;
|
|
30
|
-
float: right;
|
|
31
|
-
|
|
32
|
-
&::before {
|
|
33
|
-
content: '\f00d';
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
&.ccm-avatar-okay {
|
|
38
|
-
color: #3d9970;
|
|
39
|
-
|
|
40
|
-
&::before {
|
|
41
|
-
content: '\f00c';
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.ccm-avatar-creator {
|
|
48
|
-
border: solid 1px #999;
|
|
49
|
-
overflow: hidden;
|
|
50
|
-
position: relative;
|
|
51
|
-
transition: all 0.3s;
|
|
52
|
-
z-index: 10000;
|
|
53
|
-
|
|
54
|
-
> img.ccm-avatar-current {
|
|
55
|
-
display: inline;
|
|
56
|
-
height: 100%;
|
|
57
|
-
width: 100%;
|
|
58
|
-
z-index: 998;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
> div.saving {
|
|
62
|
-
background: rgba(127, 219, 255, 0.5);
|
|
63
|
-
color: #111;
|
|
64
|
-
font-size: 16px;
|
|
65
|
-
font-weight: bolder;
|
|
66
|
-
height: 100%;
|
|
67
|
-
left: 0;
|
|
68
|
-
position: absolute;
|
|
69
|
-
text-align: center;
|
|
70
|
-
top: 0;
|
|
71
|
-
width: 100%;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
&::before {
|
|
75
|
-
background-color: rgba(238, 238, 238, 0.8);
|
|
76
|
-
color: #3d9970;
|
|
77
|
-
content: '\f303';
|
|
78
|
-
display: block;
|
|
79
|
-
font-family: 'Font Awesome 5 Free';
|
|
80
|
-
font-weight: 600;
|
|
81
|
-
height: 100%;
|
|
82
|
-
line-height: 0%;
|
|
83
|
-
margin: 0 auto;
|
|
84
|
-
opacity: 0;
|
|
85
|
-
padding-top: 50%;
|
|
86
|
-
position: absolute;
|
|
87
|
-
text-align: center;
|
|
88
|
-
transition: all 0.3s;
|
|
89
|
-
vertical-align: middle;
|
|
90
|
-
width: 100%;
|
|
91
|
-
z-index: 999;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
&.dz-started {
|
|
95
|
-
&::before {
|
|
96
|
-
-webkit-animation: pulse 1s infinite;
|
|
97
|
-
animation: pulse 1s infinite;
|
|
98
|
-
opacity: 1;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
@keyframes pulse {
|
|
103
|
-
0% {
|
|
104
|
-
transform: scale(1);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
50% {
|
|
108
|
-
transform: scale(1.3);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
100% {
|
|
112
|
-
transform: scale(1);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
&.editing {
|
|
117
|
-
&::before {
|
|
118
|
-
display: none;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
&.dz-clickable {
|
|
123
|
-
cursor: 'pointer';
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
&.dz-clickable:hover,
|
|
127
|
-
&.dz-drag-hover {
|
|
128
|
-
border-color: #3d9970;
|
|
129
|
-
box-shadow: 0 0 20px -10px #2ecc40;
|
|
130
|
-
|
|
131
|
-
&::before {
|
|
132
|
-
opacity: 1;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="ccm-avatar-creator-container">
|
|
3
|
-
<avatar ref="shadow" v-if="img !== null"
|
|
4
|
-
@mount="attachShadow"
|
|
5
|
-
:shadow="true"
|
|
6
|
-
:img="img"
|
|
7
|
-
:imageHeight="imageHeight"
|
|
8
|
-
:imageWidth="imageWidth"
|
|
9
|
-
:cropperWidth="width"
|
|
10
|
-
:cropperHeight="height" />
|
|
11
|
-
<div ref='dropzone'
|
|
12
|
-
class="ccm-avatar-creator"
|
|
13
|
-
:style="{width: width + 'px', height: height + 'px' }"
|
|
14
|
-
:class="{editing: img !== null}">
|
|
15
|
-
<avatar ref="image" v-if="img"
|
|
16
|
-
:img="img"
|
|
17
|
-
:imageHeight="imageHeight"
|
|
18
|
-
:imageWidth="imageWidth"
|
|
19
|
-
:cropperWidth="width"
|
|
20
|
-
:cropperHeight="height" />
|
|
21
|
-
<img class="ccm-avatar-current" v-if="!img" :src="currentimage"/>
|
|
22
|
-
<div class="saving"
|
|
23
|
-
v-if="saving"
|
|
24
|
-
:style="{lineHeight: height + 'px' }">
|
|
25
|
-
<i class="fa fa-spin fa-spinner fa-circle-o-notch"></i>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
<div class="ccm-avatar-actions" v-if="img">
|
|
29
|
-
<a class="ccm-avatar-okay" :style="{width: width / 2 + 'px'}" @click="handleOkay"></a>
|
|
30
|
-
<a class="ccm-avatar-cancel" :style="{width: width / 2 + 'px'}" @click="handleCancel"></a>
|
|
31
|
-
</div>
|
|
32
|
-
<canvas ref="canvas" style="height: 0;"></canvas>
|
|
33
|
-
<div v-if="hasError" class="alert alert-danger">
|
|
34
|
-
{{errorMessage}}
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
</template>
|
|
38
|
-
|
|
39
|
-
<script src='./Cropper.js'></script>
|
|
40
|
-
<style src='./Cropper.scss' lang="scss" scoped></style>
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
// This file ensures that the layout tools work with this theme grid
|
|
2
|
-
div#ccm-theme-grid-temp,
|
|
3
|
-
div#ccm-theme-grid-edit-mode-row-wrapper {
|
|
4
|
-
div.row {
|
|
5
|
-
position: relative; // This is necessary in order for the javascript to correctly use jquery position() calls
|
|
6
|
-
}
|
|
7
|
-
}
|