Page MenuHomePhabricator

copy to clipboard button for mediawiki code boxes
Closed, ResolvedPublic

Description

A "Copy to clipboard" link above/below all code boxes. Either always visible or when you hover over it.

Investigate a mediawiki extension that doesn't require flash.

Any idea how to implement it?

Event Timeline

JasonJAyalaP raised the priority of this task from to Needs Triage.
JasonJAyalaP updated the task description. (Show Details)
JasonJAyalaP added projects: Whonix, website.
JasonJAyalaP added a subscriber: JasonJAyalaP.
Patrick triaged this task as Normal priority.Jan 16 2015, 10:28 PM
Patrick added a subscriber: fortasse.
Patrick updated the task description. (Show Details)Jan 16 2015, 10:31 PM
Patrick added a project: research.
Patrick added a subscriber: WhonixQubes.

Could you please check out http://stackoverflow.com/questions/6355300/copy-to-clipboard-without-flash/9481957#9481957 (what fortasse mentioned here), if that could be used to implement the copy to clipboard button? Or do you have any other thoughts here? @WhonixQubes

Actually, that is an issue that has caused frustration to many js developers over the years.

There are many reasons why it isn't practical (or possible) to implement it with javascript:
1- Cross-browser compatibility. Each browser handles the clipboard in a different way, and some are more picky than others.
2- Privacy and Security. It is considered a security issue to allow the browser to write to the clipboard. If it can write there, it can also read, and the clipboard may occasionally contain sensitive information such as credit card numbers, passwords, etc copied by other applications or browser windows. Furthermore, in some browsers like Firefox, one needs to change a variable value in about:config in order to enable this functionality, and ugly message will appear asking the user for permission or warning him whenever javascript triggers a clipboard copy.

For those reasons, developers usually use third-party apps such as Flash to implement this feature. Not only it will look less ugly with Flash, but implementing it with javascript wouldn't be more secure than implementing it with Flash.

The example linked to in the comment above, that uses jQuery, does not in fact copy the text to clipboard. All it does is to select the text for the user so he/she can press CTRL+C to copy it. Needless to say, it is a method that can be coded with js only without requiring jQuery. It is like half a solution, where you do the selection (which may spare the user the effort when the content to select is large) and leave the other half of the copying procedure to the user fingers. It's an approach that is somewhat popular among those who want to rely only on javascript.

I tested myself many js snippets in the past, that claim to do the job completely, and found that most of them don't work anymore (use deprecated functions) or work only for certain browsers and with certain constraints and limitations. I suggest that making a "select all text" button is sufficient, since anything beyond isn't worth the effort.

Sorry for the short essay... err... the long post.

Okay. If that is most we can do, then we should go for it. I think I saw such a box before somewhere. Dunno where. But it's useful, no?

Would you know how to implement it in the wiki? Could you try on some test page such as https://www.whonix.org/wiki/Translatetest please?

Usually we're using the <pre> tag for stuff that is supposed to be copied.

<pre>
test text box here
</pre>

We can also use the <html> tag.

When it works, we should be able to make that a mediawiki template.

Hey guys,
if we wait a while it might become more commonplace and then we could potentially get this to work.
there's api support within HTML5 called ClipboardEvent.
it's currently supported by Firefox only, but i'm hoping other browsers will add support.

check out http://stackoverflow.com/questions/23238236/using-the-clipboard-api-throws-error-is-not-defined
do remember it's not universally supported yet, so it might not be the best to work with right now.
but it's something to consider :)

Forgot to say... This shouldn't make things worse for users that have javascript disabled or using browser that don't have that feature yet.

Given that, I don't think we need to wait? We could deploy it now and then wait for browser supporting it?

Could you try getting up a demo using ClipboardEvent on the https://www.whonix.org/wiki/Translatetest2 please?

Patrick,
Trying a bit now. Can you enable javascript in the wiki settings somewhere for the testing to work?
As it stands I cannot make any javascript work - it gets read as text rather than a script.

Make sure you can only enable in that one page, lest someone try to hijack the site.
If we cannot get Javascript to work, we'll have to just leave it as "user selects, copies, pastes themselves"

In T93#1044, @crackman wrote:

