Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IDEA] In editor, drop image-link to create an external link #5309

Open
twMat opened this issue Dec 23, 2020 · 15 comments
Open

[IDEA] In editor, drop image-link to create an external link #5309

twMat opened this issue Dec 23, 2020 · 15 comments

Comments

@twMat
Copy link
Contributor

twMat commented Dec 23, 2020

I wish to easily add links to external images, like how it is done in the github editor, i.e:

Drag'n drop an image file link (from local or web) into the editor and its link appears at that specific spot - and in the correct syntax [img[...]] so the image is directly seen when the tiddler is stored.

This would tremendously simplify adding of images in TW.

Currently, imagelinks dropped into the editor from the web don't get the surrounding [img[...]] and dropping links from local into the editor instead opens the image in a new tab (win10, chrome).

Background
As a science teacher (for past 3 years), I wish to create worksheets for my pupils with physics questions etc. The idea is to tag the questions (topic, phenomena, marks, difficulty, question type, etc) so I can easily generate worksheets, exam papers, experiments, equipment-lists, etc. One question or task = one tiddler. Here's a typical example of one question:

image

As seen, questions typically have complex content; it's an arbitrary mix of text, images, tables, numbering of problem, and more.

One may argue that "the TW way" would be to split up the content into several tiddlers. This is not at all desirable because the content is typically not reused elsewhere. In fact, tiddly-fiddling must be kept to a minimum: There will be several hundreds (thousands?) of these questions. It is unavoidable to have to type the text and, elsewhere, edit the images. But the next step, to add/link the images, is a deal breaker with the current image workflow in TW. I'm hoping it doesn't have to be :-)

@saqimtiaz
Copy link
Contributor

Drag'n drop an image file link (from local or web) into the editor and its link appears at that specific spot - and in the correct syntax [img[...]] so the image is directly seen when the tiddler is stored.

What is an image file link?
Dropping an image file into the Github editor does indeed insert the image with the correct syntax. The TW 5.2.0 pre-release now has something similar.

Dropping a URL to an image file inserts just the URL as plain unformatted text into the editor in both Github and TW. This is the best that a plain text area based editor can do.

@twMat
Copy link
Contributor Author

twMat commented Jun 22, 2021

What is an image file link?

You seem to get what I mean with "image file link" - and I must say WHOA! it is super smooth to DnD an image from a local folder! That is exactly what I meant. Saq, do I have you to thank both for the heads up and for the implementation? :-)

Dropping a URL to an image file inserts just the URL as plain unformatted text into the editor in both Github and TW. This is the best that a plain text area based editor can do.

No, for Github if you DnD e.g this image (the seen image, not the url) it is inserted with the correct formatting to directly display as image:

https://upload.wikimedia.org/wikipedia/commons/7/7c/201408_cat.png

I would guess it is critical that the file link is suffixed as image file for it to be recognized. (...which is good in some sense because "creative common" images seem to be overrepresented among correctly suffixed image links).

@twMat
Copy link
Contributor Author

twMat commented Jun 22, 2021

BTW, is there any sniffing done to sense what file type a link leads to? (I recall bringing this up a long time ago apropos _canonical_uri's and that it would make sense to automatically set tiddler type based on link suffix... but that issue is no biggie because it is a bit iffy to create a _canonical_uri tid anyway... or maybe it could be automated then converting a list of links into images...?)

@saqimtiaz
Copy link
Contributor

You seem to get what I mean with "image file link" - and I must say WHOA! it is super smooth to DnD an image from a local folder! That is exactly what I meant. Saq, do I have you to thank both for the heads up and for the implementation? :-)

Maybe ;) See #5699

