[IMP] doc-ws: prepend setup code when copying from a snippet

This commit is contained in:
Xavier Morel 2014-11-07 11:27:37 +01:00
parent 0c74b9d027
commit 6f0b1fef4d
7 changed files with 162 additions and 99 deletions

View File

@ -6,7 +6,7 @@
'_static/bootstrap/js/tooltip.js',
'_static/bootstrap/js/collapse.js',
'_static/bootstrap/js/dropdown.js',
'_static/ZeroClipboard.min.js',
'_static/zeroclipboard-2.1.6/ZeroClipboard.min.js',
'_static/app.js'
] %}

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -25,7 +25,92 @@ $(function () {
});
}, 100);
// lang switcher
/*
for clipboard:
* add per-language setup code to document, hidden
* adds button to each switchable language block except when they're setup
stuff because fuck'em
* per-language, add clipboard hook to prefix with setup bit on-copy
* setup bit is... ?
* 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;
// 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);
});
// stripe page stuff
if ($('div.document-super').hasClass('stripe')) { (function () {
// iterate on highlighted PL blocks (but not results because that'd
// be gross), extract all switchable PLs in the document and add
// clipboard-copy buttons
var languages = {};
$('div.switchable').each(function () {
var language = getHighlightLanguage(this);
if (language) {
languages[language] = true;
}
});
// if can't find CSS where base rule lives something's probably
// broken, bail
var sheet = findSheet(/style\.css$/);
if (!sheet) { return; }
// build PL switcher UI and hook toggle event
$(buildSwitcher(Object.keys(languages)))
.prependTo('div.documentwrapper')
.on('click', 'li', function (e) {
$(e.target).addClass('active')
.siblings().removeClass('active');
var id = e.target.textContent;
var lastIndex = sheet.cssRules.length - 1;
var content = sheet.cssRules[lastIndex].style.cssText;
// change rule in CSS because why not (also can add new
// languages without having to e.g. change CSS or anything)
var sel = [
'.stripe .only-', id, ', ',
'.stripe .highlight-', id, ' > .highlight'
].join('');
sheet.deleteRule(lastIndex);
sheet.insertRule(sel + '{' + content + '}', lastIndex);
});
})(); }
/**
* @param {Node} node highlight node to get the language of
* @returns {String|null} either the highlight language or null
*/
function getHighlightLanguage(node) {
var classes = node.className.split(/\s+/);
for (var i = 0; i < classes.length; ++i) {
var cls = classes[i];
if (/^highlight-/.test(cls)) {
return cls.slice(10);
}
}
return null;
}
// programming language switcher
function findSheet(pattern, fromSheet) {
if (fromSheet) {
for(var i=0; i<fromSheet.cssRules.length; ++i) {
@ -63,87 +148,4 @@ $(function () {
}
return root;
}
if ($('div.document-super').hasClass('stripe')) { (function () {
var sheet = findSheet(/style\.css$/);
if (!sheet) { return; }
// collect languages
var languages = {};
$('div.switchable').each(function () {
var classes = this.className.split(/\s+/);
for (var i = 0; i < classes.length; ++i) {
var cls = classes[i];
if (!/^highlight-/.test(cls)) { continue; }
languages[cls.slice(10)] = true;
}
});
$(buildSwitcher(Object.keys(languages)))
.prependTo('div.documentwrapper')
.on('click', 'li', function (e) {
$(e.target).addClass('active')
.siblings().removeClass('active');
var id = e.target.textContent;
var lastIndex = sheet.cssRules.length - 1;
var content = sheet.cssRules[lastIndex].style.cssText;
var sel = [
'.stripe .only-', id, ', ',
'.stripe .highlight-', id, ' > .highlight'
].join('');
sheet.deleteRule(lastIndex);
sheet.insertRule(sel + '{' + content + '}', lastIndex);
});
})(); }
// Config ZeroClipboard
ZeroClipboard.config({
moviePath: '_static/ZeroClipboard.swf',
hoverClass: 'btn-clipboard-hover'
});
// Insert copy to clipboard button before .highlight or .example
$('.highlight-html, .highlight-scss').each(function () {
var highlight = $(this);
var previous = highlight.prev();
var btnHtml = '<div class="zero-clipboard"><span class="btn-clipboard">Copy</span></div>';
if (previous.hasClass('example')) {
previous.before(btnHtml.replace(/btn-clipboard/, 'btn-clipboard with-example'));
} else {
highlight.before(btnHtml);
}
});
var zeroClipboard = new ZeroClipboard($('.btn-clipboard'));
var htmlBridge = $('#global-zeroclipboard-html-bridge');
// Handlers for ZeroClipboard
zeroClipboard.on('load', function () {
htmlBridge
.data('placement', 'top')
.attr('title', 'Copy to clipboard')
.tooltip();
});
// Copy to clipboard
zeroClipboard.on('dataRequested', function (client) {
var highlight = $(this).parent().nextAll('.highlight').first();
client.setText(highlight.text());
});
// Notify copy success and reset tooltip title
zeroClipboard.on('complete', function () {
htmlBridge
.attr('title', 'Copied!')
.tooltip('fixTitle')
.tooltip('show')
.attr('title', 'Copy to clipboard')
.tooltip('fixTitle');
});
// Notify copy failure
zeroClipboard.on('noflash wrongflash', function () {
htmlBridge.attr('title', 'Flash required')
.tooltip('fixTitle')
.tooltip('show');
});
});

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -22,13 +22,74 @@ easily available over XML-RPC_ and accessible from a variety of languages.
Connection and authentication
=============================
.. kinda gross because it duplicates existing bits
.. rst-class:: setupcode hidden
.. code-block:: python
import xmlrpclib
info = xmlrpclib.ServerProxy('https://demo.odoo.com/start').start()
url, db, username, password = \
info['host'], info['database'], info['user'], info['password']
common = xmlrpclib.ServerProxy('{}/xmlrpc/2/common'.format(url))
uid = common.authenticate(db, username, password, {})
models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))
.. code-block:: ruby
require "xmlrpc/client"
info = XMLRPC::Client.new2('https://demo.odoo.com/start').call('start')
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))
.. code-block:: php
require_once('ripcord.php');
$info = ripcord::client('https://demo.odoo.com/start')->start();
list($url, $db, $username, $password) =
array($info['host'], $info['database'], $info['user'], $info['password']);
$common = ripcord::client("$url/xmlrpc/2/common");
$uid = $common->authenticate($db, $username, $password, array());
$models = ripcord::client("$url/xmlrpc/2/object");
.. code-block:: java
final XmlRpcClient client = new XmlRpcClient();
final XmlRpcClientConfigImpl start_config = new XmlRpcClientConfigImpl();
start_config.setServerURL(new URL("https://demo.odoo.com/start"));
final Map<String, String> info = (Map<String, String>)client.execute(
start_config, "start", Collections.emptyList());
final String url = info.get("host"),
db = info.get("database"),
username = info.get("user"),
password = info.get("password");
final XmlRpcClientConfigImpl common_config = new XmlRpcClientConfigImpl();
common_config.setServerURL(new URL(String.format("%s/xmlrpc/2/common", url)));
int uid = (int)client.execute(
common_config, "authenticate", Arrays.asList(
db, username, password, Collections.emptyMap()));
final XmlRpcClient models = new XmlRpcClient() {{
setConfig(new XmlRpcClientConfigImpl() {{
setServerURL(new URL(String.format("%s/xmlrpc/2/object", url)));
}});
}};
Configuration
-------------
If you already have an Odoo server installed, you can just use its
parameters
.. rst-class:: switchable
.. rst-class:: switchable setup
.. code-block:: python
@ -61,7 +122,7 @@ parameters
To make exploration simpler, you can also ask https://demo.odoo.com for a test
database:
.. rst-class:: switchable
.. rst-class:: switchable setup
.. code-block:: python
@ -134,7 +195,7 @@ authentication itself is done through the ``authenticate`` function and
returns a user identifier (``uid``) used in authenticated calls instead of
the login.
.. rst-class:: switchable
.. rst-class:: switchable setup
.. code-block:: python
@ -166,7 +227,7 @@ the login.
"protocol_version": 1,
}
.. rst-class:: switchable
.. rst-class:: switchable setup
.. code-block:: python
@ -209,7 +270,7 @@ For instance to see if we can read the ``res.partner`` model we can call
``raise_exception`` passed by keyword (in order to get a true/false result
rather than true/error):
.. rst-class:: switchable
.. rst-class:: switchable setup
.. code-block:: python