Patrick,
Trying a bit now. Can you enable javascript in the wiki settings somewhere for the testing to work?
As it stands I cannot make any javascript work - it gets read as text rather than a script.
Make sure you can only enable in that one page, lest someone try to hijack the site.
If we cannot get Javascript to work, we'll have to just leave it as "user selects, copies, pastes themselves"

Javascript is enabled by default in the wiki. You just forgot to enclose your <script> tags within <html> tags.

Since ClipboardEvent API works only on Firefox currently, the same goes for it as I explained in my previous comment. It isn't practical to deploy a solution that won't work for some of the users.

I'll work on making a template for the "select code" button.

Javascript is enabled and the test popup is working. Security is not an issue here. We are using FlaggedRevs extension. New edits won't be shown to regular users by default as long as admins have not confirmed these changes.

In T93#1046, @Patrick wrote:

Javascript is enabled and the test popup is working. Security is not an issue here. We are using FlaggedRevs extension. New edits won't be shown to regular users by default as long as admins have not confirmed these changes.

I forgot to mention that I added the forgotten <html> tags so the script can work. It wasn't working before, just as crackman said.

Patrick, can you give me the privilege necessary for creating a Template page on the wiki. My username there is Linostar.

Yes, you are now wiki admin.

Linostar added a comment.EditedJan 21 2015, 7:52 PM

I managed to do it. I found that there are some constraints on javascript code in wikimedia and the normal selecting methods don't work. As a workaround, I had to substitue the <pre> element with a <textarea> element and changed the style of the latter to look like the former.

The template can be used as in the following syntax:
{{CodeSelect|number_of_rows|actual_code_goes_here}}

Note: If your code is longer in lines that the number_of_rows you specified, a vertical scrollbar will auto-appear.

You can find a working example here:
https://www.whonix.org/wiki/Translatetest4

Nice template!

Could you make it work for special chars such as =?

Could you the Select code to the right side and make it a very small [select code]? I think that is the "standard" for such boxes? Unless someone else has a better suggestion for the style?

Can you make it disappear when javascript is disabled? Probably not?

Linostar added a comment.EditedJan 22 2015, 8:32 PM

I made a change that gets '=' to display properly instead of being a treated as a part of the template. As consequence, the new syntax for the template has become:
{{CodeSelect|number_of_rows|code=actual_code_goes_here}}

See https://www.whonix.org/wiki/Translatetest4 for examples.

I moved the button to the right and made its caption in small chars. Is that how you want it to look like?

Furthermore, I just made it so the button disappear when javascript is disabled. It turns out it's not impossible ;-)

Can the number of rows be auto detected?

Is that how you want it to look like?

Not exactly. Can the "button-style" be removed? I mean, the removing the gray surrounding. Using blue color. Text: [select code]. And text size -3.

But that's not super important. Just what I think looks best. I also go with whatever others suggest for a good style.

It turns out it's not impossible

Amazing!

In T93#1110, @Patrick wrote:

Can the number of rows be auto detected?

I am afraid not. Yes, it can be done with javascript, but if javascript is disabled, the code boxes will just look ugly.

Is that how you want it to look like?

Not exactly. Can the "button-style" be removed? I mean, the removing the gray surrounding. Using blue color. Text: [select code]. And text size -3.
But that's not super important. Just what I think looks best. I also go with whatever others suggest for a good style.

The button can be customized. If you can show me an example (e.g. a webpage or an image) of what you have in mind, it'll be easier to make it look exactly like that.

I am afraid not. Yes, it can be done with javascript, but if javascript is disabled, the code boxes will just look ugly.

How does the <pre> tag do this then? Would require a mediawiki extension then?

The button can be customized. If you can show me an example (e.g. a webpage or an image) of what you have in mind, it'll be easier to make it look exactly like that.

Haven't found a website, but the html code is simple.

<a href=just-to-make-it-look-blue>
<font size=-3>[select code]</font>
</a>

Here is a screnshot.
Screenshot:

In T93#1114, @Patrick wrote:

I am afraid not. Yes, it can be done with javascript, but if javascript is disabled, the code boxes will just look ugly.

How does the <pre> tag do this then? Would require a mediawiki extension then?

<pre> is like <div>, they autoresize based on their content because they are gifted elements of the DOM family (so it is done internally without javascript). Unfortunately, <textarea> is not gifted and pampered like them, and we seem to be stuck with <textarea> due to the restrictions on the 'window' object imposed by mediawiki.

<a href=just-to-make-it-look-blue>
<font size=-3>[select code]</font>
</a>

Here is a screnshot.
Screenshot:
{F27}

Done. See https://www.whonix.org/wiki/Translatetest4 (I made it "font size = -2" since -3 seems too small for my eyes).

Looks perfect.

We needed to disable raw html (the <html> tag) for security reasons [otherwise evil javascript could steal admin cookies due to edits by non-admin users] and are now using the safer Extension:Widgets.

Therefore moved https://www.whonix.org/wiki/Template:CodeSelect to https://www.whonix.org/wiki/Widget:CodeSelect.

The Widget: namespace does not support mediawiki variables (such as {{{1}}}) directly, but also supports parameters. See:
https://www.mediawiki.org/wiki/Extension:Widgets#Usage

See also example widget:
https://www.whonix.org/wiki/Widget:Share

And how to use it in an example template:
https://www.whonix.org/wiki/Template:Share

Having said that... Does anything change? I guess we can still use your CodeSelect code if we adjust the parameter syntax?

Can we now somehow auto detect number of rows?

To manually enter the number of rows would be kinda cumbersome. If you look through the wiki, how often we are using the <pre> tag, if we were to change them all by hand and not forget updating that number each time the content is changed, that would be kind hard. So maybe, if it doesn't work with special chars such as = as first char, could rows be auto detected?

Does not seem that widgets allow html/js code on their own when raw html is disabled, as in your:
https://www.whonix.org/wiki/Widget:Share

