[MERGE] forward port of branch 8.0 up to 2de301d

This commit is contained in:
Christophe Simonis
2015-07-07 18:13:57 +02:00
301 changed files with 16281 additions and 12753 deletions
+1
View File
@@ -151,6 +151,7 @@ for a particular financial year and for preparation of vouchers there is a modul
'test/account_validate_account_move.yml',
'test/test_edi_invoice.yml',
'test/account_report.yml',
'test/analytic_hierarchy.yml',
'test/account_fiscalyear_close.yml', #last test, as it will definitively close the demo fiscalyear
],
'installable': True,
+5 -1
View File
@@ -584,7 +584,11 @@ class account_bank_statement_line(osv.osv):
# Look for a matching amount
exact_match_amount_field = amount_field in ('debit', 'credit') and 'amount_residual' or 'amount_residual_currency'
domain_exact_amount = domain + [(exact_match_amount_field, '=', float_round(amount, precision_digits=precision_digits))]
match_id = self.get_move_lines_for_reconciliation(cr, uid, st_line, excluded_ids=excluded_ids, offset=0, limit=2, additional_domain=domain_exact_amount)
domain_exact_amount_ref = domain_exact_amount + [('ref', '=', st_line.ref)]
match_id = self.get_move_lines_for_reconciliation(cr, uid, st_line, excluded_ids=excluded_ids, offset=0, limit=2, additional_domain=domain_exact_amount_ref)
if not match_id:
match_id = self.get_move_lines_for_reconciliation(cr, uid, st_line, excluded_ids=excluded_ids, offset=0, limit=2, additional_domain=domain_exact_amount)
if match_id and len(match_id) == 1:
return match_id
+2 -2
View File
@@ -346,8 +346,8 @@ class account_invoice(models.Model):
# adapt selection of field journal_id
for field in res['fields']:
if field == 'journal_id' and type:
journal_select = self.env['account.journal']._name_search('', [('type', '=', type)], name_get_uid=1)
if field == 'journal_id' and context.get('journal_type'):
journal_select = self.env['account.journal']._name_search('', [('type', '=', context['journal_type'])], name_get_uid=1)
res['fields'][field]['selection'] = journal_select
doc = etree.XML(res['arch'])
@@ -0,0 +1,56 @@
-
We create a simple hierarchy like this
Toplevel view account
├ Real analytic account 1
└ Real analytic account 2
-
!record {model: account.analytic.account, id: analytic_account_view1}:
name: 'Toplevel view account'
type: 'view'
-
!record {model: account.analytic.account, id: analytic_account1}:
name: 'Real analytic account 1'
type: 'normal'
parent_id: analytic_account_view1
-
!record {model: account.analytic.account, id: analytic_account2}:
name: 'Real analytic account 2'
type: 'normal'
parent_id: analytic_account_view1
-
We add analytic lines in real accounts and journal
-
!record {model: account.analytic.journal, id: analytic_journal1}:
name: 'Analytic journal'
-
!record {model: account.analytic.line, id: analytic_line1}:
name: 'Analytic line 1'
account_id: analytic_account1
journal_id: analytic_journal1
general_account_id: account.a_expense
-
!record {model: account.analytic.line, id: analytic_line2}:
name: 'Analytic line 2'
account_id: analytic_account2
journal_id: analytic_journal1
general_account_id: account.a_expense
-
Now we copy the toplevel account
-
!function {model: account.analytic.account, name: copy, id: analytic_account_view1}:
- eval: "ref('analytic_account_view1')"
-
!python {model: account.analytic.account}: |
# the toplevel account has been copied with the (copy) suffix
accounts = self.search(cr, uid, [('name', 'like', '%Toplevel view account%')])
assert len(accounts) == 2, 'The toplevel account has not been copied'
accounts = self.search(cr, uid, [('name', '=', 'Toplevel view account')])
assert len(accounts) == 1, 'The toplevel account copy has a bad name'
# the sub-accounts and sub-accounts have been copied without the (copy) suffix
accounts = self.search(cr, uid, [('name', '=', 'Real analytic account 1')])
assert len(accounts) == 2, 'The sub-account has not been copied'
accounts = self.search(cr, uid, [('name', '=', 'Real analytic account 2')])
assert len(accounts) == 2, 'The sub-account has not been copied'
# the analytic lines should not be duplicated
lines = self.pool.get('account.analytic.line').search(cr, uid, [('name', 'like', '%Analytic line %')])
assert len(lines) == 2, "The analytic lines shouldn't have been copied"
+4 -2
View File
@@ -184,9 +184,9 @@ class account_analytic_account(osv.osv):
'template_id': fields.many2one('account.analytic.account', 'Template of Contract'),
'description': fields.text('Description'),
'parent_id': fields.many2one('account.analytic.account', 'Parent Analytic Account', select=2),
'child_ids': fields.one2many('account.analytic.account', 'parent_id', 'Child Accounts'),
'child_ids': fields.one2many('account.analytic.account', 'parent_id', 'Child Accounts', copy=True),
'child_complete_ids': fields.function(_child_compute, relation='account.analytic.account', string="Account Hierarchy", type='many2many'),
'line_ids': fields.one2many('account.analytic.line', 'account_id', 'Analytic Entries'),
'line_ids': fields.one2many('account.analytic.line', 'account_id', 'Analytic Entries', copy=False),
'balance': fields.function(_debit_credit_bal_qtty, type='float', string='Balance', multi='debit_credit_bal_qtty', digits_compute=dp.get_precision('Account')),
'debit': fields.function(_debit_credit_bal_qtty, type='float', string='Debit', multi='debit_credit_bal_qtty', digits_compute=dp.get_precision('Account')),
'credit': fields.function(_debit_credit_bal_qtty, type='float', string='Credit', multi='debit_credit_bal_qtty', digits_compute=dp.get_precision('Account')),
@@ -273,6 +273,8 @@ class account_analytic_account(osv.osv):
raise UserError(_("Quick account creation disallowed."))
def copy(self, cr, uid, id, default=None, context=None):
""" executed only on the toplevel copied object of the hierarchy.
Subobject are actually copied with copy_data"""
if not default:
default = {}
analytic = self.browse(cr, uid, id, context=context)
@@ -6,6 +6,7 @@ access_delivery_carrier_manager,delivery.carrier,model_delivery_carrier,base.gro
access_delivery_grid_manager,delivery.grid,model_delivery_grid,base.group_sale_manager,1,1,1,1
access_delivery_grid_line_manager,delivery.grid.line,model_delivery_grid_line,base.group_sale_manager,1,1,1,1
access_delivery_carrier_partner_manager,delivery.carrier partner_manager,model_delivery_carrier,base.group_partner_manager,1,0,0,0
access_delivery_carrier_stock_user,delivery.carrier stock_user,model_delivery_carrier,stock.group_stock_user,1,0,0,0
access_delivery_carrier_stock_manager,delivery.carrier,model_delivery_carrier,stock.group_stock_manager,1,1,1,1
access_delivery_grid_stock_manager,delivery.grid,model_delivery_grid,stock.group_stock_manager,1,1,1,1
access_delivery_grid_line_stock_manager,delivery.grid.line,model_delivery_grid_line,stock.group_stock_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
6 access_delivery_grid_manager delivery.grid model_delivery_grid base.group_sale_manager 1 1 1 1
7 access_delivery_grid_line_manager delivery.grid.line model_delivery_grid_line base.group_sale_manager 1 1 1 1
8 access_delivery_carrier_partner_manager delivery.carrier partner_manager model_delivery_carrier base.group_partner_manager 1 0 0 0
9 access_delivery_carrier_stock_user delivery.carrier stock_user model_delivery_carrier stock.group_stock_user 1 0 0 0
10 access_delivery_carrier_stock_manager delivery.carrier model_delivery_carrier stock.group_stock_manager 1 1 1 1
11 access_delivery_grid_stock_manager delivery.grid model_delivery_grid stock.group_stock_manager 1 1 1 1
12 access_delivery_grid_line_stock_manager delivery.grid.line model_delivery_grid_line stock.group_stock_manager 1 1 1 1
+1
View File
@@ -75,6 +75,7 @@ TXT_ENC_PC861 = '\x1b\x74\x23' # PC861 Icelandic
TXT_ENC_PC862 = '\x1b\x74\x24' # PC862 Hebrew
TXT_ENC_PC864 = '\x1b\x74\x25' # PC864 Arabic
TXT_ENC_PC869 = '\x1b\x74\x26' # PC869 Greek
TXT_ENC_PC936 = '\x1C\x21\x00' # PC936 GBK(Guobiao Kuozhan)
TXT_ENC_8859_2 = '\x1b\x74\x27' # ISO8859-2 Latin2
TXT_ENC_8859_9 = '\x1b\x74\x28' # ISO8859-2 Latin9
TXT_ENC_PC1098 = '\x1b\x74\x29' # PC1098 Farsi
+1
View File
@@ -748,6 +748,7 @@ class Escpos:
'cp866': TXT_ENC_PC866,
'cp862': TXT_ENC_PC862,
'cp720': TXT_ENC_PC720,
'cp936': TXT_ENC_PC936,
'iso8859_2': TXT_ENC_8859_2,
'iso8859_7': TXT_ENC_8859_7,
'iso8859_9': TXT_ENC_8859_9,
+1 -1
View File
@@ -92,7 +92,7 @@
<t t-if="attachment.file_type_icon !== 'webimage'">
<div t-attf-class="oe_attachment #{attachment.upload ? 'oe_uploading' : ''}">
<a t-att-href='attachment.url' target="_blank">
<img t-att-src="'/mail/static/src/img/mimetypes/' + attachment.file_type_icon + '.png'"></img>
<img t-att-src="'/mail/static/src/img/mimetypes/' + (attachment.file_type_icon or 'unknown') + '.png'"></img>
<div class='oe_name'><t t-raw='attachment.name' /></div>
</a>
<div class="oe_delete" t-if="!attachment.upload">
+6 -4
View File
@@ -32,7 +32,7 @@ class StockMove(osv.osv):
_inherit = 'stock.move'
_columns = {
'production_id': fields.many2one('mrp.production', 'Production Order for Produced Products', select=True),
'production_id': fields.many2one('mrp.production', 'Production Order for Produced Products', select=True, copy=False),
'raw_material_production_id': fields.many2one('mrp.production', 'Production Order for Raw Materials', select=True),
'consumed_for': fields.many2one('stock.move', 'Consumed for', help='Technical field used to make the traceability of produced products'),
}
@@ -193,6 +193,8 @@ class StockMove(osv.osv):
quantity_rest_uom = move.product_uom_qty - self.pool.get("product.uom")._compute_qty_obj(cr, uid, move.product_id.uom_id, product_qty, move.product_uom)
if float_compare(quantity_rest_uom, 0, precision_rounding=move.product_uom.rounding) != 0:
new_mov = self.split(cr, uid, move, quantity_rest, context=context)
if move.production_id:
self.write(cr, uid, [new_mov], {'production_id': move.production_id.id}, context=context)
res.append(new_mov)
vals = {'restrict_lot_id': restrict_lot_id,
'restrict_partner_id': restrict_partner_id,
@@ -224,9 +226,9 @@ class StockMove(osv.osv):
production_ids = production_obj.search(cr, uid, [('move_lines', 'in', [move.id])])
for prod_id in production_ids:
production_obj.signal_workflow(cr, uid, [prod_id], 'button_produce')
for new_move in new_moves:
production_obj.write(cr, uid, production_ids, {'move_lines': [(4, new_move)]})
res.append(new_move)
if move.production_id.id:
self.write(cr, uid, new_moves, {'production_id': move.production_id.id}, context=context)
res.append(new_moves)
return res
def write(self, cr, uid, ids, vals, context=None):
+2 -1
View File
@@ -296,7 +296,8 @@ class mrp_production(osv.osv):
if l.state in ('done','cancel','draft'):
continue
todo += l.move_dest_id_lines
if l.production_id and (l.production_id.date_finished > dt):
date_end = l.production_id.date_finished
if date_end and datetime.strptime(date_end, '%Y-%m-%d %H:%M:%S') > dt:
if l.production_id.state not in ('done','cancel'):
for wc in l.production_id.workcenter_lines:
i = self.pool.get('resource.calendar').interval_min_get(
+1 -1
View File
@@ -286,7 +286,7 @@ class mrp_repair(osv.osv):
else:
self.write(cr, uid, [o.id], {'state': 'confirmed'})
for line in o.operations:
if line.product_id.track_production:
if line.product_id.track_production and not line.lot_id:
raise UserError(_("Serial number is required for operation line with product '%s'") % (line.product_id.name))
mrp_line_obj.write(cr, uid, [l.id for l in o.operations], {'state': 'confirmed'})
return True
+1 -1
View File
@@ -13,7 +13,7 @@ def _partner_format_address(address1=False, address2=False):
def _partner_split_name(partner_name):
return [' '.join(partner_name.split()[-1:]), ' '.join(partner_name.split()[:-1])]
return [' '.join(partner_name.split()[:-1]), ' '.join(partner_name.split()[-1:])]
class ValidationError(ValueError):
@@ -62,8 +62,8 @@ class AuthorizeForm(AuthorizeCommon):
'return_url': None,
'x_currency_code': 'USD',
'x_invoice_num': 'SO004',
'x_first_name': 'Buyer',
'x_last_name': 'Norbert',
'x_first_name': 'Norbert',
'x_last_name': 'Buyer',
'x_address': 'Huge Street 2/543',
'x_city': 'Sin City',
'x_zip': '1000',
+8 -1
View File
@@ -809,6 +809,8 @@ class pos_order(osv.osv):
move_obj = self.pool.get('stock.move')
for order in self.browse(cr, uid, ids, context=context):
if all(t == 'service' for t in order.lines.mapped('product_id.type')):
continue
addr = order.partner_id and partner_obj.address_get(cr, uid, [order.partner_id.id], ['delivery']) or {}
picking_type = order.picking_type_id
picking_id = False
@@ -881,9 +883,14 @@ class pos_order(osv.osv):
statement_line_obj = self.pool.get('account.bank.statement.line')
property_obj = self.pool.get('ir.property')
order = self.browse(cr, uid, order_id, context=context)
date = data.get('payment_date', time.strftime('%Y-%m-%d'))
if len(date) > 10:
timestamp = datetime.strptime(date, tools.DEFAULT_SERVER_DATETIME_FORMAT)
ts = fields.datetime.context_timestamp(cr, uid, timestamp, context)
date = ts.strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
args = {
'amount': data['amount'],
'date': data.get('payment_date', time.strftime('%Y-%m-%d')),
'date': date,
'name': order.name + ': ' + (data.get('payment_name', '') or ''),
'partner_id': order.partner_id and self.pool.get("res.partner")._find_accounting_partner(order.partner_id).id or False,
}
+1 -1
View File
@@ -269,7 +269,7 @@ openerp.point_of_sale.load_models = function load_models(instance, module){ //mo
loaded: function(self, pricelists){ self.pricelist = pricelists[0]; },
},{
model: 'res.currency',
fields: ['symbol','position','rounding','accuracy'],
fields: ['name','symbol','position','rounding','accuracy'],
ids: function(self){ return [self.pricelist.currency_id[0]]; },
loaded: function(self, currencies){
self.currency = currencies[0];
+1 -2
View File
@@ -76,9 +76,8 @@ class product_template(osv.osv):
for sbom in bom.bom_line_ids:
my_qty = sbom.product_qty
if not sbom.attribute_value_ids:
bom_product = sbom.product_id
# No attribute_value_ids means the bom line is not variant specific
price += uom_obj._compute_price(cr, uid, bom_product.uom_po_id and bom_product.uom_po_id.id or bom_product.uom_id.id, bom_product.standard_price, sbom.product_uom.id) * my_qty
price += uom_obj._compute_price(cr, uid, sbom.product_id.uom_id.id, sbom.product_id.standard_price, sbom.product_uom.id) * my_qty
if bom.routing_id:
for wline in bom.routing_id.workcenter_lines:
+10 -2
View File
@@ -1379,7 +1379,11 @@ class procurement_order(osv.osv):
names_dict[id] = name
for procurement in procurements:
taxes_ids = procurement.product_id.supplier_taxes_id
taxes = acc_pos_obj.map_tax(cr, uid, partner.property_account_position, taxes_ids)
# It is necessary to have the appropriate fiscal position to get the right tax mapping
fp = acc_pos_obj.get_fiscal_position(cr, uid, None, partner.id, context=context)
if fp:
fp = acc_pos_obj.browse(cr, uid, fp, context=context)
taxes = acc_pos_obj.map_tax(cr, uid, fp, taxes_ids)
name = names_dict[procurement.product_id.id]
if procurement.product_id.description_purchase:
name += '\n' + procurement.product_id.description_purchase
@@ -1500,6 +1504,7 @@ class procurement_order(osv.osv):
po_line_obj = self.pool.get('purchase.order.line')
seq_obj = self.pool.get('ir.sequence')
uom_obj = self.pool.get('product.uom')
acc_pos_obj = self.pool.get('account.fiscal.position')
add_purchase_procs, create_purchase_procs = self._get_grouping_dicts(cr, uid, ids, context=context)
procs_done = []
@@ -1571,6 +1576,9 @@ class procurement_order(osv.osv):
name = seq_obj.next_by_code(cr, uid, 'purchase.order') or _('PO: %s') % procurement.name
gpo = procurement.rule_id.group_propagation_option
group = (gpo == 'fixed' and procurement.rule_id.group_id.id) or (gpo == 'propagate' and procurement.group_id.id) or False
fp = acc_pos_obj.get_fiscal_position(cr, uid, None, partner.id, context=context)
if fp:
fp = acc_pos_obj.browse(cr, uid, fp, context=context)
po_vals = {
'name': name,
'origin': procurement.origin,
@@ -1580,7 +1588,7 @@ class procurement_order(osv.osv):
'pricelist_id': partner.property_product_pricelist_purchase.id,
'date_order': purchase_date.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
'company_id': procurement.company_id.id,
'fiscal_position': partner.property_account_position.id,
'fiscal_position': fp,
'payment_term_id': partner.property_supplier_payment_term.id,
'dest_address_id': procurement.partner_dest_id.id,
'group_id': group,
+1 -1
View File
@@ -285,7 +285,7 @@ class product_product(osv.osv):
toolbar=toolbar, submenu=submenu)
if context is None:
context = {}
if ('location' in context) and context['location']:
if context.get('location') and isinstance(context['location'], int):
location_info = self.pool.get('stock.location').browse(cr, uid, context['location'])
fields=res.get('fields',{})
if fields:
+1 -1
View File
@@ -8,7 +8,7 @@
<field name="inherit_id" ref="product.product_product_tree_view"/>
<field name="arch" type="xml">
<tree position="attributes">
<attribute name="colors">{'red':virtual_available&lt;0, 'blue':virtual_available&gt;=0 and state in ('draft', 'end', 'obsolete'), 'black':virtual_available&gt;=0 and state not in ('draft', 'end', 'obsolete')}</attribute>
<attribute name="colors">red:virtual_available&lt;0;blue:virtual_available&gt;=0 and state in ('draft', 'end', 'obsolete');black:virtual_available&gt;=0 and state not in ('draft', 'end', 'obsolete')</attribute>
</tree>
<field name="price" position="after">
<field name="qty_available"/>
+11 -5
View File
@@ -1822,7 +1822,7 @@ class stock_move(osv.osv):
"the product reservation, and should be done with care."
),
'product_uom': fields.many2one('product.uom', 'Unit of Measure', required=True, states={'done': [('readonly', True)]}),
'product_uos_qty': fields.float('Quantity (UOS)', digits_compute=dp.get_precision('Product Unit of Measure'), states={'done': [('readonly', True)]}),
'product_uos_qty': fields.float('Quantity (UOS)', digits_compute=dp.get_precision('Product UoS'), states={'done': [('readonly', True)]}),
'product_uos': fields.many2one('product.uom', 'Product UOS', states={'done': [('readonly', True)]}),
'product_tmpl_id': fields.related('product_id', 'product_tmpl_id', type='many2one', relation='product.template', string='Product Template'),
@@ -2102,7 +2102,8 @@ class stock_move(osv.osv):
break
if product_uos and product_uom and (product_uom != product_uos):
result['product_uos_qty'] = product_qty * uos_coeff['uos_coeff']
precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Product UoS')
result['product_uos_qty'] = float_round(product_qty * uos_coeff['uos_coeff'], precision_digits=precision)
else:
result['product_uos_qty'] = product_qty
@@ -2132,7 +2133,8 @@ class stock_move(osv.osv):
# The clients should call onchange_quantity too anyway
if product_uos and product_uom and (product_uom != product_uos):
result['product_uom_qty'] = product_uos_qty / uos_coeff['uos_coeff']
precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Product Unit of Measure')
result['product_uom_qty'] = float_round(product_uos_qty / uos_coeff['uos_coeff'], precision_digits=precision)
else:
result['product_uom_qty'] = product_uos_qty
return {'value': result}
@@ -3393,7 +3395,10 @@ class stock_warehouse(osv.osv):
output_loc = warehouse.lot_stock_id
picking_type_obj.write(cr, uid, warehouse.in_type_id.id, {'default_location_dest_id': input_loc.id}, context=context)
picking_type_obj.write(cr, uid, warehouse.out_type_id.id, {'default_location_src_id': output_loc.id}, context=context)
picking_type_obj.write(cr, uid, warehouse.pick_type_id.id, {'active': new_delivery_step != 'ship_only'}, context=context)
picking_type_obj.write(cr, uid, warehouse.pick_type_id.id, {
'active': new_delivery_step != 'ship_only',
'default_location_dest_id': output_loc.id if new_delivery_step == 'pick_ship' else warehouse.wh_pack_stock_loc_id.id,
}, context=context)
picking_type_obj.write(cr, uid, warehouse.pack_type_id.id, {'active': new_delivery_step == 'pick_pack_ship'}, context=context)
routes_dict = self.get_routes_dict(cr, uid, ids, warehouse, context=context)
@@ -3515,7 +3520,7 @@ class stock_warehouse(osv.osv):
'code': 'internal',
'sequence_id': pick_seq_id,
'default_location_src_id': wh_stock_loc.id,
'default_location_dest_id': wh_pack_stock_loc.id,
'default_location_dest_id': output_loc.id if warehouse.delivery_steps == 'pick_ship' else wh_pack_stock_loc.id,
'active': warehouse.delivery_steps != 'ship_only',
'sequence': max_sequence + 2,
'color': color}, context=context)
@@ -3818,6 +3823,7 @@ class stock_location_path(osv.osv):
def _prepare_push_apply(self, cr, uid, rule, move, context=None):
newdate = (datetime.strptime(move.date_expected, DEFAULT_SERVER_DATETIME_FORMAT) + relativedelta.relativedelta(days=rule.delay or 0)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
return {
'origin': move.origin or move.picking_id.name or "/",
'location_id': move.location_dest_id.id,
'location_dest_id': rule.location_dest_id.id,
'date': newdate,
@@ -65,8 +65,10 @@ class stock_history(osv.osv):
products_rec = self.pool['product.product'].read(cr, uid, product_ids, ['cost_method', 'product_tmpl_id'], context=context)
products_dict = dict((product['id'], product) for product in products_rec)
cost_method_product_tmpl_ids = list(set(product['product_tmpl_id'][0] for product in products_rec if product['cost_method'] != 'real'))
cr.execute('SELECT DISTINCT ON (product_template_id, company_id) product_template_id, company_id, cost FROM product_price_history WHERE product_template_id in %s AND datetime <= %s ORDER BY product_template_id, company_id, datetime DESC', (tuple(cost_method_product_tmpl_ids), date))
histories = cr.dictfetchall()
histories = []
if cost_method_product_tmpl_ids:
cr.execute('SELECT DISTINCT ON (product_template_id, company_id) product_template_id, company_id, cost FROM product_price_history WHERE product_template_id in %s AND datetime <= %s ORDER BY product_template_id, company_id, datetime DESC', (tuple(cost_method_product_tmpl_ids), date))
histories = cr.dictfetchall()
histories_dict = {}
for history in histories:
histories_dict[(history['product_template_id'], history['company_id'])] = history['cost']
@@ -144,10 +144,12 @@ class stock_landed_cost(osv.osv):
if qty_out > 0:
debit_line = dict(debit_line,
name=(line.name + ": " + str(qty_out) + _(' already out')),
quantity=qty_out)
quantity=qty_out,
account_id=already_out_account_id)
credit_line = dict(credit_line,
name=(line.name + ": " + str(qty_out) + _(' already out')),
quantity=qty_out)
quantity=qty_out,
account_id=debit_account_id)
diff = diff * qty_out / line.quantity
if diff > 0:
debit_line['debit'] = diff
+1
View File
@@ -577,6 +577,7 @@
border-radius: 3px;
background: #f0f0fa;
color: #4C4C4C;
display: inline-block;
word-break: break-word;
}
.openerp .oe_tag_dark {
+1
View File
@@ -514,6 +514,7 @@ $sheet-padding: 16px
@include radius(3px)
background: $tag-bg-light
color: #4C4C4C
display: inline-block
word-break: break-word
.oe_tag_dark
background: $tag-bg-dark
@@ -659,6 +659,7 @@
e.preventDefault();
return this._next();
}
this.editor.form.__clicked_inside = true;
return $.when();
}
});
+4 -2
View File
@@ -6,6 +6,7 @@ import werkzeug
from openerp import tools
from openerp.addons.web import http
from openerp.addons.web.controllers.main import login_redirect
from openerp.addons.web.http import request
from openerp.addons.website.models.website import slug, unslug
from openerp.exceptions import UserError
@@ -271,7 +272,8 @@ class WebsiteBlog(http.Controller):
@http.route(['/blog/post_comment'], type='http', auth="public", methods=['GET', 'POST'], website=True)
def blog_post_comment(self, blog_post_id=0, **kw):
cr, uid, context = request.cr, request.uid, request.context
redirect_url = request.httprequest.referrer + "#comments"
post = request.registry['blog.post'].browse(cr, uid, int(blog_post_id), context=context)
redirect_url = "/blog/%s/post/%s#comments" % (slug(post.blog_id), slug(post))
if kw.get('comment'):
if not request.session.uid: # if not logged, redirect to the login form, keeping the url to post the comment
kw['comment'] = kw.get('comment').encode('utf8') # avoid crash from urlencode if accent
@@ -282,7 +284,7 @@ class WebsiteBlog(http.Controller):
blog_post = request.registry['blog.post']
post = blog_post.browse(cr, uid, blog_post_id, context=context)
self._blog_post_message(blog_post_id, kw.get('comment'), **kw)
redirect_url = "/blog/%s/post/%s#comments" % (slug(post.blog_id), slug(post))
return werkzeug.utils.redirect(redirect_url)
+1 -1
View File
@@ -14,7 +14,7 @@
<div t-attf-class="form-group #{error and 'phone' in error and 'has-error' or ''}">
<label class="col-md-3 col-sm-4 control-label" for="phone">Phone Number</label>
<div class="col-md-7 col-sm-8">
<input type="text" class="form-control" name="phone" placeholder="e.g. (+32).81.81.37.00" t-attf-value="#{phone or ''}"/>
<input type="text" class="form-control" name="phone" t-attf-value="#{phone or ''}"/>
</div>
</div>
<div name="email_from_container" t-attf-class="form-group #{error and 'email_from' in error and 'has-error' or ''}">
+14
View File
@@ -19,6 +19,7 @@
#
##############################################################################
from openerp import api
from openerp.osv import osv, fields
import uuid
import time
@@ -370,6 +371,8 @@ class sale_order_option(osv.osv):
_defaults = {
'quantity': 1,
}
# TODO master: to remove, replaced by onchange of the new api
def on_change_product_id(self, cr, uid, ids, product, uom_id=None, context=None):
vals, domain = {}, []
if not product:
@@ -399,6 +402,17 @@ class sale_order_option(osv.osv):
return {'value': {'price_unit': 0.0, 'uom_id': False}}
return self.on_change_product_id(cr, uid, ids, product, uom_id=uom_id, context=context)
@api.onchange('product_id')
def _onchange_product_id(self):
product = self.product_id.with_context(lang=self.order_id.partner_id.lang)
self.price_unit = product.list_price
self.website_description = product.quote_description or product.website_description
self.name = product.name
if product.description_sale:
self.name += '\n' + product.description_sale
self.uom_id = product.product_tmpl_id.uom_id
class product_template(osv.Model):
_inherit = "product.template"
@@ -31,7 +31,7 @@
<field name="quote_viewed" invisible="1"/>
<field name="options">
<tree string="Sales Quotation Template Lines" editable="bottom">
<field name="product_id" on_change="on_change_product_id(product_id, uom_id)"/>
<field name="product_id"/>
<field name="name"/>
<field name="quantity"/>
<field name="uom_id" groups="product.group_uom" on_change="product_uom_change(product_id, uom_id)"/>
+5
View File
@@ -152,3 +152,8 @@ doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."
pseudoxml:
$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
@echo
@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
-77
View File
@@ -1,77 +0,0 @@
:orphan:
==================
Odoo Documentation
==================
Odoo Theme
==========
The Odoo Documentation theme is a bootstrap-based mix of http://odoo.com and
http://getbootstrap.com with additional changes and additions, bundled as
a Sphinx theme.
The main style file is ``_themes/odoodoc/static/style.less``, it is not
converted on the fly and must be compiled manually when altere, using the
official node-based lessc_ tool.
``odoodoc`` must be added as an extension to a project using the theme, it
fixes some discrepancies between bootstrap_ and Sphinx_ and adds a few
features:
Sphinx Customizations
---------------------
* toctree bullet lists (HTML ``<ul>``) are given the ``nav`` class
* the main navigation bar also gets the ``navbar-nav`` and ``navbar-right``
set on its root (``navbar-right`` could probably be handled in CSS to avoid
having it in the markup)
* tables are given the ``table`` class
* colspecs are removed from tables, tables should autolayout
* ``data-`` attributes are copied straight from the docutils node to the
output HTML node
* an ``odoo`` pygments style based on the bootstrap_ documentation's
* the normal Sphinx sidebars are suppressed and a new sidebar is injected in
``div.document`` (``sidebar1`` is outside in the base Sphinx layout)
* HTML5 doctype
Additional features
-------------------
* versions switcher, uses the ``canonical_root`` setting and an additional
``versions`` setting which should be a comma-separated list of available
versions. Appends the each version and page name to the root, and displays
a list of those links on the current page
* canonical urls, requires a ``canonical_root`` setting value, and optionally
a ``canonical_branch`` (default: ``master``)
* :guilabel:`Edit on github` link in Sphinx pages if ``github_user`` and
``github_project`` are provided
* :guilabel:`[source]` links in autodoc content links to github with the same
requirements (requires Sphinx 1.2)
* ``aphorism`` class for admonitions, makes the first line of the admonition
inline and the same size as the admonition category (mostly for short,
single-phrase admonitions)
* ``exercise`` directive, mostly for training-type documents, the
``solutions`` tag_ can be used to conditionally show e.g. solutions
* a number of straight-to-HTML directives:
``h:div``
a straight div, can be used instead of ``container`` (which adds the
``container`` class to the div it generates, that's really not compatible
with Bootstrap_)
``h:address``
generates an ``<address>`` node
a bunch of roles straight to HTML inline
``mark``, ``insert``, ``delete``, ``strikethrough``, ``small`, ``kbd`` and
``var`` generate the corresponding HTML element
Requirements
------------
* Sphinx 1.1, 1.2 for code Python code links
* sphinx-patchqueue (for the content, not the theme)
.. _lessc: http://lesscss.org/#using-less
.. _bootstrap: http://getbootstrap.com
.. _sphinx: http://sphinx-doc.org
.. _tag: http://sphinx-doc.org/markup/misc.html#including-content-based-on-tags
@@ -1,16 +1,10 @@
# -*- coding: utf-8 -*-
from . import html_domain
from . import github
# add Odoo style to pygments
from . import odoo_pygments
from . import sphinx_monkeypatch
sphinx_monkeypatch.patch()
"""
Adds a new "exercise" admonition type
"""
def setup(app):
html_domain.setup(app)
github.setup(app)
app.add_directive('exercise', Exercise)
app.add_node(exercise, html=(
lambda self, node: self.visit_admonition(node, 'exercise'),
@@ -28,8 +22,3 @@ class Exercise(admonitions.BaseAdmonition):
from sphinx.locale import admonitionlabels, l_
admonitionlabels['exercise'] = l_('Exercise')
# monkeypatch PHP lexer to not require <?php
from sphinx.highlighting import lexers
from pygments.lexers.web import PhpLexer
lexers['php'] = PhpLexer(startinline=True)
@@ -3,6 +3,27 @@ import importlib
import os.path
from urlparse import urlunsplit
"""
* adds github_link(mode) context variable: provides URL (in relevant mode) of
current document on github
* if sphinx.ext.linkcode is enabled, automatically generates github linkcode
links (by setting config.linkcode_resolve)
Settings
========
* ``github_user``, username/organisation under which the project lives
* ``github_project``, name of the project on github
* (optional) ``version``, github branch to link to (default: master)
Notes
=====
* provided ``linkcode_resolve`` only supports Python domain
* generates https github links
* explicitly imports ``openerp``, so useless for anyone else
"""
def setup(app):
app.add_config_value('github_user', None, 'env')
app.add_config_value('github_project', None, 'env')
@@ -42,6 +63,7 @@ def setup(app):
return None
import openerp
# FIXME: make finding project root project-independent
project_root = os.path.join(os.path.dirname(openerp.__file__), '..')
return make_github_link(
app,
@@ -72,6 +94,11 @@ def add_doc_link(app, pagename, templatename, context, doctree):
if not app.config.github_user and app.config.github_project:
return
# FIXME: find other way to recover current document's source suffix
# in Sphinx 1.3 it's possible to have mutliple source suffixes and that
# may be useful in the future
source_suffix = app.config.source_suffix
source_suffix = source_suffix if isinstance(source_suffix, basestring) else source_suffix[0]
# can't use functools.partial because 3rd positional is line not mode
context['github_link'] = lambda mode='mode': make_github_link(
app, 'doc/%s%s' % (pagename, app.config.source_suffix), mode=mode)
context['github_link'] = lambda mode='edit': make_github_link(
app, 'doc/%s%s' % (pagename, source_suffix), mode=mode)
@@ -1,7 +1,16 @@
# -*- coding: utf-8 -*-
"""
Defines a "raw HTML" domain with a ``div[classes]`` and a number of roles
rendered more or less directly to HTML.
.. warning::
the purpose of this domain is *not* to document HTML or components
"""
from docutils import nodes, utils
from docutils.parsers.rst import Directive, directives, docutils
from docutils.parsers.rst import Directive, directives
from docutils.parsers.rst.directives.body import LineBlock
import sphinx.roles
+100
View File
@@ -0,0 +1,100 @@
# -*- coding: utf-8 -*-
from . import switcher
from . import pygments_override
import collections
import sphinx.environment
import sphinx.builders.html
from docutils import nodes
def setup(app):
switcher.setup(app)
app.add_config_value('odoo_cover_default', None, 'env')
app.add_config_value('odoo_cover_external', {}, 'env')
app.add_config_value('odoo_cover_default_external', lambda conf: conf.odoo_cover_default, 'env')
app.connect('html-page-context', update_meta)
def update_meta(app, pagename, templatename, context, doctree):
meta = context.setdefault('meta', {})
meta.setdefault('banner', app.config.odoo_cover_default)
def navbarify(node, navbar=None):
"""
:param node: toctree node to navbarify
:param navbar: Whether this toctree is a 'main' navbar, a 'side' navbar or
not a navbar at all
"""
if navbar == 'main':
# add classes to just toplevel
node['classes'].extend(['nav', 'navbar-nav', 'navbar-right'])
for list_item in node.children:
# bullet_list
# list_item
# compact_paragraph
# reference
# bullet_list
# list_item
# compact_paragraph
# reference
# no bullet_list.list_item -> don't dropdownify
if len(list_item.children) < 2 or not list_item.children[1].children:
continue
list_item['classes'].append('dropdown')
# list_item.compact_paragraph.reference
link = list_item.children[0].children[0]
link['classes'].append('dropdown-toggle')
link.attributes['data-toggle'] = 'dropdown'
# list_item.bullet_list
list_item.children[1]['classes'].append('dropdown-menu')
def resolve_content_toctree(
environment, docname, builder, toctree, prune=True, maxdepth=0,
titles_only=False, collapse=False, includehidden=False):
"""Alternative toctree resolution for main content: don't resolve the
toctree, just handle it as a normal node, in the translator
"""
return toctree
class monkey(object):
def __init__(self, obj):
self.obj = obj
def __call__(self, fn):
name = fn.__name__
old = getattr(self.obj, name)
setattr(self.obj, name, lambda self_, *args, **kwargs: \
fn(old, self_, *args, **kwargs))
@monkey(sphinx.environment.BuildEnvironment)
def resolve_toctree(old_resolve, self, docname, *args, **kwargs):
""" If navbar, bootstrapify TOC to yield a navbar
"""
navbar = kwargs.pop('navbar', None)
if docname == self.config.master_doc and not navbar:
return resolve_content_toctree(self, docname, *args, **kwargs)
toc = old_resolve(self, docname, *args, **kwargs)
if toc is None:
return None
navbarify(toc[0], navbar=navbar)
return toc
@monkey(sphinx.builders.html.StandaloneHTMLBuilder)
def render_partial(old_partial, self, node):
if isinstance(node, nodes.bullet_list) and node.children:
# side nav?
# remove single top-level item
# bullet_list/0(list_item)/1(bullet_list)
level1 = node.children[0].children
if len(level1) > 1:
node = level1[1]
node['classes'].extend(['list-group', 'nav', 'text-left'])
for n in node.traverse():
if isinstance(n, nodes.list_item):
n['classes'].append('list-group-item')
elif isinstance(n, nodes.reference):
n['classes'].append('ripple')
else:
node.clear()
return old_partial(self, node)
+134
View File
@@ -0,0 +1,134 @@
{% extends "basic/layout.html" %}
{% set script_files = script_files + [
'_static/jquery.min.js',
'_static/bootstrap.js',
'_static/doc.js',
'_static/jquery.noconflict.js',
] %}
{% set classes = [] %}
{% if pagename == master_doc %}
{% set classes = classes + ['index'] %}
{% endif %}
{% if 'code-column' in meta %}
{% set classes = classes + ['has_code_col'] %}
{% endif %}
{%- block doctype -%}
<!doctype html>
{%- endblock -%}
{%- block htmltitle -%}
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{ super() }}
{%- endblock -%}
{%- block sidebar1 -%}{%- endblock -%}
{%- block sidebar2 -%}{%- endblock -%}
{%- block relbar1 -%}{%- endblock -%}
{%- block relbar2 -%}{%- endblock -%}
{%- block footer -%}
{%- if google_analytics_key -%}
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '{{ google_analytics_key }}', 'auto');
ga('send','pageview');
</script>
{%- endif -%}
{%- endblock -%}
{%- block header -%}
<header class="{{ ' '.join(classes) }}">
<figure class="card top">
<span class="card-img" style="background-image: url('{{ pathto('_static/' + meta['banner'], True) }}');"></span>
</figure>
</header>
<nav id="main_navbar" class="navbar {{ ' '.join(classes) }}">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target=".navbar-main">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<nav class="nav navbar-nav navbar-left">
<li id="main-back"><a href="{{ pathto(master_doc) }}" class="mdi-navigation-arrow-back"></a></li>
<li>
<h1 id="main_title">{{ meta.get('main-title', title) }}</h1>
</li>
</nav>
</div>
<nav class="collapse navbar-collapse navbar-main navbar-right" role="navigation">
{% if versions %}
<ul class="navbar-nav navbar-right nav">
<li class="versions">
<a class="dropdown-toggle" data-toggle="dropdown">
{{ version }} <span class="caret"></span>
</a>
<ul class="dropdown-menu" role="menu">
{% for name, url in versions %}
<li><a href="{{ url }}">{{ name }}</a></li>
{% endfor %}
</ul>
</li>
</ul>
{% endif %}
{{ toctree(titles_only=True, maxdepth=2, includehidden=True,
collapse=False, navbar='main') }}
</nav>
</div>
</nav>
{%- endblock -%}
{%- block content -%}
<main class="container {{ ' '.join(classes) }}">
{% if pagename != master_doc %}
<div class="row">
<aside>
<div class="navbar-aside text-center">
<div class="logo_box">
<span class="logo"></span>
Documentation
</div>
{{ toc }}
{% if github_link %}
<p class="gith-container"><a href="{{ github_link(mode='edit') }}" class="gith-link">
Edit on GitHub
</a></p>
{% endif %}
</div>
</aside>
<article class="doc-body">
{% endif %}
{% block body %} {% endblock %}
{% if pagename != master_doc %}</article>
</div>
{% endif %}
<div id="mask"></div>
</main>
<div class="floating_action_container">
<a id="floating_action" class="ripple" href="#">
<i class="mdi-action-explore"></i>
</a>
<div id="floating_action_menu">
<span class="bubble"></span>
<ul class="list-group content">
<li class="list-group-item ripple"><a>Cras justo odio</a></li>
<li class="list-group-item ripple"><a>Dapibus ac facilisis in</a></li>
<li class="list-group-item ripple"><a>Morbi leo risus</a></li>
<li class="list-group-item ripple"><a>Porta ac consectetur ac</a></li>
<li class="list-group-item ripple"><a>Vestibulum at eros</a></li>
</ul>
</div>
</div>
{%- endblock -%}
+20
View File
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
from pygments.style import Style
from pygments.styles.paraiso_dark import ParaisoDarkStyle
from pygments.token import *
# extracted from getbootstrap.com
class OdooStyle(Style):
background_color = '#272727'
highlight_color = ParaisoDarkStyle.highlight_color
styles = dict(ParaisoDarkStyle.styles)
styles[Keyword] = '#cb49a8'
styles[Name.Tag] = '#21b799'
import imp
import sys
modname = 'pygments.styles.odoo'
m = imp.new_module(modname)
m.OdooStyle = OdooStyle
sys.modules[modname] = m
@@ -0,0 +1,59 @@
// Animations
.keyframes(ripple; {
100% {
opacity: 0;
.scale(2.5);
}
});
.keyframes(fadeInUp; {
0% {
opacity: 0;
.translate(0; 60px);
}
40% { opacity: 1}
100% {
opacity: 1;
.translate(none; none);
}
});
.keyframes(fadeIn; {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
});
.fadeInUp {
.animation(fadeInUp 1s);
}
.fadeIn {
.animation(fadeIn 1s);
}
// Ripple Buttons
.ripple {
z-index: 2;
}
.inner-ripple {
display: block;
position: absolute;
border-radius: 100%;
opacity: 1.3;
z-index: -1;
background: rgba(0, 0, 0, .2);
pointer-events: none;
.scale(0);
}
.inner-ripple-animated {
.animation(ripple 0.35s ease-in);
}
@@ -18,6 +18,7 @@
// Specified for the h4 to prevent conflicts of changing @headings-color
color: inherit;
}
// Provide class for links that match alerts
.alert-link {
font-weight: @alert-link-font-weight;
@@ -28,6 +29,7 @@
> ul {
margin-bottom: 0;
}
> p + p {
margin-top: 5px;
}
@@ -57,12 +59,15 @@
.alert-success {
.alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);
}
.alert-info {
.alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);
}
.alert-warning {
.alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);
}
.alert-danger {
.alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);
}
@@ -28,7 +28,9 @@
position: relative;
top: -1px;
}
.btn-xs & {
.btn-xs &,
.btn-group-xs > .btn & {
top: 0;
padding: 1px 5px;
}
@@ -44,11 +46,20 @@
}
// Account for badges in navs
a.list-group-item.active > &,
.list-group-item.active > &,
.nav-pills > .active > a > & {
color: @badge-active-color;
background-color: @badge-active-bg;
}
.list-group-item > & {
float: right;
}
.list-group-item > & + & {
margin-right: 5px;
}
.nav-pills > li > a > & {
margin-left: 3px;
}
+50
View File
@@ -0,0 +1,50 @@
// Core variables and mixins
@import "variables.less";
@import "mixins.less";
// Reset and dependencies
@import "normalize.less";
@import "print.less";
//@import "glyphicons.less";
// Core CSS
@import "scaffolding.less";
@import "type.less";
@import "code.less";
@import "grid.less";
@import "tables.less";
@import "forms.less";
@import "buttons.less";
// Components
@import "component-animations.less";
@import "dropdowns.less";
@import "button-groups.less";
@import "input-groups.less";
@import "navs.less";
@import "navbar.less";
@import "breadcrumbs.less";
@import "pagination.less";
@import "pager.less";
@import "labels.less";
@import "badges.less";
@import "jumbotron.less";
@import "thumbnails.less";
@import "alerts.less";
@import "progress-bars.less";
@import "media.less";
@import "list-group.less";
@import "panels.less";
@import "responsive-embed.less";
@import "wells.less";
@import "close.less";
// Components w/ JavaScript
@import "modals.less";
@import "tooltip.less";
@import "popovers.less";
@import "carousel.less";
// Utility classes
@import "utilities.less";
@import "responsive-utilities.less";
@@ -18,10 +18,6 @@
&.active {
z-index: 2;
}
&:focus {
// Remove focus outline when dropdown JS adds it after closing the menu
outline: 0;
}
}
}
@@ -75,13 +71,13 @@
.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
border-radius: 0;
}
.btn-group > .btn-group:first-child {
.btn-group > .btn-group:first-child:not(:last-child) {
> .btn:last-child,
> .dropdown-toggle {
.border-right-radius(0);
}
}
.btn-group > .btn-group:last-child > .btn:first-child {
.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
.border-left-radius(0);
}
@@ -198,7 +194,6 @@
}
// Justified button groups
// ----------------------
@@ -226,15 +221,23 @@
// Checkbox and radio options
//
// In order to support the browser's form validation feedback, powered by the
// `required` attribute, we have to "hide" the inputs via `opacity`. We cannot
// use `display: none;` or `visibility: hidden;` as that also hides the popover.
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
// `display: none;` or `visibility: hidden;` as that also hides the popover.
// Simply visually hiding the inputs via `opacity` would leave them clickable in
// certain cases which is prevented by using `clip` and `pointer-events`.
// This way, we ensure a DOM element is visible to position the popover from.
//
// See https://github.com/twbs/bootstrap/pull/12794 for more.
// See https://github.com/twbs/bootstrap/pull/12794 and
// https://github.com/twbs/bootstrap/pull/14559 for more information.
[data-toggle="buttons"] > .btn > input[type="radio"],
[data-toggle="buttons"] > .btn > input[type="checkbox"] {
position: absolute;
z-index: -1;
.opacity(0);
[data-toggle="buttons"] {
> .btn,
> .btn-group > .btn {
input[type="radio"],
input[type="checkbox"] {
position: absolute;
clip: rect(0,0,0,0);
pointer-events: none;
}
}
}
@@ -12,6 +12,7 @@
font-weight: @btn-font-weight;
text-align: center;
vertical-align: middle;
touch-action: manipulation;
cursor: pointer;
background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
border: 1px solid transparent;
@@ -22,13 +23,15 @@
&,
&:active,
&.active {
&:focus {
&:focus,
&.focus {
.tab-focus();
}
}
&:hover,
&:focus {
&:focus,
&.focus {
color: @btn-default-color;
text-decoration: none;
}
@@ -43,7 +46,7 @@
&.disabled,
&[disabled],
fieldset[disabled] & {
cursor: not-allowed;
cursor: @cursor-disabled;
pointer-events: none; // Future-proof disabling of clicks
.opacity(.65);
.box-shadow(none);
@@ -85,11 +88,11 @@
.btn-link {
color: @link-color;
font-weight: normal;
cursor: pointer;
border-radius: 0;
&,
&:active,
&.active,
&[disabled],
fieldset[disabled] & {
background-color: transparent;
@@ -104,7 +107,7 @@
&:hover,
&:focus {
color: @link-hover-color;
text-decoration: underline;
text-decoration: @link-hover-decoration;
background-color: transparent;
}
&[disabled],
@@ -24,6 +24,30 @@
&:extend(.img-responsive);
line-height: 1;
}
// WebKit CSS3 transforms for supported devices
@media all and (transform-3d), (-webkit-transform-3d) {
.transition-transform(~'0.6s ease-in-out');
.backface-visibility(~'hidden');
.perspective(1000);
&.next,
&.active.right {
.translate3d(100%, 0, 0);
left: 0;
}
&.prev,
&.active.left {
.translate3d(-100%, 0, 0);
left: 0;
}
&.next.left,
&.prev.right,
&.active {
.translate3d(0, 0, 0);
left: 0;
}
}
}
> .active,
@@ -124,6 +148,7 @@
width: 20px;
height: 20px;
margin-top: -10px;
line-height: 1;
font-family: serif;
}
@@ -171,6 +196,7 @@
// Internet Explorer 8-9 does not support clicks on elements without a set
// `background-color`. We cannot use `filter` since that's not viewed as a
// background color by the browser. Thus, a hack is needed.
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Internet_Explorer
//
// For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we
// set alpha transparency for the best results possible.
@@ -23,6 +23,7 @@
// Additional properties for button version
// iOS requires the button element instead of an anchor tag.
// If you want the anchor version, it requires `href="#"`.
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
button& {
padding: 0;
cursor: pointer;
@@ -32,6 +32,7 @@ kbd {
kbd {
padding: 0;
font-size: 100%;
font-weight: bold;
box-shadow: none;
}
}
@@ -27,5 +27,7 @@
position: relative;
height: 0;
overflow: hidden;
.transition(height .35s ease);
.transition-property(~"height, visibility");
.transition-duration(.35s);
.transition-timing-function(ease);
}
@@ -10,12 +10,13 @@
height: 0;
margin-left: 2px;
vertical-align: middle;
border-top: @caret-width-base solid;
border-top: @caret-width-base dashed;
border-right: @caret-width-base solid transparent;
border-left: @caret-width-base solid transparent;
}
// The dropdown wrapper (div)
.dropup,
.dropdown {
position: relative;
}
@@ -103,16 +104,15 @@
&:focus {
color: @dropdown-link-disabled-color;
}
}
// Nuke hover/focus effects
.dropdown-menu > .disabled > a {
// Nuke hover/focus effects
&:hover,
&:focus {
text-decoration: none;
background-color: transparent;
background-image: none; // Remove CSS gradient
.reset-filter();
cursor: not-allowed;
cursor: @cursor-disabled;
}
}
@@ -191,7 +191,7 @@
.dropdown-menu {
top: auto;
bottom: 100%;
margin-bottom: 1px;
margin-bottom: 2px;
}
}
@@ -212,4 +212,3 @@
}
}
}
@@ -123,7 +123,7 @@ output {
background-color: @input-bg;
background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214
border: 1px solid @input-border;
border-radius: @input-border-radius;
border-radius: @input-border-radius; // Note: This has no effect on <select>s in some browsers, due to the limited stylability of <select>s in CSS.
.box-shadow(inset 0 1px 1px rgba(0,0,0,.075));
.transition(~"border-color ease-in-out .15s, box-shadow ease-in-out .15s");
@@ -141,9 +141,13 @@ output {
&[disabled],
&[readonly],
fieldset[disabled] & {
cursor: not-allowed;
background-color: @input-bg-disabled;
opacity: 1; // iOS fix for unreadable disabled content
opacity: 1; // iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655
}
&[disabled],
fieldset[disabled] & {
cursor: @cursor-disabled;
}
// Reset height for `textarea`s
@@ -168,24 +172,26 @@ input[type="search"] {
// Special styles for iOS temporal inputs
//
// In Mobile Safari, setting `display: block` on temporal inputs causes the
// text within the input to become vertically misaligned.
// As a workaround, we set a pixel line-height that matches the
// given height of the input. Since this fucks up everything else, we have to
// appropriately reset it for Internet Explorer and the size variations.
// text within the input to become vertically misaligned. As a workaround, we
// set a pixel line-height that matches the given height of the input, but only
// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
line-height: @input-height-base;
// IE8+ misaligns the text within date inputs, so we reset
line-height: @line-height-base ~"\0";
@media screen and (-webkit-min-device-pixel-ratio: 0) {
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
line-height: @input-height-base;
&.input-sm {
line-height: @input-height-small;
}
&.input-lg {
line-height: @input-height-large;
&.input-sm,
.input-group-sm & {
line-height: @input-height-small;
}
&.input-lg,
.input-group-lg & {
line-height: @input-height-large;
}
}
}
@@ -196,7 +202,7 @@ input[type="month"] {
// horizontal forms, use the predefined grid classes.
.form-group {
margin-bottom: 15px;
margin-bottom: @form-group-margin-bottom;
}
@@ -208,11 +214,11 @@ input[type="month"] {
.checkbox {
position: relative;
display: block;
min-height: @line-height-computed; // clear the floating input if there is no label text
margin-top: 10px;
margin-bottom: 10px;
label {
min-height: @line-height-computed; // Ensure the input doesn't jump when there is no text
padding-left: 20px;
margin-bottom: 0;
font-weight: normal;
@@ -236,6 +242,7 @@ input[type="month"] {
// Radios and checkboxes on same line
.radio-inline,
.checkbox-inline {
position: relative;
display: inline-block;
padding-left: 20px;
margin-bottom: 0;
@@ -258,7 +265,7 @@ input[type="checkbox"] {
&[disabled],
&.disabled,
fieldset[disabled] & {
cursor: not-allowed;
cursor: @cursor-disabled;
}
}
// These classes are used directly on <label>s
@@ -266,7 +273,7 @@ input[type="checkbox"] {
.checkbox-inline {
&.disabled,
fieldset[disabled] & {
cursor: not-allowed;
cursor: @cursor-disabled;
}
}
// These classes are used on elements with <label> descendants
@@ -275,7 +282,7 @@ input[type="checkbox"] {
&.disabled,
fieldset[disabled] & {
label {
cursor: not-allowed;
cursor: @cursor-disabled;
}
}
}
@@ -292,6 +299,7 @@ input[type="checkbox"] {
padding-bottom: (@padding-base-vertical + 1);
// Remove default margin from `p`
margin-bottom: 0;
min-height: (@line-height-computed + @font-size-base);
&.input-lg,
&.input-sm {
@@ -305,13 +313,40 @@ input[type="checkbox"] {
//
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.
//
// The `.form-group-* form-control` variations are sadly duplicated to avoid the
// issue documented in https://github.com/twbs/bootstrap/issues/15074.
.input-sm {
.input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);
.input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);
}
.form-group-sm {
.form-control {
.input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @input-border-radius-small);
}
.form-control-static {
height: @input-height-small;
padding: @padding-small-vertical @padding-small-horizontal;
font-size: @font-size-small;
line-height: @line-height-small;
min-height: (@line-height-computed + @font-size-small);
}
}
.input-lg {
.input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);
.input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);
}
.form-group-lg {
.form-control {
.input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @input-border-radius-large);
}
.form-control-static {
height: @input-height-large;
padding: @padding-large-vertical @padding-large-horizontal;
font-size: @font-size-large;
line-height: @line-height-large;
min-height: (@line-height-computed + @font-size-large);
}
}
@@ -331,7 +366,7 @@ input[type="checkbox"] {
// Feedback icon (requires .glyphicon classes)
.form-control-feedback {
position: absolute;
top: (@line-height-computed + 5); // Height of the `label` and its margin
top: 0;
right: 0;
z-index: 2; // Ensure icon is above input groups
display: block;
@@ -339,6 +374,7 @@ input[type="checkbox"] {
height: @input-height-base;
line-height: @input-height-base;
text-align: center;
pointer-events: none;
}
.input-lg + .form-control-feedback {
width: @input-height-large;
@@ -362,10 +398,15 @@ input[type="checkbox"] {
.form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);
}
// Reposition feedback icon if input has visible label above
.has-feedback label {
// Reposition feedback icon if label is hidden with "screenreader only" state
.has-feedback label.sr-only ~ .form-control-feedback {
top: 0;
& ~ .form-control-feedback {
top: (@line-height-computed + 5); // Height of the `label` and its margin
}
&.sr-only ~ .form-control-feedback {
top: 0;
}
}
@@ -382,7 +423,6 @@ input[type="checkbox"] {
}
// Inline forms
//
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
@@ -412,6 +452,11 @@ input[type="checkbox"] {
vertical-align: middle;
}
// Make static controls behave like regular ones
.form-control-static {
display: inline-block;
}
.input-group {
display: inline-table;
vertical-align: middle;
@@ -434,8 +479,7 @@ input[type="checkbox"] {
}
// Remove default margin on radios/checkboxes that were used for stacking, and
// then undo the floating of radios and checkboxes to match (which also avoids
// a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).
// then undo the floating of radios and checkboxes to match.
.radio,
.checkbox {
display: inline-block;
@@ -453,10 +497,7 @@ input[type="checkbox"] {
margin-left: 0;
}
// Validation states
//
// Reposition the icon because it's now within a grid column and columns have
// `position: relative;` on them. Also accounts for the grid gutter padding.
// Re-override the feedback icon.
.has-feedback .form-control-feedback {
top: 0;
}
@@ -509,7 +550,6 @@ input[type="checkbox"] {
// Reposition the icon because it's now within a grid column and columns have
// `position: relative;` on them. Also accounts for the grid gutter padding.
.has-feedback .form-control-feedback {
top: 0;
right: (@grid-gutter-width / 2);
}
@@ -523,9 +563,6 @@ input[type="checkbox"] {
padding-top: ((@padding-large-vertical * @line-height-large) + 1);
}
}
.form-control {
&:extend(.input-lg);
}
}
.form-group-sm {
@media (min-width: @screen-sm-min) {
@@ -533,8 +570,5 @@ input[type="checkbox"] {
padding-top: (@padding-small-vertical + 1);
}
}
.form-control {
&:extend(.input-sm);
}
}
}
@@ -12,6 +12,7 @@
font-family: 'Glyphicons Halflings';
src: url('@{icon-font-path}@{icon-font-name}.eot');
src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),
url('@{icon-font-path}@{icon-font-name}.woff2') format('woff2'),
url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),
url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),
url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');
@@ -33,7 +34,8 @@
// Individual icons
.glyphicon-asterisk { &:before { content: "\2a"; } }
.glyphicon-plus { &:before { content: "\2b"; } }
.glyphicon-euro { &:before { content: "\20ac"; } }
.glyphicon-euro,
.glyphicon-eur { &:before { content: "\20ac"; } }
.glyphicon-minus { &:before { content: "\2212"; } }
.glyphicon-cloud { &:before { content: "\2601"; } }
.glyphicon-envelope { &:before { content: "\2709"; } }
@@ -231,3 +233,73 @@
.glyphicon-cloud-upload { &:before { content: "\e198"; } }
.glyphicon-tree-conifer { &:before { content: "\e199"; } }
.glyphicon-tree-deciduous { &:before { content: "\e200"; } }
.glyphicon-cd { &:before { content: "\e201"; } }
.glyphicon-save-file { &:before { content: "\e202"; } }
.glyphicon-open-file { &:before { content: "\e203"; } }
.glyphicon-level-up { &:before { content: "\e204"; } }
.glyphicon-copy { &:before { content: "\e205"; } }
.glyphicon-paste { &:before { content: "\e206"; } }
// The following 2 Glyphicons are omitted for the time being because
// they currently use Unicode codepoints that are outside the
// Basic Multilingual Plane (BMP). Older buggy versions of WebKit can't handle
// non-BMP codepoints in CSS string escapes, and thus can't display these two icons.
// Notably, the bug affects some older versions of the Android Browser.
// More info: https://github.com/twbs/bootstrap/issues/10106
// .glyphicon-door { &:before { content: "\1f6aa"; } }
// .glyphicon-key { &:before { content: "\1f511"; } }
.glyphicon-alert { &:before { content: "\e209"; } }
.glyphicon-equalizer { &:before { content: "\e210"; } }
.glyphicon-king { &:before { content: "\e211"; } }
.glyphicon-queen { &:before { content: "\e212"; } }
.glyphicon-pawn { &:before { content: "\e213"; } }
.glyphicon-bishop { &:before { content: "\e214"; } }
.glyphicon-knight { &:before { content: "\e215"; } }
.glyphicon-baby-formula { &:before { content: "\e216"; } }
.glyphicon-tent { &:before { content: "\26fa"; } }
.glyphicon-blackboard { &:before { content: "\e218"; } }
.glyphicon-bed { &:before { content: "\e219"; } }
.glyphicon-apple { &:before { content: "\f8ff"; } }
.glyphicon-erase { &:before { content: "\e221"; } }
.glyphicon-hourglass { &:before { content: "\231b"; } }
.glyphicon-lamp { &:before { content: "\e223"; } }
.glyphicon-duplicate { &:before { content: "\e224"; } }
.glyphicon-piggy-bank { &:before { content: "\e225"; } }
.glyphicon-scissors { &:before { content: "\e226"; } }
.glyphicon-bitcoin { &:before { content: "\e227"; } }
.glyphicon-btc { &:before { content: "\e227"; } }
.glyphicon-xbt { &:before { content: "\e227"; } }
.glyphicon-yen { &:before { content: "\00a5"; } }
.glyphicon-jpy { &:before { content: "\00a5"; } }
.glyphicon-ruble { &:before { content: "\20bd"; } }
.glyphicon-rub { &:before { content: "\20bd"; } }
.glyphicon-scale { &:before { content: "\e230"; } }
.glyphicon-ice-lolly { &:before { content: "\e231"; } }
.glyphicon-ice-lolly-tasted { &:before { content: "\e232"; } }
.glyphicon-education { &:before { content: "\e233"; } }
.glyphicon-option-horizontal { &:before { content: "\e234"; } }
.glyphicon-option-vertical { &:before { content: "\e235"; } }
.glyphicon-menu-hamburger { &:before { content: "\e236"; } }
.glyphicon-modal-window { &:before { content: "\e237"; } }
.glyphicon-oil { &:before { content: "\e238"; } }
.glyphicon-grain { &:before { content: "\e239"; } }
.glyphicon-sunglasses { &:before { content: "\e240"; } }
.glyphicon-text-size { &:before { content: "\e241"; } }
.glyphicon-text-color { &:before { content: "\e242"; } }
.glyphicon-text-background { &:before { content: "\e243"; } }
.glyphicon-object-align-top { &:before { content: "\e244"; } }
.glyphicon-object-align-bottom { &:before { content: "\e245"; } }
.glyphicon-object-align-horizontal{ &:before { content: "\e246"; } }
.glyphicon-object-align-left { &:before { content: "\e247"; } }
.glyphicon-object-align-vertical { &:before { content: "\e248"; } }
.glyphicon-object-align-right { &:before { content: "\e249"; } }
.glyphicon-triangle-right { &:before { content: "\e250"; } }
.glyphicon-triangle-left { &:before { content: "\e251"; } }
.glyphicon-triangle-bottom { &:before { content: "\e252"; } }
.glyphicon-triangle-top { &:before { content: "\e253"; } }
.glyphicon-console { &:before { content: "\e254"; } }
.glyphicon-superscript { &:before { content: "\e255"; } }
.glyphicon-subscript { &:before { content: "\e256"; } }
.glyphicon-menu-left { &:before { content: "\e257"; } }
.glyphicon-menu-right { &:before { content: "\e258"; } }
.glyphicon-menu-down { &:before { content: "\e259"; } }
.glyphicon-menu-up { &:before { content: "\e260"; } }
@@ -4,7 +4,7 @@
.jumbotron {
padding: @jumbotron-padding;
padding: @jumbotron-padding (@jumbotron-padding / 2);
margin-bottom: @jumbotron-padding;
color: @jumbotron-color;
background-color: @jumbotron-bg;
@@ -13,6 +13,7 @@
.h1 {
color: @jumbotron-heading-color;
}
p {
margin-bottom: (@jumbotron-padding / 2);
font-size: @jumbotron-font-size;
@@ -23,7 +24,8 @@
border-top-color: darken(@jumbotron-bg, 10%);
}
.container & {
.container &,
.container-fluid & {
border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container
}
@@ -32,10 +34,10 @@
}
@media screen and (min-width: @screen-sm-min) {
padding-top: (@jumbotron-padding * 1.6);
padding-bottom: (@jumbotron-padding * 1.6);
padding: (@jumbotron-padding * 1.6) 0;
.container & {
.container &,
.container-fluid & {
padding-left: (@jumbotron-padding * 2);
padding-right: (@jumbotron-padding * 2);
}
@@ -35,14 +35,6 @@
margin-bottom: 0;
.border-bottom-radius(@list-group-border-radius);
}
// Align badges within list items
> .badge {
float: right;
}
> .badge + .badge {
margin-right: 5px;
}
}
@@ -74,6 +66,7 @@ a.list-group-item {
&.disabled:focus {
background-color: @list-group-disabled-bg;
color: @list-group-disabled-color;
cursor: @cursor-disabled;
// Force color to inherit for custom content
.list-group-item-heading {
+61
View File
@@ -0,0 +1,61 @@
.media {
// Proper spacing between instances of .media
margin-top: 15px;
&:first-child {
margin-top: 0;
}
}
.media,
.media-body {
zoom: 1;
overflow: hidden;
}
.media-body {
width: 10000px;
}
.media-object {
display: block;
}
.media-right,
.media > .pull-right {
padding-left: 10px;
}
.media-left,
.media > .pull-left {
padding-right: 10px;
}
.media-left,
.media-right,
.media-body {
display: table-cell;
vertical-align: top;
}
.media-middle {
vertical-align: middle;
}
.media-bottom {
vertical-align: bottom;
}
// Reset margins on headings for tighter default spacing
.media-heading {
margin-top: 0;
margin-bottom: 5px;
}
// Media list variation
//
// Undo default ul/ol styles
.media-list {
padding-left: 0;
list-style: none;
}
+39
View File
@@ -0,0 +1,39 @@
// Mixins
// --------------------------------------------------
// Utilities
@import "mixins/hide-text.less";
@import "mixins/opacity.less";
@import "mixins/image.less";
@import "mixins/labels.less";
@import "mixins/reset-filter.less";
@import "mixins/resize.less";
@import "mixins/responsive-visibility.less";
@import "mixins/size.less";
@import "mixins/tab-focus.less";
@import "mixins/text-emphasis.less";
@import "mixins/text-overflow.less";
@import "mixins/vendor-prefixes.less";
// Components
@import "mixins/alerts.less";
@import "mixins/buttons.less";
@import "mixins/panels.less";
@import "mixins/pagination.less";
@import "mixins/list-group.less";
@import "mixins/nav-divider.less";
@import "mixins/forms.less";
@import "mixins/progress-bar.less";
@import "mixins/table-row.less";
// Skins
@import "mixins/background-variant.less";
@import "mixins/border-radius.less";
@import "mixins/gradients.less";
// Layout
@import "mixins/clearfix.less";
@import "mixins/center-block.less";
@import "mixins/nav-vertical-align.less";
@import "mixins/grid-framework.less";
@import "mixins/grid.less";
@@ -10,6 +10,7 @@
&:hover,
&:focus,
&.focus,
&:active,
&.active,
.open > .dropdown-toggle& {
@@ -28,6 +29,7 @@
&,
&:hover,
&:focus,
&.focus,
&:active,
&.active {
background-color: @background;
@@ -10,7 +10,11 @@
.radio,
.checkbox,
.radio-inline,
.checkbox-inline {
.checkbox-inline,
&.radio label,
&.checkbox label,
&.radio-inline label,
&.checkbox-inline label {
color: @text-color;
}
// Set the border and box shadow on specific inputs to match
@@ -5,7 +5,7 @@
.make-grid-columns() {
// Common styles for all sizes of grid columns, widths 1-12
.col(@index) when (@index = 1) { // initial
.col(@index) { // initial
@item: ~".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}";
.col((@index + 1), @item);
}
@@ -27,7 +27,7 @@
}
.float-grid-columns(@class) {
.col(@index) when (@index = 1) { // initial
.col(@index) { // initial
@item: ~".col-@{class}-@{index}";
.col((@index + 1), @item);
}
@@ -8,7 +8,6 @@
// Keep images from scaling beyond the width of their parents.
.img-responsive(@display: block) {
display: @display;
width: 100% \9; // Force IE10 and below to size SVG images correctly
max-width: 100%; // Part 1: Set a maximum relative to the parent
height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching
}
@@ -2,7 +2,7 @@
.label-variant(@color) {
background-color: @color;
&[href] {
&:hover,
&:focus {
@@ -99,9 +99,12 @@
// Placeholder text
.placeholder(@color: @input-color-placeholder) {
&::-moz-placeholder { color: @color; // Firefox
opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526
&:-ms-input-placeholder { color: @color; } // Internet Explorer 10+
// Firefox
&::-moz-placeholder {
color: @color;
opacity: 1; // Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526
}
&:-ms-input-placeholder { color: @color; } // Internet Explorer 10+
&::-webkit-input-placeholder { color: @color; } // Safari and Chrome
}
@@ -30,10 +30,10 @@
// When fading in the modal, animate it to slide down
&.fade .modal-dialog {
.translate3d(0, -25%, 0);
.translate(0, -25%);
.transition-transform(~"0.3s ease-out");
}
&.in .modal-dialog { .translate3d(0, 0, 0) }
&.in .modal-dialog { .translate(0, 0) }
}
.modal-open .modal {
overflow-x: hidden;
@@ -92,7 +92,7 @@
.navbar-collapse {
max-height: @navbar-collapse-max-height;
@media (max-width: @screen-xs-min) and (orientation: landscape) {
@media (max-device-width: @screen-xs-min) and (orientation: landscape) {
max-height: 200px;
}
}
@@ -141,7 +141,6 @@
right: 0;
left: 0;
z-index: @zindex-navbar-fixed;
.translate3d(0, 0, 0);
// Undo the rounded corners
@media (min-width: @grid-float-breakpoint) {
@@ -173,6 +172,10 @@
text-decoration: none;
}
> img {
display: block;
}
@media (min-width: @grid-float-breakpoint) {
.navbar > .container &,
.navbar > .container-fluid & {
@@ -271,26 +274,10 @@
padding-bottom: @navbar-padding-vertical;
}
}
&.navbar-right:last-child {
margin-right: -@navbar-padding-horizontal;
}
}
}
// Component alignment
//
// Repurpose the pull utilities as their own navbar utilities to avoid specificity
// issues with parents and chaining. Only do this when the navbar is uncollapsed
// though so that navbar contents properly stack and align in mobile.
@media (min-width: @grid-float-breakpoint) {
.navbar-left { .pull-left(); }
.navbar-right { .pull-right(); }
}
// Navbar form
//
// Extension of the `.form-inline` with some extra flavor for optimum display in
@@ -311,6 +298,10 @@
.form-group {
@media (max-width: @grid-float-breakpoint-max) {
margin-bottom: 5px;
&:last-child {
margin-bottom: 0;
}
}
}
@@ -326,11 +317,6 @@
padding-top: 0;
padding-bottom: 0;
.box-shadow(none);
// Outdent the form if last child to line up with content down the page
&.navbar-right:last-child {
margin-right: -@navbar-padding-horizontal;
}
}
}
@@ -344,6 +330,8 @@
}
// Menu position and menu caret support for dropups via extra dropup class
.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {
margin-bottom: 0;
.border-top-radius(@navbar-border-radius);
.border-bottom-radius(0);
}
@@ -375,14 +363,31 @@
float: left;
margin-left: @navbar-padding-horizontal;
margin-right: @navbar-padding-horizontal;
}
}
// Outdent the form if last child to line up with content down the page
&.navbar-right:last-child {
// Component alignment
//
// Repurpose the pull utilities as their own navbar utilities to avoid specificity
// issues with parents and chaining. Only do this when the navbar is uncollapsed
// though so that navbar contents properly stack and align in mobile.
//
// Declared after the navbar components to ensure more specificity on the margins.
@media (min-width: @grid-float-breakpoint) {
.navbar-left { .pull-left(); }
.navbar-right {
.pull-right();
margin-right: -@navbar-padding-horizontal;
~ .navbar-right {
margin-right: 0;
}
}
}
// Alternate navbars
// --------------------------------------------------
@@ -36,7 +36,7 @@
color: @nav-disabled-link-hover-color;
text-decoration: none;
background-color: transparent;
cursor: not-allowed;
cursor: @cursor-disabled;
}
}
}
@@ -1,4 +1,4 @@
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
//
// 1. Set default font family to sans-serif.
@@ -25,7 +25,8 @@ body {
//
// Correct `block` display not defined for any HTML5 element in IE 8/9.
// Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox.
// Correct `block` display not defined for `details` or `summary` in IE 10/11
// and Firefox.
// Correct `block` display not defined for `main` in IE 11.
//
@@ -38,6 +39,7 @@ footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
@@ -85,7 +87,7 @@ template {
//
a {
background: transparent;
background-color: transparent;
}
//
@@ -48,8 +48,7 @@
> span {
color: @pager-disabled-color;
background-color: @pager-bg;
cursor: not-allowed;
cursor: @cursor-disabled;
}
}
}
@@ -69,7 +69,7 @@
color: @pagination-disabled-color;
background-color: @pagination-disabled-bg;
border-color: @pagination-disabled-border;
cursor: not-allowed;
cursor: @cursor-disabled;
}
}
}
@@ -36,7 +36,11 @@
font-size: ceil((@font-size-base * 1.125));
color: inherit;
> a {
> a,
> small,
> .small,
> small > a,
> .small > a {
color: inherit;
}
}
@@ -56,7 +60,8 @@
// any kind of custom content between the two.
.panel {
> .list-group {
> .list-group,
> .panel-collapse > .list-group {
margin-bottom: 0;
.list-group-item {
@@ -100,6 +105,11 @@
> .table-responsive > .table,
> .panel-collapse > .table {
margin-bottom: 0;
caption {
padding-left: @panel-body-padding;
padding-right: @panel-body-padding;
}
}
// Add border top radius for first one
> .table:first-child,
@@ -109,6 +119,9 @@
> thead:first-child,
> tbody:first-child {
> tr:first-child {
border-top-left-radius: (@panel-border-radius - 1);
border-top-right-radius: (@panel-border-radius - 1);
td:first-child,
th:first-child {
border-top-left-radius: (@panel-border-radius - 1);
@@ -128,6 +141,9 @@
> tbody:last-child,
> tfoot:last-child {
> tr:last-child {
border-bottom-left-radius: (@panel-border-radius - 1);
border-bottom-right-radius: (@panel-border-radius - 1);
td:first-child,
th:first-child {
border-bottom-left-radius: (@panel-border-radius - 1);
@@ -140,7 +156,9 @@
}
}
> .panel-body + .table,
> .panel-body + .table-responsive {
> .panel-body + .table-responsive,
> .table + .panel-body,
> .table-responsive + .panel-body {
border-top: 1px solid @table-border-color;
}
> .table > tbody:first-child > tr:first-child th,
@@ -202,6 +220,7 @@
.panel {
margin-bottom: 0;
border-radius: @panel-border-radius;
+ .panel {
margin-top: 5px;
}
@@ -209,10 +228,13 @@
.panel-heading {
border-bottom: 0;
+ .panel-collapse > .panel-body {
+ .panel-collapse > .panel-body,
+ .panel-collapse > .list-group {
border-top: 1px solid @panel-inner-border;
}
}
.panel-footer {
border-top: 0;
+ .panel-collapse .panel-body {
@@ -11,7 +11,12 @@
display: none;
max-width: @popover-max-width;
padding: 1px;
text-align: left; // Reset given new insertion method
// Reset font and text properties given new insertion method
font-family: @font-family-base;
font-size: @font-size-base;
font-weight: normal;
line-height: @line-height-base;
text-align: left;
background-color: @popover-bg;
background-clip: padding-box;
border: 1px solid @popover-fallback-border-color;
@@ -33,8 +38,6 @@
margin: 0; // reset heading margin
padding: 8px 14px;
font-size: @font-size-base;
font-weight: normal;
line-height: 18px;
background-color: @popover-title-bg;
border-bottom: 1px solid darken(@popover-title-bg, 5%);
border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;
@@ -129,5 +132,4 @@
bottom: -@popover-arrow-width;
}
}
}
+107
View File
@@ -0,0 +1,107 @@
/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
// ==========================================================================
// Print styles.
// Inlined to avoid the additional HTTP request: h5bp.com/r
// ==========================================================================
@media print {
*,
*:before,
*:after {
background: transparent !important;
color: #000 !important; // Black prints faster: h5bp.com/s
box-shadow: none !important;
text-shadow: none !important;
}
a,
a:visited {
text-decoration: underline;
}
a[href]:after {
content: " (" attr(href) ")";
}
abbr[title]:after {
content: " (" attr(title) ")";
}
// Don't show links that are fragment identifiers,
// or use the `javascript:` pseudo protocol
a[href^="#"]:after,
a[href^="javascript:"]:after {
content: "";
}
pre,
blockquote {
border: 1px solid #999;
page-break-inside: avoid;
}
thead {
display: table-header-group; // h5bp.com/t
}
tr,
img {
page-break-inside: avoid;
}
img {
max-width: 100% !important;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
// Bootstrap specific changes start
//
// Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245
// Once fixed, we can just straight up remove this.
select {
background: #fff !important;
}
// Bootstrap components
.navbar {
display: none;
}
.btn,
.dropup > .btn {
> .caret {
border-top-color: #000 !important;
}
}
.label {
border: 1px solid #000;
}
.table {
border-collapse: collapse !important;
td,
th {
background-color: #fff !important;
}
}
.table-bordered {
th,
td {
border: 1px solid #ddd !important;
}
}
// Bootstrap specific changes end
}
@@ -19,7 +19,6 @@
}
// Bar itself
// -------------------------
@@ -29,7 +28,7 @@
height: @line-height-computed;
margin-bottom: @line-height-computed;
background-color: @progress-bg;
border-radius: @border-radius-base;
border-radius: @progress-border-radius;
.box-shadow(inset 0 1px 2px rgba(0,0,0,.1));
}
@@ -67,23 +66,6 @@
.animation(progress-bar-stripes 2s linear infinite);
}
// Account for lower percentages
.progress-bar {
&[aria-valuenow="1"],
&[aria-valuenow="2"] {
min-width: 30px;
}
&[aria-valuenow="0"] {
color: @gray-light;
min-width: 30px;
background-color: transparent;
background-image: none;
box-shadow: none;
}
}
// Variations
// -------------------------
@@ -12,7 +12,8 @@
.embed-responsive-item,
iframe,
embed,
object {
object,
video {
position: absolute;
top: 0;
left: 0;
@@ -21,14 +22,14 @@
width: 100%;
border: 0;
}
// Modifier class for 16:9 aspect ratio
&.embed-responsive-16by9 {
padding-bottom: 56.25%;
}
// Modifier class for 4:3 aspect ratio
&.embed-responsive-4by3 {
padding-bottom: 75%;
}
}
// Modifier class for 16:9 aspect ratio
.embed-responsive-16by9 {
padding-bottom: 56.25%;
}
// Modifier class for 4:3 aspect ratio
.embed-responsive-4by3 {
padding-bottom: 75%;
}

Some files were not shown because too many files have changed in this diff Show More