Open jasongisstl opened 8 years ago
Any progress on this?
Also interested in this :)
[edit]Best Approach is something like the adding a matcher to the clipboard module, watching for copypasted urls and converting them to images (new Delta().insert({image: url}); works) like the code found here: https://github.com/quilljs/quill/issues/109 by @schneidmaster Couldnt get it to works for images still tho...learning...
[edit 2] this custom matcher converts urls to links and in case they link to image, converts the urls to inline images (put it in quill.on('text-change', function(delta, oldDelta, source) {
)
var Delta = Quill.import('delta');
//convert img links to actual images
quill.clipboard.addMatcher(Node.TEXT_NODE, function(node, delta) {
var regex = /https?:\/\/[^\s]+/g;
if(typeof(node.data) !== 'string') return;
var matches = node.data.match(regex);
if(matches && matches.length > 0) {
var ops = [];
var str = node.data;
matches.forEach(function(match) {
var split = str.split(match);
if(match.match(/\.(png|jpg|jpeg|gif)$/)!=null){
var beforeLink = split.shift();
ops.push({ insert: beforeLink });
ops.push({ insert:{image: match}, attributes: { link: match }
});
str = split.join(match);
} else { //if link is not an image
var beforeLink = split.shift();
ops.push({ insert: beforeLink });
ops.push({ insert: match, attributes: { link: match }
});
str = split.join(match);
}
});
ops.push({ insert: str });
delta.ops = ops;
}
return delta;
});
~~Obviously the wrong approach > I tried to implement this in the form of a custom module, but my JS skills suck. Behaviour im looking for is to replace all urls containing images to 'inline' images (like the etherpad image plugin). I made (read: copypasta) an example that sorta works here: http://codepen.io/anon/pen/PpYjxG In the example, type a bit and Copy/Paste an image url in the editor field and it will appear as inline image. Only after that the ability to edit/type stops, which must be something obvious, but as I said..major noob...~~
Would love to see this as well. As a side note, this was how images were handled in the early stages of QuillJS. Any reason why this was removed?
I don't understand why there is base64 upload images and no support for third-party image upload. This is VERY important!
Still no update :(
I got it working like this: https://stackoverflow.com/questions/43857373/quill-editor-vuejs2-image-upload-base64-image-to-url Not directly from clipboard tho
I think here https://github.com/quilljs/quill/issues/863#issuecomment-240579430 it is written pretty well. All you need to do is to create custom handler
+6666
+1
I too would like to make public my desire for such a feature.
+1
+1 how is this not a feature yet?
Could someone from the team maybe shed some light on this please? This feature is really, REALLY needed.
+1 my team would love this feature.
For what it's worth... would be really really nice to have...
Keeping the fire alive for this request 🔥
I toss some bricks into that fire so it keeps burning longer
We got it working by extracting the base64 encoded image, storing it on the hard drive and replacing thesrc="data..."
code with src="/folder/file..."
but quill doesn't display the picture when the HTML is loaded with dangerouslyPasteHTML
the next time we open it, see https://github.com/quilljs/quill/issues/1449.
+1 would also like to see this feature built-in
var toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
[{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1' }, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean'], // remove formatting button
['image']
];
var quill = new Quill('#editor', {
theme: 'snow',
modules: {
toolbar: {
container: toolbarOptions,
handlers: {
image: imageHandler
}
}
},
});
function imageHandler() {
var range = this.quill.getSelection();
var value = prompt('What is the image URL');
if(value){
this.quill.insertEmbed(range.index, 'image', value, Quill.sources.USER);
}
}
Any progress on this?
å•¥
Hey there! Any progress?
@siberiadev in case you're working with laravel, for extracting the image you can use extract_inline_img()
from my package here: https://packagist.org/packages/repat/laravel-helper
Or just have a look at the function here and extract what you need.
In terms of displaying I haven't seen any progress.
@repat, thank you. I use Node.js for backend.
PHP and Laravel (MVC, similar to express I think) is fairly eary to read so you could:
/src=\"data:image\/([a-zA-Z]*);base64,([^\"]*)\"/
to from PCRE to EcmaScriptstr_finish
come from the official Laravel helpers: https://laravel.com/docs/5.8/helpers=> Translate it into a js function
I posted a solution above
This works like a charm
var toolbarOptions = [ ['bold', 'italic', 'underline', 'strike'], // toggled buttons ['blockquote', 'code-block'], [{ 'header': 1 }, { 'header': 2 }], // custom button values [{ 'list': 'ordered' }, { 'list': 'bullet' }], [{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript [{ 'indent': '-1' }, { 'indent': '+1' }], // outdent/indent [{ 'direction': 'rtl' }], // text direction [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown [{ 'header': [1, 2, 3, 4, 5, 6, false] }], [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme [{ 'font': [] }], [{ 'align': [] }], ['clean'], // remove formatting button ['image'] ]; var quill = new Quill('#editor', { theme: 'snow', modules: { toolbar: { container: toolbarOptions, handlers: { image: imageHandler } } }, }); function imageHandler() { var range = this.quill.getSelection(); var value = prompt('What is the image URL'); if(value){ this.quill.insertEmbed(range.index, 'image', value, Quill.sources.USER); } }
For anyone coming here using ngx-quill:
import { QuillModules, defaultModules } from 'ngx-quill';
export class MyComponent {
quillModules: QuillModules = {
toolbar: {
container: defaultModules.toolbar,
handlers: {
image: imageHandler
}
}
};
}
imageHandler(this: any) {
const tooltip = this.quill.theme.tooltip;
const originalSave = tooltip.save;
const originalHide = tooltip.hide;
tooltip.save = function(this: any) {
const range = this.quill.getSelection(true);
const value = this.textbox.value;
if (value) {
this.quill.insertEmbed(range.index, 'image', value, 'user');
}
};
// Called on hide and save.
tooltip.hide = function (this: any) {
tooltip.save = originalSave;
tooltip.hide = originalHide;
tooltip.hide();
};
tooltip.edit('image');
tooltip.textbox.placeholder = "Embed URL";
}
<quill-editor [modules]="quillModules"></quill-editor>
@chrisbmoore this works great for ngx-quill! However, it clobbers the tooltip saves for links and videos. Need to set the original save back when done. Instead of this:
function imageHandler(this: any) { const tooltip = this.quill.theme.tooltip; tooltip.save = function (this: any) { const range = this.quill.getSelection(true); const value = this.textbox.value; if (value) { this.quill.insertEmbed(range.index, 'image', value, 'user'); } } tooltip.edit('image'); }
do something like this:
imageHandler(this: any) {
const tooltip = this.quill.theme.tooltip;
const originalSave = tooltip.save;
tooltip.save = function(this: any) {
const range = this.quill.getSelection(true);
const value = this.textbox.value;
if (value) {
this.quill.insertEmbed(range.index, 'image', value, 'user');
}
tooltip.save = originalSave;
};
tooltip.edit('image');
}
@pburrows You're right, the original save function should be reset. Thanks!
@pburrows @chrisbmoore If the tooltip is closed without clicking "Save" the original save function is not restored, as the save method is not called. Do you have any idea how to solve this? I did not find some callback that is called in that case.
Update: I found a solution myself by overriding tooltip.hide() with the restore code:
tooltip.hide = function(this: any) {
tooltip.save = originalSave;
tooltip.hide = originalHide;
tooltip.hide();
};
@digilist Thanks for the correction! Yep your solution makes sense and I'll add it to my code.
Any Update on this ?
I tried to find a better way to do this... the tooltips in Quill are hidden quite effectively so that consumers can't extend on them cleanly.
Anyway, one more bit that you'll need to customize the label is this CSS snippet:
.ql-tooltip[data-mode=image]::before {
content: "Enter image URL:";
}
I tried to find a better way to do this... the tooltips in Quill are hidden quite effectively so that consumers can't extend on them cleanly.
Anyway, one more bit that you'll need to customize the label is this CSS snippet:
.ql-tooltip[data-mode=image]::before { content: "Enter image URL:"; }
It doesn't work
Other solutions did not work for me :(
I'm using a "react-quill": "^1.3.5",
So I wrote it like this:
function imageHandler() {
const { tooltip } = this.quill.theme;
const originalSave = tooltip.save;
const originalHide = tooltip.hide;
tooltip.save = () => {
const range = this.quill.getSelection(true);
const { value } = tooltip.textbox;
if (isValidURL(value)) { //isValidURL is a validator
this.quill.insertEmbed(range.index, 'image', value, Quill.sources.USER);
} else {
// error message handler
}
};
// Called on hide and save.
tooltip.hide = () => {
tooltip.save = originalSave;
tooltip.hide = originalHide;
tooltip.hide();
};
tooltip.edit('image');
tooltip.textbox.placeholder = 'Embed URL';
}
const modules = {
toolbar: {
container: [
[{ header: '1' }, { header: '2' }, { font: [] }],
[{ size: [] }],
['bold', 'italic', 'underline', 'strike', 'blockquote'],
[{ list: 'ordered' }, { list: 'bullet' }],
['link', 'image', 'video'],
],
handlers: {
image: imageHandler,
},
},
};
var toolbarOptions = [ ['bold', 'italic', 'underline', 'strike'], // toggled buttons ['blockquote', 'code-block'], [{ 'header': 1 }, { 'header': 2 }], // custom button values [{ 'list': 'ordered' }, { 'list': 'bullet' }], [{ 'script': 'sub' }, { 'script': 'super' }], // superscript/subscript [{ 'indent': '-1' }, { 'indent': '+1' }], // outdent/indent [{ 'direction': 'rtl' }], // text direction [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown [{ 'header': [1, 2, 3, 4, 5, 6, false] }], [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme [{ 'font': [] }], [{ 'align': [] }], ['clean'], // remove formatting button ['image'] ]; var quill = new Quill('#editor', { theme: 'snow', modules: { toolbar: { container: toolbarOptions, handlers: { image: imageHandler } } }, }); function imageHandler() { var range = this.quill.getSelection(); var value = prompt('What is the image URL'); if(value){ this.quill.insertEmbed(range.index, 'image', value, Quill.sources.USER); } }
Inserting images with insertEmbed
for images with URL does work, but quill doesn't allow it to be deleted, like when I press backspace or delete key, the inserted image won't disappear. Any way to solve this?
Thanks @Milutin-P, your code helped in 1.3.5, unfortunately something changed on 1.3.7 and now your code snippet doesn't work. I think the issue lies with trying to get the tooltip. const { tooltip } = this.quill.theme
I'm not sure if something changed but was wondering if you could shed some light on this issue.
thanks,
The Image button on the toolbar allows you to insert an image from your local machine. It would be brilliant if this could be extended to also allow an image URL to be provided.
It is possible to drag & drop an image from the web, but this may not be obvious to all users. Also, in our particular case, we have custom drag & drop handling which prevents this from working in our applications.
Version: 1.0.0-rc2
P.S. Thank you for all your hard work on 1.0 - it really is fantastic.