Skip to content

Commit 2205517

Browse files
authored
Merge pull request #18 from cybtachyon/hotfix/20200315-image-upload
20200315: Resolves issues with image upload dialog
2 parents 2f945e1 + 0ecc582 commit 2205517

File tree

5 files changed

+178
-238
lines changed

5 files changed

+178
-238
lines changed

js/DrupalImageEditor.es6.js

Lines changed: 92 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,179 +1,149 @@
1+
/*globals Drupal:false */
12
/*globals JSONEditor:false */
3+
/*globals jQuery:false */
24
/**
35
* @file DrupalImageEditor class.
46
*
57
* @external Drupal
68
*
79
* @external JSONEditor
10+
*
11+
* @external jQuery
812
*/
913

10-
export var DrupalImageEditor = JSONEditor.AbstractEditor.extend({
11-
getNumColumns: function () {
14+
export const DrupalImageEditor = JSONEditor.AbstractEditor.extend({
15+
getNumColumns: function() {
1216
return 4;
1317
},
14-
15-
build: function () {
18+
build: function() {
1619
this.title = this.header = this.label = this.theme.getFormInputLabel(this.getTitle(), this.isRequired());
20+
21+
// Editor options.
22+
// @todo Replace JSONEditor.defaults with this.defaults.
23+
this.options = jQuery.extend({}, {
24+
'title': 'Browse',
25+
'icon': '',
26+
'image_url': '/'
27+
}, JSONEditor.defaults.options.drupal_image || {}, this.options.drupal_image || {});
28+
1729
// Don't show uploader if this is readonly
18-
if (!this.schema.readOnly && !this.schema.readonly) {
19-
this.urlfield = this.theme.getFormInputField('text');
20-
let media_library_opener_parameters = {
21-
field_widget_id: this.urlfield.id
22-
};
23-
let opener_encoded = encodeURIComponent(JSON.stringify(media_library_opener_parameters));
24-
this.urlfield.addEventListener('change', function (e) {
30+
if(!this.schema.readOnly && !this.schema.readonly) {
31+
this.input = this.theme.getFormInputField('text');
32+
this.button = this.getButton(this.path + '-media', 'upload', Drupal.t('Select/Upload Media'));
33+
// @todo: Add support for multiple file/image URL editors.
34+
const media_library_settings = 'media_library_opener_id=patternkit.opener.jsonlibrary' +
35+
'&' + encodeURIComponent('media_library_allowed_types[0]') + '=image' +
36+
'&media_library_selected_type=image' +
37+
'&media_library_remaining=1' +
38+
'&' + encodeURIComponent('media_library_opener_parameters[field_widget_id]') + '=' + this.path;
39+
40+
this.input.addEventListener('change', (e) => {
2541
e.preventDefault();
2642
e.stopPropagation();
27-
Drupal.dialog(jQuery('<div>', {id: 'patternkit_jsonlibrary_image_dialog'})
28-
.append(jQuery('<span>', {id: 'patternkit_image_dialog_loading'})), {
29-
title: Drupal.t('Choose Image'),
30-
width: 900,
31-
height: 900
32-
}).showModal();
33-
Drupal.ajax({
34-
url: settings.imageUrl + "&media_library_opener_parameters=" + opener_encoded,
35-
base: 'patternkit_jsonlibrary_image_dialog',
36-
wrapper: 'patternkit_image_dialog_loading'
37-
}).execute({});
43+
this.setValue(e.target.value);
44+
});
45+
this.button.addEventListener('click', (e) => {
46+
e.preventDefault();
47+
e.stopPropagation();
48+
49+
// @see /core/misc/dialog/dialog.ajax.es6.js
50+
let $dialog = jQuery('#drupal-modal');
51+
if (!$dialog.length) {
52+
// Create the element if needed.
53+
$dialog = jQuery(
54+
`<div id="drupal-modal" class="ui-front"/>`,
55+
).appendTo('body');
56+
}
57+
this.dialog = Drupal.dialog($dialog.append(jQuery('<span>', {id: 'patternkit_image_dialog_loading'})), { title: Drupal.t('Choose Image'), width: 900, height: 900 }).showModal();
58+
Drupal.ajax({ url: this.options.image_url + '?' + media_library_settings, base: 'drupal-modal', wrapper: 'patternkit_image_dialog_loading' }).execute();
3859
});
3960
}
40-
let description = this.schema.description || '';
61+
62+
const description = this.schema.description || '';
63+
4164
this.preview = this.theme.getFormInputDescription(description);
4265
this.container.appendChild(this.preview);
43-
this.control = this.theme.getFormControl(this.label, this.urlfield || this.input, this.preview);
66+
67+
this.control = this.theme.getFormControl(this.label, this.input, this.preview);
4468
this.container.appendChild(this.control);
45-
window.requestAnimationFrame(() => {
46-
if (this.value) {
47-
let img = document.createElement('img');
48-
img.style.maxWidth = '100%';
49-
img.style.maxHeight = '100px';
50-
img.onload = (event) => {
51-
this.preview.appendChild(img);
52-
};
53-
img.onerror = (error) => {
54-
console.error('upload error', error);
55-
};
56-
img.src = this.container.querySelector('a').href;
57-
}
58-
});
59-
},
6069

61-
refreshPreview: function() {
62-
if (this.last_preview === this.preview_value) {
63-
return;
64-
}
65-
this.last_preview = this.preview_value;
66-
this.preview.innerHTML = '';
67-
if (!this.preview_value) {
68-
return;
69-
}
70-
let mime = this.preview_value.match(/^data:([^;,]+)[;,]/);
71-
if (mime) {
72-
mime = mime[1];
70+
if (this.button) {
71+
this.container.appendChild(this.button);
7372
}
74-
else {
75-
mime = 'unknown';
76-
}
77-
let file = this.urlfield.files[0];
78-
this.preview.innerHTML = '<strong>Type:</strong> ' + mime + ', <strong>Size:</strong> ' + file.size + ' bytes';
79-
if (mime.substr(0, 5) === "image") {
80-
this.preview.innerHTML += '<br>';
73+
74+
window.requestAnimationFrame(() => {
75+
this.refreshPreview();
76+
})
77+
},
78+
afterInputReady: function () {
79+
if (this.value) {
8180
let img = document.createElement('img');
8281
img.style.maxWidth = '100%';
8382
img.style.maxHeight = '100px';
84-
img.src = this.preview_value;
85-
this.preview.appendChild(img);
83+
img.onload = (event) => {
84+
this.preview.appendChild(img)
85+
};
86+
img.onerror = (error) => {
87+
console.error('upload error', error, this)
88+
};
89+
img.src = this.container.querySelector('input').value;
8690
}
87-
this.preview.innerHTML += '<br>';
88-
let uploadButton = this.getButton('Upload', 'upload', 'Upload');
89-
this.preview.appendChild(uploadButton);
90-
uploadButton.addEventListener('click', (event) => {
91-
event.preventDefault();
92-
uploadButton.setAttribute("disabled", "disabled");
93-
this.theme.removeInputError(this.uploader);
94-
if (this.theme.getProgressBar) {
95-
this.progressBar = this.theme.getProgressBar();
96-
this.preview.appendChild(this.progressBar);
97-
}
98-
this.jsoneditor.options.upload(this.path, file, {
99-
success: (url) => {
100-
this.setValue(url);
101-
if (this.parent) {
102-
this.parent.onChildEditorChange(this);
103-
}
104-
else {
105-
this.jsoneditor.onChange();
106-
}
107-
if (this.progressBar) {
108-
this.preview.removeChild(this.progressBar);
109-
}
110-
uploadButton.removeAttribute("disabled");
111-
},
112-
failure: (error) => {
113-
this.theme.addInputError(this.uploader, error);
114-
if (this.progressBar) {
115-
this.preview.removeChild(this.progressBar);
116-
}
117-
uploadButton.removeAttribute("disabled");
118-
},
119-
updateProgress: (progress) => {
120-
if (this.progressBar) {
121-
if (progress) {
122-
this.theme.updateProgressBar(this.progressBar, progress);
123-
}
124-
else {
125-
this.theme.updateProgressBarUnknown(this.progressBar);
126-
}
127-
}
128-
}
129-
});
130-
});
131-
if (this.jsoneditor.options.auto_upload || this.schema.options.auto_upload) {
132-
uploadButton.dispatchEvent(new MouseEvent('click'));
133-
this.preview.removeChild(uploadButton);
91+
this.theme.afterInputReady(this.input);
92+
},
93+
refreshPreview: function () {
94+
if (this.last_preview === this.value) {
95+
return;
13496
}
97+
this.last_preview = this.value;
98+
this.preview.innerHTML = '';
99+
if (!this.value) {
100+
return;
101+
}
102+
this.afterInputReady();
135103
},
136-
137104
enable: function () {
138105
if (!this.always_disabled) {
139-
if (this.urlfield) {
140-
this.urlfield.disabled = false;
106+
if (this.input) {
107+
this.input.disabled = false;
141108
}
142109
this._super();
143110
}
144111
},
145-
146112
disable: function (always_disabled) {
147113
if (always_disabled) {
148114
this.always_disabled = true;
149115
}
150-
if (this.urlfield) {
151-
this.urlfield.disabled = true;
116+
if (this.input) {
117+
this.input.disabled = true;
118+
}
119+
if (this.button) {
120+
this.button.disabled = true;
152121
}
153122
this._super();
154123
},
155-
156124
setValue: function (val) {
157125
if (this.value !== val) {
158126
this.value = val;
159-
this.urlfield.value = this.value;
160-
this.onChange();
127+
this.input.value = this.value;
128+
this.refreshPreview();
129+
this.refreshWatchedFieldValues();
130+
this.onChange(true);
161131
}
162132
},
163-
164133
destroy: function () {
165-
if (this.preview && this.preview.parentNode) {
134+
if(this.preview && this.preview.parentNode) {
166135
this.preview.parentNode.removeChild(this.preview);
167136
}
168-
if (this.title && this.title.parentNode) {
137+
if(this.title && this.title.parentNode) {
169138
this.title.parentNode.removeChild(this.title);
170139
}
171-
if (this.input && this.input.parentNode) {
140+
if(this.input && this.input.parentNode) {
172141
this.input.parentNode.removeChild(this.input);
173142
}
174-
if (this.urlfield && this.urlfield.parentNode) {
175-
this.urlfield.parentNode.removeChild(this.urlfield);
143+
if(this.input && this.input.parentNode) {
144+
this.input.parentNode.removeChild(this.input);
176145
}
146+
177147
this._super();
178148
}
179149
});

0 commit comments

Comments
 (0)