├── Makefile ├── _static ├── accounting.css ├── accounts.js ├── atom.js ├── chart-of-accounts.js ├── coa-valuation.js ├── entries.js ├── immutable.js ├── inventory.js ├── misc.js ├── prefixfree.min.js ├── react.js ├── react.min.js └── reconciliation.js ├── _themes └── odoodoc │ ├── README.rst │ ├── __init__.py │ ├── github.py │ ├── html_domain.py │ ├── layout.html │ ├── odoo_pygments.py │ ├── sphinx_monkeypatch.py │ ├── static │ ├── app.js │ ├── bootstrap │ │ ├── js │ │ │ ├── affix.js │ │ │ ├── alert.js │ │ │ ├── button.js │ │ │ ├── carousel.js │ │ │ ├── collapse.js │ │ │ ├── dropdown.js │ │ │ ├── modal.js │ │ │ ├── popover.js │ │ │ ├── scrollspy.js │ │ │ ├── tab.js │ │ │ ├── tests │ │ │ │ ├── index.html │ │ │ │ ├── unit │ │ │ │ │ ├── affix.js │ │ │ │ │ ├── alert.js │ │ │ │ │ ├── button.js │ │ │ │ │ ├── carousel.js │ │ │ │ │ ├── collapse.js │ │ │ │ │ ├── dropdown.js │ │ │ │ │ ├── modal.js │ │ │ │ │ ├── phantom.js │ │ │ │ │ ├── popover.js │ │ │ │ │ ├── scrollspy.js │ │ │ │ │ ├── tab.js │ │ │ │ │ └── tooltip.js │ │ │ │ ├── vendor │ │ │ │ │ ├── jquery.min.js │ │ │ │ │ └── qunit.js │ │ │ │ └── visual │ │ │ │ │ ├── affix.html │ │ │ │ │ ├── alert.html │ │ │ │ │ ├── button.html │ │ │ │ │ ├── carousel.html │ │ │ │ │ ├── collapse.html │ │ │ │ │ ├── dropdown.html │ │ │ │ │ ├── modal.html │ │ │ │ │ ├── popover.html │ │ │ │ │ ├── scrollspy.html │ │ │ │ │ ├── tab.html │ │ │ │ │ └── tooltip.html │ │ │ ├── tooltip.js │ │ │ └── transition.js │ │ └── less │ │ │ ├── alerts.less │ │ │ ├── badges.less │ │ │ ├── bootstrap.less │ │ │ ├── breadcrumbs.less │ │ │ ├── button-groups.less │ │ │ ├── buttons.less │ │ │ ├── carousel.less │ │ │ ├── close.less │ │ │ ├── code.less │ │ │ ├── component-animations.less │ │ │ ├── dropdowns.less │ │ │ ├── forms.less │ │ │ ├── glyphicons.less │ │ │ ├── grid.less │ │ │ ├── input-groups.less │ │ │ ├── jumbotron.less │ │ │ ├── labels.less │ │ │ ├── list-group.less │ │ │ ├── media.less │ │ │ ├── mixins.less │ │ │ ├── mixins │ │ │ ├── alerts.less │ │ │ ├── background-variant.less │ │ │ ├── border-radius.less │ │ │ ├── buttons.less │ │ │ ├── center-block.less │ │ │ ├── clearfix.less │ │ │ ├── forms.less │ │ │ ├── gradients.less │ │ │ ├── grid-framework.less │ │ │ ├── grid.less │ │ │ ├── hide-text.less │ │ │ ├── image.less │ │ │ ├── labels.less │ │ │ ├── list-group.less │ │ │ ├── nav-divider.less │ │ │ ├── nav-vertical-align.less │ │ │ ├── opacity.less │ │ │ ├── pagination.less │ │ │ ├── panels.less │ │ │ ├── progress-bar.less │ │ │ ├── reset-filter.less │ │ │ ├── resize.less │ │ │ ├── responsive-visibility.less │ │ │ ├── size.less │ │ │ ├── tab-focus.less │ │ │ ├── table-row.less │ │ │ ├── text-emphasis.less │ │ │ ├── text-overflow.less │ │ │ └── vendor-prefixes.less │ │ │ ├── modals.less │ │ │ ├── navbar.less │ │ │ ├── navs.less │ │ │ ├── normalize.less │ │ │ ├── pager.less │ │ │ ├── pagination.less │ │ │ ├── panels.less │ │ │ ├── popovers.less │ │ │ ├── print.less │ │ │ ├── progress-bars.less │ │ │ ├── responsive-embed.less │ │ │ ├── responsive-utilities.less │ │ │ ├── scaffolding.less │ │ │ ├── tables.less │ │ │ ├── theme.less │ │ │ ├── thumbnails.less │ │ │ ├── tooltip.less │ │ │ ├── type.less │ │ │ ├── utilities.less │ │ │ ├── variables.less │ │ │ └── wells.less │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ ├── github-link.png │ ├── odoo_logo_rgb.png │ ├── odoodoc.css_t │ ├── style.css │ └── style.less │ └── theme.conf ├── accounting.rst ├── conf.py ├── double-entry.rst ├── index.rst ├── inventory.rst └── valuation.rst /_static/accounting.css: -------------------------------------------------------------------------------- 1 | .intro-list p { 2 | margin: 0; 3 | cursor: pointer; 4 | } 5 | 6 | .related { 7 | background-color: hsl(219, 76%, 88%) !important; 8 | } 9 | .secondary { 10 | background-color: hsl(219, 67%, 94%) !important; 11 | } 12 | .highlight-op { 13 | background-color: hsl(219, 67%, 94%); 14 | } 15 | 16 | label:hover, 17 | label:hover, 18 | .highlighter-list li:hover { 19 | background-color: hsl(0, 0%, 94%); 20 | cursor: pointer; 21 | } 22 | 23 | .accounts-table { 24 | font-size: 90%; 25 | } 26 | 27 | .accounts-table dl { 28 | margin: 0; 29 | } 30 | 31 | .accounts-table h4, .accounts-table h5 { 32 | font-weight: normal; 33 | } 34 | 35 | .accounts-table h4 { 36 | text-align: center; 37 | } 38 | /* table root */ 39 | .accounts-table > div { 40 | display: flex; 41 | align-items: flex-start; 42 | } 43 | /* P&L & Balance Sheet columns */ 44 | .accounts-table > div > div { 45 | flex: 1; 46 | padding: 5px; 47 | margin: 0 5% 5% 5%; 48 | border: 2px solid #666; 49 | border-radius: 3px; 50 | } 51 | 52 | /* sections */ 53 | .accounts-table > div > div div { 54 | display: flex; 55 | flex-direction: column; 56 | } 57 | 58 | .accounts-table > div > div div > h5 { 59 | order: 99; 60 | 61 | text-transform: uppercase; 62 | 63 | padding: 0.3em 0; 64 | border-image: linear-gradient(to bottom, transparent, rgb(221, 225, 231), transparent, rgb(221, 225, 231), transparent) 5 0 10 / 3px 0 3px; 65 | } 66 | .accounts-table > div > div div div > h5 { 67 | /* slightly smaller than normal 14px h5 size */ 68 | font-size: 12.5px; 69 | border-image: linear-gradient(to bottom, transparent, rgb(221, 225, 231), transparent, rgb(221, 225, 231), transparent) 5 0 5; 70 | } 71 | .accounts-table dt { 72 | font-weight: normal; 73 | } 74 | .accounts-table dt span { 75 | font-style: italic; 76 | } 77 | .accounts-table dt span:last-child { 78 | font-style: normal; 79 | } 80 | 81 | .values-table tr > * { 82 | text-align: right; 83 | } 84 | .values-table tr > :first-child { 85 | text-align: left; 86 | } 87 | 88 | /* 3-column (thing, debit, credit) tables */ 89 | /* 2nd and 3rd th & td of each row right-aligned and 1/4th width */ 90 | .d-c-table tr > :nth-child(2), 91 | .d-c-table tr > :nth-child(3) { 92 | width: 25%; 93 | text-align: right; 94 | } 95 | 96 | @media (min-width: 992px) { 97 | .accounts-table, .force-right .highlighter-target { 98 | font-size: 90%; 99 | color: #888 !important; 100 | } 101 | .force-right .highlighter-target th { 102 | font-weight: normal; 103 | font-size: 110%; 104 | } 105 | .accounts-table .related, .force-right .highlighter-target .related { 106 | background-color: transparent !important; 107 | color: #eee !important; 108 | } 109 | .accounts-table .secondary, .force-right .highlighter-target .secondary { 110 | background-color: transparent !important; 111 | color: #aaa !important; 112 | } 113 | 114 | .chart-of-accounts .highlight-op, 115 | .valuation-chart .highlight-op { 116 | background-color: #030035; 117 | } 118 | } 119 | 120 | .journal-entries .entries-listing p { 121 | font-style: italic; 122 | } 123 | 124 | #reconciliation .reconciliation-example div.buttons { 125 | display: flex; 126 | justify-content: center; 127 | } 128 | #reconciliation .reconciliation-example div.buttons button { 129 | margin: 0 0.5em; 130 | } 131 | 132 | @keyframes reconcile { 133 | 0% { 134 | font-size: 100%; 135 | padding-top: 5px; 136 | padding-bottom: 5px; 137 | background-color: rgba(2, 0, 31, 0); 138 | } 139 | 60% { 140 | background-color: rgba(2, 0, 31, 1); 141 | } 142 | 80% { 143 | font-size: 100%; 144 | padding-top: 5px; 145 | padding-bottom: 5px; 146 | } 147 | 100% { 148 | font-size: 0%; 149 | padding-top: 0; 150 | padding-bottom: 0; 151 | display: none; 152 | } 153 | } 154 | .reconcile1 .invoice1, .reconcile1 .invoice1 td { 155 | animation: reconcile 5s ease-in forwards; 156 | } 157 | .reconcile2 .invoice2, .reconcile2 .invoice2 td { 158 | animation: reconcile 5s ease-in forwards; 159 | } 160 | 161 | .invoice1.reconciled, .invoice2.reconciled { 162 | display: none; 163 | } 164 | 165 | blockquote.highlights { 166 | margin-bottom: 0; 167 | text-align: center; 168 | } 169 | 170 | /* 171 | lists of alternatives 172 | */ 173 | .alternatives-controls label { 174 | display: block; 175 | } 176 | dl.alternatives > dt, 177 | dl.alternatives > dd { 178 | display: none; 179 | } 180 | dl.alternatives > dd { 181 | margin-left: 0; 182 | } 183 | -------------------------------------------------------------------------------- /_static/atom.js: -------------------------------------------------------------------------------- 1 | function createAtom(val, options) { 2 | var watchers = {}; 3 | var validator = options && options.validator || function () { return true; }; 4 | 5 | function transition(next) { 6 | if (!validator(next)) { 7 | var err = new Error(next + " failed validation"); 8 | err.name = "AssertionError"; 9 | throw err; 10 | } 11 | 12 | var prev = val; 13 | val = next; 14 | 15 | Object.keys(watchers).forEach(function (k) { 16 | watchers[k](k, atom, prev, next); 17 | }); 18 | } 19 | 20 | var atom = { 21 | addWatch: function (key, fn) { 22 | watchers[key] = fn; 23 | }, 24 | 25 | removeWatch: function (key) { 26 | delete watchers[key]; 27 | }, 28 | 29 | swap: function (fn) { 30 | var args = [val].concat([].slice.call(arguments, 1)); 31 | transition(fn.apply(null, args)); 32 | }, 33 | 34 | reset: function (v) { 35 | transition(v); 36 | }, 37 | 38 | deref: function () { 39 | return val; 40 | }, 41 | 42 | toString: function () { 43 | return "Atom(" + JSON.stringify(val) + ")"; 44 | } 45 | }; 46 | 47 | return atom; 48 | } 49 | -------------------------------------------------------------------------------- /_static/misc.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | document.addEventListener('DOMContentLoaded', function () { 3 | alternatives(); 4 | highlight(); 5 | checks_handling(); 6 | }); 7 | 8 | function highlight() { 9 | $('.highlighter-list').each(function () { 10 | var $this = $(this), 11 | $target = $($this.data('target')); 12 | $this.on('mouseout', 'li', function (e) { 13 | $(e.currentTarget).removeClass('secondary'); 14 | $target.find('.related').removeClass('related'); 15 | }).on('mouseover', 'li', function (e) { 16 | if (!e.currentTarget.contains(e.target)) { return; } 17 | 18 | var $li = $(e.currentTarget); 19 | console.log($li, $li.data('highlight'), $target.find($li.data('highlight'))); 20 | $li.addClass('secondary'); 21 | $target.find($li.data('highlight')).addClass('related'); 22 | }); 23 | }); 24 | } 25 | /** alternatives display: 26 | * - prepend control for each
27 | * - radio input with link to following dd 28 | * - label is
content 29 | * - hide all first-level dt and dd (CSS) 30 | * - on change 31 | * - hide all dds 32 | * - show dd corresponding to the selected radio 33 | * - automatically select first control on startup 34 | */ 35 | function alternatives() { 36 | $('dl.alternatives').each(function (index) { 37 | var $list = $(this), 38 | $contents = $list.children('dd'); 39 | var $controls = $('
').append( 40 | $list.children('dt').map(function () { 41 | var label = document.createElement('label'), 42 | input = document.createElement('input'); 43 | input.setAttribute('type', 'radio'); 44 | input.setAttribute('name', 'alternatives-' + index); 45 | 46 | var sibling = this; 47 | while ((sibling = sibling.nextSibling) && sibling.nodeType !== 1); 48 | input.content = sibling; 49 | 50 | label.appendChild(input); 51 | label.appendChild(document.createTextNode(' ')); 52 | label.appendChild(document.createTextNode(this.textContent)); 53 | 54 | return label; 55 | })) 56 | .insertBefore($list) 57 | .on('change', 'input', function (e) { 58 | // change event triggers only on newly selected input, not 59 | // on the one being deselected 60 | $contents.css('display', ''); 61 | var content = e.target.content; 62 | content && (content.style.display = 'block'); 63 | }) 64 | .find('input:first').click(); 65 | }); 66 | } 67 | function checks_handling() { 68 | var $section = $('.checks-handling'); 69 | if (!$section.length) { return; } 70 | 71 | var $ul = $section.find('ul') 72 | .find('li').each(function () { 73 | var txt = this.textContent; 74 | while (this.firstChild) { 75 | this.removeChild(this.firstChild) 76 | } 77 | 78 | $('
86 | 87 | {%- endblock -%} 88 | {%- block relbar2 -%}{%- endblock -%} 89 | 90 | {%- block footer %} 91 | 124 | {%- if google_analytics_key -%} 125 | 134 | {%- endif -%} 135 | {%- endblock %} 136 | -------------------------------------------------------------------------------- /_themes/odoodoc/odoo_pygments.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import imp 4 | import sys 5 | 6 | from pygments.style import Style 7 | from pygments.token import * 8 | 9 | # extracted from getbootstrap.com 10 | class OdooStyle(Style): 11 | background_color = '#ffffcc' 12 | highlight_color = '#fcf8e3' 13 | styles = { 14 | Whitespace: '#BBB', 15 | Error: 'bg:#FAA #A00', 16 | 17 | Keyword: '#069', 18 | Keyword.Type: '#078', 19 | 20 | Name.Attribute: '#4F9FCF', 21 | Name.Builtin: '#366', 22 | Name.Class: '#0A8', 23 | Name.Constant: '#360', 24 | Name.Decorator: '#99F', 25 | Name.Entity: '#999', 26 | Name.Exception: '#C00', 27 | Name.Function: '#C0F', 28 | Name.Label: '#99F', 29 | Name.Namespace: '#0CF', 30 | Name.Tag: '#2F6F9F', 31 | Name.Variable: '#033', 32 | 33 | String: '#d44950', 34 | String.Backtick: '#C30', 35 | String.Char: '#C30', 36 | String.Doc: 'italic #C30', 37 | String.Double: '#C30', 38 | String.Escape: '#C30', 39 | String.Heredoc: '#C30', 40 | String.Interol: '#C30', 41 | String.Other: '#C30', 42 | String.Regex: '#3AA', 43 | String.Single: '#C30', 44 | String.Symbol: '#FC3', 45 | 46 | Number: '#F60', 47 | 48 | Operator: '#555', 49 | Operator.Word: '#000', 50 | 51 | Comment: '#999', 52 | Comment.Preproc: '#099', 53 | 54 | Generic.Deleted: 'bg:#FCC border:#c00', 55 | Generic.Emph: 'italic', 56 | Generic.Error: '#F00', 57 | Generic.Heading: '#030', 58 | Generic.Inserted: 'bg:#CFC border:#0C0', 59 | Generic.Output: '#AAA', 60 | Generic.Prompt: '#009', 61 | Generic.Strong: '', 62 | Generic.Subheading: '#030', 63 | Generic.Traceback: '#9C6', 64 | } 65 | 66 | 67 | modname = 'pygments.styles.odoo' 68 | m = imp.new_module(modname) 69 | m.OdooStyle = OdooStyle 70 | sys.modules[modname] = m 71 | -------------------------------------------------------------------------------- /_themes/odoodoc/sphinx_monkeypatch.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import sphinx.roles 3 | import sphinx.environment 4 | from sphinx.writers.html import HTMLTranslator 5 | from docutils.writers.html4css1 import HTMLTranslator as DocutilsTranslator 6 | 7 | def patch(): 8 | # navify toctree (oh god) 9 | @monkey(sphinx.environment.BuildEnvironment) 10 | def resolve_toctree(old_resolve, self, *args, **kwargs): 11 | """ If navbar, bootstrapify TOC to yield a navbar 12 | 13 | """ 14 | navbar = kwargs.pop('navbar', None) 15 | toc = old_resolve(self, *args, **kwargs) 16 | if toc is None: 17 | return None 18 | 19 | navbarify(toc[0], navbar=navbar) 20 | return toc 21 | 22 | # monkeypatch visit_table to remove border and add .table 23 | HTMLTranslator.visit_table = visit_table 24 | # disable colspec crap 25 | HTMLTranslator.write_colspecs = lambda self: None 26 | # copy data- attributes straight from source to dest 27 | HTMLTranslator.starttag = starttag_data 28 | 29 | def navbarify(node, navbar=None): 30 | """ 31 | :param node: toctree node to navbarify 32 | :param navbar: Whether this toctree is a 'main' navbar, a 'side' navbar or 33 | not a navbar at all 34 | """ 35 | if navbar == 'side': 36 | for n in node.traverse(): 37 | if n.tagname == 'bullet_list': 38 | n['classes'].append('nav') 39 | elif navbar == 'main': 40 | # add classes to just toplevel 41 | node['classes'].extend(['nav', 'navbar-nav', 'navbar-right']) 42 | for list_item in node.children: 43 | # bullet_list 44 | # list_item 45 | # compact_paragraph 46 | # reference 47 | # bullet_list 48 | # list_item 49 | # compact_paragraph 50 | # reference 51 | # no bullet_list.list_item -> don't dropdownify 52 | if not list_item.children[1].children: 53 | continue 54 | 55 | list_item['classes'].append('dropdown') 56 | # list_item.compact_paragraph.reference 57 | link = list_item.children[0].children[0] 58 | link['classes'].append('dropdown-toggle') 59 | link.attributes['data-toggle'] = 'dropdown' 60 | # list_item.bullet_list 61 | list_item.children[1]['classes'].append('dropdown-menu') 62 | 63 | def visit_table(self, node): 64 | """ 65 | * remove border 66 | * add table class 67 | """ 68 | self._table_row_index = 0 69 | self.context.append(self.compact_p) 70 | self.compact_p = True 71 | 72 | classes = {self.settings.table_style} 73 | node_classes = node.get('classes', []) 74 | if 'no-table' in node_classes: node_classes.remove('no-table') 75 | else: classes.add('table') 76 | 77 | self.body.append(self.starttag(node, 'table', CLASS=' '.join(classes).strip())) 78 | 79 | def starttag_data(self, node, tagname, suffix='\n', empty=False, **attributes): 80 | attributes.update( 81 | (k, v) for k, v in node.attributes.iteritems() 82 | if k.startswith('data-') 83 | ) 84 | # oh dear 85 | return DocutilsTranslator.starttag( 86 | self, node, tagname, suffix=suffix, empty=empty, **attributes) 87 | 88 | class monkey(object): 89 | def __init__(self, obj): 90 | self.obj = obj 91 | def __call__(self, fn): 92 | name = fn.__name__ 93 | old = getattr(self.obj, name) 94 | setattr(self.obj, name, lambda self_, *args, **kwargs: \ 95 | fn(old, self_, *args, **kwargs)) 96 | -------------------------------------------------------------------------------- /_themes/odoodoc/static/bootstrap/js/affix.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: affix.js v3.2.0 3 | * http://getbootstrap.com/javascript/#affix 4 | * ======================================================================== 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // AFFIX CLASS DEFINITION 14 | // ====================== 15 | 16 | var Affix = function (element, options) { 17 | this.options = $.extend({}, Affix.DEFAULTS, options) 18 | 19 | this.$target = $(this.options.target) 20 | .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) 21 | .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) 22 | 23 | this.$element = $(element) 24 | this.affixed = 25 | this.unpin = 26 | this.pinnedOffset = null 27 | 28 | this.checkPosition() 29 | } 30 | 31 | Affix.VERSION = '3.2.0' 32 | 33 | Affix.RESET = 'affix affix-top affix-bottom' 34 | 35 | Affix.DEFAULTS = { 36 | offset: 0, 37 | target: window 38 | } 39 | 40 | Affix.prototype.getPinnedOffset = function () { 41 | if (this.pinnedOffset) return this.pinnedOffset 42 | this.$element.removeClass(Affix.RESET).addClass('affix') 43 | var scrollTop = this.$target.scrollTop() 44 | var position = this.$element.offset() 45 | return (this.pinnedOffset = position.top - scrollTop) 46 | } 47 | 48 | Affix.prototype.checkPositionWithEventLoop = function () { 49 | setTimeout($.proxy(this.checkPosition, this), 1) 50 | } 51 | 52 | Affix.prototype.checkPosition = function () { 53 | if (!this.$element.is(':visible')) return 54 | 55 | var scrollHeight = $(document).height() 56 | var scrollTop = this.$target.scrollTop() 57 | var position = this.$element.offset() 58 | var offset = this.options.offset 59 | var offsetTop = offset.top 60 | var offsetBottom = offset.bottom 61 | 62 | if (typeof offset != 'object') offsetBottom = offsetTop = offset 63 | if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) 64 | if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) 65 | 66 | var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false : 67 | offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' : 68 | offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false 69 | 70 | if (this.affixed === affix) return 71 | if (this.unpin != null) this.$element.css('top', '') 72 | 73 | var affixType = 'affix' + (affix ? '-' + affix : '') 74 | var e = $.Event(affixType + '.bs.affix') 75 | 76 | this.$element.trigger(e) 77 | 78 | if (e.isDefaultPrevented()) return 79 | 80 | this.affixed = affix 81 | this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null 82 | 83 | this.$element 84 | .removeClass(Affix.RESET) 85 | .addClass(affixType) 86 | .trigger($.Event(affixType.replace('affix', 'affixed'))) 87 | 88 | if (affix == 'bottom') { 89 | this.$element.offset({ 90 | top: scrollHeight - this.$element.height() - offsetBottom 91 | }) 92 | } 93 | } 94 | 95 | 96 | // AFFIX PLUGIN DEFINITION 97 | // ======================= 98 | 99 | function Plugin(option) { 100 | return this.each(function () { 101 | var $this = $(this) 102 | var data = $this.data('bs.affix') 103 | var options = typeof option == 'object' && option 104 | 105 | if (!data) $this.data('bs.affix', (data = new Affix(this, options))) 106 | if (typeof option == 'string') data[option]() 107 | }) 108 | } 109 | 110 | var old = $.fn.affix 111 | 112 | $.fn.affix = Plugin 113 | $.fn.affix.Constructor = Affix 114 | 115 | 116 | // AFFIX NO CONFLICT 117 | // ================= 118 | 119 | $.fn.affix.noConflict = function () { 120 | $.fn.affix = old 121 | return this 122 | } 123 | 124 | 125 | // AFFIX DATA-API 126 | // ============== 127 | 128 | $(window).on('load', function () { 129 | $('[data-spy="affix"]').each(function () { 130 | var $spy = $(this) 131 | var data = $spy.data() 132 | 133 | data.offset = data.offset || {} 134 | 135 | if (data.offsetBottom) data.offset.bottom = data.offsetBottom 136 | if (data.offsetTop) data.offset.top = data.offsetTop 137 | 138 | Plugin.call($spy, data) 139 | }) 140 | }) 141 | 142 | }(jQuery); 143 | -------------------------------------------------------------------------------- /_themes/odoodoc/static/bootstrap/js/alert.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: alert.js v3.2.0 3 | * http://getbootstrap.com/javascript/#alerts 4 | * ======================================================================== 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // ALERT CLASS DEFINITION 14 | // ====================== 15 | 16 | var dismiss = '[data-dismiss="alert"]' 17 | var Alert = function (el) { 18 | $(el).on('click', dismiss, this.close) 19 | } 20 | 21 | Alert.VERSION = '3.2.0' 22 | 23 | Alert.prototype.close = function (e) { 24 | var $this = $(this) 25 | var selector = $this.attr('data-target') 26 | 27 | if (!selector) { 28 | selector = $this.attr('href') 29 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 30 | } 31 | 32 | var $parent = $(selector) 33 | 34 | if (e) e.preventDefault() 35 | 36 | if (!$parent.length) { 37 | $parent = $this.hasClass('alert') ? $this : $this.parent() 38 | } 39 | 40 | $parent.trigger(e = $.Event('close.bs.alert')) 41 | 42 | if (e.isDefaultPrevented()) return 43 | 44 | $parent.removeClass('in') 45 | 46 | function removeElement() { 47 | // detach from parent, fire event then clean up data 48 | $parent.detach().trigger('closed.bs.alert').remove() 49 | } 50 | 51 | $.support.transition && $parent.hasClass('fade') ? 52 | $parent 53 | .one('bsTransitionEnd', removeElement) 54 | .emulateTransitionEnd(150) : 55 | removeElement() 56 | } 57 | 58 | 59 | // ALERT PLUGIN DEFINITION 60 | // ======================= 61 | 62 | function Plugin(option) { 63 | return this.each(function () { 64 | var $this = $(this) 65 | var data = $this.data('bs.alert') 66 | 67 | if (!data) $this.data('bs.alert', (data = new Alert(this))) 68 | if (typeof option == 'string') data[option].call($this) 69 | }) 70 | } 71 | 72 | var old = $.fn.alert 73 | 74 | $.fn.alert = Plugin 75 | $.fn.alert.Constructor = Alert 76 | 77 | 78 | // ALERT NO CONFLICT 79 | // ================= 80 | 81 | $.fn.alert.noConflict = function () { 82 | $.fn.alert = old 83 | return this 84 | } 85 | 86 | 87 | // ALERT DATA-API 88 | // ============== 89 | 90 | $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) 91 | 92 | }(jQuery); 93 | -------------------------------------------------------------------------------- /_themes/odoodoc/static/bootstrap/js/button.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: button.js v3.2.0 3 | * http://getbootstrap.com/javascript/#buttons 4 | * ======================================================================== 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // BUTTON PUBLIC CLASS DEFINITION 14 | // ============================== 15 | 16 | var Button = function (element, options) { 17 | this.$element = $(element) 18 | this.options = $.extend({}, Button.DEFAULTS, options) 19 | this.isLoading = false 20 | } 21 | 22 | Button.VERSION = '3.2.0' 23 | 24 | Button.DEFAULTS = { 25 | loadingText: 'loading...' 26 | } 27 | 28 | Button.prototype.setState = function (state) { 29 | var d = 'disabled' 30 | var $el = this.$element 31 | var val = $el.is('input') ? 'val' : 'html' 32 | var data = $el.data() 33 | 34 | state = state + 'Text' 35 | 36 | if (data.resetText == null) $el.data('resetText', $el[val]()) 37 | 38 | $el[val](data[state] == null ? this.options[state] : data[state]) 39 | 40 | // push to event loop to allow forms to submit 41 | setTimeout($.proxy(function () { 42 | if (state == 'loadingText') { 43 | this.isLoading = true 44 | $el.addClass(d).attr(d, d) 45 | } else if (this.isLoading) { 46 | this.isLoading = false 47 | $el.removeClass(d).removeAttr(d) 48 | } 49 | }, this), 0) 50 | } 51 | 52 | Button.prototype.toggle = function () { 53 | var changed = true 54 | var $parent = this.$element.closest('[data-toggle="buttons"]') 55 | 56 | if ($parent.length) { 57 | var $input = this.$element.find('input') 58 | if ($input.prop('type') == 'radio') { 59 | if ($input.prop('checked') && this.$element.hasClass('active')) changed = false 60 | else $parent.find('.active').removeClass('active') 61 | } 62 | if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change') 63 | } 64 | 65 | if (changed) this.$element.toggleClass('active') 66 | } 67 | 68 | 69 | // BUTTON PLUGIN DEFINITION 70 | // ======================== 71 | 72 | function Plugin(option) { 73 | return this.each(function () { 74 | var $this = $(this) 75 | var data = $this.data('bs.button') 76 | var options = typeof option == 'object' && option 77 | 78 | if (!data) $this.data('bs.button', (data = new Button(this, options))) 79 | 80 | if (option == 'toggle') data.toggle() 81 | else if (option) data.setState(option) 82 | }) 83 | } 84 | 85 | var old = $.fn.button 86 | 87 | $.fn.button = Plugin 88 | $.fn.button.Constructor = Button 89 | 90 | 91 | // BUTTON NO CONFLICT 92 | // ================== 93 | 94 | $.fn.button.noConflict = function () { 95 | $.fn.button = old 96 | return this 97 | } 98 | 99 | 100 | // BUTTON DATA-API 101 | // =============== 102 | 103 | $(document).on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { 104 | var $btn = $(e.target) 105 | if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 106 | Plugin.call($btn, 'toggle') 107 | e.preventDefault() 108 | }) 109 | 110 | }(jQuery); 111 | -------------------------------------------------------------------------------- /_themes/odoodoc/static/bootstrap/js/collapse.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: collapse.js v3.2.0 3 | * http://getbootstrap.com/javascript/#collapse 4 | * ======================================================================== 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // COLLAPSE PUBLIC CLASS DEFINITION 14 | // ================================ 15 | 16 | var Collapse = function (element, options) { 17 | this.$element = $(element) 18 | this.options = $.extend({}, Collapse.DEFAULTS, options) 19 | this.transitioning = null 20 | 21 | if (this.options.parent) this.$parent = $(this.options.parent) 22 | if (this.options.toggle) this.toggle() 23 | } 24 | 25 | Collapse.VERSION = '3.2.0' 26 | 27 | Collapse.DEFAULTS = { 28 | toggle: true 29 | } 30 | 31 | Collapse.prototype.dimension = function () { 32 | var hasWidth = this.$element.hasClass('width') 33 | return hasWidth ? 'width' : 'height' 34 | } 35 | 36 | Collapse.prototype.show = function () { 37 | if (this.transitioning || this.$element.hasClass('in')) return 38 | 39 | var startEvent = $.Event('show.bs.collapse') 40 | this.$element.trigger(startEvent) 41 | if (startEvent.isDefaultPrevented()) return 42 | 43 | var actives = this.$parent && this.$parent.find('> .panel > .in') 44 | 45 | if (actives && actives.length) { 46 | var hasData = actives.data('bs.collapse') 47 | if (hasData && hasData.transitioning) return 48 | Plugin.call(actives, 'hide') 49 | hasData || actives.data('bs.collapse', null) 50 | } 51 | 52 | var dimension = this.dimension() 53 | 54 | this.$element 55 | .removeClass('collapse') 56 | .addClass('collapsing')[dimension](0) 57 | 58 | this.transitioning = 1 59 | 60 | var complete = function () { 61 | this.$element 62 | .removeClass('collapsing') 63 | .addClass('collapse in')[dimension]('') 64 | this.transitioning = 0 65 | this.$element 66 | .trigger('shown.bs.collapse') 67 | } 68 | 69 | if (!$.support.transition) return complete.call(this) 70 | 71 | var scrollSize = $.camelCase(['scroll', dimension].join('-')) 72 | 73 | this.$element 74 | .one('bsTransitionEnd', $.proxy(complete, this)) 75 | .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize]) 76 | } 77 | 78 | Collapse.prototype.hide = function () { 79 | if (this.transitioning || !this.$element.hasClass('in')) return 80 | 81 | var startEvent = $.Event('hide.bs.collapse') 82 | this.$element.trigger(startEvent) 83 | if (startEvent.isDefaultPrevented()) return 84 | 85 | var dimension = this.dimension() 86 | 87 | this.$element[dimension](this.$element[dimension]())[0].offsetHeight 88 | 89 | this.$element 90 | .addClass('collapsing') 91 | .removeClass('collapse') 92 | .removeClass('in') 93 | 94 | this.transitioning = 1 95 | 96 | var complete = function () { 97 | this.transitioning = 0 98 | this.$element 99 | .trigger('hidden.bs.collapse') 100 | .removeClass('collapsing') 101 | .addClass('collapse') 102 | } 103 | 104 | if (!$.support.transition) return complete.call(this) 105 | 106 | this.$element 107 | [dimension](0) 108 | .one('bsTransitionEnd', $.proxy(complete, this)) 109 | .emulateTransitionEnd(350) 110 | } 111 | 112 | Collapse.prototype.toggle = function () { 113 | this[this.$element.hasClass('in') ? 'hide' : 'show']() 114 | } 115 | 116 | 117 | // COLLAPSE PLUGIN DEFINITION 118 | // ========================== 119 | 120 | function Plugin(option) { 121 | return this.each(function () { 122 | var $this = $(this) 123 | var data = $this.data('bs.collapse') 124 | var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) 125 | 126 | if (!data && options.toggle && option == 'show') option = !option 127 | if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) 128 | if (typeof option == 'string') data[option]() 129 | }) 130 | } 131 | 132 | var old = $.fn.collapse 133 | 134 | $.fn.collapse = Plugin 135 | $.fn.collapse.Constructor = Collapse 136 | 137 | 138 | // COLLAPSE NO CONFLICT 139 | // ==================== 140 | 141 | $.fn.collapse.noConflict = function () { 142 | $.fn.collapse = old 143 | return this 144 | } 145 | 146 | 147 | // COLLAPSE DATA-API 148 | // ================= 149 | 150 | $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { 151 | var href 152 | var $this = $(this) 153 | var target = $this.attr('data-target') 154 | || e.preventDefault() 155 | || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 156 | var $target = $(target) 157 | var data = $target.data('bs.collapse') 158 | var option = data ? 'toggle' : $this.data() 159 | var parent = $this.attr('data-parent') 160 | var $parent = parent && $(parent) 161 | 162 | if (!data || !data.transitioning) { 163 | if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed') 164 | $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed') 165 | } 166 | 167 | Plugin.call($target, option) 168 | }) 169 | 170 | }(jQuery); 171 | -------------------------------------------------------------------------------- /_themes/odoodoc/static/bootstrap/js/dropdown.js: -------------------------------------------------------------------------------- 1 | /* ======================================================================== 2 | * Bootstrap: dropdown.js v3.2.0 3 | * http://getbootstrap.com/javascript/#dropdowns 4 | * ======================================================================== 5 | * Copyright 2011-2014 Twitter, Inc. 6 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 7 | * ======================================================================== */ 8 | 9 | 10 | +function ($) { 11 | 'use strict'; 12 | 13 | // DROPDOWN CLASS DEFINITION 14 | // ========================= 15 | 16 | var backdrop = '.dropdown-backdrop' 17 | var toggle = '[data-toggle="dropdown"]' 18 | var Dropdown = function (element) { 19 | $(element).on('click.bs.dropdown', this.toggle) 20 | } 21 | 22 | Dropdown.VERSION = '3.2.0' 23 | 24 | Dropdown.prototype.toggle = function (e) { 25 | var $this = $(this) 26 | 27 | if ($this.is('.disabled, :disabled')) return 28 | 29 | var $parent = getParent($this) 30 | var isActive = $parent.hasClass('open') 31 | 32 | clearMenus() 33 | 34 | if (!isActive) { 35 | if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { 36 | // if mobile we use a backdrop because click events don't delegate 37 | $('