BTW, is there any sniffing done to sense what file type a link leads to? (I recall bringing this up a long time ago apropos _canonical_uri's and that it would make sense to automatically set tiddler type based on link suffix... but that issue is no biggie because it is a bit iffy to create a _canonical_uri tid anyway... or maybe it could be automated then converting a list of links into images...?)

When a link is dragged into the editor, it is the same as dragging some text. We don't do any special handling for text dragged and dropped or pasted into the editor. What you get is the default browser behaviour. Doing some special handling for text that looks like image link is somewhere between tricky to very complicated, without also having to intentionally deal with all change events in the text area such as copy and paste, dragging text selections within the text area etc, all of which we get for free with the browser handling. If you remind me post 5.2.0 release, I will take a look to see if there is any low hanging fruit here.

@saqimtiaz
Copy link
Contributor

OK, it turns out that given we have #5699 in place, it is relatively easy to implement this (at least for Chrome, I didn't test other browsers yet). Some quick POC code:

	EditTextWidget.prototype.handlePasteEvent = function(event) {
		if(event.clipboardData.files.length) {
			event.preventDefault();
			event.stopPropagation();
			this.dispatchDOMEvent(this.cloneEvent(event,["clipboardData"]));
		} else {
+			if(event.clipboardData.types.indexOf("text/plain")!== -1) {
+				var textData = event.clipboardData.getData("text");
+				if(/http(s?:)?\/\/?[^\'"<>]+?\.(jpg|jpeg|gif|png)/.test(textData)) {
+					event.preventDefault();
+					event.stopPropagation();
+					var operation = this.engine.createTextOperation();
+					var handler = this.editorOperations["insert-text"];
+					handler.call(this,{paramObject:{text: `[img[${textData}]]`}},operation);
+					var newText = this.engine.executeTextOperation(operation);
+					this.engine.fixHeight();
+					this.saveChanges(newText);					
+				}
				
			}
		}
	};

@Jermolene is this something we wish to add support for? Namely, when an image URL is pasted or dropped into the framed editor or codemirror, wrap it in the wiki syntax for an image transclusion?

As long as their aren't any unexpected cross-browser issues it looks straight forward. A more ambitious approach could be to allow users to define a series of filters (akin to how $:/config/FileSystemPaths works) that transform the incoming text according to the first filter that fits, or let it through untouched.

@saqimtiaz
Copy link
Contributor

is this something we wish to add support for? Namely, when an image URL is pasted or dropped into the framed editor or codemirror, wrap it in the wiki syntax for an image transclusion?

Having slept on this, I am not sure that we would want to hardcode behaviour like this into the core and that this might be better explored through plugins.

Thoughts @Jermolene @twMat ?

@Jermolene
Copy link
Owner

Having slept on this, I am not sure that we would want to hardcode behaviour like this into the core and that this might be better explored through plugins.

Thoughts @Jermolene @twMat ?

As you've noted, the problem is that in general it is not possible to tell the type of a resource from it's URL; the exception is when the URL ends with a file extension, which is not required by the web protocols, and therefore not something that we can rely on. The risk is that the user experience will be brittle: some URLs will work, and others not. Given the complexity of modern URLs, the user may not be able to easily check whether there is an extension.

So, I think something like this is best approached by thinking about what core hooks would be required to allow this to be done as a customisation.

@saqimtiaz
Copy link
Contributor

saqimtiaz commented Jun 23, 2021

@Jermolene agreed. The hooks required would be in the handling of paste and drop events in EditTextWidget.

However, I am in favour of first testing this via an exploratory (not public) plugin that overwrites the related core functions handlePasteEvent and handleDropEvent, before we commit to core hooks that we will then need to maintain in perpetuity.

@twMat
Copy link
Contributor Author

twMat commented Jun 23, 2021

Thoughts @Jermolene @twMat ?

Core / plugin / whatever - I'm happy as long as we affirm the value that this would bring to end users.

@Telumire
Copy link
Contributor

Hello everyone, I opened a similar issue but twMat told me about this thread (thanks !) so I'm bringing my suggestions here instead :)

While I understand why drag and dropping an image URL could be an issue, how about drag and dropping local image files ? I think it would be still very useful for users with a local setup and an image folder from which they want to import images for their wiki.

Now, I can think of a caveat : According to https://developer.mozilla.org/en-US/docs/Web/API/File, browsers do not give access to the file path. However, we can get the file name just fine : https://jsbin.com/vuyifovido/edit?html,js,output

In order for this feature to work, the user would be prompted to set the name of the folder containing the image (defaulting to img), allowing TiddlyWiki to find the pictures. I'm guessing that tiddlydesktop would not have the same limitation (?) , since electron app can access file path.

The file tree would be like that :

/root/tiddlywiki.html
/root/img/filename.png

When an image is drag&drop into a tiddler, TiddlyWiki show a prompt to choose between importing the image or linking it into the wiki. The choice can be saved for later use. If linking is chosen, the user is prompted to specify the folder path (defaulting to img/), this setting is saved.

The following code is then inserted into the wiki : [img[img/filename.png]].

This way, new users are less likely to accidentally bloat their TiddlyWiki file (the prompt should allude to this, something like "Warning : importing image into the wiki can slow it down. Linking is recommended."), and it allows to quickly add new images to the wiki.

@saqimtiaz
Copy link
Contributor

saqimtiaz commented Jul 13, 2021

@Telumire

A solution that requires that the images are a given directory is rather restrictive and will be error prone and likely to lead to misunderstandings on the part of the user. I think that as discussed a bit further above, these customizations should be explored as plugins and the only requirement for the core at this time should be to provide the hooks to be able to do so.

@Telumire
Copy link
Contributor

Telumire commented Jul 14, 2021

@saqimtiaz Yes I can see how this could get confusing.

Then, instead of asking for a singular directory path, maybe the wiki could save the last used folder path ?

Users already needs to specify a directory when they want to insert an image. The prompt displayed when clicking on the EditorToolbar/picture button could show a checkbox offering to save the last used path, for the duration of the session, for example.

This way, the path would be filled out for the next time an image is dropped into a tiddler, and the user can modify it any time they wish, or uncheck to disable it altogether. This would save a lot of time for a teacher or a student with a lot of pictures of diagrams inside a same folder, for example.

I'd argue that new users would probably expect that to be a vanilla feature rather than a plugin, but a plugin would be equally great, of course :)

@saqimtiaz
Copy link
Contributor

Then, instead of asking for a singular directory path, maybe the wiki could save the last used folder path ?

That doesn't help much in terms of making it less error prone for users.

I'd argue that new users would probably expect that to be a vanilla feature rather than a plugin, but a plugin would be equally great, of course :)

Features only make it into the core when they can be implemented reliably and consistently. There are too many caveats and exceptions to this proposal, which is why a plugin is more appropriate.

Note that the External Attachments plugin (for use on TiddlyDesktop) already offers most if not all of what you are asking for, precisely because there are fewer restrictions as we have control over the browser.

@saqimtiaz
Copy link
Contributor

saqimtiaz commented Mar 28, 2022

A more ambitious approach could be to allow users to define a series of filters (akin to how $:/config/FileSystemPaths works) that transform the incoming text according to the first filter that fits, or let it through untouched.

I had a quick look at this today in terms of allowing a cascade of filters to transform text being pasted. The frustration is that it isn't particularly friendly to write a filter that wraps a title in the wikitext for an image transclusion due to the square brackets needed. You end up having to define a global macro like:
\define imagewrap() [img[$(currentTiddler)$]]
and use it within a filter:
[suffix[png]then<imagewrap>].

Alternatively you can end up with a very complex filter construction using :map and charcode[]:

[suffix[png]addprefix[[img[]] :map[charcode[93]addprefix<currentTiddler>] :map[charcode[93]addprefix<currentTiddler>]


As an aside, a macro version of the charcode operator would be useful so you can do things like: :map[addsuffix<charcode 93>addsuffix<charcode 93>]

@pmario
Copy link
Contributor

pmario commented Mar 28, 2022

As an aside, a macro version of the charcode operator would be useful so you can do things like: :map[addsuffix<charcode 93>addsuffix<charcode 93>]

I think I did a macro like this some month ago. .. But I have to dig out the code, since it is berried in an experimental branch. ..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants