Modify

Opened 4 years ago

Closed 4 years ago

Last modified 3 years ago

#13831 closed enhancement (fixed)

Pasted URLs in TracLinks syntax

Reported by: anonymous Owned by: lucid
Priority: normal Component: TextareaKeyBindingsPlugin
Severity: normal Keywords: patch
Cc: Trac Release:

Description

When a user copies a URL, it would be convenient to convert it to TracLinks syntax automatically if applicable.

For example when https://trac-hacks.org/ticket/13737 is pasted, the plugin could hook into the Javascript onpaste-event and transform the text to #13737.

  • Bonus: Support special URL parameter syntax like @: etc.
    • For example https://trac-hacks.org/browser/textareakeybindingsplugin/trunk/textareakeybindings/web_ui.py?rev=17665&marks=15#L2 to source:textareakeybindingsplugin/trunk/textareakeybindings/web_ui.py@17665:15#L2
    • Bonus: Add the current revision automatically if no revision was provided?
  • Bonus: Support for InterWiki / InterTrac
    • for example https://trac.edgewall.org/wiki/TracLinks to t:TracLinks.
  • Bonus: Support custom transformations (C:\Source\Dir\file.ext -> source:Dir/file.exe)

Attachments (0)

Change History (6)

comment:1 Changed 4 years ago by anonymous

  • textareakeybindings/htdocs/js/textareakeybindings.js

    diff -r 26de950c8c2a -r a045bfe6d642 textareakeybindings/htdocs/js/textareakeybindings.js
    a b  
    6161        }
    6262
    6363    });
     64    $(document).delegate('textarea', 'paste', function(e) {
     65
     66        let text_to_insert = (e.originalEvent.clipboardData || window.clipboardData).getData('text');
     67       
     68        const data = textareakeybindings;
     69        const pattern_re = new RegExp(data.baseurl_pattern);
     70        text_to_insert = text_to_insert.replace(pattern_re, function(match, realm, rest, offset, string) {
     71            if (realm == 'wiki' ||
     72                realm == '') {
     73                return realm + ':'+ rest;
     74            }
     75            if (realm == 'ticket') {
     76                if (rest.includes('#comment:')) {
     77                    const t = rest.split('#comment:');
     78                    return 'comment:' + t[1] + ':ticket:' + t[0];
     79                }
     80                return '#' + rest;
     81            }
     82            if (realm == 'browser') {
     83                const url = new URL(match);
     84                if (url.searchParams.has('rev')) {
     85                    const rev = url.searchParams.get('rev');
     86                    url.searchParams.delete('rev');
     87                    url.pathname = url.pathname + '@' + rev;
     88                }
     89                if (url.searchParams.has('marks')) {
     90                    const marks = url.searchParams.get('marks');
     91                    url.searchParams.delete('marks');
     92                    url.pathname = url.pathname + ':' + marks;
     93                }
     94                return 'source:' + url.href.replace(pattern_re, '$2')
     95            }
     96            if (realm == 'attachment') {
     97                // TODO
     98            }
     99            return match;
     100        });
     101
     102        Object.keys(data.links).forEach(key => {
     103            const url = data.links[key];
     104            text_to_insert = text_to_insert.split(url).join(key + ':');
     105        });
     106
     107        const start = e.target.selectionStart;
     108        e.target.value = e.target.value.slice(0, start) + text_to_insert + e.target.value.slice(e.target.selectionEnd);
     109        e.target.selectionStart = start + text_to_insert.length;
     110        e.target.selectionEnd = start + text_to_insert.length;
     111        event.preventDefault();
     112    });
    64113 })(jQuery);
  • textareakeybindings/web_ui.py

    diff -r 26de950c8c2a -r a045bfe6d642 textareakeybindings/web_ui.py
    a b  
    99
    1010from trac.core import *
    1111from trac.web import IRequestFilter
    12 from trac.web.chrome import ITemplateProvider, add_script
     12from trac.web.chrome import ITemplateProvider, add_script, add_script_data
     13from trac.wiki.interwiki import InterWikiMap
    1314
    1415
    1516class TextareaKeyBindingsModule(Component):
     
    2728            req.path_info.startswith('/ticket') or
    2829            req.path_info.startswith('/newticket')):
    2930            self.env.log.debug('Injecting textareakeybindings.js')
     31
     32            links = {}
     33            links.update((name, url)
     34                        for name, url, title
     35                        in InterWikiMap(self.env).interwiki_map.values()
     36                        if not '$' in url)
     37
     38            baseurl_pattern = '%s/(\w+)/(\S+)' % (re.escape(req.base_url),)
     39            script_data = {
     40                'baseurl_pattern': baseurl_pattern,
     41                'links': links,
     42            }
     43            add_script_data(req, {'textareakeybindings': script_data})
    3044            add_script(req, 'textareakeybindings/js/textareakeybindings.js')
    3145        return (template, data, content_type)
    3246

comment:2 Changed 4 years ago by figaro

Keywords: patch added

comment:3 Changed 4 years ago by anonymous

                                          ||
 		                realm == ''

I left this in the diff by mistake. Other simple realms (that only require the same handling as wiki:) could be added there.

comment:4 Changed 4 years ago by lucid

Resolution: fixed
Status: newclosed

In 17776:

TextareaKeyBindingsPlugin: Transform pasted links to TracLinks syntax. (fix #13831)

comment:5 Changed 3 years ago by lucid

In 17970:

TextareaKeyBindingsPlugin: Transform also InterWiki links with $-parameters. (fix #13831)

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain lucid.
The resolution will be deleted. Next status will be 'reopened'.

Add Comment


E-mail address and name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.