[ADD] theme 8.0

This commit is contained in:
Design
2021-05-11 15:41:12 +02:00
committed by Jeremy Kersten
commit 51c615247e
3583 changed files with 121845 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
import ir_qweb
import ir_attachment
import controllers
import website
+22
View File
@@ -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,
}
+1
View File
@@ -0,0 +1 @@
import main
+149
View File
@@ -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)
+34
View File
@@ -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
+13
View File
@@ -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)
+344
View File
@@ -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]
+653
View File
@@ -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;
}
+565
View File
@@ -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:
+727
View File
@@ -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;
}
+590
View File
@@ -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
}
// }}}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

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');
});
})();
File diff suppressed because it is too large Load Diff
+289
View File
@@ -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 = "";
}
});
})();
+95
View File
@@ -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;
}
+13
View File
@@ -0,0 +1,13 @@
#wrapwrap {
display: table;
table-layout: fixed;
width: 100%;
> * {
display: table-row;
}
> footer {
height: 100%;
}
}
+294
View File
@@ -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>
+268
View File
@@ -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&amp;action=website.action_module_website">Install Apps</a></li>
<li class="divider"></li>
</ul>
</xpath>
</template>
</data>
</openerp>
+45
View File
@@ -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>
+132
View File
@@ -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