Perhaps you should enable <html> tags only in template pages instead? (if that's possible)

As for detecting row numbers, the best I can come with is the following: if javascript is enabled, detect row numbers and adjust the height accordingly using js; if js is disabled, then display the textarea with fixed row number (6 for example) and vertical scrolling arrows if number of rows exceed 6.

How does that sound?

Does not seem that widgets allow html/js code on their own when raw html is disabled, as in your:
https://www.whonix.org/wiki/Widget:Share

Not sure I understand. The raw html is not correctly rendered on that https://www.whonix.org/wiki/Widget:Share page. But the calling page https://www.whonix.org/wiki/Template:Share shows the correctly rendered html that is based on the widget page's html code.

Perhaps you should enable <html> tags only in template pages instead? (if that's possible)

Unfortunately, that's not possible. (Not saying it's impossible, but would require writing a mediwiki extension for that and html extensions getting right seems very hard - judged by all the attempts that were made in past.)

As for detecting row numbers, the best I can come with is the following: if javascript is enabled, detect row numbers and adjust the height accordingly using js; if js is disabled, then display the textarea with fixed row number (6 for example) and vertical scrolling arrows if number of rows exceed 6.

How does that sound?

Better but still impractical.

If you go to https://www.whonix.org/wiki/Special:ReplaceText - be careful with that one - and enter <pre> as search term, then continue and look at the results... And then abort... You see how many times we are using that tag. Going through all of them would be a lot work and I am sure editors would be confused and/or mess up entering correct row number.

In T93#1312, @Patrick wrote:

Does not seem that widgets allow html/js code on their own when raw html is disabled, as in your:
https://www.whonix.org/wiki/Widget:Share

Not sure I understand. The raw html is not correctly rendered on that https://www.whonix.org/wiki/Widget:Share page. But the calling page https://www.whonix.org/wiki/Template:Share shows the correctly rendered html that is based on the widget page's html code.

Perhaps you should enable <html> tags only in template pages instead? (if that's possible)

Unfortunately, that's not possible. (Not saying it's impossible, but would require writing a mediwiki extension for that and html extensions getting right seems very hard - judged by all the attempts that were made in past.)

My mistake. I assumed the widget would render correctly on its own page like template pages do. Since the widget can render html tags correctly, I'll make the necessary changes so the 'code' parameter is replaced properly in the widget.

As for detecting row numbers, the best I can come with is the following: if javascript is enabled, detect row numbers and adjust the height accordingly using js; if js is disabled, then display the textarea with fixed row number (6 for example) and vertical scrolling arrows if number of rows exceed 6.
How does that sound?

Better but still impractical.
If you go to https://www.whonix.org/wiki/Special:ReplaceText - be careful with that one - and enter <pre> as search term, then continue and look at the results... And then abort... You see how many times we are using that tag. Going through all of them would be a lot work and I am sure editors would be confused and/or mess up entering correct row number.

I think you misunderstood me a bit. By making a default value for the number of rows, it means we need not to insert the row number manually in the widget tag. If javascript is enabled, the default value will be overrided based on the height of the element. Otherwise, vertical scrollbars (if js is disabled) will show to allow the users to scroll within the CodeSelect element.

Linostar added a comment.EditedJan 30 2015, 12:43 PM

I've added the auto-resizing feature. You can test with js enabled/disabled to see how it would look on:
https://www.whonix.org/wiki/Translatetest5

Furthermore, I made the template page use the CodeSelect widget instead of redirecting to the widget page. That way, you can write: {{CodeSelect|code=<your code here>}} which is a bit easier (from a wiki editor perspective) than putting a widget tag. But both will lead to the same result (see the sources of Template:CodeSelect and Translatetest5 for more info).

Without javascript, it's too much scrolling. Just two lines are visible. The rest needs to be scrolled.

Did you remove the configure lines number feature?

Here is an good example, on how we are using the <pre> tag:
https://www.whonix.org/wiki/Security_Guide#Updates

I am afraid to say, manually counting the number of lines, adjusting that for the whole wiki looks like too impractical, because that would be too much work. And fail, as soon as the content within that tag is changed, I am sure wiki editors would forget the update the number of lines.

Could the line number without javascript feature be implemented using a mediawiki extension?
https://www.mediawiki.org/wiki/Manual:Developing_extensions

We could look if we find a similar extension that implements a different <tag> and see how they implemented that. Surely it could then be "gifted"?

Not sure if that would be overkill / too much work.

The problem is that mediawiki doesn't allow full access (or any access) to the window object in javascript. That's why I am unable to select the contents of an element unless it is an input text or a textarea, both containing an embedded selecting function and don't need to use the window object.

I'll look into mediawiki extensions. Hopefully, we'll find some kind of solution there.

I was too blind to see the most obvious solution! No need to use mediawiki extensions even.

I fixed it! Now, a user with js disabled will see the code box with auto height. No need to hardcode the number of rows anymore (whether js is enabled or not).

What did I do?
tldr;
Display a normal <pre> if js is disabled, and an auto-height selectable <textarea> if js is enabled.

Reason: We aren't showing the "[select code]" anyway for users with js disabled, so why bother show them a textarea. It is better to show them a pre element that has the auto-height gift by default.

You can test the results on: https://www.whonix.org/wiki/Translatetest5

I think that's the last issue in this bug, or is there anything else?

Awesome, nice and simple fix!

Just a minor thing, can we abolish the code= part for the template?

Linostar added a comment.EditedFeb 3 2015, 6:51 PM

Unfortunately, it is necessary to keep it. Without it, any code that contains a '=' will face a problem.

For example, if you have a this code:

a=15;
print(a);

If you write

{{CodeSelect|a=15;
print(a);}}

the template will think that a is a template variable, and everything after the '=' sign will be treated as the value of this variable. And since there is no variable called a anywhere in the template code I've written, no text will appear in the code box.

tldr;
Attributing a parameter name (such as code) is necessary so any '=' is properly escaped and not considered as part of the template code.

Okay, alright.


As a personal matter of taste, instead of writing the following style (a)

{{CodeSelect|code=sudo apt-get update}}

I prefer to write the following style (b)

{{CodeSelect|code=
sudo apt-get update
}}

Because then I can abstract the "markup magic", forget about it, and just concentrate on what I really wanted to write.

There is no difference at the moment and I guess I am lucky it is parsed that way.


Currently doing a beta test here:
https://www.whonix.org/wiki/Security_Guide

There is one issue. When writing this (b) [but same as (a)], i.e. just using a single line, with javascript enabled...

{{CodeSelect|code=
sudo apt-get update
}}

Within the CodeSelect area, it adds an extra empty line after "sudo apt-get update" at the bottom. Can this be fixed?

Also there is a bit much space between
normal text area and
CodeSelect area
and next normal text area.

Could you fix that as well please?

Linostar added a comment.EditedFeb 3 2015, 9:36 PM

Within the CodeSelect area, it adds an extra empty line after "sudo apt-get update" at the bottom. Can this be fixed?

Fixed.

Also there is a bit much space between
normal text area and
CodeSelect area
and next normal text area.
Could you fix that as well please?

The apparently extra space you see is because [select code] is aligned to the right, leaving much space on the left that is looking like a blank line, especially when the line above it is short.
Other than that, the space is the standard space between paragraphs in wikis, and it looks like this value can't be easily reduced (I tried but it seems that mediawiki css rules are overriding my css rules).

Please read this security advice about editing MediaWiki:Common.css:
https://www.whonix.org/wiki/Dev/CSS

Then... Perhaps you could make the required css changes on the https://www.whonix.org/wiki/MediaWiki:Common.css page? I'd speculate, that you have a lot more freedom there.

And if all cords break, I think using mediawiki skins (we are using this one: https://github.com/OSAS/strapping-mediawiki which is open source) one has an almost unlimited options for customization?

In T93#1398, @Patrick wrote:

Please read this security advice about editing MediaWiki:Common.css:
https://www.whonix.org/wiki/Dev/CSS
Then... Perhaps you could make the required css changes on the https://www.whonix.org/wiki/MediaWiki:Common.css page? I'd speculate, that you have a lot more freedom there.
And if all cords break, I think using mediawiki skins (we are using this one: https://github.com/OSAS/strapping-mediawiki which is open source) one has an almost unlimited options for customization?

Unfortunately, css rules in MediaWiki:common.css didn't have the desired effect either (or I am doing it wrong, but I don't think it is the case). Personally, I think it looks acceptable as it currently is.

Linostar added a comment.EditedFeb 9 2015, 3:24 PM

I have decided to give it another chance, and got some results. I found that the problem wasn't in the <div> tags, but because of the <textarea>. It turns out that <textarea> has a default margin-bottom value of 10px. I changed that value to 0, which shortened the distance between the CodeSelect box and the line(s) after.

You can see the result on: http://www.whonix.org/wiki/Translatetest6

It looks better.

Do you think the extra spaces can be further reduced?

See:
https://www.whonix.org/wiki/Security_Guide#Updates
(Between "Should look similar to this." and the next code block there is too much space for my taste.)

In T93#1727, @Patrick wrote:

It looks better.
Do you think the extra spaces can be further reduced?
See:
https://www.whonix.org/wiki/Security_Guide#Updates
(Between "Should look similar to this." and the next code block there is too much space for my taste.)

Yes! I removed all the whitespace above the [select code] link. Now, there is nothing else except for the standard paragraph spacing in mediawiki. See https://www.whonix.org/wiki/Translatetest6 where I added a long line to illustrate better the distance between the link and what's above.

Looks better. Yes. Makes sense.

Is it possible to limit the line length, so there can be reserved space for [select code], to further reduce space between text and code boxes?

You mean you want [select code] link inside the box instead of outside?

No.

To use less space between text and [select code], I was thinking to introduce some "invisible table" in the whole textarea. Normal text lines get the left 95% of space. And [select code] on the right gets the rest 5% (or how little) space.

In other words, that way even super long lines like on https://www.whonix.org/wiki/Translatetest6 would not interfere with [select code].

In the current example, the line would just be sad fsfsnjksffdgd sfgdgdggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggggg f . A very long and then broken. Therefore [select code] could move up.

Nope. Controlling something outside the widget is not possible from inside the widget, especially when the lines outside are put in <p> element, which is an element that does not possess a width attribute.

I propose moving the [select code] link to the left. That will make the gap disappear.

Making only the lines before a CodeSelect shorter is not possible, because you can't know what element comes next or before in css. Making all lines shorter is possible perhaps, but will likely break the layout of other elements and the page.

Okay, I see. So without having this feature natively supported by the skin or even mediawiki itself, there is no way?

What about moving [select code] inside the codebox? Is that even possible? Optically non-ideal, but in my opinion still better than the gap. Users who manually select select all, would they also select the text [select code] or could that be made exempt?

In T93#1816, @Patrick wrote:

What about moving [select code] inside the codebox? Is that even possible? Optically non-ideal, but in my opinion still better than the gap. Users who manually select select all, would they also select the text [select code] or could that be made exempt?

Like this?
https://www.whonix.org/wiki/Security_Guide#Updates

Patrick assigned this task to Linostar.Feb 10 2015, 1:35 PM

Closeable or anything left to do here?

Patrick closed this task as Resolved.Feb 10 2015, 3:01 PM