[ADD] theme 8.0
@@ -0,0 +1,4 @@
|
||||
import ir_qweb
|
||||
import ir_attachment
|
||||
import controllers
|
||||
import website
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
'name': 'Theme Support Engine',
|
||||
'category': 'Website',
|
||||
'summary': 'Support layer for Themes in 8.0',
|
||||
'version': '1.1',
|
||||
'description': """
|
||||
Support layer for themes in 8.0.
|
||||
|
||||
This module requires `lessc` and its `clean-css` plugin to be installed on your system. Please refer to the `Less CSS via nodejs` section of https://www.odoo.com/documentation/8.0/setup/install.html#setup-install-source for installation instructions.
|
||||
""",
|
||||
'author': 'Odoo SA',
|
||||
'depends': ['website'],
|
||||
'data': [
|
||||
'views/snippets.xml',
|
||||
'views/themes.xml',
|
||||
'views/website_templates.xml',
|
||||
'views/website_backend_navbar.xml',
|
||||
],
|
||||
'qweb': ['static/src/xml/website.backend.xml'],
|
||||
'installable': True,
|
||||
'application': False,
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
import main
|
||||
@@ -0,0 +1,149 @@
|
||||
import werkzeug
|
||||
from openerp.http import request
|
||||
from openerp.addons.web import http
|
||||
from openerp.addons.website.controllers.main import Website
|
||||
from openerp.addons.base.ir.ir_qweb import QWebTemplateNotFound
|
||||
from openerp.addons.website_less.ir_qweb import AssetsBundle
|
||||
from openerp.addons.web.controllers.main import Home, make_conditional, BUNDLE_MAXAGE
|
||||
|
||||
|
||||
class Home_less(Home):
|
||||
|
||||
@http.route([
|
||||
'/web/js/<xmlid>',
|
||||
'/web/js/<xmlid>/<version>',
|
||||
], type='http', auth='public')
|
||||
def js_bundle(self, xmlid, version=None, **kw):
|
||||
try:
|
||||
bundle = AssetsBundle(xmlid)
|
||||
except QWebTemplateNotFound:
|
||||
return request.not_found()
|
||||
|
||||
response = request.make_response(bundle.js(), [('Content-Type', 'application/javascript')])
|
||||
return make_conditional(response, bundle.last_modified, max_age=BUNDLE_MAXAGE)
|
||||
|
||||
@http.route([
|
||||
'/web/css/<xmlid>',
|
||||
'/web/css/<xmlid>/<version>',
|
||||
], type='http', auth='public')
|
||||
def css_bundle(self, xmlid, version=None, **kw):
|
||||
try:
|
||||
bundle = AssetsBundle(xmlid)
|
||||
except QWebTemplateNotFound:
|
||||
return request.not_found()
|
||||
|
||||
response = request.make_response(bundle.css(), [('Content-Type', 'text/css')])
|
||||
return make_conditional(response, bundle.last_modified, max_age=BUNDLE_MAXAGE)
|
||||
|
||||
|
||||
class Website_less(Website):
|
||||
#------------------------------------------------------
|
||||
# Themes
|
||||
#------------------------------------------------------
|
||||
|
||||
def get_view_ids(self, xml_ids):
|
||||
ids = []
|
||||
imd = request.registry['ir.model.data']
|
||||
for xml_id in xml_ids:
|
||||
if "." in xml_id:
|
||||
xml = xml_id.split(".")
|
||||
view_model, id = imd.get_object_reference(request.cr, request.uid, xml[0], xml[1])
|
||||
else:
|
||||
id = int(xml_id)
|
||||
ids.append(id)
|
||||
return ids
|
||||
|
||||
@http.route(['/website/theme_customize_get'], type='json', auth="public", website=True)
|
||||
def theme_customize_get(self, xml_ids):
|
||||
view = request.registry["ir.ui.view"]
|
||||
enable = []
|
||||
disable = []
|
||||
ids = self.get_view_ids(xml_ids)
|
||||
context = dict(request.context or {}, active_test=True)
|
||||
for v in view.browse(request.cr, request.uid, ids, context=context):
|
||||
if v.active:
|
||||
enable.append(v.xml_id)
|
||||
else:
|
||||
disable.append(v.xml_id)
|
||||
return [enable, disable]
|
||||
|
||||
@http.route(['/website/theme_customize'], type='json', auth="public", website=True)
|
||||
def theme_customize(self, enable, disable):
|
||||
""" enable or Disable lists of ``xml_id`` of the inherit templates
|
||||
"""
|
||||
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
|
||||
view = pool["ir.ui.view"]
|
||||
context = dict(request.context or {}, active_test=True)
|
||||
|
||||
def set_active(ids, active):
|
||||
if ids:
|
||||
view.write(cr, uid, self.get_view_ids(ids), {'active': active}, context=context)
|
||||
|
||||
set_active(disable, False)
|
||||
set_active(enable, True)
|
||||
|
||||
return True
|
||||
|
||||
@http.route(['/website/theme_customize_reload'], type='http', auth="public", website=True)
|
||||
def theme_customize_reload(self, href, enable, disable):
|
||||
self.theme_customize(enable and enable.split(",") or [], disable and disable.split(",") or [])
|
||||
return request.redirect(href + ("&theme=true" if "#" in href else "#theme=true"))
|
||||
|
||||
@http.route(['/website/multi_render'], type='json', auth="public", website=True)
|
||||
def multi_render(self, ids_or_xml_ids, values=None):
|
||||
res = {}
|
||||
for id_or_xml_id in ids_or_xml_ids:
|
||||
res[id_or_xml_id] = request.registry["ir.ui.view"].render(request.cr, request.uid,
|
||||
id_or_xml_id, values=values, engine='ir.qweb', context=request.context)
|
||||
return res
|
||||
|
||||
@http.route([
|
||||
'/website/image',
|
||||
'/website/image/<xmlid>',
|
||||
'/website/image/<xmlid>/<field>',
|
||||
'/website/image/<xmlid>/<int:max_width>x<int:max_height>',
|
||||
'/website/image/<xmlid>/<field>/<int:max_width>x<int:max_height>',
|
||||
'/website/image/<model>/<id>/<field>',
|
||||
'/website/image/<model>/<id>/<field>/<int:max_width>x<int:max_height>',
|
||||
], auth="public", website=True)
|
||||
def website_image(self, model=None, id=None, field=None, xmlid=None, max_width=None, max_height=None):
|
||||
""" Fetches the requested field and ensures it does not go above
|
||||
(max_width, max_height), resizing it if necessary.
|
||||
|
||||
If the record is not found or does not have the requested field,
|
||||
returns a placeholder image via :meth:`~.placeholder`.
|
||||
|
||||
Sets and checks conditional response parameters:
|
||||
* :mailheader:`ETag` is always set (and checked)
|
||||
* :mailheader:`Last-Modified is set iif the record has a concurrency
|
||||
field (``__last_update``)
|
||||
|
||||
The requested field is assumed to be base64-encoded image data in
|
||||
all cases.
|
||||
|
||||
xmlid can be used to load the image. But the field image must by base64-encoded
|
||||
"""
|
||||
if xmlid and "." in xmlid:
|
||||
try:
|
||||
record = request.env['ir.model.data'].xmlid_to_object(xmlid)
|
||||
model, id = record._name, record.id
|
||||
except:
|
||||
raise werkzeug.exceptions.NotFound()
|
||||
env.ref
|
||||
if model == 'ir.attachment' and not field:
|
||||
if record.sudo().type == 'url':
|
||||
field = "url"
|
||||
else:
|
||||
field = "datas"
|
||||
elif model and id and field:
|
||||
idsha = id.split('_')
|
||||
try:
|
||||
id = idsha[0]
|
||||
except IndexError:
|
||||
raise werkzeug.exceptions.NotFound()
|
||||
else:
|
||||
raise werkzeug.exceptions.NotFound()
|
||||
|
||||
response = werkzeug.wrappers.Response()
|
||||
return request.registry['website']._image(
|
||||
request.cr, request.uid, model, id, field, response, max_width, max_height)
|
||||
@@ -0,0 +1,34 @@
|
||||
You need to install the *Less CSS* compiler to run this module
|
||||
|
||||
* on Linux, use your distribution's package manager to install nodejs and npm.
|
||||
* In debian wheezy and Ubuntu 13.10 and before you need to install nodejs manually:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ wget -qO- https://deb.nodesource.com/setup | bash -
|
||||
$ apt-get install -y nodejs
|
||||
|
||||
* In later debian (>jessie) and ubuntu (>14.04) you may need to add a symlink as npm packages call ``node`` but debian calls the binary ``nodejs``
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ apt-get install -y npm
|
||||
$ sudo ln -s /usr/bin/nodejs /usr/bin/node
|
||||
|
||||
* Once npm is installed, use it to install less and less-plugin-clean-css:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo npm install -g less less-plugin-clean-css
|
||||
|
||||
* on OS X, install nodejs via your preferred package manager (`homebrew <http://brew.sh/>`_, `macports <https://www.macports.org/>`_) then install less and less-plugin-clean-css:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ sudo npm install -g less less-plugin-clean-css
|
||||
|
||||
* on Windows, `install nodejs <http://nodejs.org/download/>`_, reboot (to update the `PATH`) and install less and less-plugin-clean-css:
|
||||
|
||||
.. code-block:: ps1
|
||||
|
||||
C:\> npm install -g less less-plugin-clean-css
|
||||
@@ -0,0 +1,13 @@
|
||||
from openerp.osv import fields, osv
|
||||
|
||||
|
||||
class ir_attachment(osv.osv):
|
||||
_inherit = "ir.attachment"
|
||||
|
||||
def invalidate_bundle(self, cr, uid, type='%', xmlid=None, context=None):
|
||||
assert type in ('%', 'css', 'js'), "Unhandled bundle type"
|
||||
xmlid = '%' if xmlid is None else xmlid + '%'
|
||||
domain = [('url', '=like', '/web/%s/%s/%%' % (type, xmlid))]
|
||||
ids = self.search(cr, uid, domain, context=context)
|
||||
if ids:
|
||||
self.unlink(cr, uid, ids, context=context)
|
||||
@@ -0,0 +1,344 @@
|
||||
import os
|
||||
import re
|
||||
import logging
|
||||
from lxml import etree, html
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
import openerp
|
||||
from openerp.osv import orm
|
||||
from openerp.tools import which
|
||||
from openerp.addons.base.ir.ir_qweb import AssetError, JavascriptAsset, QWebException
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class QWeb_less(orm.AbstractModel):
|
||||
_name = "website.qweb"
|
||||
_inherit = "website.qweb"
|
||||
|
||||
def render_tag_call_assets(self, element, template_attributes, generated_attributes, qwebcontext):
|
||||
""" This special 't-call' tag can be used in order to aggregate/minify javascript and css assets"""
|
||||
if len(element):
|
||||
# An asset bundle is rendered in two differents contexts (when genereting html and
|
||||
# when generating the bundle itself) so they must be qwebcontext free
|
||||
# even '0' variable is forbidden
|
||||
template = qwebcontext.get('__template__')
|
||||
raise QWebException("t-call-assets cannot contain children nodes", template=template)
|
||||
xmlid = template_attributes['call-assets']
|
||||
cr, uid, context = [getattr(qwebcontext, attr) for attr in ('cr', 'uid', 'context')]
|
||||
bundle = AssetsBundle(xmlid, cr=cr, uid=uid, context=context, registry=self.pool)
|
||||
css = self.get_attr_bool(template_attributes.get('css'), default=True)
|
||||
js = self.get_attr_bool(template_attributes.get('js'), default=True)
|
||||
return bundle.to_html(css=css, js=js, debug=bool(qwebcontext.get('debug')))
|
||||
|
||||
def render_tag_snippet(self, element, template_attributes, generated_attributes, qwebcontext):
|
||||
d = qwebcontext.copy()
|
||||
d[0] = self.render_element(element, template_attributes, generated_attributes, d)
|
||||
cr = d.get('request') and d['request'].cr or None
|
||||
uid = d.get('request') and d['request'].uid or None
|
||||
|
||||
template = self.eval_format(template_attributes["snippet"], d)
|
||||
document = self.render(cr, uid, template, d)
|
||||
node = etree.fromstring(document)
|
||||
|
||||
id = int(node.get('data-oe-id', self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, template, raise_if_not_found=True)))
|
||||
node.set('data-oe-name', self.pool['ir.ui.view'].browse(cr, uid, id, context=qwebcontext.context).name)
|
||||
node.set('data-oe-type', "snippet")
|
||||
node.set('data-oe-thumbnail', template_attributes.get('thumbnail', "oe-thumbnail"))
|
||||
|
||||
return html.tostring(node, encoding='UTF-8')
|
||||
|
||||
|
||||
class AssetsBundle(openerp.addons.base.ir.ir_qweb.AssetsBundle):
|
||||
rx_preprocess_imports = re.compile("""(@import\s?['"]([^'"]+)['"](;?))""")
|
||||
|
||||
def parse(self):
|
||||
fragments = html.fragments_fromstring(self.html)
|
||||
for el in fragments:
|
||||
if isinstance(el, basestring):
|
||||
self.remains.append(el)
|
||||
elif isinstance(el, html.HtmlElement):
|
||||
src = el.get('src', '')
|
||||
href = el.get('href', '')
|
||||
atype = el.get('type')
|
||||
media = el.get('media')
|
||||
if el.tag == 'style':
|
||||
if atype == 'text/sass' or src.endswith('.sass'):
|
||||
self.stylesheets.append(SassAsset(self, inline=el.text, media=media))
|
||||
elif atype == 'text/less' or src.endswith('.less'):
|
||||
self.stylesheets.append(LessStylesheetAsset(self, inline=el.text, media=media))
|
||||
else:
|
||||
self.stylesheets.append(StylesheetAsset(self, inline=el.text, media=media))
|
||||
elif el.tag == 'link' and el.get('rel') == 'stylesheet' and self.can_aggregate(href):
|
||||
if href.endswith('.sass') or atype == 'text/sass':
|
||||
self.stylesheets.append(SassAsset(self, url=href, media=media))
|
||||
elif href.endswith('.less') or atype == 'text/less':
|
||||
self.stylesheets.append(LessStylesheetAsset(self, url=href, media=media))
|
||||
else:
|
||||
self.stylesheets.append(StylesheetAsset(self, url=href, media=media))
|
||||
elif el.tag == 'script' and not src:
|
||||
self.javascripts.append(JavascriptAsset(self, inline=el.text))
|
||||
elif el.tag == 'script' and self.can_aggregate(src):
|
||||
self.javascripts.append(JavascriptAsset(self, url=src))
|
||||
else:
|
||||
self.remains.append(html.tostring(el))
|
||||
else:
|
||||
try:
|
||||
self.remains.append(html.tostring(el))
|
||||
except Exception:
|
||||
# notYETimplementederror
|
||||
raise NotImplementedError
|
||||
|
||||
def to_html(self, sep=None, css=True, js=True, debug=False):
|
||||
if sep is None:
|
||||
sep = '\n '
|
||||
response = []
|
||||
if debug:
|
||||
if css and self.stylesheets:
|
||||
self.preprocess_css()
|
||||
if self.css_errors:
|
||||
msg = '\n'.join(self.css_errors)
|
||||
self.stylesheets.append(StylesheetAsset(self, inline=self.css_message(msg)))
|
||||
for style in self.stylesheets:
|
||||
response.append(style.to_html())
|
||||
if js:
|
||||
for jscript in self.javascripts:
|
||||
response.append(jscript.to_html())
|
||||
else:
|
||||
url_for = self.context.get('url_for', lambda url: url)
|
||||
if css and self.stylesheets:
|
||||
href = '/web/css/%s/%s' % (self.xmlid, self.version)
|
||||
response.append('<link href="%s" rel="stylesheet"/>' % url_for(href))
|
||||
if js:
|
||||
src = '/web/js/%s/%s' % (self.xmlid, self.version)
|
||||
response.append('<script type="text/javascript" src="%s"></script>' % url_for(src))
|
||||
response.extend(self.remains)
|
||||
return sep + sep.join(response)
|
||||
|
||||
def css(self):
|
||||
content = self.get_cache('css')
|
||||
if content is None:
|
||||
content = self.preprocess_css()
|
||||
|
||||
if self.css_errors:
|
||||
msg = '\n'.join(self.css_errors)
|
||||
content += self.css_message(msg)
|
||||
|
||||
# move up all @import rules to the top
|
||||
matches = []
|
||||
|
||||
def push(matchobj):
|
||||
matches.append(matchobj.group(0))
|
||||
return ''
|
||||
|
||||
content = re.sub(self.rx_css_import, push, content)
|
||||
|
||||
matches.append(content)
|
||||
content = u'\n'.join(matches)
|
||||
if self.css_errors:
|
||||
return content
|
||||
self.set_cache('css', content)
|
||||
|
||||
return content
|
||||
|
||||
def set_cache(self, type, content):
|
||||
ira = self.registry['ir.attachment']
|
||||
ira.invalidate_bundle(self.cr, openerp.SUPERUSER_ID, type=type, xmlid=self.xmlid)
|
||||
url = '/web/%s/%s/%s' % (type, self.xmlid, self.version)
|
||||
ira.create(self.cr, openerp.SUPERUSER_ID, dict(
|
||||
datas=content.encode('utf8').encode('base64'),
|
||||
type='binary',
|
||||
name=url,
|
||||
url=url,
|
||||
), context=self.context)
|
||||
|
||||
def css_message(self, message):
|
||||
# '\A' == css content carriage return
|
||||
message = message.replace('\n', '\\A ').replace('"', '\\"')
|
||||
return """
|
||||
body:before {
|
||||
background: #ffc;
|
||||
width: 100%%;
|
||||
font-size: 14px;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
content: "%s";
|
||||
}
|
||||
""" % message
|
||||
|
||||
def preprocess_css(self):
|
||||
"""
|
||||
Checks if the bundle contains any sass/less content, then compiles it to css.
|
||||
Returns the bundle's flat css.
|
||||
"""
|
||||
for atype in (SassAsset, LessStylesheetAsset):
|
||||
assets = [asset for asset in self.stylesheets if isinstance(asset, atype)]
|
||||
if assets:
|
||||
cmd = assets[0].get_command()
|
||||
source = '\n'.join([asset.get_source() for asset in assets])
|
||||
compiled = self.compile_css(cmd, source)
|
||||
|
||||
fragments = self.rx_css_split.split(compiled)
|
||||
at_rules = fragments.pop(0)
|
||||
if at_rules:
|
||||
# Sass and less moves @at-rules to the top in order to stay css 2.1 compatible
|
||||
self.stylesheets.insert(0, StylesheetAsset(self, inline=at_rules))
|
||||
while fragments:
|
||||
asset_id = fragments.pop(0)
|
||||
asset = next(asset for asset in self.stylesheets if asset.id == asset_id)
|
||||
asset._content = fragments.pop(0)
|
||||
|
||||
return '\n'.join(asset.minify() for asset in self.stylesheets)
|
||||
|
||||
def compile_sass(self):
|
||||
self.preprocess_css()
|
||||
|
||||
def compile_css(self, cmd, source):
|
||||
"""Sanitizes @import rules, remove duplicates @import rules, then compile"""
|
||||
imports = []
|
||||
|
||||
def sanitize(matchobj):
|
||||
ref = matchobj.group(2)
|
||||
line = '@import "%s"%s' % (ref, matchobj.group(3))
|
||||
if '.' not in ref and line not in imports and not ref.startswith(('.', '/', '~')):
|
||||
imports.append(line)
|
||||
return line
|
||||
msg = "Local import '%s' is forbidden for security reasons." % ref
|
||||
_logger.warning(msg)
|
||||
self.css_errors.append(msg)
|
||||
return ''
|
||||
source = re.sub(self.rx_preprocess_imports, sanitize, source)
|
||||
|
||||
try:
|
||||
compiler = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
|
||||
except Exception:
|
||||
msg = "Could not execute command %r" % cmd[0]
|
||||
_logger.error(msg)
|
||||
self.css_errors.append(msg)
|
||||
return ''
|
||||
result = compiler.communicate(input=source.encode('utf-8'))
|
||||
if compiler.returncode:
|
||||
error = self.get_preprocessor_error(''.join(result), source=source)
|
||||
_logger.warning(error)
|
||||
self.css_errors.append(error)
|
||||
return ''
|
||||
compiled = result[0].strip().decode('utf8')
|
||||
return compiled
|
||||
|
||||
def get_preprocessor_error(self, stderr, source=None):
|
||||
"""Improve and remove sensitive information from sass/less compilator error messages"""
|
||||
error = stderr.split('Load paths')[0].replace(' Use --trace for backtrace.', '')
|
||||
if 'Cannot load compass' in error:
|
||||
error += "Maybe you should install the compass gem using this extra argument:\n\n" \
|
||||
" $ sudo gem install compass --pre\n"
|
||||
error += "This error occured while compiling the bundle '%s' containing:" % self.xmlid
|
||||
for asset in self.stylesheets:
|
||||
if isinstance(asset, (SassAsset, LessStylesheetAsset)):
|
||||
error += '\n - %s' % (asset.url if asset.url else '<inline sass>')
|
||||
return error
|
||||
|
||||
|
||||
class StylesheetAsset(openerp.addons.base.ir.ir_qweb.StylesheetAsset):
|
||||
|
||||
@property
|
||||
def content(self):
|
||||
if self._content is None:
|
||||
self._content = self.inline or self._fetch_content()
|
||||
return self._content
|
||||
|
||||
def _fetch_content(self):
|
||||
try:
|
||||
content = openerp.addons.base.ir.ir_qweb.WebAsset._fetch_content(self)
|
||||
web_dir = os.path.dirname(self.url)
|
||||
|
||||
if self.rx_import:
|
||||
content = self.rx_import.sub(
|
||||
r"""@import \1%s/""" % (web_dir,),
|
||||
content,
|
||||
)
|
||||
|
||||
if self.rx_url:
|
||||
content = self.rx_url.sub(
|
||||
r"url(\1%s/" % (web_dir,),
|
||||
content,
|
||||
)
|
||||
|
||||
if self.rx_charset:
|
||||
# remove charset declarations, we only support utf-8
|
||||
content = self.rx_charset.sub('', content)
|
||||
|
||||
return content
|
||||
except AssetError, e:
|
||||
self.bundle.css_errors.append(e.message)
|
||||
return ''
|
||||
|
||||
|
||||
class SassAsset(StylesheetAsset, openerp.addons.base.ir.ir_qweb.SassAsset):
|
||||
|
||||
def to_html(self):
|
||||
if self.url:
|
||||
ira = self.registry['ir.attachment']
|
||||
url = self.html_url % self.url
|
||||
domain = [('type', '=', 'binary'), ('url', '=', url)]
|
||||
ira_id = ira.search(self.cr, openerp.SUPERUSER_ID, domain, context=self.context)
|
||||
datas = self.content.encode('utf8').encode('base64')
|
||||
if ira_id:
|
||||
# TODO: update only if needed
|
||||
ira.write(self.cr, openerp.SUPERUSER_ID, ira_id, {'datas': datas}, context=self.context)
|
||||
else:
|
||||
ira.create(self.cr, openerp.SUPERUSER_ID, dict(
|
||||
datas=datas,
|
||||
mimetype='text/css',
|
||||
type='binary',
|
||||
name=url,
|
||||
url=url,
|
||||
), context=self.context)
|
||||
return super(SassAsset, self).to_html()
|
||||
|
||||
def get_command(self):
|
||||
defpath = os.environ.get('PATH', os.defpath).split(os.pathsep)
|
||||
sass = which('sass', path=os.pathsep.join(defpath))
|
||||
return [sass, '--stdin', '-t', 'compressed', '--unix-newlines', '--compass',
|
||||
'-r', 'bootstrap-sass']
|
||||
|
||||
|
||||
class LessStylesheetAsset(StylesheetAsset):
|
||||
html_url = '%s.css'
|
||||
rx_import = None
|
||||
|
||||
def minify(self):
|
||||
return self.with_header()
|
||||
|
||||
def to_html(self):
|
||||
if self.url:
|
||||
ira = self.registry['ir.attachment']
|
||||
url = self.html_url % self.url
|
||||
domain = [('type', '=', 'binary'), ('url', '=', url)]
|
||||
ira_id = ira.search(self.cr, openerp.SUPERUSER_ID, domain, context=self.context)
|
||||
datas = self.content.encode('utf8').encode('base64')
|
||||
if ira_id:
|
||||
# TODO: update only if needed
|
||||
ira.write(self.cr, openerp.SUPERUSER_ID, ira_id, {'datas': datas}, context=self.context)
|
||||
else:
|
||||
ira.create(self.cr, openerp.SUPERUSER_ID, dict(
|
||||
datas=datas,
|
||||
mimetype='text/css',
|
||||
type='binary',
|
||||
name=url,
|
||||
url=url,
|
||||
), context=self.context)
|
||||
return super(LessStylesheetAsset, self).to_html()
|
||||
|
||||
def get_source(self):
|
||||
content = self.inline or self._fetch_content()
|
||||
return "/*! %s */\n%s" % (self.id, content)
|
||||
|
||||
def get_command(self):
|
||||
defpath = os.environ.get('PATH', os.defpath).split(os.pathsep)
|
||||
if os.name == 'nt':
|
||||
lessc = which('lessc.cmd', path=os.pathsep.join(defpath))
|
||||
else:
|
||||
lessc = which('lessc', path=os.pathsep.join(defpath))
|
||||
webpath = openerp.http.addons_manifest['web']['addons_path']
|
||||
lesspath = os.path.join(webpath, 'web', 'static', 'lib', 'bootstrap', 'less')
|
||||
return [lessc, '-', '--clean-css', '--no-js', '--no-color', '--include-path=%s' % lesspath]
|
||||
@@ -0,0 +1,653 @@
|
||||
@charset "UTF-8";
|
||||
/* ---- CKEditor Minimal Reset ---- {{{ */
|
||||
.navbar.navbar-inverse .cke_chrome {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.navbar.navbar-inverse .cke_inner {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.navbar.navbar-inverse .cke_toolbar {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.navbar.navbar-inverse .cke_combo_button {
|
||||
padding-top: 3px;
|
||||
padding-bottom: 3px;
|
||||
}
|
||||
.navbar.navbar-inverse .cke_button {
|
||||
padding-top: 7px;
|
||||
padding-bottom: 7px;
|
||||
}
|
||||
|
||||
.navbar.navbar-inverse .cke_top {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
border: none;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
-ms-filter: "alpha(opacity=50)";
|
||||
}
|
||||
|
||||
#cke_1_top {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#cke_wrapwrap {
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
#cke_wrapwrap .cke_button {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
#cke_wrapwrap .cke_combo_button {
|
||||
padding-top: 1px;
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
/* ---- OpenERP Style ---- {{{ */
|
||||
.oe_website_editorbar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 2px;
|
||||
margin: 0;
|
||||
z-index: 20000;
|
||||
background: #414141, url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iIzY0NjA2MCIvPjxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iIzI2MjYyNiIvPjwvbGluZWFyR3JhZGllbnQ+PC9kZWZzPjxyZWN0IHg9IjAiIHk9IjAiIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JhZCkiIC8+PC9zdmc+IA==');
|
||||
background: #414141, -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #646060), color-stop(100%, #262626));
|
||||
background: #414141, -moz-linear-gradient(#646060, #262626);
|
||||
background: #414141, -webkit-linear-gradient(#646060, #262626);
|
||||
background: #414141, linear-gradient(#646060, #262626);
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.oe_website_editorbar li {
|
||||
display: inline;
|
||||
color: #eee;
|
||||
}
|
||||
.oe_website_editorbar li:hover {
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
text-shadow: black 0px 0px 3px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.oe_website_editorbar .oe_rte_toolbar div.dropdown {
|
||||
display: inline-block;
|
||||
}
|
||||
.oe_website_editorbar .oe_rte_toolbar div.dropdown li {
|
||||
display: list-item;
|
||||
}
|
||||
.oe_website_editorbar .oe_rte_toolbar button {
|
||||
font-family: FontAwesome;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
text-decoration: inherit;
|
||||
}
|
||||
.oe_website_editorbar .oe_rte_toolbar button.oe_button_list {
|
||||
padding-right: 3px;
|
||||
}
|
||||
.oe_website_editorbar .oe_rte_toolbar button.oe_button_list:after {
|
||||
content: "";
|
||||
padding-left: 6px;
|
||||
}
|
||||
|
||||
.oe_editable:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.css_editable_display {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.css_editable_hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.cke_editable .css_editable_mode_hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cke_editable .css_editable_mode_display {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.oe_structure.oe_empty:empty, [data-oe-type=html]:empty, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child {
|
||||
background-image: url("/website/static/src/img/edit_here.png") !important;
|
||||
}
|
||||
|
||||
.oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before {
|
||||
content: "Press The Top-Left Edit Button" !important;
|
||||
}
|
||||
|
||||
[data-oe-type=html].oe_no_empty:empty:before {
|
||||
content: "" !important;
|
||||
}
|
||||
|
||||
[data-oe-type=html].oe_no_empty:empty {
|
||||
background-image: none !important;
|
||||
height: 16px !important;
|
||||
}
|
||||
|
||||
#website-top-edit {
|
||||
width: 100%;
|
||||
}
|
||||
#website-top-edit > ul > li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#website-top-navbar {
|
||||
min-height: 34px;
|
||||
height: 34px;
|
||||
}
|
||||
#website-top-navbar form {
|
||||
margin: 0;
|
||||
}
|
||||
#website-top-navbar form button, #website-top-navbar form a {
|
||||
padding: 4px 8px 4px 8px;
|
||||
margin-top: 2px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* ---- EDITOR BAR ---- {{{ */
|
||||
table.editorbar-panel {
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
}
|
||||
table.editorbar-panel td {
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
table.editorbar-panel td.selected {
|
||||
background-color: #b1c9d9;
|
||||
}
|
||||
|
||||
.link-style .dropdown > .btn {
|
||||
min-width: 160px;
|
||||
}
|
||||
.link-style .link-style {
|
||||
display: none;
|
||||
}
|
||||
.link-style li {
|
||||
text-align: center;
|
||||
}
|
||||
.link-style li label {
|
||||
width: 100px;
|
||||
margin: 0 5px;
|
||||
}
|
||||
.link-style .col-sm-2 > * {
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
/* ---- TRANSLATIONS ---- {{{ */
|
||||
.oe_translate_or {
|
||||
color: white;
|
||||
padding: 0 0 0 1em;
|
||||
}
|
||||
|
||||
.oe_translate_examples li {
|
||||
margin: 10px;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.oe_translatable_text {
|
||||
outline: 1px solid black;
|
||||
}
|
||||
|
||||
.oe_translatable_field {
|
||||
outline: 1px dashed black;
|
||||
}
|
||||
|
||||
.oe_translatable_text.oe_dirty, .oe_translatable_field.oe_dirty {
|
||||
outline-color: red;
|
||||
}
|
||||
|
||||
.oe_translatable_text.oe_dirty:empty {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.oe_translatable_todo {
|
||||
background: #ffffb6;
|
||||
}
|
||||
|
||||
/* ---- MENU ---- {{{ */
|
||||
div.oe_menu_buttons {
|
||||
top: -8px;
|
||||
right: -8px;
|
||||
}
|
||||
|
||||
ul.oe_menu_editor .fa-home {
|
||||
display: none;
|
||||
}
|
||||
ul.oe_menu_editor > li:first-child > div > span > .fa-home {
|
||||
display: block;
|
||||
}
|
||||
ul.oe_menu_editor .oe_menu_placeholder {
|
||||
outline: 1px dashed #4183C4;
|
||||
}
|
||||
ul.oe_menu_editor ul {
|
||||
list-style: none;
|
||||
}
|
||||
ul.oe_menu_editor li div {
|
||||
cursor: move;
|
||||
}
|
||||
ul.oe_menu_editor .disclose {
|
||||
cursor: pointer;
|
||||
width: 10px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ---- RTE ---- {{{ */
|
||||
.oe_editable .btn, .btn.oe_editable {
|
||||
-moz-user-select: auto;
|
||||
-ms-user-select: auto;
|
||||
-webkit-user-select: auto;
|
||||
user-select: auto;
|
||||
cursor: text !important;
|
||||
}
|
||||
|
||||
.modal-dialog.select-media {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.modal .existing-attachments .pager {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.modal .image-preview {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.modal.nosave .wait {
|
||||
display: inline-block !important;
|
||||
visibility: visible !important;
|
||||
}
|
||||
.modal.nosave .modal-body .filepicker, .modal.nosave .modal-body .image-preview {
|
||||
display: none;
|
||||
}
|
||||
.modal.nosave .modal-body .wait {
|
||||
width: 100%;
|
||||
}
|
||||
.modal.nosave .modal-footer .save {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.modal .font-icons-icons {
|
||||
font-size: 2em;
|
||||
max-height: 9em;
|
||||
overflow: auto;
|
||||
}
|
||||
.modal .font-icons-icons .font-icons-icon {
|
||||
display: inline-block;
|
||||
width: 2em;
|
||||
padding: 0.25em;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.modal .font-icons {
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
.modal .font-icons:before {
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
|
||||
opacity: 0.7;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 3px;
|
||||
font-size: 2em;
|
||||
}
|
||||
.modal #icon-search {
|
||||
padding-left: 2.5em;
|
||||
}
|
||||
.modal #fa-preview {
|
||||
text-align: center;
|
||||
}
|
||||
.modal #fa-preview span {
|
||||
cursor: pointer;
|
||||
padding: 0 15px;
|
||||
}
|
||||
.modal #fa-preview .font-icons-selected {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
.existing-attachments .pager .disabled {
|
||||
display: none;
|
||||
}
|
||||
.existing-attachments .existing-attachment-cell {
|
||||
position: relative;
|
||||
}
|
||||
.existing-attachments .existing-attachment-cell .img {
|
||||
border: 1px solid #848490;
|
||||
}
|
||||
.existing-attachments .existing-attachment-cell .existing-attachment-remove {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 15px;
|
||||
cursor: pointer;
|
||||
background: white;
|
||||
padding: 2px;
|
||||
border: 1px solid #848490;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
-moz-border-radius-bottomright: 8px;
|
||||
-webkit-border-bottom-right-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
}
|
||||
.existing-attachments .existing-attachment-cell.media_selected > i, .existing-attachments .existing-attachment-cell.media_selected > img {
|
||||
border-width: 5px;
|
||||
border-color: #00f8f8;
|
||||
}
|
||||
|
||||
.cke_widget_wrapper {
|
||||
position: static !important;
|
||||
}
|
||||
|
||||
.cke_widget_inline {
|
||||
display: inline !important;
|
||||
}
|
||||
|
||||
.cke_widget_editable:empty:after {
|
||||
opacity: 0.3;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
.cke_widget_editable:not([placeholder]):empty::after {
|
||||
content: " ";
|
||||
}
|
||||
.cke_widget_editable[placeholder]:not(:focus):empty::after {
|
||||
content: attr(placeholder);
|
||||
}
|
||||
|
||||
.oe_carlos_danger {
|
||||
outline: 1px solid red !important;
|
||||
background-color: #ffd9dd !important;
|
||||
}
|
||||
|
||||
.hover-edition {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.preview-container {
|
||||
text-align: center;
|
||||
line-height: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
.preview-container > * {
|
||||
max-height: 100px;
|
||||
line-height: 100px;
|
||||
margin: 0 auto;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.cke_editable .fa {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.img-responsive {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ---- MOBILE PREVIEW ---- {{{ */
|
||||
.oe_mobile_preview.modal .modal-content {
|
||||
height: 660px;
|
||||
background-color: #000000;
|
||||
border: 2px solid #1C1F1F;
|
||||
-moz-border-radius: 10px;
|
||||
-webkit-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
margin: auto;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
max-width: 330px;
|
||||
}
|
||||
.oe_mobile_preview.modal .modal-content .modal-header {
|
||||
background-color: #000000;
|
||||
border-bottom: 0;
|
||||
-moz-border-radius-topleft: 10px;
|
||||
-webkit-border-top-left-radius: 10px;
|
||||
border-top-left-radius: 10px;
|
||||
-moz-border-radius-topright: 10px;
|
||||
-webkit-border-top-right-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
}
|
||||
.oe_mobile_preview.modal .modal-content .modal-header .modal-title {
|
||||
color: #1C1F1F;
|
||||
}
|
||||
.oe_mobile_preview.modal .modal-content .modal-header .close {
|
||||
color: lightgrey;
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
|
||||
opacity: 1;
|
||||
}
|
||||
.oe_mobile_preview.modal .modal-content .modal-header .close:hover {
|
||||
color: #E00101;
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(enabled=false);
|
||||
opacity: 1;
|
||||
}
|
||||
.oe_mobile_preview.modal .modal-content .modal-body {
|
||||
background-color: #000000;
|
||||
max-height: 600px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.oe_mobile_preview.modal .modal-content .modal-body .oe_mobile_viewport {
|
||||
width: 320px;
|
||||
height: 568px;
|
||||
padding: 5px;
|
||||
border: none;
|
||||
}
|
||||
.oe_mobile_preview.modal .modal-content .modal-footer {
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
/* ---- SEO TOOLS ---- {{{ */
|
||||
.oe_seo_configuration .modal-dialog {
|
||||
width: 80%;
|
||||
}
|
||||
.oe_seo_configuration .oe_remove {
|
||||
color: #E00101;
|
||||
}
|
||||
.oe_seo_configuration .oe_seo_suggestion {
|
||||
cursor: pointer;
|
||||
}
|
||||
.oe_seo_configuration .oe_seo_keyword {
|
||||
padding: 0.2em 0.4em 0.2em 0.5em;
|
||||
-moz-border-radius: 0.4em;
|
||||
-webkit-border-radius: 0.4em;
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g {
|
||||
line-height: 1.2;
|
||||
list-style: none;
|
||||
list-style-image: none;
|
||||
list-style-position: outside;
|
||||
list-style-type: none;
|
||||
font-size: small;
|
||||
font-family: arial, sans-serif;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g h3 {
|
||||
font-size: medium;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .r {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
-webkit-text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .r a {
|
||||
color: #1e0fbe;
|
||||
text-decoration: underline;
|
||||
text-transform: none;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .r a em {
|
||||
font-style: normal !important;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .s {
|
||||
color: #444;
|
||||
max-width: 42em;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .kv, .oe_seo_configuration li.oe_seo_preview_g .slp {
|
||||
display: block;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .f {
|
||||
color: #666;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .f cite {
|
||||
color: #006621;
|
||||
font-style: normal;
|
||||
font-size: 14px;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .st {
|
||||
line-height: 1.24;
|
||||
}
|
||||
|
||||
/* ---- ACE EDITOR ---- {{{ */
|
||||
.oe_ace_view_editor {
|
||||
position: fixed;
|
||||
right: 0;
|
||||
z-index: 1001;
|
||||
height: 100%;
|
||||
background: #2F3129;
|
||||
color: white;
|
||||
}
|
||||
.oe_ace_view_editor .oe_ace_view_editor_title {
|
||||
width: 100%;
|
||||
padding-top: 0;
|
||||
padding-left: 0;
|
||||
height: 30px;
|
||||
}
|
||||
.oe_ace_view_editor .oe_ace_view_editor_title .oe_view_list {
|
||||
width: 50%;
|
||||
height: 30px;
|
||||
font-size: 14px;
|
||||
font-family: "Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace;
|
||||
line-height: normal;
|
||||
}
|
||||
.oe_ace_view_editor .oe_ace_view_editor_title .btn {
|
||||
height: 30px;
|
||||
padding: 0 4px 0 4px;
|
||||
font-size: 14px;
|
||||
font-family: "Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace;
|
||||
line-height: normal;
|
||||
}
|
||||
.oe_ace_view_editor .ace_editor {
|
||||
position: absolute;
|
||||
top: 50px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
.oe_ace_view_editor .ace_editor .ace_gutter {
|
||||
cursor: ew-resize;
|
||||
}
|
||||
.oe_ace_view_editor #ace-view-id {
|
||||
padding: 0 1em;
|
||||
}
|
||||
.oe_ace_view_editor.oe_ace_open {
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=97);
|
||||
opacity: 0.97;
|
||||
}
|
||||
.oe_ace_view_editor.oe_ace_closed {
|
||||
z-index: -1000;
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* ---- CUSTOMIZE THEME ---- {{{ */
|
||||
#theme_error {
|
||||
background: #ffc;
|
||||
}
|
||||
|
||||
#theme_customize_modal {
|
||||
overflow: visible;
|
||||
overflow-y: auto;
|
||||
z-index: 1020;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
display: block;
|
||||
}
|
||||
#theme_customize_modal .modal-dialog {
|
||||
top: 75px;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
font-family: "Lato-Regular";
|
||||
font-weight: normal;
|
||||
text-transform: capitalize;
|
||||
letter-spacing: normal;
|
||||
}
|
||||
#theme_customize_modal .modal-h5 {
|
||||
color: #ffffff;
|
||||
font-family: "Lato-Regular";
|
||||
font-weight: normal;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: normal;
|
||||
font-size: 14px;
|
||||
color: white;
|
||||
padding: 4px 0 4px 4px;
|
||||
background-color: #bdc3c7;
|
||||
}
|
||||
#theme_customize_modal table {
|
||||
width: 100%;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
#theme_customize_modal label {
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
#theme_customize_modal label > div, #theme_customize_modal label > img {
|
||||
border: 1px solid #fff;
|
||||
line-height: 30px;
|
||||
font-size: 0.9em;
|
||||
margin: 2px 4px;
|
||||
}
|
||||
#theme_customize_modal label.checked > div, #theme_customize_modal label.checked > img {
|
||||
box-shadow: 2px 2px 3px #888;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
#theme_customize_modal label img {
|
||||
width: 60px;
|
||||
height: 35px;
|
||||
margin: 2px;
|
||||
border: 1px solid rgba(136, 136, 136, 0.5);
|
||||
}
|
||||
#theme_customize_modal label input {
|
||||
display: none;
|
||||
}
|
||||
#theme_customize_modal .loading_backdrop {
|
||||
display: none;
|
||||
}
|
||||
#theme_customize_modal.loading .loading_backdrop {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #000;
|
||||
opacity: 0.3;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* ---- force the browse to re-compute the stylesheets ---- */
|
||||
body.theme_customize_css_loading {
|
||||
magin-top: 1px;
|
||||
}
|
||||
body.theme_customize_css_loading #wrapwrap {
|
||||
magin-top: -1px;
|
||||
}
|
||||
@@ -0,0 +1,565 @@
|
||||
@import "common"
|
||||
|
||||
/* ---- CKEditor Minimal Reset ---- {{{ */
|
||||
|
||||
.navbar.navbar-inverse .cke_chrome
|
||||
border: none
|
||||
|
||||
.navbar.navbar-inverse .cke_inner
|
||||
background: rgba(0, 0, 0, 0)
|
||||
|
||||
.navbar.navbar-inverse
|
||||
.cke_toolbar
|
||||
position: relative
|
||||
top: 1px
|
||||
.cke_combo_button
|
||||
padding-top: 3px
|
||||
padding-bottom: 3px
|
||||
.cke_button
|
||||
padding-top: 7px
|
||||
padding-bottom: 7px
|
||||
|
||||
.navbar.navbar-inverse .cke_top
|
||||
background: rgba(0, 0, 0, 0)
|
||||
border: none
|
||||
+box-shadow(none)
|
||||
-ms-filter: "alpha(opacity=50)"
|
||||
|
||||
#cke_1_top
|
||||
padding: 0
|
||||
|
||||
#cke_wrapwrap
|
||||
-moz-box-shadow: none
|
||||
-webkit-box-shadow: none
|
||||
box-shadow: none
|
||||
.cke_button
|
||||
padding-top: 5px
|
||||
padding-bottom: 5px
|
||||
.cke_combo_button
|
||||
padding-top: 1px
|
||||
padding-bottom: 1px
|
||||
|
||||
// }}}
|
||||
|
||||
/* ---- OpenERP Style ---- {{{ */
|
||||
|
||||
.oe_website_editorbar
|
||||
position: fixed
|
||||
top: 0
|
||||
right: 0
|
||||
display: block
|
||||
width: 100%
|
||||
padding: 2px
|
||||
margin: 0
|
||||
z-index: 20000
|
||||
@include background(#414141, linear-gradient(#646060, #262626))
|
||||
+box-sizing(border-box)
|
||||
li
|
||||
display: inline
|
||||
color: #eee
|
||||
&:hover
|
||||
background: rgba(0,0,0,0.2)
|
||||
+text-shadow(black 0px 0px 3px)
|
||||
color: white
|
||||
|
||||
.oe_website_editorbar .oe_rte_toolbar
|
||||
div.dropdown
|
||||
display: inline-block
|
||||
li
|
||||
display: list-item
|
||||
|
||||
button
|
||||
font-family: FontAwesome
|
||||
font-weight: normal
|
||||
font-style: normal
|
||||
text-decoration: inherit
|
||||
&.oe_button_list
|
||||
padding-right: 3px
|
||||
&:after
|
||||
content: "\F0D7"
|
||||
padding-left: 6px
|
||||
|
||||
.oe_editable:focus
|
||||
outline: none !important
|
||||
|
||||
.css_editable_display
|
||||
display: block !important
|
||||
|
||||
.css_editable_hidden
|
||||
display: none !important
|
||||
|
||||
.cke_editable .css_editable_mode_hidden
|
||||
display: none
|
||||
|
||||
.cke_editable .css_editable_mode_display
|
||||
display: block !important
|
||||
|
||||
.oe_structure.oe_empty:empty, [data-oe-type=html]:empty, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child
|
||||
background-image: url('/website/static/src/img/edit_here.png') !important
|
||||
|
||||
.oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before
|
||||
content: 'Press The Top-Left Edit Button' !important
|
||||
|
||||
[data-oe-type=html].oe_no_empty:empty:before
|
||||
content: '' !important
|
||||
|
||||
[data-oe-type=html].oe_no_empty:empty
|
||||
background-image: none !important
|
||||
height: 16px !important
|
||||
|
||||
#website-top-edit
|
||||
width: 100%
|
||||
> ul > li
|
||||
margin: 0
|
||||
|
||||
#website-top-navbar
|
||||
min-height: 34px
|
||||
height: 34px
|
||||
form
|
||||
margin: 0
|
||||
button, a
|
||||
padding: 4px 8px 4px 8px
|
||||
margin-top: 2px
|
||||
font-size: 13px
|
||||
|
||||
// }}}
|
||||
|
||||
/* ---- EDITOR BAR ---- {{{ */
|
||||
|
||||
table.editorbar-panel
|
||||
cursor: pointer
|
||||
width: 100%
|
||||
td
|
||||
border: 1px solid #aaa
|
||||
td.selected
|
||||
background-color: #b1c9d9
|
||||
|
||||
.link-style
|
||||
.dropdown > .btn
|
||||
min-width: 160px
|
||||
.link-style
|
||||
display: none
|
||||
li
|
||||
text-align: center
|
||||
label
|
||||
width: 100px
|
||||
margin: 0 5px
|
||||
.col-sm-2 > *
|
||||
line-height: 2em
|
||||
|
||||
// }}}
|
||||
|
||||
/* ---- TRANSLATIONS ---- {{{ */
|
||||
|
||||
.oe_translate_or
|
||||
color: white
|
||||
padding: 0 0 0 1em
|
||||
.oe_translate_examples li
|
||||
margin: 10px
|
||||
padding: 4px
|
||||
.oe_translatable_text
|
||||
outline: 1px solid black
|
||||
.oe_translatable_field
|
||||
outline: 1px dashed black
|
||||
.oe_translatable_text.oe_dirty, .oe_translatable_field.oe_dirty
|
||||
outline-color: red
|
||||
.oe_translatable_text.oe_dirty:empty
|
||||
padding: 0 10px
|
||||
.oe_translatable_todo
|
||||
background: rgb(255, 255, 182)
|
||||
|
||||
// }}}
|
||||
|
||||
/* ---- MENU ---- {{{ */
|
||||
|
||||
div.oe_menu_buttons
|
||||
top: -8px
|
||||
right: -8px
|
||||
|
||||
ul.oe_menu_editor
|
||||
.fa-home
|
||||
display: none
|
||||
> li:first-child > div > span > .fa-home
|
||||
display: block
|
||||
.oe_menu_placeholder
|
||||
outline: 1px dashed #4183C4
|
||||
ul
|
||||
list-style: none
|
||||
li div
|
||||
cursor: move
|
||||
.disclose
|
||||
cursor: pointer
|
||||
width: 10px
|
||||
display: none
|
||||
|
||||
// }}}
|
||||
|
||||
/* ---- RTE ---- {{{ */
|
||||
|
||||
// bootstrap makes .btn elements unselectable -> RTE double-click can't know
|
||||
// about them either
|
||||
.oe_editable .btn, .btn.oe_editable
|
||||
+user-select(auto)
|
||||
cursor: text !important
|
||||
|
||||
.modal-dialog.select-media
|
||||
width: 80%
|
||||
|
||||
.modal .existing-attachments
|
||||
.pager
|
||||
margin: 0
|
||||
|
||||
.modal .image-preview
|
||||
margin-bottom: 0.5em
|
||||
|
||||
.modal-footer
|
||||
text-align: left
|
||||
|
||||
.modal.nosave
|
||||
.wait
|
||||
display: inline-block !important
|
||||
visibility: visible !important
|
||||
.modal-body
|
||||
.filepicker, .image-preview
|
||||
display: none
|
||||
.wait
|
||||
width: 100%
|
||||
.modal-footer .save
|
||||
display: none
|
||||
|
||||
// fontawesome modal
|
||||
.modal
|
||||
.font-icons-icons
|
||||
font-size: 2em
|
||||
max-height: 9em
|
||||
overflow: auto
|
||||
|
||||
.font-icons-icon
|
||||
display: inline-block
|
||||
width: 2em
|
||||
padding: 0.25em
|
||||
text-align: center
|
||||
cursor: pointer
|
||||
|
||||
.font-icons
|
||||
position: relative
|
||||
display: block
|
||||
|
||||
&:before
|
||||
+opacity(0.7)
|
||||
position: absolute
|
||||
top: 2px
|
||||
left: 3px
|
||||
font-size: 2em
|
||||
#icon-search
|
||||
padding-left: 2.5em
|
||||
|
||||
#fa-preview
|
||||
text-align: center
|
||||
|
||||
span
|
||||
cursor: pointer
|
||||
padding: 0 15px
|
||||
.font-icons-selected
|
||||
background-color: #ddd
|
||||
|
||||
$attachment-border-color: #848490
|
||||
.existing-attachments
|
||||
.pager .disabled
|
||||
display: none
|
||||
|
||||
.existing-attachment-cell
|
||||
position: relative
|
||||
.img
|
||||
border: 1px solid $attachment-border-color
|
||||
.existing-attachment-remove
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 15px // padding-left on col-*
|
||||
|
||||
cursor: pointer
|
||||
background: white
|
||||
padding: 2px
|
||||
border: 1px solid $attachment-border-color
|
||||
border-top: none
|
||||
border-left: none
|
||||
+border-bottom-right-radius(8px)
|
||||
&.media_selected
|
||||
> i, > img
|
||||
border-width: 5px
|
||||
border-color: rgb(0, 248, 248)
|
||||
|
||||
// wrapper positioned relatively for drag&drop widget which is disabled below.
|
||||
// Breaks completely horribly crazy products listing page, so take it out.
|
||||
.cke_widget_wrapper
|
||||
position: static !important
|
||||
|
||||
.cke_widget_inline
|
||||
display: inline !important
|
||||
|
||||
// prevent inline widgets from entirely disappearing when their (textual)
|
||||
// content is removed
|
||||
.cke_widget_editable
|
||||
// basic config
|
||||
&:empty:after
|
||||
opacity: 0.3
|
||||
white-space: pre-wrap
|
||||
// no @placeholder -> just add some padding
|
||||
&:not([placeholder]):empty::after
|
||||
content: " "
|
||||
// with placeholder and when not (yet) focused -> display placeholder
|
||||
&[placeholder]:not(:focus):empty::after
|
||||
content: attr(placeholder)
|
||||
|
||||
.oe_carlos_danger
|
||||
outline: 1px solid red !important
|
||||
background-color: #ffd9dd !important
|
||||
|
||||
.hover-edition
|
||||
display: inline-block
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
// This z-index is due to .navbar of bootstrap & jQuery-transfo
|
||||
z-index: 1001
|
||||
.preview-container
|
||||
text-align: center
|
||||
line-height: 100px
|
||||
height: 100px
|
||||
> *
|
||||
max-height: 100px
|
||||
line-height: 100px
|
||||
margin: 0 auto
|
||||
display: inline-block
|
||||
|
||||
// fontawesome
|
||||
.cke_editable .fa
|
||||
cursor: pointer
|
||||
|
||||
.img-responsive
|
||||
text-align: center
|
||||
|
||||
// }}}
|
||||
|
||||
/* ---- MOBILE PREVIEW ---- {{{ */
|
||||
|
||||
$mobile_preview_background: #000000
|
||||
$mobile_preview_border: #1C1F1F
|
||||
$icon_close: #E00101
|
||||
.oe_mobile_preview
|
||||
&.modal .modal-content
|
||||
height: 660px
|
||||
background-color: $mobile_preview_background
|
||||
border: 2px solid $mobile_preview_border
|
||||
+border-radius(10px)
|
||||
margin: auto
|
||||
top: 0
|
||||
left: 0
|
||||
bottom: 0
|
||||
right: 0
|
||||
max-width: 330px
|
||||
.modal-header
|
||||
background-color: $mobile_preview_background
|
||||
border-bottom: 0
|
||||
+border-top-left-radius(10px)
|
||||
+border-top-right-radius(10px)
|
||||
.modal-title
|
||||
color: $mobile_preview_border
|
||||
.close
|
||||
color: lightgrey
|
||||
+opacity(1)
|
||||
.close:hover
|
||||
color: $icon_close
|
||||
+opacity(1)
|
||||
.modal-body
|
||||
background-color: $mobile_preview_background
|
||||
max-height: 600px
|
||||
padding: 0
|
||||
margin: 0
|
||||
.oe_mobile_viewport
|
||||
width: 320px
|
||||
height: 568px
|
||||
padding: 5px
|
||||
border: none
|
||||
.modal-footer
|
||||
background-color: $mobile_preview_background
|
||||
|
||||
// }}}
|
||||
|
||||
/* ---- SEO TOOLS ---- {{{ */
|
||||
|
||||
$remove_color: $icon_close
|
||||
$in_title_color: #5cb85c
|
||||
$in_description_color: #428bca
|
||||
$in_body_color: #5bc0de
|
||||
$highlighted_text_color: #ffffff
|
||||
.oe_seo_configuration
|
||||
.modal-dialog
|
||||
width: 80%
|
||||
.oe_remove
|
||||
color: $remove_color
|
||||
.oe_seo_suggestion
|
||||
cursor: pointer
|
||||
.oe_seo_keyword
|
||||
padding: .2em .4em .2em .5em
|
||||
+border-radius(.4em)
|
||||
li.oe_seo_preview_g
|
||||
line-height: 1.2
|
||||
list-style: none
|
||||
list-style-image: none
|
||||
list-style-position: outside
|
||||
list-style-type: none
|
||||
font-size: small
|
||||
font-family: arial,sans-serif
|
||||
h3
|
||||
font-size: medium
|
||||
.r
|
||||
margin: 0
|
||||
font-size: 16px
|
||||
font-style: normal
|
||||
font-weight: normal
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
-webkit-text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
a
|
||||
color: rgb(30, 15, 190)
|
||||
text-decoration: underline
|
||||
text-transform: none
|
||||
em
|
||||
font-style: normal !important
|
||||
.s
|
||||
color: #444
|
||||
max-width: 42em
|
||||
.kv,.slp
|
||||
display: block
|
||||
margin-bottom: 1px
|
||||
.f
|
||||
color: #666
|
||||
margin-bottom: 1px
|
||||
cite
|
||||
color: #006621
|
||||
font-style: normal
|
||||
font-size: 14px
|
||||
.st
|
||||
line-height: 1.24
|
||||
|
||||
|
||||
// }}}
|
||||
|
||||
/* ---- ACE EDITOR ---- {{{ */
|
||||
|
||||
$editorbar_height: 30px
|
||||
$infobar_height: 20px
|
||||
// TODO Fix => might break with themes
|
||||
|
||||
.oe_ace_view_editor
|
||||
position: fixed
|
||||
// top property is set programmatically
|
||||
right: 0
|
||||
z-index: 1001
|
||||
height: 100%
|
||||
background: #2F3129
|
||||
color: white
|
||||
.oe_ace_view_editor_title
|
||||
width: 100%
|
||||
padding-top: 0
|
||||
padding-left: 0
|
||||
height: $editorbar_height
|
||||
.oe_view_list
|
||||
width: 50%
|
||||
height: $editorbar_height
|
||||
@include editor-font
|
||||
.btn
|
||||
height: $editorbar_height
|
||||
padding: 0 4px 0 4px
|
||||
@include editor-font
|
||||
.ace_editor
|
||||
position: absolute
|
||||
top: $editorbar_height + $infobar_height
|
||||
right: 0
|
||||
// bottom property is set programmatically
|
||||
left: 0
|
||||
.ace_gutter
|
||||
cursor: ew-resize
|
||||
#ace-view-id
|
||||
padding: 0 1em
|
||||
&.oe_ace_open
|
||||
+opacity(0.97)
|
||||
&.oe_ace_closed
|
||||
z-index: -1000
|
||||
+opacity(0)
|
||||
|
||||
// }}}
|
||||
|
||||
/* ---- CUSTOMIZE THEME ---- {{{ */
|
||||
#theme_error
|
||||
background: #ffc
|
||||
#theme_customize_modal
|
||||
overflow: visible
|
||||
z-index: 1020
|
||||
background: rgba(0, 0, 0, 0)
|
||||
display: block
|
||||
.modal-dialog
|
||||
top: 75px
|
||||
width: auto
|
||||
margin: 0
|
||||
position: absolute
|
||||
right: 10px
|
||||
font-family: 'Lato-Regular'
|
||||
font-weight: normal
|
||||
text-transform: capitalize
|
||||
letter-spacing: normal
|
||||
.modal-h5
|
||||
color: #ffffff
|
||||
font-family: 'Lato-Regular'
|
||||
font-weight: normal
|
||||
text-transform: uppercase
|
||||
letter-spacing: normal
|
||||
font-size: 14px
|
||||
color: white
|
||||
padding: 4px 0 4px 4px
|
||||
background-color: #bdc3c7
|
||||
table
|
||||
width: 100%
|
||||
margin-bottom: 8px
|
||||
label
|
||||
display: block
|
||||
text-align: center
|
||||
> div, > img
|
||||
border: 1px solid #fff
|
||||
line-height: 30px
|
||||
font-size: 0.9em
|
||||
margin: 2px 4px
|
||||
&.checked
|
||||
> div, > img
|
||||
box-shadow: 2px 2px 3px #888
|
||||
border: 1px solid #666
|
||||
img
|
||||
width: 60px
|
||||
height: 35px
|
||||
margin: 2px
|
||||
border: 1px solid rgba(136, 136, 136, 0.5)
|
||||
input
|
||||
display: none
|
||||
.loading_backdrop
|
||||
display: none
|
||||
&.loading
|
||||
.loading_backdrop
|
||||
display: block
|
||||
width: 100%
|
||||
height: 100%
|
||||
background: #000
|
||||
opacity: 0.3
|
||||
position: absolute
|
||||
z-index: 1
|
||||
|
||||
/* ---- force the browse to re-compute the stylesheets ---- */
|
||||
body.theme_customize_css_loading
|
||||
magin-top: 1px
|
||||
#wrapwrap
|
||||
magin-top: -1px
|
||||
|
||||
// }}}
|
||||
|
||||
// vim:tabstop=4:shiftwidth=4:softtabstop=4:fdm=marker:
|
||||
@@ -0,0 +1,727 @@
|
||||
/* ---- SNIPPET EDITOR ---- {{{ */
|
||||
#oe_snippets {
|
||||
position: fixed;
|
||||
top: 34px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
padding-top: 6px;
|
||||
background: #282828;
|
||||
-webkit-box-shadow: 0px 10px 10px -10px black inset;
|
||||
-moz-box-shadow: 0px 10px 10px -10px black inset;
|
||||
box-shadow: 0px 10px 10px -10px black inset;
|
||||
z-index: 1010;
|
||||
overflow: hidden;
|
||||
}
|
||||
#oe_snippets:hover {
|
||||
height: auto;
|
||||
}
|
||||
#oe_snippets .scroll {
|
||||
white-space: nowrap;
|
||||
overflow-y: none;
|
||||
}
|
||||
#oe_snippets .nav {
|
||||
display: inline-block;
|
||||
border-bottom: none !important;
|
||||
vertical-align: middle;
|
||||
min-width: 120px;
|
||||
z-index: 1;
|
||||
}
|
||||
#oe_snippets .nav > li {
|
||||
display: block;
|
||||
float: none;
|
||||
}
|
||||
#oe_snippets .nav > li.active {
|
||||
background: black !important;
|
||||
}
|
||||
#oe_snippets .nav > li > a {
|
||||
padding: 2px 10px !important;
|
||||
width: 100%;
|
||||
display: block;
|
||||
border: 0;
|
||||
}
|
||||
#oe_snippets .pill-content {
|
||||
border: 0;
|
||||
}
|
||||
#oe_snippets .tab-content {
|
||||
margin-right: 120px;
|
||||
display: inline-block;
|
||||
white-space: normal;
|
||||
background: black;
|
||||
}
|
||||
#oe_snippets .tab-content > div {
|
||||
background: black;
|
||||
}
|
||||
#oe_snippets .tab-content > div label {
|
||||
width: 44px;
|
||||
color: white;
|
||||
padding-left: 10px;
|
||||
}
|
||||
#oe_snippets .tab-content > div label div {
|
||||
width: 100px;
|
||||
text-align: center;
|
||||
-webkit-transform: translate(-39px, 44px);
|
||||
-moz-transform: translate(-39px, 44px);
|
||||
-ms-transform: translate(-39px, 44px);
|
||||
-o-transform: translate(-39px, 44px);
|
||||
transform: translate(-39px, 44px);
|
||||
-webkit-transform-origin: 50% 50% 50%;
|
||||
-moz-transform-origin: 50% 50% 50%;
|
||||
-ms-transform-origin: 50% 50% 50%;
|
||||
-o-transform-origin: 50% 50% 50%;
|
||||
transform-origin: 50% 50% 50%;
|
||||
}
|
||||
|
||||
.oe_snippet {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 93px;
|
||||
margin-left: 1px;
|
||||
margin-top: 0px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
cursor: move;
|
||||
}
|
||||
.oe_snippet .oe_snippet_thumbnail {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
color: white;
|
||||
position: relative;
|
||||
}
|
||||
.oe_snippet .oe_snippet_thumbnail:hover .oe_snippet_thumbnail_img {
|
||||
-webkit-transform: scale(0.95, 0.95);
|
||||
-moz-transform: scale(0.95, 0.95);
|
||||
-ms-transform: scale(0.95, 0.95);
|
||||
-o-transform: scale(0.95, 0.95);
|
||||
transform: scale(0.95, 0.95);
|
||||
}
|
||||
.oe_snippet .oe_snippet_thumbnail .oe_snippet_thumbnail_title {
|
||||
font-size: 12px;
|
||||
display: block;
|
||||
text-shadow: 0 0 2px black;
|
||||
}
|
||||
.oe_snippet .oe_snippet_thumbnail .oe_snippet_thumbnail_img {
|
||||
height: 74px;
|
||||
background-size: cover;
|
||||
margin-bottom: 5px;
|
||||
-webkit-transform: scale(1, 1);
|
||||
-moz-transform: scale(1, 1);
|
||||
-ms-transform: scale(1, 1);
|
||||
-o-transform: scale(1, 1);
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
.oe_snippet .oe_snippet_thumbnail span, .oe_snippet .oe_snippet_thumbnail div {
|
||||
line-height: 18px;
|
||||
}
|
||||
.oe_snippet > :not(.oe_snippet_thumbnail) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
#oe_snippets .oe_snippet_thumbnail {
|
||||
background: #747474, -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 100, color-stop(0%, rgba(0, 0, 0, 0.25)), color-stop(100%, rgba(0, 0, 0, 0.4)));
|
||||
background: #747474, -webkit-radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
|
||||
background: #747474, -moz-radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
|
||||
background: #747474, -o-radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
|
||||
background: #747474, radial-gradient(rgba(0, 0, 0, 0.25), rgba(0, 0, 0, 0.4));
|
||||
}
|
||||
|
||||
/* ---- SNIPPETS DROP ZONES ---- {{{ */
|
||||
.oe_drop_zone.oe_insert {
|
||||
display: block;
|
||||
height: 48px;
|
||||
margin: 0px;
|
||||
margin-top: -4px;
|
||||
margin-bottom: -44px;
|
||||
-webkit-transition: margin 250ms linear;
|
||||
-moz-transition: margin 250ms linear;
|
||||
-o-transition: margin 250ms linear;
|
||||
transition: margin 250ms linear;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
}
|
||||
.oe_drop_zone.oe_insert:not(.oe_vertical):before {
|
||||
content: "";
|
||||
display: block;
|
||||
border-top: dashed 2px rgba(209, 178, 255, 0.72);
|
||||
position: relative;
|
||||
top: 0px;
|
||||
}
|
||||
.oe_drop_zone.oe_insert.oe_hover:before {
|
||||
border-top: dashed 2px rgba(116, 255, 161, 0.72);
|
||||
}
|
||||
.oe_drop_zone.oe_insert.oe_vertical {
|
||||
width: 48px;
|
||||
float: left;
|
||||
position: relative;
|
||||
margin: 0px -24px !important;
|
||||
}
|
||||
.oe_drop_zone.oe_insert.oe_overlay {
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-ms-border-radius: 3px;
|
||||
-o-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
background: rgba(153, 0, 255, 0.5);
|
||||
}
|
||||
|
||||
.oe_drop_zone, .oe_drop_zone_style {
|
||||
border: none;
|
||||
background: rgba(153, 0, 255, 0.3);
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
-ms-border-radius: 4px;
|
||||
-o-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.oe_drop_zone.oe_hover, .oe_drop_zone_style.oe_hover {
|
||||
background: rgba(0, 255, 133, 0.3);
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.oe_drop_zone_style {
|
||||
color: white;
|
||||
height: 48px;
|
||||
margin-bottom: 32px;
|
||||
padding-top: 12px;
|
||||
}
|
||||
|
||||
/* ---- SNIPPET MANIPULATOR ---- {{{ */
|
||||
.resize_editor_busy {
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.oe_overlay {
|
||||
display: none;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
z-index: 1001;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
-ms-border-radius: 3px;
|
||||
-o-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
-webkit-transition: opacity 100ms linear;
|
||||
-moz-transition: opacity 100ms linear;
|
||||
-o-transition: opacity 100ms linear;
|
||||
transition: opacity 100ms linear;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.oe_overlay.oe_active {
|
||||
display: block;
|
||||
}
|
||||
.oe_overlay .oe_handle {
|
||||
display: block !important;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: -2px;
|
||||
}
|
||||
.oe_overlay .oe_handle > div {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
border-style: dashed;
|
||||
border-width: 1px;
|
||||
border-color: #666666;
|
||||
-webkit-box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.5), 0px 0px 0px 1px rgba(255, 255, 255, 0.5) inset;
|
||||
-moz-box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.5), 0px 0px 0px 1px rgba(255, 255, 255, 0.5) inset;
|
||||
box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.5), 0px 0px 0px 1px rgba(255, 255, 255, 0.5) inset;
|
||||
}
|
||||
.oe_overlay .oe_handle.e:before, .oe_overlay .oe_handle.w:before, .oe_overlay .oe_handle.s:before, .oe_overlay .oe_handle.n:before, .oe_overlay .oe_handle.size .oe_handle_button {
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
display: block;
|
||||
background: white;
|
||||
border: solid 1px rgba(0, 0, 0, 0.2);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
-ms-border-radius: 5px;
|
||||
-o-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin: -9px;
|
||||
padding-left: 1px;
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
font-family: FontAwesome;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
-webkit-transition: background 100ms linear;
|
||||
-moz-transition: background 100ms linear;
|
||||
-o-transition: background 100ms linear;
|
||||
transition: background 100ms linear;
|
||||
}
|
||||
.oe_overlay .oe_handle.e:hover:before, .oe_overlay .oe_handle.w:hover:before, .oe_overlay .oe_handle.s:hover:before, .oe_overlay .oe_handle.n:hover:before {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
-webkit-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
|
||||
-moz-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
|
||||
box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.oe_overlay .oe_handle.e, .oe_overlay .oe_handle.w {
|
||||
top: 4px;
|
||||
height: 100%;
|
||||
}
|
||||
.oe_overlay .oe_handle.e:before, .oe_overlay .oe_handle.w:before {
|
||||
content: "\f0d9-\f0da";
|
||||
line-height: 16px;
|
||||
}
|
||||
.oe_overlay .oe_handle.e > div, .oe_overlay .oe_handle.w > div {
|
||||
width: 0;
|
||||
height: 100%;
|
||||
top: 2px;
|
||||
left: 8px;
|
||||
}
|
||||
.oe_overlay .oe_handle.e {
|
||||
left: auto;
|
||||
right: -6px;
|
||||
cursor: w-resize;
|
||||
}
|
||||
.oe_overlay .oe_handle.w {
|
||||
left: -6px;
|
||||
cursor: e-resize;
|
||||
}
|
||||
.oe_overlay .oe_handle.s, .oe_overlay .oe_handle.n {
|
||||
left: 2px;
|
||||
width: 100%;
|
||||
}
|
||||
.oe_overlay .oe_handle.s:before, .oe_overlay .oe_handle.n:before {
|
||||
content: "\f07d";
|
||||
text-align: center;
|
||||
padding: 1px;
|
||||
}
|
||||
.oe_overlay .oe_handle.s > div, .oe_overlay .oe_handle.n > div {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
top: 7px;
|
||||
left: 1px;
|
||||
}
|
||||
.oe_overlay .oe_handle.s {
|
||||
top: auto;
|
||||
cursor: n-resize;
|
||||
}
|
||||
.oe_overlay .oe_handle.n {
|
||||
cursor: s-resize;
|
||||
}
|
||||
.oe_overlay .oe_handle.n > div {
|
||||
top: 5px;
|
||||
}
|
||||
.oe_overlay .oe_handle.size {
|
||||
z-index: 3;
|
||||
top: auto;
|
||||
left: 50%;
|
||||
bottom: -6px;
|
||||
margin-left: -50px;
|
||||
}
|
||||
.oe_overlay .oe_handle.size .oe_handle_button {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
text-align: center;
|
||||
margin-left: -52px;
|
||||
margin-top: -10px;
|
||||
left: 0px;
|
||||
}
|
||||
.oe_overlay .oe_handle.size .oe_handle_button:hover {
|
||||
background: rgba(30, 30, 30, 0.8);
|
||||
color: white;
|
||||
-webkit-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
|
||||
-moz-box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
|
||||
box-shadow: 0 0 5px 3px rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.oe_overlay .oe_handle.size .size {
|
||||
position: absolute;
|
||||
width: 64px;
|
||||
cursor: row-resize;
|
||||
top: 9px;
|
||||
margin-left: 52px;
|
||||
padding: 0 5px;
|
||||
}
|
||||
.oe_overlay .oe_handle.size .auto_size {
|
||||
position: absolute;
|
||||
width: 100px;
|
||||
top: 9px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.oe_overlay .oe_handle.readonly {
|
||||
cursor: auto !important;
|
||||
}
|
||||
.oe_overlay .oe_handle.readonly:before, .oe_overlay .oe_handle.readonly.size {
|
||||
display: none !important;
|
||||
}
|
||||
.oe_overlay .icon.btn {
|
||||
display: inline-block;
|
||||
}
|
||||
.oe_overlay .oe_overlay_options {
|
||||
position: absolute;
|
||||
left: 50% !important;
|
||||
text-align: center;
|
||||
top: -20px;
|
||||
z-index: 1002;
|
||||
}
|
||||
.oe_overlay .oe_overlay_options > .btn-group {
|
||||
left: -50%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.oe_overlay .oe_overlay_options > .btn-group > a {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
float: none;
|
||||
margin: 0 -3px;
|
||||
}
|
||||
.oe_overlay .oe_overlay_options .btn, .oe_overlay .oe_overlay_options a {
|
||||
cursor: pointer;
|
||||
}
|
||||
.oe_overlay .oe_overlay_options .dropdown {
|
||||
display: inline-block;
|
||||
}
|
||||
.oe_overlay .oe_overlay_options .dropdown-menu {
|
||||
text-align: left;
|
||||
min-width: 180px;
|
||||
}
|
||||
.oe_overlay .oe_overlay_options .dropdown-menu select, .oe_overlay .oe_overlay_options .dropdown-menu input {
|
||||
display: block;
|
||||
}
|
||||
.oe_overlay.block-w-left .w:before {
|
||||
content: "\F061" !important;
|
||||
}
|
||||
.oe_overlay.block-w-right .w:before {
|
||||
content: "\F060" !important;
|
||||
}
|
||||
.oe_overlay.block-w-left.block-w-right .w {
|
||||
display: none !important;
|
||||
}
|
||||
.oe_overlay.block-e-left .e:before {
|
||||
content: "\F061" !important;
|
||||
}
|
||||
.oe_overlay.block-e-right .e:before {
|
||||
content: "\F060" !important;
|
||||
}
|
||||
.oe_overlay.block-e-left.block-e-right .e {
|
||||
display: none !important;
|
||||
}
|
||||
.oe_overlay.block-s-top .s:before {
|
||||
content: "\F063" !important;
|
||||
}
|
||||
.oe_overlay.block-s-bottom .s:before {
|
||||
content: "\f062" !important;
|
||||
}
|
||||
.oe_overlay.block-n-top .n:before {
|
||||
content: "\F063" !important;
|
||||
}
|
||||
.oe_overlay.block-n-bottom .n:before {
|
||||
content: "\f062" !important;
|
||||
}
|
||||
|
||||
.s-resize-important, .s-resize-important * {
|
||||
cursor: s-resize !important;
|
||||
}
|
||||
|
||||
.n-resize-important, .n-resize-important * {
|
||||
cursor: n-resize !important;
|
||||
}
|
||||
|
||||
.e-resize-important, .e-resize-important * {
|
||||
cursor: e-resize !important;
|
||||
}
|
||||
|
||||
.w-resize-important, .w-resize-important * {
|
||||
cursor: w-resize !important;
|
||||
}
|
||||
|
||||
.move-important, .move-important * {
|
||||
cursor: move !important;
|
||||
}
|
||||
|
||||
/* add CSS for bootstrap dropdown multi level */
|
||||
.dropdown-submenu {
|
||||
position: relative;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.dropdown-submenu > .dropdown-menu {
|
||||
top: 0;
|
||||
left: 100%;
|
||||
margin-top: -6px;
|
||||
margin-left: -1px;
|
||||
-webkit-border-radius: 0 6px 6px 6px;
|
||||
-moz-border-radius: 0 6px 6px 6px;
|
||||
border-radius: 0 6px 6px 6px;
|
||||
}
|
||||
.dropdown-submenu:hover > .dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
.dropdown-submenu:hover > a:after {
|
||||
border-left-color: white;
|
||||
}
|
||||
.dropdown-submenu > a:after {
|
||||
display: block;
|
||||
content: " ";
|
||||
float: right;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
border-style: solid;
|
||||
border-width: 5px 0 5px 5px;
|
||||
border-left-color: #cccccc;
|
||||
margin-top: 5px;
|
||||
margin-right: -10px;
|
||||
}
|
||||
.dropdown-submenu.pull-left {
|
||||
float: none;
|
||||
}
|
||||
.dropdown-submenu.pull-left > .dropdown-menu {
|
||||
left: -100%;
|
||||
margin-left: 10px;
|
||||
-webkit-border-radius: 6px 0 6px 6px;
|
||||
-moz-border-radius: 6px 0 6px 6px;
|
||||
border-radius: 6px 0 6px 6px;
|
||||
}
|
||||
|
||||
.oe_snippet_list {
|
||||
width: auto;
|
||||
white-space: nowrap;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.oe_snippet_editor {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 214px;
|
||||
background: #a0a0a0;
|
||||
box-shadow: 0 1px 3px #646464 inset;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet {
|
||||
box-sizing: border-box;
|
||||
display: inline-block;
|
||||
width: 220px;
|
||||
height: 160px;
|
||||
border-radius: 3px;
|
||||
background: white;
|
||||
margin: 20px 20px 20px 0;
|
||||
cursor: pointer;
|
||||
border: 2px solid rgba(0, 0, 0, 0);
|
||||
box-shadow: 0 1px 3px #646464;
|
||||
position: relative;
|
||||
top: 0;
|
||||
overflow: hidden;
|
||||
vertical-align: top;
|
||||
user-select: none;
|
||||
white-space: normal;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet:after {
|
||||
content: attr(name);
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
text-align: center;
|
||||
color: black;
|
||||
padding: 8px;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet.oe_selected, .oe_snippet_editor .oe_snippet.oe_active {
|
||||
border: 2px solid #9789ff;
|
||||
box-shadow: 0px 3px 17px rgba(99, 53, 150, 0.59);
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet > * {
|
||||
margin-top: 16px;
|
||||
line-height: 1em;
|
||||
zoom: 0.6;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet > .container {
|
||||
margin-top: 15px;
|
||||
zoom: 0.17;
|
||||
line-height: 0.999em;
|
||||
line-height: 1em;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet > .row {
|
||||
margin-top: 0px;
|
||||
zoom: 0.23;
|
||||
line-height: 0.999em;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet > .span6 {
|
||||
margin-top: 18px;
|
||||
zoom: 0.34;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet > .span12 {
|
||||
margin-top: 16px;
|
||||
zoom: 0.23;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet > p {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
font-size: 20px;
|
||||
padding: 16px;
|
||||
zoom: 1;
|
||||
margin: 0px;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet.oe_new {
|
||||
background: gray;
|
||||
box-shadow: 0px 1px 3px #5a5a5a inset;
|
||||
border: 0px;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet.oe_new.oe_selected, .oe_snippet_editor .oe_snippet.oe_new.oe_active {
|
||||
box-shadow: 0px 2px 0px 0px #9789ff inset, 0px 3px 17px rgba(99, 53, 150, 0.59) inset;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet.oe_new > * {
|
||||
zoom: 1;
|
||||
margin: 0;
|
||||
line-height: 160px;
|
||||
text-align: center;
|
||||
color: white;
|
||||
font-size: 48px;
|
||||
}
|
||||
.oe_snippet_editor .oe_snippet.oe_new:after {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
color: white;
|
||||
text-shadow: 0px 1px 3px black;
|
||||
line-height: 160px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.oe_snippet_drop {
|
||||
position: relative;
|
||||
border: 2px dashed #ae34ff;
|
||||
background: rgba(147, 52, 255, 0.1);
|
||||
min-height: 28px;
|
||||
margin: -16px auto;
|
||||
border-radius: 5px;
|
||||
max-width: 50%;
|
||||
}
|
||||
.oe_snippet_drop.oe_accepting {
|
||||
border: 2px dashed #34ffa6;
|
||||
background: rgba(52, 255, 190, 0.1);
|
||||
}
|
||||
|
||||
#website-top-edit li.oe_snippet_editorbar {
|
||||
padding: 1px 8px 2px;
|
||||
font: normal normal normal 12px Arial, Helvetica, Tahoma, Verdana, Sans-Serif;
|
||||
float: left;
|
||||
margin-top: 6px;
|
||||
border: 1px solid #a6a6a6;
|
||||
border-bottom-color: #979797;
|
||||
background: #eeeeee;
|
||||
border-radius: 3px;
|
||||
}
|
||||
#website-top-edit li.oe_snippet_editorbar > * {
|
||||
display: inline-block;
|
||||
height: 22px;
|
||||
padding: 4px 6px;
|
||||
outline: 0;
|
||||
border: 0;
|
||||
}
|
||||
#website-top-edit li.oe_snippet_editorbar a.button .icon {
|
||||
cursor: inherit;
|
||||
background-repeat: no-repeat;
|
||||
margin-top: 1px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* ---- COLOR-PICKER ---- {{{ */
|
||||
.colorpicker {
|
||||
margin: 0 auto;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
border: 0;
|
||||
}
|
||||
.colorpicker td {
|
||||
padding: 0;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
.colorpicker td > * {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 2px;
|
||||
margin: 3px;
|
||||
padding: 0;
|
||||
border-width: 1px;
|
||||
display: block;
|
||||
}
|
||||
.colorpicker .only-text {
|
||||
display: none;
|
||||
}
|
||||
.colorpicker .automatic-color {
|
||||
background: white;
|
||||
border-left: 7px solid #ff3333;
|
||||
border-top: 7px solid #00ee00;
|
||||
border-right: 8px solid #3333ff;
|
||||
border-bottom: 8px solid #ffee00;
|
||||
margin: 4px 3px 3px 3px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.cke_panel_container table.colorpicker tr:first-child td {
|
||||
padding-top: 6px;
|
||||
}
|
||||
.cke_panel_container table.colorpicker tr:last-child td {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
|
||||
/* snippets default margins */
|
||||
.s_banner {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.s_big_message {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.s_text_block {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.s_features {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.s_big_picture {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.s_three_columns {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.s_references {
|
||||
margin-top: 16px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.s_quotes_slider {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.s_features_grid {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
@@ -0,0 +1,590 @@
|
||||
@import "compass/css3"
|
||||
@import "compass/css3/user-interface"
|
||||
@import "compass/css3/transition"
|
||||
|
||||
|
||||
/* ---- SNIPPET EDITOR ---- {{{ */
|
||||
|
||||
#oe_snippets
|
||||
position: fixed
|
||||
top: 34px
|
||||
left: 0px
|
||||
right: 0px
|
||||
padding-top: 6px
|
||||
// top property is set programmatically
|
||||
background: rgb(40,40,40)
|
||||
+box-shadow(0px 10px 10px -10px black inset)
|
||||
z-index: 1010
|
||||
overflow: hidden
|
||||
&:hover
|
||||
height: auto
|
||||
.scroll
|
||||
white-space: nowrap
|
||||
overflow-y: none
|
||||
.nav
|
||||
display: inline-block
|
||||
border-bottom: none !important
|
||||
vertical-align: middle
|
||||
min-width: 120px
|
||||
> li
|
||||
display: block
|
||||
float: none
|
||||
&.active
|
||||
background: black !important
|
||||
> a
|
||||
padding: 2px 10px !important
|
||||
width: 100%
|
||||
display: block
|
||||
border: 0
|
||||
z-index: 1
|
||||
.pill-content
|
||||
border: 0
|
||||
.tab-content
|
||||
margin-right: 120px
|
||||
display: inline-block
|
||||
white-space: normal
|
||||
background: black
|
||||
> div
|
||||
background: rgb(0,0,0)
|
||||
label
|
||||
width: 44px
|
||||
color: #fff
|
||||
padding-left: 10px
|
||||
|
||||
div
|
||||
width: 100px
|
||||
text-align: center
|
||||
@include transform( translate(-39px, 44px) , rotate(-90deg) )
|
||||
@include transform-origin(50% 50%)
|
||||
|
||||
.oe_snippet
|
||||
display: inline-block
|
||||
vertical-align: top
|
||||
width: 93px
|
||||
margin-left: 1px
|
||||
margin-top: 0px
|
||||
position: relative
|
||||
overflow: hidden
|
||||
+user-select(none)
|
||||
cursor: move
|
||||
.oe_snippet_thumbnail
|
||||
text-align: center
|
||||
height: 100%
|
||||
background: rgba(0, 0, 0, 0)
|
||||
color: white
|
||||
position: relative
|
||||
&:hover
|
||||
.oe_snippet_thumbnail_img
|
||||
@include transform( scale(.95,.95))
|
||||
.oe_snippet_thumbnail_title
|
||||
font-size: 12px
|
||||
display: block
|
||||
+text-shadow(0 0 2px rgb(0,0,0))
|
||||
.oe_snippet_thumbnail_img
|
||||
height: 74px
|
||||
background-size: cover
|
||||
margin-bottom: 5px
|
||||
@include transform( scale(1,1))
|
||||
span, div
|
||||
line-height: 18px
|
||||
& > :not(.oe_snippet_thumbnail)
|
||||
display: none !important
|
||||
|
||||
#oe_snippets .oe_snippet_thumbnail
|
||||
@include background(#747474, radial-gradient(rgba(0,0,0,0.25),rgba(0,0,0,0.4)))
|
||||
|
||||
// }}}}
|
||||
|
||||
/* ---- SNIPPETS DROP ZONES ---- {{{ */
|
||||
|
||||
.oe_drop_zone.oe_insert
|
||||
display: block
|
||||
height: 48px
|
||||
margin: 0px
|
||||
margin-top: -4px
|
||||
margin-bottom: -44px
|
||||
@include transition(margin 250ms linear)
|
||||
width: 100%
|
||||
position: absolute
|
||||
z-index: 1000
|
||||
&:not(.oe_vertical):before
|
||||
content: ""
|
||||
display: block
|
||||
border-top: dashed 2px rgba(209, 178, 255, 0.72)
|
||||
position: relative
|
||||
top: 0px
|
||||
&.oe_hover:before
|
||||
border-top: dashed 2px rgba(116, 255, 161, 0.72)
|
||||
&.oe_vertical
|
||||
width: 48px
|
||||
float: left
|
||||
position: relative
|
||||
margin: 0px -24px !important
|
||||
&.oe_overlay
|
||||
+border-radius(3px)
|
||||
//@include background-image( repeating-linear-gradient(45deg, rgba(255,255,255,.1) ,rgba(255,255,255,.1) 35px, rgba(0,0,0,.1) 35px, rgba(0,0,0,.1) 75px))
|
||||
//background-size: 100px 100px
|
||||
background: rgba(153, 0, 255,.5)
|
||||
|
||||
.oe_drop_zone, .oe_drop_zone_style
|
||||
border: none
|
||||
//@include background-image( repeating-linear-gradient(45deg, rgba(255,255,255,.1) ,rgba(255,255,255,.1) 35px, rgba(0,0,0,.1) 35px, rgba(0,0,0,.1) 75px))
|
||||
//background-size: 100px 100px
|
||||
background: rgba(153, 0, 255, .3)
|
||||
+border-radius(4px)
|
||||
&.oe_hover
|
||||
background: rgba(0, 255, 133, .3)
|
||||
z-index: 1001
|
||||
|
||||
.oe_drop_zone_style
|
||||
color: white
|
||||
height: 48px
|
||||
margin-bottom: 32px
|
||||
padding-top: 12px
|
||||
|
||||
// }}}
|
||||
|
||||
/* ---- SNIPPET MANIPULATOR ---- {{{ */
|
||||
|
||||
.resize_editor_busy
|
||||
background-color: rgba(0,0,0,0.3)
|
||||
|
||||
.oe_overlay
|
||||
display: none
|
||||
height: 0
|
||||
position: absolute
|
||||
background: rgba(0, 0, 0, 0)
|
||||
z-index: 1001
|
||||
//@include background-image( repeating-linear-gradient(45deg, rgba(255,255,255,.02) ,rgba(255,255,255,.02) 35px, rgba(0,0,0,.02) 35px, rgba(0,0,0,.02) 75px))
|
||||
+border-radius(3px)
|
||||
@include transition(opacity 100ms linear)
|
||||
+box-sizing(border-box)
|
||||
&.oe_active
|
||||
display: block
|
||||
.oe_handle
|
||||
display: block !important
|
||||
position: absolute
|
||||
top: 50%
|
||||
left: 50%
|
||||
+box-sizing(border-box)
|
||||
width: 16px
|
||||
height: 16px
|
||||
margin: -2px
|
||||
> div
|
||||
z-index: 1
|
||||
position: absolute
|
||||
border-style: dashed
|
||||
border-width: 1px
|
||||
border-color: #666666
|
||||
+box-shadow(0px 0px 0px 1px rgba(255,255,255,0.5), 0px 0px 0px 1px rgba(255,255,255,0.5) inset)
|
||||
&.e:before, &.w:before, &.s:before, &.n:before, &.size .oe_handle_button
|
||||
z-index: 2
|
||||
position: relative
|
||||
top: 50%
|
||||
left: 50%
|
||||
display: block
|
||||
background: rgba(255, 255, 255, 1)
|
||||
border: solid 1px rgba(0, 0, 0, .2)
|
||||
+border-radius(5px)
|
||||
width: 18px
|
||||
height: 18px
|
||||
margin: -9px
|
||||
padding-left: 1px
|
||||
font-size: 14px
|
||||
line-height: 14px
|
||||
font-family: FontAwesome
|
||||
color: rgba(0,0,0,.5)
|
||||
@include transition(background 100ms linear)
|
||||
&.e, &.w, &.s, &.n
|
||||
&:hover:before
|
||||
background: rgba(0, 0, 0, .5)
|
||||
color: #fff
|
||||
+box-shadow(0 0 5px 3px rgba(255,255,255,.7))
|
||||
&.e, &.w
|
||||
top: 4px
|
||||
height: 100%
|
||||
&:before
|
||||
content: "\f0d9-\f0da"
|
||||
line-height: 16px
|
||||
> div
|
||||
width: 0
|
||||
height: 100%
|
||||
top: 2px
|
||||
left: 8px
|
||||
&.e
|
||||
left: auto
|
||||
right: -6px
|
||||
cursor: w-resize
|
||||
&.w
|
||||
left: -6px
|
||||
cursor: e-resize
|
||||
&.s, &.n
|
||||
left: 2px
|
||||
width: 100%
|
||||
&:before
|
||||
content: "\f07d"
|
||||
text-align: center
|
||||
padding: 1px
|
||||
> div
|
||||
width: 100%
|
||||
height: 0
|
||||
top: 7px
|
||||
left: 1px
|
||||
&.s
|
||||
top: auto
|
||||
cursor: n-resize
|
||||
&.n
|
||||
cursor: s-resize
|
||||
> div
|
||||
top: 5px
|
||||
&.size
|
||||
z-index: 3
|
||||
top: auto
|
||||
left: 50%
|
||||
bottom: -6px
|
||||
margin-left: -50px
|
||||
.oe_handle_button
|
||||
position: relative
|
||||
z-index: 3
|
||||
text-align: center
|
||||
margin-left: -52px
|
||||
margin-top: -10px
|
||||
left: 0px
|
||||
&:hover
|
||||
background: rgba(30, 30, 30, .8)
|
||||
color: #fff
|
||||
+box-shadow(0 0 5px 3px rgba(255,255,255,.7))
|
||||
.size
|
||||
position: absolute
|
||||
width: 64px
|
||||
cursor: row-resize
|
||||
top: 9px
|
||||
margin-left: 52px
|
||||
padding: 0 5px
|
||||
.auto_size
|
||||
position: absolute
|
||||
width: 100px
|
||||
top: 9px
|
||||
cursor: pointer
|
||||
&.readonly
|
||||
cursor: auto !important
|
||||
&:before, &.size
|
||||
display: none !important
|
||||
|
||||
.icon.btn
|
||||
display: inline-block
|
||||
|
||||
.oe_overlay_options
|
||||
position: absolute
|
||||
left: 50% !important
|
||||
text-align: center
|
||||
top: -20px
|
||||
z-index: 1002
|
||||
> .btn-group
|
||||
left: -50%
|
||||
white-space: nowrap
|
||||
> a
|
||||
cursor: pointer
|
||||
display: inline-block
|
||||
float: none
|
||||
margin: 0 -3px
|
||||
.btn, a
|
||||
cursor: pointer
|
||||
.dropdown
|
||||
display: inline-block
|
||||
.dropdown-menu
|
||||
text-align: left
|
||||
min-width: 180px
|
||||
.dropdown-menu select,.dropdown-menu input
|
||||
display: block
|
||||
|
||||
&.block-w-left .w:before
|
||||
content: "\F061" !important
|
||||
&.block-w-right .w:before
|
||||
content: "\F060" !important
|
||||
&.block-w-left.block-w-right .w
|
||||
display: none !important
|
||||
&.block-e-left .e:before
|
||||
content: "\F061" !important
|
||||
&.block-e-right .e:before
|
||||
content: "\F060" !important
|
||||
&.block-e-left.block-e-right .e
|
||||
display: none !important
|
||||
|
||||
&.block-s-top .s:before
|
||||
content: "\F063" !important
|
||||
&.block-s-bottom .s:before
|
||||
content: "\f062" !important
|
||||
&.block-n-top .n:before
|
||||
content: "\F063" !important
|
||||
&.block-n-bottom .n:before
|
||||
content: "\f062" !important
|
||||
|
||||
|
||||
.s-resize-important, .s-resize-important *
|
||||
cursor: s-resize !important
|
||||
.n-resize-important, .n-resize-important *
|
||||
cursor: n-resize !important
|
||||
.e-resize-important, .e-resize-important *
|
||||
cursor: e-resize !important
|
||||
.w-resize-important, .w-resize-important *
|
||||
cursor: w-resize !important
|
||||
.move-important, .move-important *
|
||||
cursor: move !important
|
||||
|
||||
// }}}
|
||||
|
||||
|
||||
/* add CSS for bootstrap dropdown multi level */
|
||||
.dropdown-submenu
|
||||
position: relative
|
||||
z-index: 1000
|
||||
.dropdown-submenu
|
||||
&>.dropdown-menu
|
||||
top: 0
|
||||
left: 100%
|
||||
margin-top: -6px
|
||||
margin-left: -1px
|
||||
-webkit-border-radius: 0 6px 6px 6px
|
||||
-moz-border-radius: 0 6px 6px 6px
|
||||
border-radius: 0 6px 6px 6px
|
||||
&:hover
|
||||
&>.dropdown-menu
|
||||
display: block
|
||||
&>a:after
|
||||
border-left-color: #ffffff
|
||||
&>a:after
|
||||
display: block
|
||||
content: " "
|
||||
float: right
|
||||
width: 0
|
||||
height: 0
|
||||
border-color: rgba(0, 0, 0, 0)
|
||||
border-style: solid
|
||||
border-width: 5px 0 5px 5px
|
||||
border-left-color: #cccccc
|
||||
margin-top: 5px
|
||||
margin-right: -10px
|
||||
&.pull-left
|
||||
float: none
|
||||
&>.dropdown-menu
|
||||
left: -100%
|
||||
margin-left: 10px
|
||||
-webkit-border-radius: 6px 0 6px 6px
|
||||
-moz-border-radius: 6px 0 6px 6px
|
||||
border-radius: 6px 0 6px 6px
|
||||
|
||||
.oe_snippet_list
|
||||
width: auto
|
||||
white-space: nowrap
|
||||
margin-left: 20px
|
||||
|
||||
.oe_snippet_editor
|
||||
position: fixed
|
||||
z-index: 1000
|
||||
bottom: 0
|
||||
left: 0
|
||||
right: 0
|
||||
height: 214px
|
||||
background: rgb(160,160,160)
|
||||
box-shadow: 0 1px 3px rgb(100,100,100) inset
|
||||
.oe_snippet
|
||||
box-sizing: border-box
|
||||
display: inline-block
|
||||
width: 220px
|
||||
height: 160px
|
||||
border-radius: 3px
|
||||
background: white
|
||||
margin: 20px 20px 20px 0
|
||||
cursor: pointer
|
||||
border: 2px solid rgba(0, 0, 0, 0)
|
||||
box-shadow: 0 1px 3px rgb(100,100,100)
|
||||
position: relative
|
||||
top: 0
|
||||
overflow: hidden
|
||||
vertical-align: top
|
||||
user-select: none
|
||||
white-space: normal
|
||||
&:after
|
||||
content: attr(name)
|
||||
position: absolute
|
||||
bottom: 0px
|
||||
left: 0px
|
||||
right: 0px
|
||||
background: rgba(255,255,255,0.8)
|
||||
text-align: center
|
||||
color: black
|
||||
padding: 8px
|
||||
&.oe_selected, &.oe_active
|
||||
border: 2px solid rgb(151, 137, 255)
|
||||
box-shadow: 0px 3px 17px rgba(99, 53, 150, 0.59)
|
||||
& > *
|
||||
margin-top: 16px
|
||||
line-height: 1em
|
||||
zoom: 0.6
|
||||
& > .container
|
||||
margin-top: 15px
|
||||
zoom: 0.17
|
||||
line-height: 0.999em
|
||||
line-height: 1em
|
||||
& > .row
|
||||
margin-top: 0px
|
||||
zoom: 0.23
|
||||
line-height: 0.999em
|
||||
& > .span6
|
||||
margin-top: 18px
|
||||
zoom: 0.34
|
||||
& > .span12
|
||||
margin-top: 16px
|
||||
zoom: 0.23
|
||||
& > p
|
||||
position: absolute
|
||||
top: 0
|
||||
right: 0
|
||||
left: 0
|
||||
bottom: 0
|
||||
font-size: 20px
|
||||
padding: 16px
|
||||
zoom: 1
|
||||
margin: 0px
|
||||
&.oe_new
|
||||
background: gray
|
||||
box-shadow: 0px 1px 3px rgb(90,90,90) inset
|
||||
border: 0px
|
||||
&.oe_selected, &.oe_active
|
||||
box-shadow: 0px 2px 0px 0px rgb(151,137,255) inset, 0px 3px 17px rgba(99, 53, 150, 0.59) inset
|
||||
& > *
|
||||
zoom: 1
|
||||
margin: 0
|
||||
line-height: 160px
|
||||
text-align: center
|
||||
color: white
|
||||
font-size: 48px
|
||||
&:after
|
||||
position: absolute
|
||||
left: 0px
|
||||
right: 0px
|
||||
top: 0px
|
||||
bottom: 0px
|
||||
background: rgba(0, 0, 0, 0)
|
||||
color: white
|
||||
text-shadow: 0px 1px 3px black
|
||||
line-height: 160px
|
||||
padding: 0px
|
||||
|
||||
.oe_snippet_drop
|
||||
position: relative
|
||||
border: 2px dashed rgb(174, 52, 255)
|
||||
background: rgba(147, 52, 255, 0.1)
|
||||
min-height: 28px
|
||||
margin: -16px auto
|
||||
border-radius: 5px
|
||||
max-width: 50%
|
||||
&.oe_accepting
|
||||
border: 2px dashed rgb(52, 255, 166)
|
||||
background: rgba(52, 255, 190, 0.1)
|
||||
|
||||
#website-top-edit
|
||||
li.oe_snippet_editorbar
|
||||
padding: 1px 8px 2px
|
||||
font: normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif
|
||||
float: left
|
||||
margin-top: 6px
|
||||
border: 1px solid #a6a6a6
|
||||
border-bottom-color: #979797
|
||||
background: #eeeeee
|
||||
border-radius: 3px
|
||||
& > *
|
||||
display: inline-block
|
||||
height: 22px
|
||||
padding: 4px 6px
|
||||
outline: 0
|
||||
border: 0
|
||||
|
||||
a.button .icon
|
||||
cursor: inherit
|
||||
background-repeat: no-repeat
|
||||
margin-top: 1px
|
||||
width: 16px
|
||||
height: 16px
|
||||
display: inline-block
|
||||
|
||||
/* ---- COLOR-PICKER ---- {{{ */
|
||||
|
||||
.colorpicker
|
||||
margin: 0 auto
|
||||
background: rgba(0, 0, 0, 0)
|
||||
border: 0
|
||||
td
|
||||
padding: 0
|
||||
background: rgba(0, 0, 0, 0)
|
||||
> *
|
||||
width: 16px
|
||||
height: 16px
|
||||
border-radius: 2px
|
||||
margin: 3px
|
||||
padding: 0
|
||||
border-width: 1px
|
||||
display: block
|
||||
.only-text
|
||||
display: none
|
||||
.automatic-color
|
||||
background: #fff
|
||||
border-left: 7px solid #f33
|
||||
border-top: 7px solid #0e0
|
||||
border-right: 8px solid #33f
|
||||
border-bottom: 8px solid #fe0
|
||||
margin: 4px 3px 3px 3px
|
||||
width: 0
|
||||
height: 0
|
||||
.cke_panel_container table.colorpicker
|
||||
tr:first-child td
|
||||
padding-top: 6px
|
||||
tr:last-child td
|
||||
padding-bottom: 6px
|
||||
|
||||
|
||||
/* snippets default margins */
|
||||
.s_banner {
|
||||
margin-bottom: 32px
|
||||
}
|
||||
|
||||
.s_big_message {
|
||||
margin-top: 16px
|
||||
margin-bottom: 16px
|
||||
}
|
||||
|
||||
.s_text_block {
|
||||
margin-top: 16px
|
||||
margin-bottom: 16px
|
||||
}
|
||||
|
||||
.s_features {
|
||||
margin-top: 16px
|
||||
}
|
||||
|
||||
.s_big_picture {
|
||||
margin-top: 16px
|
||||
margin-bottom: 16px
|
||||
}
|
||||
|
||||
.s_three_columns {
|
||||
margin-top: 16px
|
||||
margin-bottom: 16px
|
||||
}
|
||||
|
||||
.s_references {
|
||||
margin-top: 16px
|
||||
margin-bottom: 32px
|
||||
}
|
||||
|
||||
.s_quotes_slider {
|
||||
margin-bottom: 0px
|
||||
}
|
||||
|
||||
.s_features_grid {
|
||||
margin-bottom: 16px
|
||||
}
|
||||
|
||||
|
||||
// }}}
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,118 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var website = openerp.website;
|
||||
|
||||
CKEDITOR.plugins.add('customColor', {
|
||||
requires: 'panelbutton,floatpanel',
|
||||
init: function (editor) {
|
||||
function create_button (buttonID, label) {
|
||||
var btnID = buttonID;
|
||||
editor.ui.add(buttonID, CKEDITOR.UI_PANELBUTTON, {
|
||||
label: label,
|
||||
title: label,
|
||||
modes: { wysiwyg: true },
|
||||
editorFocus: true,
|
||||
context: 'font',
|
||||
panel: {
|
||||
css: [ '/web/css/web.assets_common/' + (new Date().getTime()),
|
||||
'/web/css/website.assets_frontend/' + (new Date().getTime()),
|
||||
'/web/css/website.assets_editor/' + (new Date().getTime())],
|
||||
attributes: { 'role': 'listbox', 'aria-label': label },
|
||||
},
|
||||
enable: function () {
|
||||
this.setState(CKEDITOR.TRISTATE_OFF);
|
||||
},
|
||||
disable: function () {
|
||||
this.setState(CKEDITOR.TRISTATE_DISABLED);
|
||||
},
|
||||
onBlock: function (panel, block) {
|
||||
var self = this;
|
||||
var html = openerp.qweb.render('website_less.colorpicker');
|
||||
block.autoSize = true;
|
||||
block.element.setHtml( html );
|
||||
$(block.element.$).on('click', 'button', function () {
|
||||
self.clicked(this);
|
||||
});
|
||||
if (btnID === "TextColor") {
|
||||
$(".only-text", block.element.$).css("display", "block");
|
||||
$(".only-bg", block.element.$).css("display", "none");
|
||||
}
|
||||
var $body = $(block.element.$).parents("body");
|
||||
setTimeout(function () {
|
||||
$body.css('background-color', '#fff');
|
||||
}, 0);
|
||||
},
|
||||
getClasses: function () {
|
||||
var self = this;
|
||||
var classes = [];
|
||||
var id = this._.id;
|
||||
var block = this._.panel._.panel._.blocks[id];
|
||||
var $root = $(block.element.$);
|
||||
$root.find("button").map(function () {
|
||||
var color = self.getClass(this);
|
||||
if(color) classes.push( color );
|
||||
});
|
||||
return classes;
|
||||
},
|
||||
getClass: function (button) {
|
||||
var color = btnID === "BGColor" ? $(button).attr("class") : $(button).attr("class").replace(/^bg-/i, 'text-');
|
||||
return color.length && color;
|
||||
},
|
||||
clicked: function (button) {
|
||||
var className = this.getClass(button);
|
||||
var ancestor = editor.getSelection().getCommonAncestor();
|
||||
|
||||
editor.focus();
|
||||
this._.panel.hide();
|
||||
editor.fire('saveSnapshot');
|
||||
|
||||
// remove style
|
||||
var classes = [];
|
||||
var $ancestor = $(ancestor.$);
|
||||
var $fonts = $(ancestor.$).find('font');
|
||||
if (!ancestor.$.tagName) {
|
||||
$ancestor = $ancestor.parent();
|
||||
}
|
||||
if ($ancestor.is('font')) {
|
||||
$fonts = $fonts.add($ancestor[0]);
|
||||
}
|
||||
|
||||
$fonts.filter("."+this.getClasses().join(",.")).map(function () {
|
||||
var className = $(this).attr("class");
|
||||
if (classes.indexOf(className) === -1) {
|
||||
classes.push(className);
|
||||
}
|
||||
});
|
||||
for (var k in classes) {
|
||||
editor.removeStyle( new CKEDITOR.style({
|
||||
element: 'font',
|
||||
attributes: { 'class': classes[k] },
|
||||
}) );
|
||||
}
|
||||
|
||||
// add new style
|
||||
if (className) {
|
||||
editor.applyStyle( new CKEDITOR.style({
|
||||
element: 'font',
|
||||
attributes: { 'class': className },
|
||||
}) );
|
||||
}
|
||||
editor.fire('saveSnapshot');
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
create_button("BGColor", "Background Color");
|
||||
create_button("TextColor", "Text Color");
|
||||
}
|
||||
});
|
||||
|
||||
website.RTE = website.RTE.extend({
|
||||
_config: function () {
|
||||
var config = this._super.apply(this, arguments);
|
||||
config.extraPlugins = 'customColor,' + config.extraPlugins;
|
||||
return config
|
||||
},
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,80 @@
|
||||
// Backported from 52ca425
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var website = openerp.website;
|
||||
|
||||
function load_called_template () {
|
||||
var ids_or_xml_ids = _.uniq($("[data-oe-call]").map(function () {return $(this).data('oe-call');}).get());
|
||||
if (ids_or_xml_ids.length) {
|
||||
openerp.jsonRpc('/website/multi_render', 'call', {
|
||||
'ids_or_xml_ids': ids_or_xml_ids
|
||||
}).then(function (data) {
|
||||
for (var k in data) {
|
||||
var $data = $(data[k]);
|
||||
// clean t-oe
|
||||
$data.each(function () {
|
||||
for (var k=0; k<this.attributes.length; k++) {
|
||||
if (this.attributes[k].name.indexOf('data-oe-') === 0) {
|
||||
$(this).removeAttr(this.attributes[k].name);
|
||||
k--;
|
||||
}
|
||||
}
|
||||
});
|
||||
// end
|
||||
$("[data-oe-call='"+k+"']").each(function () {
|
||||
$(this).replaceWith($data.clone());
|
||||
});
|
||||
}
|
||||
$(document).trigger('scroll');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(load_called_template);
|
||||
|
||||
$(document).ready(function () {
|
||||
$(".o_animation")
|
||||
.removeClass("o_displayed o_displayed_top o_displayed_middle o_displayed_bottom");
|
||||
$(document)
|
||||
.on('scroll', function (event) {
|
||||
var docViewTop = $(document.body).scrollTop();
|
||||
var docViewBottom = docViewTop + $(document.body).height();
|
||||
|
||||
$(".o_animation")
|
||||
.each(function () {
|
||||
var $el = $(this);
|
||||
var elemTop = $el.offset().top;
|
||||
var elemBottom = elemTop + $el.height();
|
||||
var elemMiddle = elemTop + $el.height()*0.4;
|
||||
var visible = elemBottom >= docViewTop && elemTop <= docViewBottom;
|
||||
|
||||
if (visible) {
|
||||
$el.addClass("o_displayed o_visible");
|
||||
} else {
|
||||
$el.removeClass("o_visible");
|
||||
}
|
||||
|
||||
if (visible && elemTop > docViewTop) {
|
||||
$el.addClass("o_displayed_top o_visible_top");
|
||||
} else {
|
||||
$el.removeClass("o_visible_top");
|
||||
}
|
||||
if (visible && elemMiddle < docViewBottom && elemMiddle > docViewTop) {
|
||||
$el.addClass("o_displayed_middle o_visible_middle");
|
||||
} else {
|
||||
$el.removeClass("o_visible_middle");
|
||||
}
|
||||
if (visible && elemBottom < docViewBottom) {
|
||||
$el.addClass("o_displayed_bottom o_visible_bottom");
|
||||
} else {
|
||||
$el.removeClass("o_visible_bottom");
|
||||
}
|
||||
|
||||
});
|
||||
})
|
||||
.trigger('scroll');
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,289 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
openerp.jsonRpc('/web/dataset/call', 'call', {
|
||||
'model': 'ir.ui.view',
|
||||
'method': 'read_template',
|
||||
'args': ['website_less.theme_customize', openerp.website.get_context()]
|
||||
}).done(function (data) {
|
||||
openerp.qweb.add_template(data);
|
||||
});
|
||||
openerp.jsonRpc('/web/dataset/call', 'call', {
|
||||
'model': 'ir.ui.view',
|
||||
'method': 'read_template',
|
||||
'args': ['website_less.colorpicker', openerp.website.get_context()]
|
||||
}).done(function (data) {
|
||||
openerp.qweb.add_template(data);
|
||||
});
|
||||
|
||||
openerp.website.Theme = openerp.Widget.extend({
|
||||
template: 'website_less.theme_customize',
|
||||
events: {
|
||||
'change input[data-xmlid],input[data-enable],input[data-disable]': 'change_selection',
|
||||
'click .close': 'close',
|
||||
'click': 'click',
|
||||
},
|
||||
start: function () {
|
||||
var self = this;
|
||||
this.timer = null;
|
||||
this.reload = false;
|
||||
this.flag = false;
|
||||
this.$el.addClass("theme_customize_modal");
|
||||
this.active_select_tags();
|
||||
this.$inputs = $("input[data-xmlid],input[data-enable],input[data-disable]");
|
||||
setTimeout(function () {self.$el.addClass('in');}, 0);
|
||||
this.keydown_escape = function (event) {
|
||||
if (event.keyCode === 27) {
|
||||
self.close();
|
||||
}
|
||||
};
|
||||
$(document).on('keydown', this.keydown_escape);
|
||||
return this.load_xml_data().then(function () {
|
||||
self.flag = true;
|
||||
});
|
||||
},
|
||||
active_select_tags: function () {
|
||||
var uniqueID = 0;
|
||||
var self = this;
|
||||
var $selects = this.$('select:has(option[data-xmlid],option[data-enable],option[data-disable])');
|
||||
$selects.each(function () {
|
||||
uniqueID++;
|
||||
var $select = $(this);
|
||||
var $options = $select.find('option[data-xmlid], option[data-enable], option[data-disable]');
|
||||
$options.each(function () {
|
||||
var $option = $(this);
|
||||
var $input = $('<input style="display: none;" type="radio" name="theme_customize_modal-select-'+uniqueID+'"/>');
|
||||
$input.attr('id', $option.attr('id'));
|
||||
$input.attr('data-xmlid', $option.data('xmlid'));
|
||||
$input.attr('data-enable', $option.data('enable'));
|
||||
$input.attr('data-disable', $option.data('disable'));
|
||||
$option.removeAttr('id');
|
||||
$option.data('input', $input);
|
||||
$input.on('update', function () {
|
||||
$option.attr('selected', $(this).prop("checked"));
|
||||
});
|
||||
self.$el.append($input);
|
||||
});
|
||||
$select.data("value", $options.first());
|
||||
$options.first().attr("selected", true);
|
||||
});
|
||||
$selects.change(function () {
|
||||
var $option = $(this).find('option:selected');
|
||||
$(this).data("value").data("input").prop("checked", true).change();
|
||||
$(this).data("value", $option);
|
||||
$option.data("input").change();
|
||||
});
|
||||
},
|
||||
load_xml_data: function (xml_ids) {
|
||||
var self = this;
|
||||
$('#theme_error').remove();
|
||||
return openerp.jsonRpc('/website/theme_customize_get', 'call', {
|
||||
'xml_ids': this.get_xml_ids(this.$inputs)
|
||||
}).done(function (data) {
|
||||
self.$inputs.filter('[data-xmlid]').each(function () {
|
||||
if (!_.difference(self.get_xml_ids($(this)), data[1]).length) {
|
||||
$(this).prop("checked", false).change();
|
||||
}
|
||||
if (!_.difference(self.get_xml_ids($(this)), data[0]).length) {
|
||||
$(this).prop("checked", true).change();
|
||||
}
|
||||
});
|
||||
}).fail(function (d, error) {
|
||||
$('body').prepend($('<div id="theme_error"/>').text(error.data.message));
|
||||
});
|
||||
},
|
||||
get_inputs: function (string) {
|
||||
return this.$inputs.filter('#'+string.split(",").join(", #"));
|
||||
},
|
||||
get_xml_ids: function ($inputs) {
|
||||
var xml_ids = [];
|
||||
$inputs.each(function () {
|
||||
if ($(this).data('xmlid') && $(this).data('xmlid').length) {
|
||||
xml_ids = xml_ids.concat($(this).data('xmlid').split(","));
|
||||
}
|
||||
});
|
||||
return xml_ids;
|
||||
},
|
||||
compute_stylesheets: function () {
|
||||
var self = this;
|
||||
self.has_error = false;
|
||||
$('link[href*=".assets_"]').attr('data-loading', true);
|
||||
function theme_customize_css_onload() {
|
||||
if ($('link[data-loading]').size()) {
|
||||
$('body').toggleClass('theme_customize_css_loading');
|
||||
setTimeout(theme_customize_css_onload, 50);
|
||||
} else {
|
||||
$('body').removeClass('theme_customize_css_loading');
|
||||
self.$el.removeClass("loading");
|
||||
|
||||
if (window.getComputedStyle($('button[data-toggle="collapse"]:first')[0]).getPropertyValue('position') === 'static' ||
|
||||
window.getComputedStyle($('#theme_customize_modal')[0]).getPropertyValue('display') === 'none') {
|
||||
if (self.has_error) {
|
||||
window.location.hash = "theme=true";
|
||||
window.location.reload();
|
||||
} else {
|
||||
self.has_error = true;
|
||||
$('link[href*=".assets_"][data-error]').removeAttr('data-error').attr('data-loading', true);
|
||||
self.update_stylesheets();
|
||||
setTimeout(theme_customize_css_onload, 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
theme_customize_css_onload();
|
||||
},
|
||||
update_stylesheets: function () {
|
||||
$('link[href*=".assets_"]').each(function update () {
|
||||
var $style = $(this);
|
||||
var href = $style.attr("href").replace(/[^\/]+$/, new Date().getTime());
|
||||
var $asset = $('<link rel="stylesheet" href="'+href+'"/>');
|
||||
$asset.attr("onload", "$(this).prev().attr('disable', true).remove(); $(this).removeAttr('onload').removeAttr('onerror');");
|
||||
$asset.attr("onerror", "$(this).prev().removeAttr('data-loading').attr('data-error','loading'); $(this).attr('disable', true).remove();");
|
||||
$style.after($asset);
|
||||
});
|
||||
},
|
||||
update_style: function (enable, disable, reload) {
|
||||
var self = this;
|
||||
if (this.$el.hasClass("loading")) return;
|
||||
this.$el.addClass("loading");
|
||||
|
||||
if (!reload && $('link[href*=".assets_"]').size()) {
|
||||
this.compute_stylesheets();
|
||||
return openerp.jsonRpc('/website/theme_customize', 'call', {
|
||||
'enable': enable,
|
||||
'disable': disable
|
||||
}).then(function () {
|
||||
self.update_stylesheets();
|
||||
});
|
||||
} else {
|
||||
var href = '/website/theme_customize_reload'+
|
||||
'?href='+encodeURIComponent(window.location.href)+
|
||||
'&enable='+encodeURIComponent(enable.join(","))+
|
||||
'&disable='+encodeURIComponent(disable.join(","));
|
||||
window.location.href = href;
|
||||
return $.Deferred();
|
||||
}
|
||||
},
|
||||
enable_disable: function (data, enable) {
|
||||
if (!data) return;
|
||||
this.$('#'+data.split(",").join(", #")).each(function () {
|
||||
var check = $(this).prop("checked");
|
||||
var $label = $(this).closest("label");
|
||||
$(this).attr("checked", enable);
|
||||
if (enable) $label.addClass("checked");
|
||||
else $label.removeClass("checked");
|
||||
if (check != enable) {
|
||||
$(this).change();
|
||||
}
|
||||
});
|
||||
},
|
||||
change_selection: function (event) {
|
||||
var self = this;
|
||||
if (this.$el.hasClass("loading")) return;
|
||||
|
||||
var $option = $(event.target),
|
||||
checked = $option.prop("checked");
|
||||
|
||||
if (checked) {
|
||||
this.enable_disable($option.data('enable'), true);
|
||||
this.enable_disable($option.data('disable'), false);
|
||||
$option.closest("label").addClass("checked");
|
||||
} else {
|
||||
$option.closest("label").removeClass("checked");
|
||||
}
|
||||
$option.prop("checked", checked);
|
||||
|
||||
var $enable = this.$inputs.filter('[data-xmlid]:checked');
|
||||
$enable.closest("label").addClass("checked");
|
||||
var $disable = this.$inputs.filter('[data-xmlid]:not(:checked)');
|
||||
$disable.closest("label").removeClass("checked");
|
||||
|
||||
var $sets = this.$inputs.filter('input[data-enable]:not([data-xmlid]), input[data-disable]:not([data-xmlid])');
|
||||
$sets.each(function () {
|
||||
var $set = $(this);
|
||||
var checked = true;
|
||||
if ($set.data("enable")) {
|
||||
self.get_inputs($(this).data("enable")).each(function () {
|
||||
if (!$(this).prop("checked")) checked = false;
|
||||
});
|
||||
}
|
||||
if ($set.data("disable")) {
|
||||
self.get_inputs($(this).data("disable")).each(function () {
|
||||
if ($(this).prop("checked")) checked = false;
|
||||
});
|
||||
}
|
||||
if (checked) {
|
||||
$set.prop("checked", true).closest("label").addClass("checked");
|
||||
} else {
|
||||
$set.prop("checked", false).closest("label").removeClass("checked");
|
||||
}
|
||||
$set.trigger('update');
|
||||
});
|
||||
|
||||
if (this.flag && $option.data('reload') && document.location.href.match(new RegExp( $option.data('reload') ))) {
|
||||
this.reload = true;
|
||||
}
|
||||
|
||||
clearTimeout(this.timer);
|
||||
if (this.flag) {
|
||||
this.timer = setTimeout(function () {
|
||||
self.update_style(self.get_xml_ids($enable), self.get_xml_ids($disable), self.reload);
|
||||
self.reload = false;
|
||||
},0);
|
||||
} else {
|
||||
this.timer = setTimeout(function () { self.reload = false; },0);
|
||||
}
|
||||
},
|
||||
click: function (event) {
|
||||
if (!$(event.target).closest("#theme_customize_modal > *").length) {
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
close: function () {
|
||||
var self = this;
|
||||
$(document).off('keydown', this.keydown_escape);
|
||||
$('#theme_error').remove();
|
||||
$('link[href*=".assets_"]').removeAttr('data-loading');
|
||||
this.$el.removeClass('in');
|
||||
this.$el.addClass('out');
|
||||
setTimeout(function () {self.destroy();}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
function themeError(message) {
|
||||
var _t = openerp._t;
|
||||
|
||||
if (message.indexOf('lessc')) {
|
||||
message = '<span class="text-muted">' + message + "</span><br/><br/>" + _t("Please install or update node-less");
|
||||
}
|
||||
|
||||
var $error = $( openerp.qweb.render('website.error_dialog', {
|
||||
title: _t("Theme Error"),
|
||||
message: message
|
||||
}));
|
||||
$error.appendTo("body").modal();
|
||||
$error.on('hidden.bs.modal', function () {
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
openerp.website.ready().done(function() {
|
||||
function theme_customize() {
|
||||
var error = window.getComputedStyle(document.body, ':before').getPropertyValue('content');
|
||||
if (error && error !== 'none') {
|
||||
return themeError(eval(error));
|
||||
}
|
||||
var Theme = openerp.website.Theme;
|
||||
if (Theme.open && !Theme.open.isDestroyed()) return;
|
||||
Theme.open = new Theme();
|
||||
Theme.open.appendTo("body");
|
||||
}
|
||||
$(document).on('click', "#theme_customize a",theme_customize);
|
||||
if ((window.location.hash || "").indexOf("theme=true") !== -1) {
|
||||
theme_customize();
|
||||
window.location.hash = "";
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,95 @@
|
||||
/* Clean Colors */
|
||||
|
||||
@color-blue: #3498DB;
|
||||
@color-turquoise: #1ABC9C;
|
||||
@color-green: #2ECC71;
|
||||
@color-yellow: #F1C40F;
|
||||
@color-orange: #E67E22;
|
||||
@color-red: #E74C3C;
|
||||
@color-pink: #f74b94;
|
||||
@color-purple: #9B59B6;
|
||||
@color-brown: #7b5844;
|
||||
|
||||
@color-blue-dark: #2980B9;
|
||||
@color-turquoise-dark: #16A085;
|
||||
@color-green-dark: #27AE60;
|
||||
@color-yellow-dark: #f3ac12;
|
||||
@color-orange-dark: #D35400;
|
||||
@color-red-dark: #C0392B;
|
||||
@color-pink-dark: #ea3884;
|
||||
@color-purple-dark: #8E44AD;
|
||||
@color-brown-dark: #604434;
|
||||
|
||||
@color-blue-light: lighten(@color-blue, 20%);
|
||||
@color-turquoise-light: lighten(@color-turquoise, 20%);
|
||||
@color-green-light: lighten(@color-green, 20%);
|
||||
@color-yellow-light: lighten(@color-yellow, 20%);
|
||||
@color-orange-light: lighten(@color-orange, 20%);
|
||||
@color-red-light: lighten(@color-red, 20%);
|
||||
@color-pink-light: lighten(@color-pink, 20%);
|
||||
@color-purple-light: lighten(@color-purple, 20%);
|
||||
@color-brown-light: lighten(@color-brown, 20%);
|
||||
|
||||
@color-clouds: #ECF0F1;
|
||||
@color-silver: #BDC3C7;
|
||||
@color-concrete: #95A5A6;
|
||||
@color-stone: #7F8C8D;
|
||||
@color-asphalt: #34495E;
|
||||
@color-midnight: #2C3E50;
|
||||
|
||||
|
||||
@color-concrete-dark: #445b5c;
|
||||
|
||||
/* +++++ NEW COLORS +++++ */
|
||||
|
||||
@color-wind: #f7f7f7;
|
||||
@color-clay: #e1dcd5;
|
||||
@color-sand: #c5bcb1;
|
||||
@color-beach: #f3bf91;
|
||||
@color-forest: #254c3a;
|
||||
@color-twilight: #3b2c50;
|
||||
@color-burgundy: #8e362d;
|
||||
@color-marine: #212d3a;
|
||||
|
||||
/* GRAYS --------------------------------------------------------- */
|
||||
|
||||
@gray-darker: lighten(#000, 20%);
|
||||
@gray-dark: lighten(#000, 40%);
|
||||
@gray: lighten(#000, 55%);
|
||||
@gray-light: lighten(#000, 70%);
|
||||
@gray-lighter: lighten(#000, 80%);
|
||||
|
||||
/* Backgrounds Colors ------------------------------------------------*/
|
||||
|
||||
@bg-blue: background(@color-blue);
|
||||
@bg-turquoise: background(@color-turquoise);
|
||||
@bg-green: background(@color-green);
|
||||
@bg-yellow: background(@color-yellow);
|
||||
@bg-orange: background(@color-orange);
|
||||
@bg-red: background(@color-red);
|
||||
@bg-pink: background(@color-pink);
|
||||
@bg-purple: background(@color-purple);
|
||||
@bg-brown: background(@color-brown);
|
||||
|
||||
|
||||
/* ---- Default Color HTML Class ---- */
|
||||
|
||||
.bg-blue { background-color: @color-blue;}
|
||||
.bg-turquoise { background-color: @color-turquoise;}
|
||||
.bg-green { background-color: @color-green;}
|
||||
.bg-yellow { background-color: @color-yellow;}
|
||||
.bg-orange { background-color: @color-orange;}
|
||||
.bg-red { background-color: @color-red;}
|
||||
.bg-pink { background-color: @color-pink;}
|
||||
.bg-purple { background-color: @color-purple;}
|
||||
.bg-brown { background-color: @color-brown;}
|
||||
|
||||
.text-blue { color: @color-blue;}
|
||||
.text-turquoise { color: @color-turquoise;}
|
||||
.text-green { color: @color-green;}
|
||||
.text-yellow { color: @color-yellow;}
|
||||
.text-orange { color: @color-orange;}
|
||||
.text-red { color: @color-red;}
|
||||
.text-pink { color: @color-pink;}
|
||||
.text-purple { color: @color-purple;}
|
||||
.text-brown { color: @color-brown;}
|
||||
@@ -0,0 +1 @@
|
||||
@import "bootstrap";
|
||||
@@ -0,0 +1,77 @@
|
||||
/* GRAYS --------------------------------------------------------- */
|
||||
|
||||
@gray-darker: lighten(#000, 30%);
|
||||
|
||||
/* COLORS --------------------------------------------------------- */
|
||||
|
||||
@color-primary: @color-purple;
|
||||
@color-success: @color-purple-dark;
|
||||
@color-info: @color-twilight;
|
||||
@color-warning: @color-red-dark;
|
||||
@color-danger: @color-midnight;
|
||||
|
||||
/* COLORED BG -------------------------------------------------------- */
|
||||
|
||||
.bg-primary {
|
||||
background-color: @color-clouds;
|
||||
}
|
||||
.bg-success {
|
||||
background-color: @color-purple;
|
||||
}
|
||||
.bg-info {
|
||||
background-color: @color-twilight;
|
||||
}
|
||||
.bg-warning {
|
||||
background-color: @color-purple-dark;
|
||||
}
|
||||
.bg-danger {
|
||||
background-color: @color-midnight;
|
||||
}
|
||||
|
||||
/* TEXTS & LINKS --------------------------------------------------- */
|
||||
|
||||
@text-muted: @color-primary;
|
||||
@link-color: @color-primary;
|
||||
@link-hover-color: @color-success;
|
||||
|
||||
/* BUTTONS --------------------------------------------------------- */
|
||||
|
||||
@btn-primary-bg: @color-silver;
|
||||
@btn-success-bg: @color-concrete;
|
||||
@btn-info-bg: @color-purple;
|
||||
@btn-warning-bg: @color-purple-light;
|
||||
@btn-danger-bg: @color-red;
|
||||
|
||||
.btn .fa {
|
||||
color: white;}
|
||||
|
||||
.btn-default .fa {
|
||||
color: @gray-dark;}
|
||||
|
||||
/* rgba(0, 0, 0, 0) BG --------------------------------------------------- */
|
||||
/* Used in snippets Prx Image Color and Prx Image Shade ------------- */
|
||||
|
||||
.bg-rgba(0, 0, 0, 0)-color { background: @color-twilight; opacity: 0.85;}
|
||||
.bg-rgba(0, 0, 0, 0)-shade { background: black; opacity: 0.5;}
|
||||
|
||||
/* Footer ----------------------------------------------------------- */
|
||||
|
||||
#wrapwrap footer {
|
||||
background-color: @color-concrete-dark;
|
||||
color: @gray-light;
|
||||
}
|
||||
footer ul li a {
|
||||
color: @color-clouds;
|
||||
}
|
||||
footer ul li a:hover {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
footer h4 {
|
||||
color: @gray-lighter;
|
||||
padding-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
footer .fa {
|
||||
color: @color-concrete;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/* COLORS --------------------------------------------------------- */
|
||||
|
||||
@color-primary: @color-blue;
|
||||
@color-success: @color-turquoise;
|
||||
@color-info: @color-green;
|
||||
@color-warning: @color-asphalt;
|
||||
@color-danger: @color-midnight;
|
||||
|
||||
/* COLORED BG -------------------------------------------------------- */
|
||||
|
||||
.bg-primary {
|
||||
background-color: @color-wind;
|
||||
}
|
||||
.bg-success {
|
||||
background-color: @color-silver;
|
||||
}
|
||||
.bg-info {
|
||||
background-color: @color-blue;
|
||||
}
|
||||
.bg-warning {
|
||||
background-color: @color-blue-dark;
|
||||
}
|
||||
.bg-danger {
|
||||
background-color: @color-asphalt;
|
||||
}
|
||||
|
||||
/* TEXTS & LINKS --------------------------------------------------- */
|
||||
|
||||
@text-muted: @color-primary;
|
||||
@link-color: @color-primary;
|
||||
@link-hover-color: @color-info;
|
||||
|
||||
/* BUTTONS --------------------------------------------------------- */
|
||||
|
||||
@btn-primary-bg: @color-blue;
|
||||
@btn-success-bg: @color-turquoise;
|
||||
@btn-info-bg: @color-green;
|
||||
@btn-warning-bg: @color-orange;
|
||||
@btn-danger-bg: @color-red;
|
||||
|
||||
.btn .fa {
|
||||
color: white;}
|
||||
|
||||
.btn-default .fa {
|
||||
color: @gray-dark;}
|
||||
|
||||
/* rgba(0, 0, 0, 0) BG --------------------------------------------------- */
|
||||
/* Used in snippets Prx Image Color and Prx Image Shade ------------- */
|
||||
|
||||
.bg-rgba(0, 0, 0, 0)-color { background: @color-blue-dark; opacity: 0.9;}
|
||||
.bg-rgba(0, 0, 0, 0)-shade { background: black; opacity: 0.5;}
|
||||
|
||||
/* Footer ----------------------------------------------------------- */
|
||||
|
||||
#wrapwrap footer {
|
||||
background-color: @color-midnight;
|
||||
color: @gray;
|
||||
}
|
||||
footer ul li a {
|
||||
color: @color-silver;
|
||||
}
|
||||
|
||||
footer ul li a:hover {
|
||||
color: @color-clouds;
|
||||
text-decoration: none;
|
||||
}
|
||||
footer h4 {
|
||||
color: @color-stone;
|
||||
padding-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
footer .fa {
|
||||
color: @gray-light;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/* COLORS --------------------------------------------------------- */
|
||||
|
||||
@color-primary: @color-green;
|
||||
@color-success: @color-turquoise;
|
||||
@color-info: @color-turquoise-dark;
|
||||
@color-warning: @color-asphalt;
|
||||
@color-danger: @color-midnight;
|
||||
|
||||
/* COLORED BG -------------------------------------------------------- */
|
||||
|
||||
.bg-primary {
|
||||
background-color: @color-wind;
|
||||
}
|
||||
.bg-success {
|
||||
background-color: @color-silver;
|
||||
}
|
||||
.bg-info {
|
||||
background-color: @color-green-dark;
|
||||
}
|
||||
.bg-warning {
|
||||
background-color: @color-green;
|
||||
}
|
||||
.bg-danger {
|
||||
background-color: @color-forest;
|
||||
}
|
||||
|
||||
/* TEXTS & LINKS --------------------------------------------------- */
|
||||
|
||||
@text-muted: @color-success;
|
||||
@link-color: @color-success;
|
||||
@link-hover-color: @color-primary;
|
||||
|
||||
/* BUTTONS --------------------------------------------------------- */
|
||||
|
||||
@btn-primary-bg: @color-green;
|
||||
@btn-success-bg: @color-turquoise;
|
||||
@btn-info-bg: @color-blue;
|
||||
@btn-warning-bg: @color-orange;
|
||||
@btn-danger-bg: @color-red;
|
||||
|
||||
.btn .fa {
|
||||
color: white;}
|
||||
|
||||
.btn-default .fa {
|
||||
color: @gray-dark;}
|
||||
|
||||
/* rgba(0, 0, 0, 0) BG --------------------------------------------------- */
|
||||
/* Used in snippets Prx Image Color and Prx Image Shade ------------- */
|
||||
|
||||
.bg-rgba(0, 0, 0, 0)-color { background: @color-green-dark; opacity: 0.9;}
|
||||
.bg-rgba(0, 0, 0, 0)-shade { background: black; opacity: 0.5;}
|
||||
|
||||
/* Footer ----------------------------------------------------------- */
|
||||
|
||||
#wrapwrap footer {
|
||||
background-color: @color-concrete-dark;
|
||||
color: @gray;
|
||||
}
|
||||
footer ul li a {
|
||||
color: @color-clouds;
|
||||
}
|
||||
footer ul li a:hover {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
footer h4 {
|
||||
color: @color-silver;
|
||||
padding-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
footer .fa {
|
||||
color: @color-clouds;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/* COLORS --------------------------------------------------------- */
|
||||
|
||||
@color-primary: @color-orange;
|
||||
@color-success: @color-red;
|
||||
@color-info: @color-yellow-dark;
|
||||
@color-warning: @color-red-dark;
|
||||
@color-danger: @color-orange-dark;
|
||||
|
||||
/* COLORED BG -------------------------------------------------------- */
|
||||
|
||||
.bg-primary {
|
||||
background-color: @color-sand;
|
||||
}
|
||||
.bg-success {
|
||||
background-color: @color-yellow;
|
||||
}
|
||||
.bg-info {
|
||||
background-color: @color-orange;
|
||||
}
|
||||
.bg-warning {
|
||||
background-color: @color-yellow-dark;
|
||||
}
|
||||
.bg-danger {
|
||||
background-color: @color-orange-dark;
|
||||
}
|
||||
|
||||
/* TEXTS & LINKS ------------------------------------------------------- */
|
||||
|
||||
@text-muted: @gray;
|
||||
@link-color: @color-info;
|
||||
@link-hover-color: @color-primary;
|
||||
|
||||
/* BUTTONS --------------------------------------------------------- */
|
||||
|
||||
@btn-primary-bg: @color-yellow;
|
||||
@btn-success-bg: @color-orange;
|
||||
@btn-info-bg: @color-yellow-dark;
|
||||
@btn-warning-bg: @color-orange-dark;
|
||||
@btn-danger-bg: @color-red-dark;
|
||||
|
||||
.btn .fa {
|
||||
color: white;}
|
||||
|
||||
.btn-default .fa {
|
||||
color: @gray-dark;}
|
||||
|
||||
/* rgba(0, 0, 0, 0) BG --------------------------------------------------- */
|
||||
/* Used in snippets Prx Image Color and Prx Image Shade ------------- */
|
||||
|
||||
.bg-rgba(0, 0, 0, 0)-color { background: @color-orange-dark; opacity: 0.85;}
|
||||
.bg-rgba(0, 0, 0, 0)-shade { background: black; opacity: 0.5;}
|
||||
|
||||
/* Footer ----------------------------------------------------------- */
|
||||
|
||||
#wrapwrap footer {
|
||||
background-color: @color-orange-dark;
|
||||
color: white;
|
||||
}
|
||||
footer ul li a {
|
||||
color: @color-beach;
|
||||
}
|
||||
footer ul li a:hover {
|
||||
color: @color-yellow;
|
||||
text-decoration: none;
|
||||
}
|
||||
footer h4 {
|
||||
color: @color-beach;
|
||||
padding-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
footer .fa {
|
||||
color: @color-beach;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/* GRAYS --------------------------------------------------------- */
|
||||
|
||||
@gray: lighten(#000, 50%);
|
||||
|
||||
/* COLORS --------------------------------------------------------- */
|
||||
|
||||
@color-primary: @color-red;
|
||||
@color-success: @color-red-dark;
|
||||
@color-info: @color-orange;
|
||||
@color-warning: @color-purple;
|
||||
@color-danger: @color-orange-dark;
|
||||
|
||||
/* COLORED BG -------------------------------------------------------- */
|
||||
|
||||
.bg-primary {
|
||||
background-color: @color-sand;
|
||||
}
|
||||
.bg-success {
|
||||
background-color: @color-red;
|
||||
}
|
||||
.bg-info {
|
||||
background-color: @color-red-dark;
|
||||
}
|
||||
.bg-warning {
|
||||
background-color: @color-orange;
|
||||
}
|
||||
.bg-danger {
|
||||
background-color: @color-orange-dark;
|
||||
}
|
||||
|
||||
/* TEXT & LINKS -------------------------------------------------------- */
|
||||
|
||||
@text-muted: @gray;
|
||||
@link-color: @color-primary;
|
||||
@link-hover-color: @color-success;
|
||||
|
||||
/* BUTTONS --------------------------------------------------------- */
|
||||
|
||||
@btn-primary-bg: @color-red;
|
||||
@btn-success-bg: @color-orange;
|
||||
@btn-info-bg: @color-yellow-dark;
|
||||
@btn-warning-bg: @color-orange-dark;
|
||||
@btn-danger-bg: @color-red-dark;
|
||||
|
||||
.btn .fa {
|
||||
color: white;}
|
||||
|
||||
.btn-default .fa {
|
||||
color: @gray-dark;}
|
||||
|
||||
/* rgba(0, 0, 0, 0) BG --------------------------------------------------- */
|
||||
/* Used in snippets Prx Image Color and Prx Image Shade ------------- */
|
||||
|
||||
.bg-rgba(0, 0, 0, 0)-color { background: @color-red-dark; opacity: 0.85;}
|
||||
.bg-rgba(0, 0, 0, 0)-shade { background: black; opacity: 0.5;}
|
||||
|
||||
/* Footer ----------------------------------------------------------- */
|
||||
|
||||
#wrapwrap footer {
|
||||
background-color: @color-burgundy;
|
||||
color: @gray-lighter;
|
||||
}
|
||||
footer ul li a {
|
||||
color: white;
|
||||
}
|
||||
footer ul li a:hover {
|
||||
color: @color-orange;
|
||||
text-decoration: none;
|
||||
}
|
||||
footer h4 {
|
||||
color: @color-sand;
|
||||
padding-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
footer .fa {
|
||||
color: @color-red;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/* COLORS --------------------------------------------------------- */
|
||||
|
||||
@color-primary: @color-concrete;
|
||||
@color-success: @color-turquoise;
|
||||
@color-info: @color-stone;
|
||||
@color-warning: @color-concrete-dark;
|
||||
@color-danger: @color-midnight;
|
||||
|
||||
/* COLORED BG -------------------------------------------------------- */
|
||||
|
||||
.bg-primary {
|
||||
background-color: @color-clouds;
|
||||
}
|
||||
.bg-success {
|
||||
background-color: @color-silver;
|
||||
}
|
||||
.bg-info {
|
||||
background-color: @color-stone;
|
||||
}
|
||||
.bg-warning {
|
||||
background-color: @color-concrete-dark;
|
||||
}
|
||||
.bg-danger {
|
||||
background-color: @color-asphalt;
|
||||
}
|
||||
|
||||
/* TEXT & LINKS -------------------------------------------------------- */
|
||||
|
||||
@text-muted: @color-primary;
|
||||
@link-color: @color-primary;
|
||||
@link-hover-color: @color-info;
|
||||
|
||||
/* BUTTONS --------------------------------------------------------- */
|
||||
|
||||
@btn-primary-bg: @color-concrete;
|
||||
@btn-success-bg: @color-blue;
|
||||
@btn-info-bg: @color-asphalt;
|
||||
@btn-warning-bg: @color-red;
|
||||
@btn-danger-bg: @color-red-dark;
|
||||
|
||||
.btn .fa {
|
||||
color: white;}
|
||||
|
||||
.btn-default .fa {
|
||||
color: @gray-dark;}
|
||||
|
||||
/* rgba(0, 0, 0, 0) BG --------------------------------------------------- */
|
||||
/* Used in snippets Prx Image Color and Prx Image Shade ------------- */
|
||||
|
||||
.bg-rgba(0, 0, 0, 0)-color { background: @color-stone; opacity: 0.9;}
|
||||
.bg-rgba(0, 0, 0, 0)-shade { background: black; opacity: 0.5;}
|
||||
|
||||
/* Footer ----------------------------------------------------------- */
|
||||
|
||||
#wrapwrap footer {
|
||||
background-color: @color-concrete-dark;
|
||||
color: @color-concrete;
|
||||
}
|
||||
footer ul li a {
|
||||
color: @color-clouds;
|
||||
}
|
||||
footer ul li a:hover {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
footer h4 {
|
||||
color: @color-silver;
|
||||
padding-bottom: 12px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
footer .fa {
|
||||
color: @color-clouds;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
@font-family-sans-serif: Georgia, "Times New Roman", Times, serif;
|
||||
@font-family-serif: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
@@ -0,0 +1,4 @@
|
||||
#wrapwrap {
|
||||
width: 85%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#wrapwrap {
|
||||
display: table;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
|
||||
> * {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
> footer {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<template id="website_less.snippets" inherit_id="website.snippets">
|
||||
|
||||
<!-- Add name attributes to snippets -->
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Banner']]" position="attributes">
|
||||
<attribute name="name">Banner</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Text-Image']]" position="attributes">
|
||||
<attribute name="name">Text-Image</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Image-Text']]" position="attributes">
|
||||
<attribute name="name">Image-Text</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Image-Floating']]" position="attributes">
|
||||
<attribute name="name">Image-Floating</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Big Message']]" position="attributes">
|
||||
<attribute name="name">Big Message</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Text Block']]" position="attributes">
|
||||
<attribute name="name">Text Block</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Title']]" position="attributes">
|
||||
<attribute name="name">Title</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Features']]" position="attributes">
|
||||
<attribute name="name">Features</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Big Picture']]" position="attributes">
|
||||
<attribute name="name">Big Picture</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Three Columns']]" position="attributes">
|
||||
<attribute name="name">Three Columns</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Well']]" position="attributes">
|
||||
<attribute name="name">Well</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Quote']]" position="attributes">
|
||||
<attribute name="name">Quote</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Panel']]" position="attributes">
|
||||
<attribute name="name">Panel</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Image Floating']]" position="attributes">
|
||||
<attribute name="name">Image Floating</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Separator']]" position="attributes">
|
||||
<attribute name="name">Separator</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Share']]" position="attributes">
|
||||
<attribute name="name">Share</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Image Gallery']]" position="attributes">
|
||||
<attribute name="name">Image Gallery</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Comparisons']]" position="attributes">
|
||||
<attribute name="name">Comparisons</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Button']]" position="attributes">
|
||||
<attribute name="name">Button</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='FAQ']]" position="attributes">
|
||||
<attribute name="name">FAQ</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='References']]" position="attributes">
|
||||
<attribute name="name">References</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Quotes Slider']]" position="attributes">
|
||||
<attribute name="name">Quotes Slider</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Feature Grid']]" position="attributes">
|
||||
<attribute name="name">Feature Grid</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Parallax']]" position="attributes">
|
||||
<attribute name="name">Parallax</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[div[span[@class='oe_snippet_thumbnail_title']][span='Parallax Slider']]" position="attributes">
|
||||
<attribute name="name">Parallax Slider</attribute>
|
||||
</xpath>
|
||||
|
||||
<!-- Add class names on snippets and remove margins classes -->
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Banner']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body carousel slide s_banner</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Text-Image']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_text_image</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Image-Text']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_image_text</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Image-Floating']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body para_large s_image_floating</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Big Message']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body jumbotron s_big_message</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Text Block']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_text_block</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Title']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_title</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Features']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_features</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Big Picture']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body oe_dark s_big_picture</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Three Columns']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_three_columns</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Well']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body well s_well</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Quote']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_quote</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Panel']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body panel panel-default s_panel</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Image Floating']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body o_image_floating o_margin_l pull-right s_image_floating</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Separator']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_separator</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Share']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body oe_share s_share</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Image Gallery']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_image_gallery</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Comparisons']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_comparisons</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Button']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body jumbotron s_button</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='FAQ']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_faq</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='References']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_references</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Quotes Slider']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body carousel quotecarousel slide s_quotes_slider</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Feature Grid']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body s_feature_grid</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Parallax']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body parallax s_parallax</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[span[@class='oe_snippet_thumbnail_title']][span='Parallax Slider']/following-sibling::*[1]" position="attributes">
|
||||
<attribute name="class">oe_snippet_body parallax s_parallax_slider</attribute>
|
||||
</xpath>
|
||||
|
||||
</template>
|
||||
|
||||
<template id="website_less.snippet_options" inherit_id="website.snippet_options">
|
||||
|
||||
<!-- Add new snippet options API attributes to old snippet options -->
|
||||
<xpath expr="//div[@data-snippet-option-id='blog-style']" position="attributes">
|
||||
<attribute name="data-js">blog-style</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='background']" position="attributes">
|
||||
<attribute name="data-js">background</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='carousel']" position="attributes">
|
||||
<attribute name="data-js">carousel</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='margin-y']" position="attributes">
|
||||
<attribute name="data-js">margin-y</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='resize']" position="attributes">
|
||||
<attribute name="data-js">resize</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='margin-x']" position="attributes">
|
||||
<attribute name="data-js">margin-x</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='content']" position="attributes">
|
||||
<attribute name="data-js">content</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='separator']" position="attributes">
|
||||
<attribute name="data-js">separator</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='image_floating_margin']" position="attributes">
|
||||
<attribute name="data-js">image_floating_margin</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='image_floating_hidelink']" position="attributes">
|
||||
<attribute name="data-js">image_floating_hidelink</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='image_floating_side']" position="attributes">
|
||||
<attribute name="data-js">image_floating_side</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='parallax']" position="attributes">
|
||||
<attribute name="data-js">parallax</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='media']" position="attributes">
|
||||
<attribute name="data-js">media</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//div[@data-snippet-option-id='transform']" position="attributes">
|
||||
<attribute name="data-js">transform</attribute>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[@data-js='background']//ul[@class='dropdown-menu']" position="replace">
|
||||
<ul class="dropdown-menu">
|
||||
<li data-background="/website/static/src/img/parallax/parallax_bg.jpg"><a>Sunflower</a></li>
|
||||
<li data-background="/website/static/src/img/banner/business_guy.jpg"><a>Business Guy</a></li>
|
||||
<li data-background="/website/static/src/img/banner/flower_field.jpg"><a>Flowers Field</a></li>
|
||||
<li data-background="/website/static/src/img/banner/landscape.jpg"><a>Landscape</a></li>
|
||||
<li data-background="/website/static/src/img/banner/mountains.jpg"><a>Mountains</a></li>
|
||||
<li data-background="/website/static/src/img/banner/greenfields.jpg"><a>Greenfields</a></li>
|
||||
<li data-background="/website/static/src/img/banner/aqua.jpg"><a>Aqua</a></li>
|
||||
<li data-background="/website/static/src/img/banner/baby_blue.jpg"><a>Baby Blue</a></li>
|
||||
<li data-background="/website/static/src/img/banner/black.jpg"><a>Black</a></li>
|
||||
<li data-background="/website/static/src/img/banner/color_splash.jpg"><a>Color Splash</a></li>
|
||||
<li data-background="/website/static/src/img/banner/mango.jpg"><a>Mango</a></li>
|
||||
<li data-background="/website/static/src/img/banner/orange_red.jpg"><a>Orange Red</a></li>
|
||||
<li data-background="/website/static/src/img/banner/flower.jpg"><a>Purple</a></li>
|
||||
<li data-background="/website/static/src/img/banner/velour.jpg"><a>Velour</a></li>
|
||||
<li data-background="/website/static/src/img/banner/wood.jpg"><a>Wood</a></li>
|
||||
<li data-background="/website/static/src/img/banner/yellow_green.jpg"><a>Yellow Green</a></li>
|
||||
<li data-background="/website/static/src/img/parallax/quote.png"><a>Quote</a></li>
|
||||
<li data-background=""><a>None</a></li>
|
||||
<li><a style="background: none; padding: 5px; border-top: 1px solid #ddd;"></a></li>
|
||||
<li data-choose_image="choose_image"><a><b>Choose an image...</b></a></li>
|
||||
</ul>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="." position="inside">
|
||||
<div data-js='colorpicker' data-selector="section, .carousel, .parallax">
|
||||
<li class="dropdown-submenu">
|
||||
<a tabindex="-1" href="#">Color</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li></li>
|
||||
</ul>
|
||||
</li>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,268 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!--
|
||||
Customize Themes
|
||||
|
||||
Use INPUT type 'checkbox' or 'radio' or use OPTION in select box
|
||||
'data-xmlid' (optional) xml id of the template to add if the input is checked.
|
||||
You can set a list of xml id separate by comma (all template is enable or
|
||||
disable in same time)
|
||||
'data-enable' (optional) to checked one or more HTML ids, or list separate by comma
|
||||
'data-disable' (optional) to unchecked one or more HTML ids, or list separate by comma
|
||||
'data-reload="/"' (optional) force the reloading of the page if the url match with
|
||||
the string ( = regexp).
|
||||
Otherwise, only the '/web/css/website.assets_frontend' is reloaded
|
||||
|
||||
For the sets (data-enable and/or data-disable without data-xmlid), the set is
|
||||
automatically checked if:
|
||||
- all related fields are enabled for data-enable
|
||||
- all related fields are disabled for data-disable
|
||||
else unchecked
|
||||
|
||||
HTML apply classes:
|
||||
- 'checked': on the parent label when input is checked
|
||||
- 'in': on the container (e.g.: bootstrap modal) after added in DOM (removed together
|
||||
out is added)
|
||||
- 'out': on the container 1 second before removed from ths DOM
|
||||
- 'loading': on the container/modal when the new css is loading
|
||||
-->
|
||||
|
||||
<template id="website_less.theme_customize" name="Theme Modal for Customization">
|
||||
<div id="theme_customize_modal" class="modal fade">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<input id="less" data-xmlid="website_less.option_bootstrap_less" style="display: none;"/>
|
||||
|
||||
<div class="loading_backdrop"></div>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close">×</button>
|
||||
<h4 class="modal-title" id="mySmallModalLabel">Customize your theme</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<h5 class="modal-h5">LAYOUT</h5>
|
||||
<table name="layout">
|
||||
<tr>
|
||||
<td class=" text-center" width="50%">
|
||||
<label class=" center-block">
|
||||
<div class="text-center" style="background-image: url(/website_less/static/src/img/theme/layout-full.gif); background-size: 100%; line-height: 40px;">FULL WIDTH</div>
|
||||
<input name="layoutvar" type="radio" data-xmlid=""/>
|
||||
</label>
|
||||
</td>
|
||||
<td class=" text-center">
|
||||
<label class=" center-block">
|
||||
<div class="text-center" style="background-image: url(/website_less/static/src/img/theme/layout-boxed.gif); background-size: 100%; line-height: 40px;">BOXED</div>
|
||||
<input name="layoutvar" type="radio" data-xmlid="website_less.option_layout_boxed" data-enable="less"/>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h5 class="modal-h5">MAIN COLOR</h5>
|
||||
<table name="color">
|
||||
<tr>
|
||||
<td>
|
||||
<label class="chd-color-combi">
|
||||
<img src="/website_less/static/src/img/theme/variant-stone.gif" alt="Stone" class="chd-color-combi-img"/>
|
||||
<input name="colorvar" type="radio" data-xmlid="" data-disable="less"/>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<label class="chd-color-combi">
|
||||
<img src="/website_less/static/src/img/theme/variant-emerald.gif" alt="Emerald" class="chd-color-combi-img"/>
|
||||
<input name="colorvar" type="radio" data-xmlid="website_less.option_color_emerald" data-enable="less"/>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<label class="chd-color-combi">
|
||||
<img src="/website_less/static/src/img/theme/variant-cobalt.gif" alt="Cobalt" class="chd-color-combi-img"/>
|
||||
<input name="colorvar" type="radio" data-xmlid="website_less.option_color_cobalt" data-enable="less"/>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<label class="chd-color-combi">
|
||||
<img src="/website_less/static/src/img/theme/variant-amethyst.gif" alt="Amethyst" class="chd-color-combi-img"/>
|
||||
<input name="colorvar" type="radio" data-xmlid="website_less.option_color_amethyst" data-enable="less"/>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<label class="chd-color-combi">
|
||||
<img src="/website_less/static/src/img/theme/variant-ruby.gif" alt="Blue" class="chd-color-combi-img"/>
|
||||
<input name="colorvar" type="radio" data-xmlid="website_less.option_color_ruby" data-enable="less"/>
|
||||
</label>
|
||||
</td>
|
||||
<td>
|
||||
<label class="chd-color-combi">
|
||||
<img src="/website_less/static/src/img/theme/variant-gold.gif" alt="Gold" class="chd-color-combi-img"/>
|
||||
<input name="colorvar" type="radio" data-xmlid="website_less.option_color_gold" data-enable="less"/>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h5 class="modal-h5">FONTS COMBINATIONS</h5>
|
||||
<table name="font">
|
||||
<tr>
|
||||
<td width="50%">
|
||||
<label>
|
||||
<div>
|
||||
<span style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif; font-size:11px">Helvetica</span>
|
||||
<span style="font-family:Georgia, 'Times New Roman', Times, serif; font-size:11px" >/ Georgia</span>
|
||||
</div>
|
||||
<input name="theme" type="radio" data-xmlid=""/>
|
||||
</label>
|
||||
</td>
|
||||
<td width="50%">
|
||||
<label>
|
||||
<div>
|
||||
<span style="font-family:Georgia, 'Times New Roman', Times, serif; font-size:11px" >Georgia</span>
|
||||
<span style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif; font-size:11px">/ Helvetica</span>
|
||||
<input name="theme" type="radio" data-xmlid="website_less.option_font" data-enable="less"/>
|
||||
</div>
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- color-picker -->
|
||||
<!-- HTML class to hide option for one mode : only-text, only-bg -->
|
||||
|
||||
<template id="website_less.colorpicker" name="Color-Picker">
|
||||
<table class="colorpicker">
|
||||
<tr>
|
||||
<td><button class="automatic-color" title="Automatic Color"/></td>
|
||||
<td><button class="bg-primary" title="Primary Color"/></td>
|
||||
<td><button class="bg-success" title="Success Color"/></td>
|
||||
<td><button class="bg-info" title="Info Color"/></td>
|
||||
<td><button class="bg-warning" title="Warning Color"/></td>
|
||||
<td><button class="bg-danger" title="Danger Color"/></td>
|
||||
</tr>
|
||||
<tr><td colspan="8"><hr style="width: 100%; height: 1px;"/></td></tr>
|
||||
<tr>
|
||||
<td><button class="bg-blue"/></td>
|
||||
<td><button class="bg-turquoise"/></td>
|
||||
<td><button class="bg-green"/></td>
|
||||
<td><button class="bg-yellow"/></td>
|
||||
<td><button class="bg-red"/></td>
|
||||
<td><button class="bg-pink"/></td>
|
||||
<td><button class="bg-purple"/></td>
|
||||
<td><button class="bg-brown"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<!-- Disable old themes before activating the less option -->
|
||||
<record id="website.theme_amelia" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
<record id="website.theme_cerulean" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
<record id="website.theme_cosmo" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
<record id="website.theme_cyborg" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
<record id="website.theme_flatly" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
<record id="website.theme_journal" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
<record id="website.theme_readable" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
<record id="website.theme_simplex" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
<record id="website.theme_slate" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
<record id="website.theme_spacelab" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
<record id="website.theme_united" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
<record id="website.theme_yeti" model="ir.ui.view">
|
||||
<field name="active" eval='False'/>
|
||||
</record>
|
||||
|
||||
<!-- Bootstrap Less File layout
|
||||
|
||||
Each theme module must override the following view to active bootstrap:
|
||||
<record id="website_less.option_bootstrap_less" model="ir.ui.view">
|
||||
<field name="active" eval='True'/>
|
||||
</record>
|
||||
-->
|
||||
<template id="website_less.option_bootstrap_less" name="option_bootstrap_less" inherit_id="website.theme" active="True" customize_show="False">
|
||||
<xpath expr="//link[@id='bootstrap_css']" position="replace">
|
||||
<link rel="stylesheet" href='/website_less/static/src/less/import_bootstrap.less'/>
|
||||
<link rel="stylesheet" href='/website_less/static/src/less/colors.less' t-ignore="true"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Default Options Toggle -->
|
||||
<template id="website_less.default_options" name="Default Customize Options" inherit_id="website.theme">
|
||||
<xpath expr="//link[last()]" position="after">
|
||||
<!-- Default options inherit from this view so we can easily disable it to reset all options -->
|
||||
<t id="default_options" t-if="True"></t>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Option layout -->
|
||||
|
||||
<template id="website_less.option_layout_boxed" name="option_layout_boxed" inherit_id="website_less.default_options" active="False" customize_show="True">
|
||||
<xpath expr="//t[@id='default_options']" position="inside">
|
||||
<link href="/website_less/static/src/less/option_layout_boxed.less" rel="stylesheet" type="text/less"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Option color -->
|
||||
|
||||
<template id="website_less.option_color_stone" name="option_color_stone" inherit_id="website_less.default_options" active="False" customize_show="True">
|
||||
<xpath expr="//t[@id='default_options']" position="inside">
|
||||
<link href="/website_less/static/src/less/option_color_stone.less" rel="stylesheet" type="text/less"/>
|
||||
</xpath>
|
||||
</template>
|
||||
<template id="website_less.option_color_emerald" name="option_color_emerald" inherit_id="website_less.default_options" active="False" customize_show="True">
|
||||
<xpath expr="//t[@id='default_options']" position="inside">
|
||||
<link href="/website_less/static/src/less/option_color_emerald.less" rel="stylesheet" type="text/less"/>
|
||||
</xpath>
|
||||
</template>
|
||||
<template id="website_less.option_color_cobalt" name="option_color_cobalt" inherit_id="website_less.default_options" active="False" customize_show="True">
|
||||
<xpath expr="//t[@id='default_options']" position="inside">
|
||||
<link href="/website_less/static/src/less/option_color_cobalt.less" rel="stylesheet" type="text/less"/>
|
||||
</xpath>
|
||||
</template>
|
||||
<template id="website_less.option_color_amethyst" name="option_color_amethyst" inherit_id="website_less.default_options" active="False" customize_show="True">
|
||||
<xpath expr="//t[@id='default_options']" position="inside">
|
||||
<link href="/website_less/static/src/less/option_color_amethyst.less" rel="stylesheet" type="text/less"/>
|
||||
</xpath>
|
||||
</template>
|
||||
<template id="website_less.option_color_ruby" name="option_color_ruby" inherit_id="website_less.default_options" active="False" customize_show="True">
|
||||
<xpath expr="//t[@id='default_options']" position="inside">
|
||||
<link href="/website_less/static/src/less/option_color_ruby.less" rel="stylesheet" type="text/less"/>
|
||||
</xpath>
|
||||
</template>
|
||||
<template id="website_less.option_color_gold" name="option_color_gold" inherit_id="website_less.default_options" active="False" customize_show="True">
|
||||
<xpath expr="//t[@id='default_options']" position="inside">
|
||||
<link href="/website_less/static/src/less/option_color_gold.less" rel="stylesheet" type="text/less"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="website_less.option_font" name="option_font" inherit_id="website_less.default_options" active="False" customize_show="True">
|
||||
<xpath expr="//t[@id='default_options']" position="inside">
|
||||
<link href="/website_less/static/src/less/option_font.less" rel="stylesheet" type="text/less"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,16 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<template id="website_less.user_navbar" inherit_id="website.user_navbar">
|
||||
<xpath expr="//ul[@class='dropdown-menu' and @role='menu']" position="replace">
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li id="html_editor"><a href="#advanced-view-editor" data-action='ace'>HTML Editor</a></li>
|
||||
<li id="theme_customize"><a href="#">Customize Theme</a></li>
|
||||
<li id="install_apps"><a href="/web#return_label=Website&action=website.action_module_website">Install Apps</a></li>
|
||||
<li class="divider"></li>
|
||||
</ul>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,45 @@
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<template id="website_less.theme" inherit_id="website.theme" name="Fix table-row in theme">
|
||||
<xpath expr='//link[@href="/website/static/src/css/website.css"]' position="after">
|
||||
<link rel="stylesheet" href='/website_less/static/src/less/website.less'/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="website_less.assets_editor" inherit_id="website.assets_editor" name="Editor assets for Less">
|
||||
<xpath expr='//link[@href="/website/static/src/css/editor.css"]' position="replace">
|
||||
<link rel='stylesheet' href='/website_less/static/src/css/editor.css'/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr='//link[@href="/website/static/src/css/snippets.css"]' position="replace">
|
||||
<link rel='stylesheet' href='/website_less/static/src/css/snippets.css'/>
|
||||
</xpath>
|
||||
|
||||
<xpath expr='//script[@src="/website/static/src/js/website.editor.js"]' position="after">
|
||||
<script type="text/javascript" src="/website_less/static/src/js/website.editor.js"></script>
|
||||
</xpath>
|
||||
|
||||
<xpath expr='//script[@src="/website/static/src/js/website.snippets.editor.js"]' position="replace">
|
||||
<script type="text/javascript" src="/website_less/static/src/js/website.snippets.editor.js"></script>
|
||||
</xpath>
|
||||
|
||||
<xpath expr='//link[last()]' position="after">
|
||||
<script type="text/javascript" src="/website_less/static/src/js/website.theme.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="website_less.assets_frontend" inherit_id="website.assets_frontend">
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/website_less/static/src/js/website.snippets.animation.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="website_less.footer_default" inherit_id="website.footer_default">
|
||||
<xpath expr='//div[@class="container hidden-print"]' position="attributes">
|
||||
<attribute name="id">footer</attribute>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -0,0 +1,132 @@
|
||||
import os
|
||||
import time
|
||||
import hashlib
|
||||
import datetime
|
||||
import cStringIO
|
||||
from PIL import Image
|
||||
from sys import maxint
|
||||
|
||||
import openerp
|
||||
from openerp.osv import osv, orm
|
||||
from openerp.addons.web.http import request
|
||||
from openerp.tools import image_resize_and_sharpen, image_save_for_web
|
||||
|
||||
|
||||
class website(osv.osv):
|
||||
_inherit = "website"
|
||||
|
||||
def _image(self, cr, uid, model, id, field, response, max_width=maxint, max_height=maxint, cache=None, context=None):
|
||||
""" Fetches the requested field and ensures it does not go above
|
||||
(max_width, max_height), resizing it if necessary.
|
||||
|
||||
Resizing is bypassed if the object provides a $field_big, which will
|
||||
be interpreted as a pre-resized version of the base field.
|
||||
|
||||
If the record is not found or does not have the requested field,
|
||||
returns a placeholder image via :meth:`~._image_placeholder`.
|
||||
|
||||
Sets and checks conditional response parameters:
|
||||
* :mailheader:`ETag` is always set (and checked)
|
||||
* :mailheader:`Last-Modified is set iif the record has a concurrency
|
||||
field (``__last_update``)
|
||||
|
||||
The requested field is assumed to be base64-encoded image data in
|
||||
all cases.
|
||||
"""
|
||||
Model = self.pool[model]
|
||||
id = int(id)
|
||||
|
||||
ids = Model.search(cr, uid,
|
||||
[('id', '=', id)], context=context)
|
||||
if not ids and 'website_published' in Model._fields:
|
||||
ids = Model.search(cr, openerp.SUPERUSER_ID,
|
||||
[('id', '=', id), ('website_published', '=', True)], context=context)
|
||||
if not ids:
|
||||
return self._image_placeholder(response)
|
||||
|
||||
concurrency = '__last_update'
|
||||
[record] = Model.read(cr, openerp.SUPERUSER_ID, [id],
|
||||
[concurrency, field],
|
||||
context=context)
|
||||
|
||||
if concurrency in record:
|
||||
server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT
|
||||
try:
|
||||
response.last_modified = datetime.datetime.strptime(
|
||||
record[concurrency], server_format + '.%f')
|
||||
except ValueError:
|
||||
# just in case we have a timestamp without microseconds
|
||||
response.last_modified = datetime.datetime.strptime(
|
||||
record[concurrency], server_format)
|
||||
|
||||
# Field does not exist on model or field set to False
|
||||
if not record.get(field):
|
||||
# FIXME: maybe a field which does not exist should be a 404?
|
||||
return self._image_placeholder(response)
|
||||
|
||||
response.set_etag(hashlib.sha1(record[field]).hexdigest())
|
||||
response.make_conditional(request.httprequest)
|
||||
|
||||
if cache:
|
||||
response.cache_control.max_age = cache
|
||||
response.expires = int(time.time() + cache)
|
||||
|
||||
# conditional request match
|
||||
if response.status_code == 304:
|
||||
return response
|
||||
|
||||
if model == 'ir.attachment' and field == 'url':
|
||||
path = record.get(field).strip('/')
|
||||
|
||||
# Check that we serve a file from within the module
|
||||
if os.path.normpath(path).startswith('..'):
|
||||
return self._image_placeholder(response)
|
||||
|
||||
# Check that the file actually exists
|
||||
path = path.split('/')
|
||||
resource = openerp.modules.get_module_resource(path[0], *path[1:])
|
||||
if not resource:
|
||||
return self._image_placeholder(response)
|
||||
|
||||
data = open(resource, 'rb').read()
|
||||
else:
|
||||
data = record[field].decode('base64')
|
||||
image = Image.open(cStringIO.StringIO(data))
|
||||
response.mimetype = Image.MIME[image.format]
|
||||
|
||||
filename = '%s_%s.%s' % (model.replace('.', '_'), id, str(image.format).lower())
|
||||
response.headers['Content-Disposition'] = 'inline; filename="%s"' % filename
|
||||
|
||||
if (not max_width) and (not max_height):
|
||||
response.data = data
|
||||
return response
|
||||
|
||||
w, h = image.size
|
||||
max_w = int(max_width) if max_width else maxint
|
||||
max_h = int(max_height) if max_height else maxint
|
||||
|
||||
if w < max_w and h < max_h:
|
||||
response.data = data
|
||||
else:
|
||||
size = (max_w, max_h)
|
||||
img = image_resize_and_sharpen(image, size, preserve_aspect_ratio=True)
|
||||
image_save_for_web(img, response.stream, format=image.format)
|
||||
# invalidate content-length computed by make_conditional as
|
||||
# writing to response.stream does not do it (as of werkzeug 0.9.3)
|
||||
del response.headers['Content-Length']
|
||||
|
||||
return response
|
||||
|
||||
class ir_http(orm.AbstractModel):
|
||||
_inherit = 'ir.http'
|
||||
|
||||
def _serve_attachment(self):
|
||||
response = super(ir_http, self)._serve_attachment()
|
||||
if response and response.mimetype == 'application/octet-stream':
|
||||
# Try to set mimetype via attachment mimetype field
|
||||
attach = self.pool['ir.attachment'].search_read(request.cr, openerp.SUPERUSER_ID,
|
||||
[('type', '=', 'binary'), ('url', '=', request.httprequest.path)],
|
||||
['mimetype'], context=request.context)
|
||||
if attach and attach[0].get('mimetype'):
|
||||
response.mimetype = attach[0].get('mimetype')
|
||||
return response
|
||||