[ADD] ZeroClipboard-based "copy" button on snippets

Also fix ruby setup code, some of its bits were actually Python and didn't
quite work when pasted into irb...
This commit is contained in:
Xavier Morel 2014-11-07 14:00:49 +01:00
parent c98e5b2d2c
commit 5d79dd80e5
4 changed files with 80 additions and 46 deletions

View File

@ -35,28 +35,28 @@ $(function () {
* actually not all blocks because we don't want to add the setup bits to
the setup bits, so that's kinda shit
*/
document.addEventListener('copy', function (e) {
var target = $(e.target).closest('.switchable:not(.setup)').get(0);
// not in a switchable
if (!target) { return; }
var lang = getHighlightLanguage(target);
if (!lang) {
// switchable without highlight (e.g. language-specific notes),
// don't munge
return;
}
e.preventDefault();
// get generic setup code
var prefix = document.querySelector('.setupcode.highlight-' + lang).textContent;
document.addEventListener('copy', copyCode);
// prepend setup code to current snippet, get all of current snippet
// in case only part of it was selected
var data = prefix + target.textContent;
// sane browsers
e.clipboardData.setData('text/plain', data);
// MSIE
e.clipboardData.setData('Text', data);
ZeroClipboard.config({
swfPath: '../_static/zeroclipboard-2.1.6/ZeroClipboard.swf',
flashLoadTimeout: 3e3,
});
var zc = new ZeroClipboard();
zc.on('ready', function () {
var $highlighted = $('.switchable:not(.setup) .highlight').addClass('with-btn-clipboard');
var $clipboard_buttons =
$('<button type="button" class="btn-clipboard">Copy</button>')
.on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function () {
$(this).removeClass('active');
})
.prependTo($highlighted);
zc.clip($clipboard_buttons);
});
zc.on('copy', function (e) {
// yellow flash
$(e.target).addClass('active');
copyCode(e);
});
// stripe page stuff
@ -96,6 +96,36 @@ $(function () {
});
})(); }
function copyCode(e) {
// works for both C-c and "Copy" button if copy button is injected
// inside highlighted code section
var target = $(e.target).closest('.switchable:not(.setup)').get(0);
// not in a switchable
if (!target) { return; }
var lang = getHighlightLanguage(target);
if (!lang) {
// switchable without highlight (e.g. language-specific notes),
// don't munge
return;
}
// get generic setup code
var setup_selector = '.setupcode.highlight-' + lang + ' pre';
var setup = document.querySelector(setup_selector).textContent;
// prepend setup code to current snippet, get all of current snippet
// in case only part of it was selected. Ensure we don't get e.g.
// button text around snippet itself
var data = setup + '\n' + target.querySelector('pre').textContent;
// sane browsers & ZeroClipboard
e.clipboardData.setData('text/plain', data);
// MSIE
e.clipboardData.setData('Text', data);
// no preventDefault on ZC event
e.preventDefault && e.preventDefault();
}
/**
* @param {Node} node highlight node to get the language of
* @returns {String|null} either the highlight language or null

View File

@ -6653,23 +6653,20 @@ div.section > h2 {
word-break: normal;
word-wrap: normal;
}
.switchable .highlight.with-btn-clipboard pre {
padding-right: 50px;
}
/*
* ZeroClipboard styles
*/
.zero-clipboard {
.highlight {
position: relative;
display: none;
}
@media (min-width: 768px) {
.zero-clipboard {
display: block;
}
}
.btn-clipboard {
position: absolute;
top: 0;
right: 0;
z-index: 10;
z-index: 3;
display: block;
padding: 5px 8px;
font-size: 12px;
@ -6679,10 +6676,14 @@ div.section > h2 {
border: 1px solid #e1e1e8;
border-radius: 0 4px 0 4px;
}
.btn-clipboard-hover {
color: #fff;
background-color: #a24689;
border-color: #a24689;
.btn-clipboard:focus {
outline: none;
}
.btn-clipboard.active {
background-color: #ffffad;
-webkit-transition: background-color 0.5s linear;
-o-transition: background-color 0.5s linear;
transition: background-color 0.5s linear;
}
img.align-center {
display: block;

View File

@ -473,23 +473,22 @@ div.section > h2 {
word-break: normal;
word-wrap: normal;
}
.switchable .highlight.with-btn-clipboard pre {
// avoid copy button overlapping with even long lines
padding-right: 50px;
}
/*
* ZeroClipboard styles
*/
.zero-clipboard {
.highlight {
position: relative;
display: none;
@media (min-width: @screen-sm-min) {
display: block;
}
}
.btn-clipboard {
position: absolute;
top: 0;
right: 0;
z-index: 10;
z-index: 3;
display: block;
padding: 5px 8px;
font-size: 12px;
@ -498,11 +497,15 @@ div.section > h2 {
background-color: #fff;
border: 1px solid #e1e1e8;
border-radius: 0 4px 0 4px;
}
.btn-clipboard-hover {
color: #fff;
background-color: @brand-primary;
border-color: @brand-primary;
&:focus {
outline: none;
}
&.active {
background-color: #ffffad;
.transition(background-color .5s linear);
}
}
// rST styles

View File

@ -43,8 +43,8 @@ Connection and authentication
url, db, username, password = \
info['host'], info['database'], info['user'], info['password']
common = XMLRPC::Client.new2("#{url}/xmlrpc/2/common")
uid = common.authenticate(db, username, password, {})
models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))
uid = common.call('authenticate', db, username, password, {})
models = XMLRPC::Client.new2("#{url}/xmlrpc/2/object").proxy
.. code-block:: php