[MERGE] merge with latest trunk

bzr revid: rma@tinyerp.com-20140407100240-vk43kganr5g0gz5i
This commit is contained in:
Randhir Mayatra rma-openerp 2014-04-07 15:32:40 +05:30
commit c037ebb362
368 changed files with 1524 additions and 1384 deletions

View File

@ -6,6 +6,3 @@ sys.modules['openerp.addons.web.http'] = openerp.http
http = openerp.http http = openerp.http
import controllers import controllers
import cli
wsgi_postload = http.wsgi_postload

View File

@ -11,7 +11,6 @@ This module provides the core of the OpenERP Web Client.
""", """,
'depends': ['base'], 'depends': ['base'],
'auto_install': True, 'auto_install': True,
'post_load': 'wsgi_postload',
'data': [ 'data': [
'views/webclient_templates.xml', 'views/webclient_templates.xml',
], ],
@ -87,7 +86,6 @@ This module provides the core of the OpenERP Web Client.
"static/test/data.js", "static/test/data.js",
"static/test/list-utils.js", "static/test/list-utils.js",
"static/test/formats.js", "static/test/formats.js",
"static/test/jsonrpc.js",
"static/test/rpc-misordered.js", "static/test/rpc-misordered.js",
"static/test/evals.js", "static/test/evals.js",
"static/test/search.js", "static/test/search.js",

View File

@ -1 +0,0 @@
import test_js

View File

@ -1,35 +0,0 @@
import logging
import optparse
import sys
import unittest2
import openerp
import openerp.addons.web.tests
_logger = logging.getLogger(__name__)
class TestJs(openerp.cli.Command):
def run(self, args):
self.parser = parser = optparse.OptionParser()
parser.add_option("-d", "--database", dest="db_name", default=False, help="specify the database name")
parser.add_option("--xmlrpc-port", dest="xmlrpc_port", default=8069, help="specify the TCP port for the XML-RPC protocol", type="int")
# proably need to add both --superadmin-password and --database-admin-password
self.parser.parse_args(args)
# test ony uses db_name xmlrpc_port admin_passwd, so use the server one for the actual parsing
config = openerp.tools.config
config.parse_config(args)
# needed until runbot is fixed
config['db_password'] = config['admin_passwd']
# run js tests
openerp.netsvc.init_alternative_logger()
suite = unittest2.TestSuite()
suite.addTests(unittest2.TestLoader().loadTestsFromModule(openerp.addons.web.tests.test_js))
r = unittest2.TextTestRunner(verbosity=2).run(suite)
if r.errors or r.failures:
sys.exit(1)
# vim:et:ts=4:sw=4:

View File

@ -14,6 +14,7 @@ import hashlib
import os import os
import re import re
import simplejson import simplejson
import sys
import time import time
import urllib2 import urllib2
import zlib import zlib
@ -37,10 +38,14 @@ from openerp.http import request, serialize_exception as _serialize_exception
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
env = jinja2.Environment( if hasattr(sys, 'frozen'):
loader=jinja2.PackageLoader('openerp.addons.web', "views"), # When running on compiled windows binary, we don't have access to package loader.
autoescape=True path = os.path.realpath(os.path.join(os.path.dirname(__file__), '..', 'views'))
) loader = jinja2.FileSystemLoader(path)
else:
loader = jinja2.PackageLoader('openerp.addons.web', "views")
env = jinja2.Environment(loader=loader, autoescape=True)
env.filters["json"] = simplejson.dumps env.filters["json"] = simplejson.dumps
#---------------------------------------------------------- #----------------------------------------------------------
@ -359,7 +364,13 @@ def manifest_glob(extension, addons=None, db=None, include_remotes=False):
r.append((None, pattern)) r.append((None, pattern))
else: else:
for path in glob.glob(os.path.normpath(os.path.join(addons_path, addon, pattern))): for path in glob.glob(os.path.normpath(os.path.join(addons_path, addon, pattern))):
r.append((path, fs2web(path[len(addons_path):]))) # Hack for IE, who limit 288Ko, 4095 rules, 31 sheets
# http://support.microsoft.com/kb/262161/en
if pattern == "static/lib/bootstrap/css/bootstrap.css":
if include_remotes:
r.insert(0, (None, fs2web(path[len(addons_path):])))
else:
r.append((path, fs2web(path[len(addons_path):])))
return r return r
def manifest_list(extension, mods=None, db=None, debug=False): def manifest_list(extension, mods=None, db=None, debug=False):
@ -424,6 +435,15 @@ def set_cookie_and_redirect(redirect_url):
redirect.autocorrect_location_header = False redirect.autocorrect_location_header = False
return redirect return redirect
def login_redirect():
url = '/web/login?'
if request.debug:
url += 'debug&'
return """<html><head><script>
window.location = '%sredirect=' + encodeURIComponent(window.location);
</script></head></html>
""" % (url,)
def load_actions_from_ir_values(key, key2, models, meta): def load_actions_from_ir_values(key, key2, models, meta):
Values = request.session.model('ir.values') Values = request.session.model('ir.values')
actions = Values.get(key, key2, models, meta, request.context) actions = Values.get(key, key2, models, meta, request.context)
@ -622,7 +642,7 @@ class Home(http.Controller):
@http.route('/', type='http', auth="none") @http.route('/', type='http', auth="none")
def index(self, s_action=None, db=None, **kw): def index(self, s_action=None, db=None, **kw):
return http.local_redirect('/web', query=request.params) return http.local_redirect('/web', query=request.params, keep_hash=True)
@http.route('/web', type='http', auth="none") @http.route('/web', type='http', auth="none")
def web_client(self, s_action=None, **kw): def web_client(self, s_action=None, **kw):
@ -635,7 +655,7 @@ class Home(http.Controller):
} }
return render_bootstrap_template("web.webclient_bootstrap", headers=headers) return render_bootstrap_template("web.webclient_bootstrap", headers=headers)
else: else:
return http.local_redirect('/web/login', query=request.params) return login_redirect()
@http.route('/web/login', type='http', auth="none") @http.route('/web/login', type='http', auth="none")
def web_login(self, redirect=None, **kw): def web_login(self, redirect=None, **kw):
@ -930,10 +950,11 @@ class Database(http.Controller):
return simplejson.dumps([[],[{'error': openerp.tools.ustr(e), 'title': _('Backup Database')}]]) return simplejson.dumps([[],[{'error': openerp.tools.ustr(e), 'title': _('Backup Database')}]])
@http.route('/web/database/restore', type='http', auth="none") @http.route('/web/database/restore', type='http', auth="none")
def restore(self, db_file, restore_pwd, new_db): def restore(self, db_file, restore_pwd, new_db, mode):
try: try:
copy = mode == 'copy'
data = base64.b64encode(db_file.read()) data = base64.b64encode(db_file.read())
request.session.proxy("db").restore(restore_pwd, new_db, data) request.session.proxy("db").restore(restore_pwd, new_db, data, copy)
return '' return ''
except openerp.exceptions.AccessDenied, e: except openerp.exceptions.AccessDenied, e:
raise Exception("AccessDenied") raise Exception("AccessDenied")
@ -1589,8 +1610,8 @@ class Export(http.Controller):
model, map(operator.itemgetter('name'), export_fields_list)) model, map(operator.itemgetter('name'), export_fields_list))
return [ return [
{'name': field_name, 'label': fields_data[field_name]} {'name': field['name'], 'label': fields_data[field['name']]}
for field_name in fields_data.keys() for field in export_fields_list
] ]
def fields_info(self, model, export_fields): def fields_info(self, model, export_fields):
@ -1649,6 +1670,8 @@ class Export(http.Controller):
for k, v in self.fields_info(model, export_fields).iteritems()) for k, v in self.fields_info(model, export_fields).iteritems())
class ExportFormat(object): class ExportFormat(object):
raw_data = False
@property @property
def content_type(self): def content_type(self):
""" Provides the format's content type """ """ Provides the format's content type """
@ -1681,7 +1704,7 @@ class ExportFormat(object):
ids = ids or Model.search(domain, 0, False, False, request.context) ids = ids or Model.search(domain, 0, False, False, request.context)
field_names = map(operator.itemgetter('name'), fields) field_names = map(operator.itemgetter('name'), fields)
import_data = Model.export_data(ids, field_names, request.context).get('datas',[]) import_data = Model.export_data(ids, field_names, self.raw_data, context=request.context).get('datas',[])
if import_compat: if import_compat:
columns_headers = field_names columns_headers = field_names
@ -1734,6 +1757,8 @@ class CSVExport(ExportFormat, http.Controller):
return data return data
class ExcelExport(ExportFormat, http.Controller): class ExcelExport(ExportFormat, http.Controller):
# Excel needs raw data to correctly handle numbers and date values
raw_data = True
@http.route('/web/export/xls', type='http', auth="user") @http.route('/web/export/xls', type='http', auth="user")
@serialize_exception @serialize_exception
@ -1755,14 +1780,20 @@ class ExcelExport(ExportFormat, http.Controller):
worksheet.write(0, i, fieldname) worksheet.write(0, i, fieldname)
worksheet.col(i).width = 8000 # around 220 pixels worksheet.col(i).width = 8000 # around 220 pixels
style = xlwt.easyxf('align: wrap yes') base_style = xlwt.easyxf('align: wrap yes')
date_style = xlwt.easyxf('align: wrap yes', num_format_str='YYYY-MM-DD')
datetime_style = xlwt.easyxf('align: wrap yes', num_format_str='YYYY-MM-DD HH:mm:SS')
for row_index, row in enumerate(rows): for row_index, row in enumerate(rows):
for cell_index, cell_value in enumerate(row): for cell_index, cell_value in enumerate(row):
cell_style = base_style
if isinstance(cell_value, basestring): if isinstance(cell_value, basestring):
cell_value = re.sub("\r", " ", cell_value) cell_value = re.sub("\r", " ", cell_value)
if cell_value is False: cell_value = None elif isinstance(cell_value, datetime.datetime):
worksheet.write(row_index + 1, cell_index, cell_value, style) cell_style = datetime_style
elif isinstance(cell_value, datetime.date):
cell_style = date_style
worksheet.write(row_index + 1, cell_index, cell_value, cell_style)
fp = StringIO() fp = StringIO()
workbook.save(fp) workbook.save(fp)

View File

@ -157,10 +157,3 @@ class TestRunnerController(http.Controller):
# replace OS path separators (from join & normpath) by URI ones # replace OS path separators (from join & normpath) by URI ones
yield path[len(root):].replace(os.path.sep, '/') yield path[len(root):].replace(os.path.sep, '/')
@http.route('/web/tests/set_session_value', type='json', auth="none")
def set_session_value(self, value):
request.session.some_test_value = value
@http.route('/web/tests/get_session_value', type='json', auth="none")
def get_session_value(self):
return request.session.some_test_value

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:06+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -1849,7 +1849,7 @@ msgstr "الافتراضي"
#: code:addons/web/static/src/xml/base.xml:468 #: code:addons/web/static/src/xml/base.xml:468
#, python-format #, python-format
msgid "OpenERP" msgid "OpenERP"
msgstr "كروز" msgstr "OpenERP"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -2213,7 +2213,7 @@ msgstr "زر"
#: code:addons/web/static/src/xml/base.xml:440 #: code:addons/web/static/src/xml/base.xml:440
#, python-format #, python-format
msgid "OpenERP is a trademark of the" msgid "OpenERP is a trademark of the"
msgstr "كروز علامة تجارية ملك" msgstr "OpenERP علامة تجارية ملك"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -2241,7 +2241,7 @@ msgstr "False"
#: code:addons/web/static/src/xml/base.xml:426 #: code:addons/web/static/src/xml/base.xml:426
#, python-format #, python-format
msgid "About OpenERP" msgid "About OpenERP"
msgstr "حول كروز" msgstr "حول OpenERP"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:06+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:06+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:06+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:06+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:06+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
"X-Poedit-Language: Czech\n" "X-Poedit-Language: Czech\n"
#. module: web #. module: web
@ -1610,7 +1610,7 @@ msgstr "Mažu databázi"
#: code:addons/web/static/src/xml/base.xml:467 #: code:addons/web/static/src/xml/base.xml:467
#, python-format #, python-format
msgid "Powered by" msgid "Powered by"
msgstr "" msgstr "Založeno na"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
"Language: es\n" "Language: es\n"
#. module: web #. module: web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:06+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,15 +14,15 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web
#: code:addons/web/static/src/xml/base.xml:147 #: code:addons/web/static/src/xml/base.xml:147
#, python-format #, python-format
msgid "Default language:" msgid "Default language:"
msgstr "デフォルト言語:" msgstr "デフォルト言語:"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -503,7 +503,7 @@ msgstr "ログ (perm_read) のビュー"
#: code:addons/web/static/src/js/view_form.js:1071 #: code:addons/web/static/src/js/view_form.js:1071
#, python-format #, python-format
msgid "Set Default" msgid "Set Default"
msgstr "デフォルト設定" msgstr "デフォルト設定"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -524,7 +524,7 @@ msgstr "数十秒前"
#: code:addons/web/static/src/xml/base.xml:873 #: code:addons/web/static/src/xml/base.xml:873
#, python-format #, python-format
msgid "Condition:" msgid "Condition:"
msgstr "状態:" msgstr "条件:"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -1564,7 +1564,7 @@ msgstr ""
#: code:addons/web/static/src/xml/base.xml:899 #: code:addons/web/static/src/xml/base.xml:899
#, python-format #, python-format
msgid "All users" msgid "All users"
msgstr "全てのユーザ" msgstr "全ユーザ"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -1664,7 +1664,7 @@ msgstr ""
#: code:addons/web/static/src/js/view_form.js:1078 #: code:addons/web/static/src/js/view_form.js:1078
#, python-format #, python-format
msgid "Save default" msgid "Save default"
msgstr "デフォルト保存" msgstr "デフォルト保存"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -1693,7 +1693,7 @@ msgstr "項目は空です。何も保存するものはありません。"
#: code:addons/web/static/src/xml/base.xml:567 #: code:addons/web/static/src/xml/base.xml:567
#, python-format #, python-format
msgid "Manage Views" msgid "Manage Views"
msgstr "ビュー管理" msgstr "ビュー管理"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -1757,7 +1757,7 @@ msgstr "次の理由でインポートに失敗しました:"
#: code:addons/web/static/src/xml/base.xml:561 #: code:addons/web/static/src/xml/base.xml:561
#, python-format #, python-format
msgid "JS Tests" msgid "JS Tests"
msgstr "" msgstr "JSテスト"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -1836,7 +1836,7 @@ msgstr "ドメイン:"
#: code:addons/web/static/src/xml/base.xml:856 #: code:addons/web/static/src/xml/base.xml:856
#, python-format #, python-format
msgid "Default:" msgid "Default:"
msgstr "デフォルト:" msgstr "デフォルト"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -1928,7 +1928,7 @@ msgstr ""
#: code:addons/web/static/src/xml/base.xml:559 #: code:addons/web/static/src/xml/base.xml:559
#, python-format #, python-format
msgid "Set Defaults" msgid "Set Defaults"
msgstr "" msgstr "デフォルト値設定"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -2417,7 +2417,7 @@ msgstr "ID"
#: code:addons/web/static/src/xml/base.xml:892 #: code:addons/web/static/src/xml/base.xml:892
#, python-format #, python-format
msgid "Only you" msgid "Only you"
msgstr "あなただけ" msgstr "自分のみ"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -2334,7 +2334,7 @@ msgstr "'%s' нь хөрвүүлэх боломжгүй огноо, огнооц
#: code:addons/web/static/src/xml/base.xml:325 #: code:addons/web/static/src/xml/base.xml:325
#, python-format #, python-format
msgid "Duplicate" msgid "Duplicate"
msgstr "Хувилах" msgstr "Хуулбарлан үүсгэх"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:31+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:07+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -15,8 +15,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:32+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:30+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:06+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,15 +14,15 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web
#: code:addons/web/static/src/xml/base.xml:147 #: code:addons/web/static/src/xml/base.xml:147
#, python-format #, python-format
msgid "Default language:" msgid "Default language:"
msgstr "ภาษาหลัก:" msgstr "ภาษาหลัก"
#. module: web #. module: web
#. openerp-web #. openerp-web
@ -475,7 +475,7 @@ msgstr "เปิดใช้งานโหมดนักพัฒนา"
#: code:addons/web/static/src/js/chrome.js:341 #: code:addons/web/static/src/js/chrome.js:341
#, python-format #, python-format
msgid "Loading (%d)" msgid "Loading (%d)"
msgstr "กำลังโหลด (% d)" msgstr "กำลังโหลด (%d)"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:08+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web #. module: web
#. openerp-web #. openerp-web

View File

@ -6,7 +6,7 @@
.cleditorButton {float:left; width:24px; height:24px; margin:1px 0 1px 0; background: url('images/buttons.gif')} .cleditorButton {float:left; width:24px; height:24px; margin:1px 0 1px 0; background: url('images/buttons.gif')}
.cleditorDisabled {opacity:0.3; filter:alpha(opacity=30)} .cleditorDisabled {opacity:0.3; filter:alpha(opacity=30)}
.cleditorDivider {float:left; width:1px; height:23px; margin:1px 0 1px 0; background:#CCC} .cleditorDivider {float:left; width:1px; height:23px; margin:1px 0 1px 0; background:#CCC}
.cleditorPopup {border:solid 1px #999; background-color:white; position:absolute; font:10pt Arial,Verdana; cursor:default; z-index:10000} .cleditorPopup {border:solid 1px #999; background-color:white; color:#333333; position:absolute; font:10pt Arial,Verdana; cursor:default; z-index:10000}
.cleditorList div {padding:2px 4px 2px 4px} .cleditorList div {padding:2px 4px 2px 4px}
.cleditorList p, .cleditorList p,
.cleditorList h1, .cleditorList h1,

View File

@ -1,18 +1,13 @@
/** /*!
@preserve CLEditor WYSIWYG HTML Editor v1.3.0 CLEditor WYSIWYG HTML Editor v1.4.4
http://premiumsoftware.net/cleditor http://premiumsoftware.net/CLEditor
requires jQuery v1.4.2 or later requires jQuery v1.4.2 or later
Copyright 2010, Chris Landowski, Premium Software, LLC Copyright 2010, Chris Landowski, Premium Software, LLC
Dual licensed under the MIT or GPL Version 2 licenses. Dual licensed under the MIT or GPL Version 2 licenses.
*/ */
// ==ClosureCompiler== (function ($) {
// @compilation_level SIMPLE_OPTIMIZATIONS
// @output_file_name jquery.cleditor.min.js
// ==/ClosureCompiler==
(function($) {
//============== //==============
// jQuery Plugin // jQuery Plugin
@ -22,7 +17,7 @@
// Define the defaults used for all new cleditor instances // Define the defaults used for all new cleditor instances
defaultOptions: { defaultOptions: {
width: 500, // width not including margins, borders or padding width: 'auto', // width not including margins, borders or padding
height: 250, // height not including margins, borders or padding height: 250, // height not including margins, borders or padding
controls: // controls to add to the toolbar controls: // controls to add to the toolbar
"bold italic underline strikethrough subscript superscript | font size " + "bold italic underline strikethrough subscript superscript | font size " +
@ -46,7 +41,7 @@
[["Paragraph", "<p>"], ["Header 1", "<h1>"], ["Header 2", "<h2>"], [["Paragraph", "<p>"], ["Header 1", "<h1>"], ["Header 2", "<h2>"],
["Header 3", "<h3>"], ["Header 4","<h4>"], ["Header 5","<h5>"], ["Header 3", "<h3>"], ["Header 4","<h4>"], ["Header 5","<h5>"],
["Header 6","<h6>"]], ["Header 6","<h6>"]],
useCSS: false, // use CSS to style HTML when possible (not supported in ie) useCSS: true, // use CSS to style HTML when possible (not supported in ie)
docType: // Document type contained within the editor docType: // Document type contained within the editor
'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">', '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
docCSSFile: // CSS file used to style the document contained within the editor docCSSFile: // CSS file used to style the document contained within the editor
@ -57,7 +52,7 @@
// Define all usable toolbar buttons - the init string property is // Define all usable toolbar buttons - the init string property is
// expanded during initialization back into the buttons object and // expanded during initialization back into the buttons object and
// seperate object properties are created for each button. // separate object properties are created for each button.
// e.g. buttons.size.title = "Font Size" // e.g. buttons.size.title = "Font Size"
buttons: { buttons: {
// name,title,command,popupName (""=use name) // name,title,command,popupName (""=use name)
@ -109,7 +104,7 @@
// Loop through all matching textareas and create the editors // Loop through all matching textareas and create the editors
this.each(function(idx, elem) { this.each(function(idx, elem) {
if (elem.tagName == "TEXTAREA") { if (elem.tagName.toUpperCase() === "TEXTAREA") {
var data = $.data(elem, CLEDITOR); var data = $.data(elem, CLEDITOR);
if (!data) data = new cleditor(elem, options); if (!data) data = new cleditor(elem, options);
$result = $result.add(data); $result = $result.add(data);
@ -129,6 +124,7 @@
// Misc constants // Misc constants
BACKGROUND_COLOR = "backgroundColor", BACKGROUND_COLOR = "backgroundColor",
BLURRED = "blurred",
BUTTON = "button", BUTTON = "button",
BUTTON_NAME = "buttonName", BUTTON_NAME = "buttonName",
CHANGE = "change", CHANGE = "change",
@ -136,6 +132,7 @@
CLICK = "click", CLICK = "click",
DISABLED = "disabled", DISABLED = "disabled",
DIV_TAG = "<div>", DIV_TAG = "<div>",
FOCUSED = "focused",
TRANSPARENT = "transparent", TRANSPARENT = "transparent",
UNSELECTABLE = "unselectable", UNSELECTABLE = "unselectable",
@ -152,12 +149,15 @@
PROMPT_CLASS = "cleditorPrompt", // prompt popup divs inside body PROMPT_CLASS = "cleditorPrompt", // prompt popup divs inside body
MSG_CLASS = "cleditorMsg", // message popup div inside body MSG_CLASS = "cleditorMsg", // message popup div inside body
// Test for ie // Browser detection
ie = $.browser.msie, ua = navigator.userAgent.toLowerCase(),
ie6 = /msie\s6/i.test(navigator.userAgent), ie = /msie/.test(ua),
ie6 = /msie\s6/.test(ua),
iege11 = /(trident)(?:.*rv:([\w.]+))?/.test(ua),
webkit = /webkit/.test(ua),
// Test for iPhone/iTouch/iPad // Test for iPhone/iTouch/iPad
iOS = /iphone|ipad|ipod/i.test(navigator.userAgent), iOS = /iphone|ipad|ipod/i.test(ua),
// Popups are created once as needed and shared by all editor instances // Popups are created once as needed and shared by all editor instances
popups = {}, popups = {},
@ -223,19 +223,26 @@
var $group = $(DIV_TAG) var $group = $(DIV_TAG)
.addClass(GROUP_CLASS) .addClass(GROUP_CLASS)
.appendTo($toolbar); .appendTo($toolbar);
// Initialize the group width
var groupWidth = 0;
// Add the buttons to the toolbar // Add the buttons to the toolbar
$.each(options.controls.split(" "), function(idx, buttonName) { $.each(options.controls.split(" "), function(idx, buttonName) {
if (buttonName === "") return true; if (buttonName === "") return true;
// Divider // Divider
if (buttonName == "|") { if (buttonName === "|") {
// Add a new divider to the group // Add a new divider to the group
var $div = $(DIV_TAG) var $div = $(DIV_TAG)
.addClass(DIVIDER_CLASS) .addClass(DIVIDER_CLASS)
.appendTo($group); .appendTo($group);
// Update the group width
$group.width(groupWidth + 1);
groupWidth = 0;
// Create a new group // Create a new group
$group = $(DIV_TAG) $group = $(DIV_TAG)
.addClass(GROUP_CLASS) .addClass(GROUP_CLASS)
@ -258,6 +265,10 @@
.appendTo($group) .appendTo($group)
.hover(hoverEnter, hoverLeave); .hover(hoverEnter, hoverLeave);
// Update the group width
groupWidth += 24;
$group.width(groupWidth + 1);
// Prepare the button image // Prepare the button image
var map = {}; var map = {};
if (button.css) map = button.css; if (button.css) map = button.css;
@ -295,7 +306,7 @@
// Bind the window resize event when the width or height is auto or % // Bind the window resize event when the width or height is auto or %
if (/auto|%/.test("" + options.width + options.height)) if (/auto|%/.test("" + options.width + options.height))
$(window).resize(function() { $(window).bind('resize.cleditor', function () {
//Forcefully blurred iframe contentWindow, chrome, IE, safari doesn't trigger blur on window resize and due to which text disappears //Forcefully blurred iframe contentWindow, chrome, IE, safari doesn't trigger blur on window resize and due to which text disappears
var contentWindow = editor.$frame[0].contentWindow; var contentWindow = editor.$frame[0].contentWindow;
if(!$.browser.mozilla && contentWindow){ if(!$.browser.mozilla && contentWindow){
@ -306,7 +317,6 @@
refresh(editor); refresh(editor);
} }
}); });
// Create the iframe and resize the controls // Create the iframe and resize the controls
refresh(editor); refresh(editor);
@ -347,13 +357,26 @@
return editor; return editor;
}; };
}); });
// blurred - shortcut for .bind("blurred", handler) or .trigger("blurred")
fn.blurred = function(handler) {
var $this = $(this);
return handler ? $this.bind(BLURRED, handler) : $this.trigger(BLURRED);
};
// change - shortcut for .bind("change", handler) or .trigger("change") // change - shortcut for .bind("change", handler) or .trigger("change")
fn.change = function(handler) { fn.change = function change(handler) {
console.log('change test');
var $this = $(this); var $this = $(this);
return handler ? $this.bind(CHANGE, handler) : $this.trigger(CHANGE); return handler ? $this.bind(CHANGE, handler) : $this.trigger(CHANGE);
}; };
// focused - shortcut for .bind("focused", handler) or .trigger("focused")
fn.focused = function(handler) {
var $this = $(this);
return handler ? $this.bind(FOCUSED, handler) : $this.trigger(FOCUSED);
};
//=============== //===============
// Event Handlers // Event Handlers
//=============== //===============
@ -369,7 +392,7 @@
popup = popups[popupName]; popup = popups[popupName];
// Check if disabled // Check if disabled
if (editor.disabled || $(buttonDiv).attr(DISABLED) == DISABLED) if (editor.disabled || $(buttonDiv).attr(DISABLED) === DISABLED)
return; return;
// Fire the buttonClick event // Fire the buttonClick event
@ -387,7 +410,7 @@
return false; return false;
// Toggle source // Toggle source
if (buttonName == "source") { if (buttonName === "source") {
// Show the iframe // Show the iframe
if (sourceMode(editor)) { if (sourceMode(editor)) {
@ -418,10 +441,10 @@
var $popup = $(popup); var $popup = $(popup);
// URL // URL
if (popupName == "url") { if (popupName === "url") {
// Check for selection before showing the link url popup // Check for selection before showing the link url popup
if (buttonName == "link" && selectedText(editor) === "") { if (buttonName === "link" && selectedText(editor) === "") {
showMessage(editor, "A selection is required when inserting a link.", buttonDiv); showMessage(editor, "A selection is required when inserting a link.", buttonDiv);
return false; return false;
} }
@ -447,7 +470,7 @@
} }
// Paste as Text // Paste as Text
else if (popupName == "pastetext") { else if (popupName === "pastetext") {
// Wire up the submit button click event handler // Wire up the submit button click event handler
$popup.children(":button") $popup.children(":button")
@ -475,13 +498,13 @@
return false; // stop propagination to document click return false; // stop propagination to document click
} }
// propaginate to documnt click // propaginate to document click
return; return;
} }
// Print // Print
else if (buttonName == "print") else if (buttonName === "print")
editor.$frame[0].contentWindow.print(); editor.$frame[0].contentWindow.print();
// All other buttons // All other buttons
@ -526,19 +549,19 @@
useCSS = editor.options.useCSS; useCSS = editor.options.useCSS;
// Get the command value // Get the command value
if (buttonName == "font") if (buttonName === "font")
// Opera returns the fontfamily wrapped in quotes // Opera returns the fontfamily wrapped in quotes
value = target.style.fontFamily.replace(/"/g, ""); value = target.style.fontFamily.replace(/"/g, "");
else if (buttonName == "size") { else if (buttonName === "size") {
if (target.tagName == "DIV") if (target.tagName.toUpperCase() === "DIV")
target = target.children[0]; target = target.children[0];
value = target.innerHTML; value = target.innerHTML;
} }
else if (buttonName == "style") else if (buttonName === "style")
value = "<" + target.tagName + ">"; value = "<" + target.tagName + ">";
else if (buttonName == "color") else if (buttonName === "color")
value = hex(target.style.backgroundColor); value = hex(target.style.backgroundColor);
else if (buttonName == "highlight") { else if (buttonName === "highlight") {
value = hex(target.style.backgroundColor); value = hex(target.style.backgroundColor);
if (ie) command = 'backcolor'; if (ie) command = 'backcolor';
else useCSS = true; else useCSS = true;
@ -610,7 +633,7 @@
$popup.html(popupContent); $popup.html(popupContent);
// Color // Color
else if (popupName == "color") { else if (popupName === "color") {
var colors = options.colors.split(" "); var colors = options.colors.split(" ");
if (colors.length < 10) if (colors.length < 10)
$popup.width("auto"); $popup.width("auto");
@ -622,7 +645,7 @@
} }
// Font // Font
else if (popupName == "font") else if (popupName === "font")
$.each(options.fonts.split(","), function(idx, font) { $.each(options.fonts.split(","), function(idx, font) {
$(DIV_TAG).appendTo($popup) $(DIV_TAG).appendTo($popup)
.css("fontFamily", font) .css("fontFamily", font)
@ -630,28 +653,28 @@
}); });
// Size // Size
else if (popupName == "size") else if (popupName === "size")
$.each(options.sizes.split(","), function(idx, size) { $.each(options.sizes.split(","), function(idx, size) {
$(DIV_TAG).appendTo($popup) $(DIV_TAG).appendTo($popup)
.html("<font size=" + size + ">" + size + "</font>"); .html('<font size="' + size + '">' + size + '</font>');
}); });
// Style // Style
else if (popupName == "style") else if (popupName === "style")
$.each(options.styles, function(idx, style) { $.each(options.styles, function(idx, style) {
$(DIV_TAG).appendTo($popup) $(DIV_TAG).appendTo($popup)
.html(style[1] + style[0] + style[1].replace("<", "</")); .html(style[1] + style[0] + style[1].replace("<", "</"));
}); });
// URL // URL
else if (popupName == "url") { else if (popupName === "url") {
$popup.html('Enter URL:<br><input type=text value="http://" size=35><br><input type=button value="Submit">'); $popup.html('Enter URL:<br /><input type="text" value="http://" size="35" /><br /><input type="button" value="Submit" />');
popupTypeClass = PROMPT_CLASS; popupTypeClass = PROMPT_CLASS;
} }
// Paste as Text // Paste as Text
else if (popupName == "pastetext") { else if (popupName === "pastetext") {
$popup.html('Paste your content here and click submit.<br /><textarea cols=40 rows=3></textarea><br /><input type=button value=Submit>'); $popup.html('Paste your content here and click submit.<br /><textarea cols="40" rows="3"></textarea><br /><input type="button" value="Submit" />');
popupTypeClass = PROMPT_CLASS; popupTypeClass = PROMPT_CLASS;
} }
@ -720,12 +743,12 @@
} }
// Execute the command and check for error // Execute the command and check for error
var success = true, description; var success = true, message;
if (ie && command.toLowerCase() == "inserthtml") if (ie && command.toLowerCase() === "inserthtml")
getRange(editor).pasteHTML(value); getRange(editor).pasteHTML(value);
else { else {
try { success = editor.doc.execCommand(command, 0, value || null); } try { success = editor.doc.execCommand(command, 0, value || null); }
catch (err) { description = err.description; success = false; } catch (err) { message = err.message; success = false; }
if (!success) { if (!success) {
if ("cutcopypaste".indexOf(command) > -1) if ("cutcopypaste".indexOf(command) > -1)
showMessage(editor, "For security reasons, your browser does not support the " + showMessage(editor, "For security reasons, your browser does not support the " +
@ -733,13 +756,14 @@
button); button);
else else
showMessage(editor, showMessage(editor,
(description ? description : "Error executing the " + command + " command."), (message ? message : "Error executing the " + command + " command."),
button); button);
} }
} }
// Enable the buttons // Enable the buttons and update the textarea
refreshButtons(editor); refreshButtons(editor);
updateTextArea(editor, true);
return success; return success;
} }
@ -765,19 +789,26 @@
return editor.$frame[0].contentWindow.getSelection(); return editor.$frame[0].contentWindow.getSelection();
} }
// Returns the hex value for the passed in string. // hex - returns the hex value for the passed in color string
// hex("rgb(255, 0, 0)"); // #FF0000
// hex("#FF0000"); // #FF0000
// hex("#F00"); // #FF0000
function hex(s) { function hex(s) {
var m = /rgba?\((\d+), (\d+), (\d+)/.exec(s),
c = s.split(""); // hex("rgb(255, 0, 0)") returns #FF0000
var m = /rgba?\((\d+), (\d+), (\d+)/.exec(s);
if (m) { if (m) {
s = ( m[1] << 16 | m[2] << 8 | m[3] ).toString(16); s = (m[1] << 16 | m[2] << 8 | m[3]).toString(16);
while (s.length < 6) while (s.length < 6)
s = "0" + s; s = "0" + s;
return "#" + s;
} }
return "#" + (s.length == 6 ? s : c[1] + c[1] + c[2] + c[2] + c[3] + c[3]);
// hex("#F00") returns #FF0000
var c = s.split("");
if (s.length === 4)
return "#" + c[1] + c[1] + c[2] + c[2] + c[3] + c[3];
// hex("#FF0000") returns #FF0000
return s;
} }
// hidePopups - hides all popups // hidePopups - hides all popups
@ -792,9 +823,8 @@
// imagesPath - returns the path to the images folder // imagesPath - returns the path to the images folder
function imagesPath() { function imagesPath() {
var cssFile = "jquery.cleditor.css", var href = $("link[href*=cleditor]").attr("href");
href = $("link[href$='" + cssFile +"']").attr("href"); return href.replace(/^(.*\/)[^\/]+$/, '$1') + "images/";
return href.substr(0, href.length - cssFile.length) + "images/";
} }
// imageUrl - Returns the css url string for a filemane // imageUrl - Returns the css url string for a filemane
@ -813,7 +843,7 @@
editor.$frame.remove(); editor.$frame.remove();
// Create a new iframe // Create a new iframe
var $frame = editor.$frame = $('<iframe frameborder="0" src="javascript:true;">') var $frame = editor.$frame = $('<iframe frameborder="0" src="javascript:true;" />')
.hide() .hide()
.appendTo($main); .appendTo($main);
@ -833,14 +863,14 @@
// Work around for bug in IE which causes the editor to lose // Work around for bug in IE which causes the editor to lose
// focus when clicking below the end of the document. // focus when clicking below the end of the document.
if (ie) if (ie || iege11)
$doc.click(function() {focus(editor);}); $doc.click(function() {focus(editor);});
// Load the content // Load the content
updateFrame(editor); updateFrame(editor);
// Bind the ie specific iframe event handlers // Bind the ie specific iframe event handlers
if (ie) { if (ie || iege11) {
// Save the current user selection. This code is needed since IE will // Save the current user selection. This code is needed since IE will
// reset the selection just after the beforedeactivate event and just // reset the selection just after the beforedeactivate event and just
@ -848,19 +878,19 @@
$doc.bind("beforedeactivate beforeactivate selectionchange keypress", function(e) { $doc.bind("beforedeactivate beforeactivate selectionchange keypress", function(e) {
// Flag the editor as inactive // Flag the editor as inactive
if (e.type == "beforedeactivate") if (e.type === "beforedeactivate")
editor.inactive = true; editor.inactive = true;
// Get rid of the bogus selection and flag the editor as active // Get rid of the bogus selection and flag the editor as active
else if (e.type == "beforeactivate") { else if (e.type === "beforeactivate") {
if (!editor.inactive && editor.range && editor.range.length > 1) if (!editor.inactive && editor.range && editor.range.length > 1)
editor.range.shift(); editor.range.shift();
delete editor.inactive; delete editor.inactive;
} }
// Save the selection when the editor is active // Save the selection when the editor is active
else if (!editor.inactive) { else if (!editor.inactive) {
if (!editor.range) if (!editor.range)
editor.range = []; editor.range = [];
editor.range.unshift(getRange(editor)); editor.range.unshift(getRange(editor));
@ -871,22 +901,31 @@
}); });
// Restore the text range when the iframe gains focus // Restore the text range and trigger focused event when the iframe gains focus
$frame.focus(function() { $frame.focus(function() {
restoreRange(editor); restoreRange(editor);
$(editor).triggerHandler(FOCUSED);
});
// Trigger blurred event when the iframe looses focus
$frame.blur(function() {
$(editor).triggerHandler(BLURRED);
}); });
} }
// Update the textarea when the iframe loses focus // Trigger focused and blurred events for all other browsers
($.browser.mozilla ? $doc : $(contentWindow)).blur(function() { else {
updateTextArea(editor, true); $(editor.$frame[0].contentWindow)
}); .focus(function () { $(editor).triggerHandler(FOCUSED); })
.blur(function () { $(editor).triggerHandler(BLURRED); });
}
// Enable the toolbar buttons as the user types or clicks // Enable the toolbar buttons and update the textarea as the user types or clicks
$doc.click(hidePopups) $doc.click(hidePopups)
.bind("keyup mouseup", function() { .bind("keyup mouseup", function() {
refreshButtons(editor); refreshButtons(editor);
updateTextArea(editor, true);
}); });
// Show the textarea for iPhone/iTouch/iPad or // Show the textarea for iPhone/iTouch/iPad or
@ -906,7 +945,7 @@
$toolbar.height(hgt); $toolbar.height(hgt);
// Resize the iframe // Resize the iframe
hgt = (/%/.test("" + options.height) ? $main.height() : parseInt(options.height)) - hgt; hgt = (/%/.test("" + options.height) ? $main.height() : parseInt(options.height, 10)) - hgt;
$frame.width(wid).height(hgt); $frame.width(wid).height(hgt);
// Resize the textarea. IE6 textareas have a 1px top // Resize the textarea. IE6 textareas have a 1px top
@ -927,7 +966,7 @@
function refreshButtons(editor) { function refreshButtons(editor) {
// Webkit requires focus before queryCommandEnabled will return anything but false // Webkit requires focus before queryCommandEnabled will return anything but false
if (!iOS && $.browser.webkit && !editor.focused) { if (!iOS && webkit && !editor.focused) {
editor.$frame[0].contentWindow.focus(); editor.$frame[0].contentWindow.focus();
window.focus(); window.focus();
editor.focused = true; editor.focused = true;
@ -963,14 +1002,14 @@
if (enabled === undefined) if (enabled === undefined)
enabled = true; enabled = true;
} }
else if (((inSourceMode || iOS) && button.name != "source") || else if (((inSourceMode || iOS) && button.name !== "source") ||
(ie && (command == "undo" || command == "redo"))) (ie && (command === "undo" || command === "redo")))
enabled = false; enabled = false;
else if (command && command != "print") { else if (command && command !== "print") {
if (ie && command == "hilitecolor") if (ie && command === "hilitecolor")
command = "backcolor"; command = "backcolor";
// IE does not support inserthtml, so it's always enabled // IE does not support inserthtml, so it's always enabled
if (!ie || command != "inserthtml") { if (!ie || command !== "inserthtml") {
try {enabled = queryObj.queryCommandEnabled(command);} try {enabled = queryObj.queryCommandEnabled(command);}
catch (err) {enabled = false;} catch (err) {enabled = false;}
} }
@ -991,8 +1030,12 @@
// restoreRange - restores the current ie selection // restoreRange - restores the current ie selection
function restoreRange(editor) { function restoreRange(editor) {
if (ie && editor.range) if (editor.range) {
editor.range[0].select(); if (ie)
editor.range[0].select();
else if (iege11)
getSelection(editor).addRange(editor.range[0]);
}
} }
// select - selects all the text in either the textarea or iframe // select - selects all the text in either the textarea or iframe
@ -1084,7 +1127,7 @@
// of potentially heavy updateFrame callbacks. // of potentially heavy updateFrame callbacks.
if (updateFrameCallback) { if (updateFrameCallback) {
var sum = checksum(code); var sum = checksum(code);
if (checkForChange && editor.areaChecksum == sum) if (checkForChange && editor.areaChecksum === sum)
return; return;
editor.areaChecksum = sum; editor.areaChecksum = sum;
} }
@ -1100,7 +1143,7 @@
editor.frameChecksum = checksum(html); editor.frameChecksum = checksum(html);
// Update the iframe and trigger the change event // Update the iframe and trigger the change event
if (html != $body.html()) { if (html !== $body.html()) {
$body.html(html); $body.html(html);
$(editor).triggerHandler(CHANGE); $(editor).triggerHandler(CHANGE);
} }
@ -1119,7 +1162,7 @@
// of potentially heavy updateTextArea callbacks. // of potentially heavy updateTextArea callbacks.
if (updateTextAreaCallback) { if (updateTextAreaCallback) {
var sum = checksum(html); var sum = checksum(html);
if (checkForChange && editor.frameChecksum == sum) if (checkForChange && editor.frameChecksum === sum)
return; return;
editor.frameChecksum = sum; editor.frameChecksum = sum;
} }
@ -1132,7 +1175,7 @@
editor.areaChecksum = checksum(code); editor.areaChecksum = checksum(code);
// Update the textarea and trigger the change event // Update the textarea and trigger the change event
if (code != $area.val()) { if (code !== $area.val()) {
$area.val(code); $area.val(code);
$(editor).triggerHandler(CHANGE); $(editor).triggerHandler(CHANGE);
} }

View File

@ -1,31 +0,0 @@
/*
CLEditor WYSIWYG HTML Editor v1.3.0
http://premiumsoftware.net/cleditor
requires jQuery v1.4.2 or later
Copyright 2010, Chris Landowski, Premium Software, LLC
Dual licensed under the MIT or GPL Version 2 licenses.
*/
(function(e){function aa(a){var b=this,c=a.target,d=e.data(c,x),h=s[d],f=h.popupName,i=p[f];if(!(b.disabled||e(c).attr(n)==n)){var g={editor:b,button:c,buttonName:d,popup:i,popupName:f,command:h.command,useCSS:b.options.useCSS};if(h.buttonClick&&h.buttonClick(a,g)===false)return false;if(d=="source"){if(t(b)){delete b.range;b.$area.hide();b.$frame.show();c.title=h.title}else{b.$frame.hide();b.$area.show();c.title="Show Rich Text"}setTimeout(function(){u(b)},100)}else if(!t(b))if(f){var j=e(i);if(f==
"url"){if(d=="link"&&M(b)===""){z(b,"A selection is required when inserting a link.",c);return false}j.children(":button").unbind(q).bind(q,function(){var k=j.find(":text"),o=e.trim(k.val());o!==""&&v(b,g.command,o,null,g.button);k.val("http://");r();w(b)})}else f=="pastetext"&&j.children(":button").unbind(q).bind(q,function(){var k=j.find("textarea"),o=k.val().replace(/\n/g,"<br />");o!==""&&v(b,g.command,o,null,g.button);k.val("");r();w(b)});if(c!==e.data(i,A)){N(b,i,c);return false}return}else if(d==
"print")b.$frame[0].contentWindow.print();else if(!v(b,g.command,g.value,g.useCSS,c))return false;w(b)}}function O(a){a=e(a.target).closest("div");a.css(H,a.data(x)?"#FFF":"#FFC")}function P(a){e(a.target).closest("div").css(H,"transparent")}function ba(a){var b=a.data.popup,c=a.target;if(!(b===p.msg||e(b).hasClass(B))){var d=e.data(b,A),h=e.data(d,x),f=s[h],i=f.command,g,j=this.options.useCSS;if(h=="font")g=c.style.fontFamily.replace(/"/g,"");else if(h=="size"){if(c.tagName=="DIV")c=c.children[0];
g=c.innerHTML}else if(h=="style")g="<"+c.tagName+">";else if(h=="color")g=Q(c.style.backgroundColor);else if(h=="highlight"){g=Q(c.style.backgroundColor);if(l)i="backcolor";else j=true}b={editor:this,button:d,buttonName:h,popup:b,popupName:f.popupName,command:i,value:g,useCSS:j};if(!(f.popupClick&&f.popupClick(a,b)===false)){if(b.command&&!v(this,b.command,b.value,b.useCSS,d))return false;r();w(this)}}}function C(a){for(var b=1,c=0,d=0;d<a.length;++d){b=(b+a.charCodeAt(d))%65521;c=(c+b)%65521}return c<<
16|b}function R(a,b,c,d,h){if(p[a])return p[a];var f=e(m).hide().addClass(ca).appendTo("body");if(d)f.html(d);else if(a=="color"){b=b.colors.split(" ");b.length<10&&f.width("auto");e.each(b,function(i,g){e(m).appendTo(f).css(H,"#"+g)});c=da}else if(a=="font")e.each(b.fonts.split(","),function(i,g){e(m).appendTo(f).css("fontFamily",g).html(g)});else if(a=="size")e.each(b.sizes.split(","),function(i,g){e(m).appendTo(f).html("<font size="+g+">"+g+"</font>")});else if(a=="style")e.each(b.styles,function(i,
g){e(m).appendTo(f).html(g[1]+g[0]+g[1].replace("<","</"))});else if(a=="url"){f.html('Enter URL:<br><input type=text value="http://" size=35><br><input type=button value="Submit">');c=B}else if(a=="pastetext"){f.html("Paste your content here and click submit.<br /><textarea cols=40 rows=3></textarea><br /><input type=button value=Submit>");c=B}if(!c&&!d)c=S;f.addClass(c);l&&f.attr(I,"on").find("div,font,p,h1,h2,h3,h4,h5,h6").attr(I,"on");if(f.hasClass(S)||h===true)f.children().hover(O,P);p[a]=f[0];
return f[0]}function T(a,b){if(b){a.$area.attr(n,n);a.disabled=true}else{a.$area.removeAttr(n);delete a.disabled}try{if(l)a.doc.body.contentEditable=!b;else a.doc.designMode=!b?"on":"off"}catch(c){}u(a)}function v(a,b,c,d,h){D(a);if(!l){if(d===undefined||d===null)d=a.options.useCSS;a.doc.execCommand("styleWithCSS",0,d.toString())}d=true;var f;if(l&&b.toLowerCase()=="inserthtml")y(a).pasteHTML(c);else{try{d=a.doc.execCommand(b,0,c||null)}catch(i){f=i.description;d=false}d||("cutcopypaste".indexOf(b)>
-1?z(a,"For security reasons, your browser does not support the "+b+" command. Try using the keyboard shortcut or context menu instead.",h):z(a,f?f:"Error executing the "+b+" command.",h))}u(a);return d}function w(a){setTimeout(function(){t(a)?a.$area.focus():a.$frame[0].contentWindow.focus();u(a)},0)}function y(a){if(l)return J(a).createRange();return J(a).getRangeAt(0)}function J(a){if(l)return a.doc.selection;return a.$frame[0].contentWindow.getSelection()}function Q(a){var b=/rgba?\((\d+), (\d+), (\d+)/.exec(a),
c=a.split("");if(b)for(a=(b[1]<<16|b[2]<<8|b[3]).toString(16);a.length<6;)a="0"+a;return"#"+(a.length==6?a:c[1]+c[1]+c[2]+c[2]+c[3]+c[3])}function r(){e.each(p,function(a,b){e(b).hide().unbind(q).removeData(A)})}function U(){var a=e("link[href$='jquery.cleditor.css']").attr("href");return a.substr(0,a.length-19)+"images/"}function K(a){var b=a.$main,c=a.options;a.$frame&&a.$frame.remove();var d=a.$frame=e('<iframe frameborder="0" src="javascript:true;">').hide().appendTo(b),h=d[0].contentWindow,f=
a.doc=h.document,i=e(f);f.open();f.write(c.docType+"<html>"+(c.docCSSFile===""?"":'<head><link rel="stylesheet" type="text/css" href="'+c.docCSSFile+'" /></head>')+'<body style="'+c.bodyStyle+'"></body></html>');f.close();l&&i.click(function(){w(a)});E(a);if(l){i.bind("beforedeactivate beforeactivate selectionchange keypress",function(g){if(g.type=="beforedeactivate")a.inactive=true;else if(g.type=="beforeactivate"){!a.inactive&&a.range&&a.range.length>1&&a.range.shift();delete a.inactive}else if(!a.inactive){if(!a.range)a.range=
[];for(a.range.unshift(y(a));a.range.length>2;)a.range.pop()}});d.focus(function(){D(a)})}(e.browser.mozilla?i:e(h)).blur(function(){V(a,true)});i.click(r).bind("keyup mouseup",function(){u(a)});L?a.$area.show():d.show();e(function(){var g=a.$toolbar,j=g.children("div:last"),k=b.width();j=j.offset().top+j.outerHeight()-g.offset().top+1;g.height(j);j=(/%/.test(""+c.height)?b.height():parseInt(c.height))-j;d.width(k).height(j);a.$area.width(k).height(ea?j-2:j);T(a,a.disabled);u(a)})}function u(a){if(!L&&
e.browser.webkit&&!a.focused){a.$frame[0].contentWindow.focus();window.focus();a.focused=true}var b=a.doc;if(l)b=y(a);var c=t(a);e.each(a.$toolbar.find("."+W),function(d,h){var f=e(h),i=e.cleditor.buttons[e.data(h,x)],g=i.command,j=true;if(a.disabled)j=false;else if(i.getEnabled){j=i.getEnabled({editor:a,button:h,buttonName:i.name,popup:p[i.popupName],popupName:i.popupName,command:i.command,useCSS:a.options.useCSS});if(j===undefined)j=true}else if((c||L)&&i.name!="source"||l&&(g=="undo"||g=="redo"))j=
false;else if(g&&g!="print"){if(l&&g=="hilitecolor")g="backcolor";if(!l||g!="inserthtml")try{j=b.queryCommandEnabled(g)}catch(k){j=false}}if(j){f.removeClass(X);f.removeAttr(n)}else{f.addClass(X);f.attr(n,n)}})}function D(a){l&&a.range&&a.range[0].select()}function M(a){D(a);if(l)return y(a).text;return J(a).toString()}function z(a,b,c){var d=R("msg",a.options,fa);d.innerHTML=b;N(a,d,c)}function N(a,b,c){var d,h,f=e(b);if(c){var i=e(c);d=i.offset();h=--d.left;d=d.top+i.height()}else{i=a.$toolbar;
d=i.offset();h=Math.floor((i.width()-f.width())/2)+d.left;d=d.top+i.height()-2}r();f.css({left:h,top:d}).show();if(c){e.data(b,A,c);f.bind(q,{popup:b},e.proxy(ba,a))}setTimeout(function(){f.find(":text,textarea").eq(0).focus().select()},100)}function t(a){return a.$area.is(":visible")}function E(a,b){var c=a.$area.val(),d=a.options,h=d.updateFrame,f=e(a.doc.body);if(h){var i=C(c);if(b&&a.areaChecksum==i)return;a.areaChecksum=i}c=h?h(c):c;c=c.replace(/<(?=\/?script)/ig,"&lt;");if(d.updateTextArea)a.frameChecksum=
C(c);if(c!=f.html()){f.html(c);e(a).triggerHandler(F)}}function V(a,b){var c=e(a.doc.body).html(),d=a.options,h=d.updateTextArea,f=a.$area;if(h){var i=C(c);if(b&&a.frameChecksum==i)return;a.frameChecksum=i}c=h?h(c):c;if(d.updateFrame)a.areaChecksum=C(c);if(c!=f.val()){f.val(c);e(a).triggerHandler(F)}}e.cleditor={defaultOptions:{width:500,height:250,controls:"bold italic underline strikethrough subscript superscript | font size style | color highlight removeformat | bullets numbering | outdent indent | alignleft center alignright justify | undo redo | rule image link unlink | cut copy paste pastetext | print source",
colors:"FFF FCC FC9 FF9 FFC 9F9 9FF CFF CCF FCF CCC F66 F96 FF6 FF3 6F9 3FF 6FF 99F F9F BBB F00 F90 FC6 FF0 3F3 6CC 3CF 66C C6C 999 C00 F60 FC3 FC0 3C0 0CC 36F 63F C3C 666 900 C60 C93 990 090 399 33F 60C 939 333 600 930 963 660 060 366 009 339 636 000 300 630 633 330 030 033 006 309 303",fonts:"Arial,Arial Black,Comic Sans MS,Courier New,Narrow,Garamond,Georgia,Impact,Sans Serif,Serif,Tahoma,Trebuchet MS,Verdana",sizes:"1,2,3,4,5,6,7",styles:[["Paragraph","<p>"],["Header 1","<h1>"],["Header 2","<h2>"],
["Header 3","<h3>"],["Header 4","<h4>"],["Header 5","<h5>"],["Header 6","<h6>"]],useCSS:false,docType:'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',docCSSFile:"",bodyStyle:"margin:4px; font:10pt Arial,Verdana; cursor:text"},buttons:{init:"bold,,|italic,,|underline,,|strikethrough,,|subscript,,|superscript,,|font,,fontname,|size,Font Size,fontsize,|style,,formatblock,|color,Font Color,forecolor,|highlight,Text Highlight Color,hilitecolor,color|removeformat,Remove Formatting,|bullets,,insertunorderedlist|numbering,,insertorderedlist|outdent,,|indent,,|alignleft,Align Text Left,justifyleft|center,,justifycenter|alignright,Align Text Right,justifyright|justify,,justifyfull|undo,,|redo,,|rule,Insert Horizontal Rule,inserthorizontalrule|image,Insert Image,insertimage,url|link,Insert Hyperlink,createlink,url|unlink,Remove Hyperlink,|cut,,|copy,,|paste,,|pastetext,Paste as Text,inserthtml,|print,,|source,Show Source"},
imagesPath:function(){return U()}};e.fn.cleditor=function(a){var b=e([]);this.each(function(c,d){if(d.tagName=="TEXTAREA"){var h=e.data(d,Y);h||(h=new cleditor(d,a));b=b.add(h)}});return b};var H="backgroundColor",A="button",x="buttonName",F="change",Y="cleditor",q="click",n="disabled",m="<div>",I="unselectable",W="cleditorButton",X="cleditorDisabled",ca="cleditorPopup",S="cleditorList",da="cleditorColor",B="cleditorPrompt",fa="cleditorMsg",l=e.browser.msie,ea=/msie\s6/i.test(navigator.userAgent),
L=/iphone|ipad|ipod/i.test(navigator.userAgent),p={},Z,s=e.cleditor.buttons;e.each(s.init.split("|"),function(a,b){var c=b.split(","),d=c[0];s[d]={stripIndex:a,name:d,title:c[1]===""?d.charAt(0).toUpperCase()+d.substr(1):c[1],command:c[2]===""?d:c[2],popupName:c[3]===""?d:c[3]}});delete s.init;cleditor=function(a,b){var c=this;c.options=b=e.extend({},e.cleditor.defaultOptions,b);var d=c.$area=e(a).hide().data(Y,c).blur(function(){E(c,true)}),h=c.$main=e(m).addClass("cleditorMain").width(b.width).height(b.height),
f=c.$toolbar=e(m).addClass("cleditorToolbar").appendTo(h),i=e(m).addClass("cleditorGroup").appendTo(f);e.each(b.controls.split(" "),function(g,j){if(j==="")return true;if(j=="|"){e(m).addClass("cleditorDivider").appendTo(i);i=e(m).addClass("cleditorGroup").appendTo(f)}else{var k=s[j],o=e(m).data(x,k.name).addClass(W).attr("title",k.title).bind(q,e.proxy(aa,c)).appendTo(i).hover(O,P),G={};if(k.css)G=k.css;else if(k.image)G.backgroundImage="url("+U()+k.image+")";if(k.stripIndex)G.backgroundPosition=
k.stripIndex*-24;o.css(G);l&&o.attr(I,"on");k.popupName&&R(k.popupName,b,k.popupClass,k.popupContent,k.popupHover)}});h.insertBefore(d).append(d);if(!Z){e(document).click(function(g){g=e(g.target);g.add(g.parents()).is("."+B)||r()});Z=true}/auto|%/.test(""+b.width+b.height)&&e(window).resize(function(){K(c)});K(c)};var $=cleditor.prototype;e.each([["clear",function(a){a.$area.val("");E(a)}],["disable",T],["execCommand",v],["focus",w],["hidePopups",r],["sourceMode",t,true],["refresh",K],["select",
function(a){setTimeout(function(){t(a)?a.$area.select():v(a,"selectall")},0)}],["selectedHTML",function(a){D(a);a=y(a);if(l)return a.htmlText;var b=e("<layer>")[0];b.appendChild(a.cloneContents());return b.innerHTML},true],["selectedText",M,true],["showMessage",z],["updateFrame",E],["updateTextArea",V]],function(a,b){$[b[0]]=function(){for(var c=[this],d=0;d<arguments.length;d++)c.push(arguments[d]);c=b[1].apply(this,c);if(b[2])return c;return this}});$.change=function(a){var b=e(this);return a?b.bind(F,
a):b.trigger(F)}})(jQuery);

View File

@ -13,7 +13,7 @@
} }
.fa { .fa {
display: inline-block; display: inline-block;
font-family: FontAwesome; font-family: FontAwesome !important;
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
line-height: 1; line-height: 1;

View File

@ -1,6 +1,6 @@
// Underscore.js 1.5.2 // Underscore.js 1.6.0
// http://underscorejs.org // http://underscorejs.org
// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Underscore may be freely distributed under the MIT license. // Underscore may be freely distributed under the MIT license.
(function() { (function() {
@ -65,7 +65,7 @@
} }
// Current version. // Current version.
_.VERSION = '1.5.2'; _.VERSION = '1.6.0';
// Collection Functions // Collection Functions
// -------------------- // --------------------
@ -74,7 +74,7 @@
// Handles objects with the built-in `forEach`, arrays, and raw objects. // Handles objects with the built-in `forEach`, arrays, and raw objects.
// Delegates to **ECMAScript 5**'s native `forEach` if available. // Delegates to **ECMAScript 5**'s native `forEach` if available.
var each = _.each = _.forEach = function(obj, iterator, context) { var each = _.each = _.forEach = function(obj, iterator, context) {
if (obj == null) return; if (obj == null) return obj;
if (nativeForEach && obj.forEach === nativeForEach) { if (nativeForEach && obj.forEach === nativeForEach) {
obj.forEach(iterator, context); obj.forEach(iterator, context);
} else if (obj.length === +obj.length) { } else if (obj.length === +obj.length) {
@ -87,6 +87,7 @@
if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return; if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
} }
} }
return obj;
}; };
// Return the results of applying the iterator to each element. // Return the results of applying the iterator to each element.
@ -152,10 +153,10 @@
}; };
// Return the first value which passes a truth test. Aliased as `detect`. // Return the first value which passes a truth test. Aliased as `detect`.
_.find = _.detect = function(obj, iterator, context) { _.find = _.detect = function(obj, predicate, context) {
var result; var result;
any(obj, function(value, index, list) { any(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) { if (predicate.call(context, value, index, list)) {
result = value; result = value;
return true; return true;
} }
@ -166,33 +167,33 @@
// Return all the elements that pass a truth test. // Return all the elements that pass a truth test.
// Delegates to **ECMAScript 5**'s native `filter` if available. // Delegates to **ECMAScript 5**'s native `filter` if available.
// Aliased as `select`. // Aliased as `select`.
_.filter = _.select = function(obj, iterator, context) { _.filter = _.select = function(obj, predicate, context) {
var results = []; var results = [];
if (obj == null) return results; if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
each(obj, function(value, index, list) { each(obj, function(value, index, list) {
if (iterator.call(context, value, index, list)) results.push(value); if (predicate.call(context, value, index, list)) results.push(value);
}); });
return results; return results;
}; };
// Return all the elements for which a truth test fails. // Return all the elements for which a truth test fails.
_.reject = function(obj, iterator, context) { _.reject = function(obj, predicate, context) {
return _.filter(obj, function(value, index, list) { return _.filter(obj, function(value, index, list) {
return !iterator.call(context, value, index, list); return !predicate.call(context, value, index, list);
}, context); }, context);
}; };
// Determine whether all of the elements match a truth test. // Determine whether all of the elements match a truth test.
// Delegates to **ECMAScript 5**'s native `every` if available. // Delegates to **ECMAScript 5**'s native `every` if available.
// Aliased as `all`. // Aliased as `all`.
_.every = _.all = function(obj, iterator, context) { _.every = _.all = function(obj, predicate, context) {
iterator || (iterator = _.identity); predicate || (predicate = _.identity);
var result = true; var result = true;
if (obj == null) return result; if (obj == null) return result;
if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
each(obj, function(value, index, list) { each(obj, function(value, index, list) {
if (!(result = result && iterator.call(context, value, index, list))) return breaker; if (!(result = result && predicate.call(context, value, index, list))) return breaker;
}); });
return !!result; return !!result;
}; };
@ -200,13 +201,13 @@
// Determine if at least one element in the object matches a truth test. // Determine if at least one element in the object matches a truth test.
// Delegates to **ECMAScript 5**'s native `some` if available. // Delegates to **ECMAScript 5**'s native `some` if available.
// Aliased as `any`. // Aliased as `any`.
var any = _.some = _.any = function(obj, iterator, context) { var any = _.some = _.any = function(obj, predicate, context) {
iterator || (iterator = _.identity); predicate || (predicate = _.identity);
var result = false; var result = false;
if (obj == null) return result; if (obj == null) return result;
if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
each(obj, function(value, index, list) { each(obj, function(value, index, list) {
if (result || (result = iterator.call(context, value, index, list))) return breaker; if (result || (result = predicate.call(context, value, index, list))) return breaker;
}); });
return !!result; return !!result;
}; };
@ -232,25 +233,19 @@
// Convenience version of a common use case of `map`: fetching a property. // Convenience version of a common use case of `map`: fetching a property.
_.pluck = function(obj, key) { _.pluck = function(obj, key) {
return _.map(obj, function(value){ return value[key]; }); return _.map(obj, _.property(key));
}; };
// Convenience version of a common use case of `filter`: selecting only objects // Convenience version of a common use case of `filter`: selecting only objects
// containing specific `key:value` pairs. // containing specific `key:value` pairs.
_.where = function(obj, attrs, first) { _.where = function(obj, attrs) {
if (_.isEmpty(attrs)) return first ? void 0 : []; return _.filter(obj, _.matches(attrs));
return _[first ? 'find' : 'filter'](obj, function(value) {
for (var key in attrs) {
if (attrs[key] !== value[key]) return false;
}
return true;
});
}; };
// Convenience version of a common use case of `find`: getting the first object // Convenience version of a common use case of `find`: getting the first object
// containing specific `key:value` pairs. // containing specific `key:value` pairs.
_.findWhere = function(obj, attrs) { _.findWhere = function(obj, attrs) {
return _.where(obj, attrs, true); return _.find(obj, _.matches(attrs));
}; };
// Return the maximum element or (element-based computation). // Return the maximum element or (element-based computation).
@ -260,13 +255,15 @@
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.max.apply(Math, obj); return Math.max.apply(Math, obj);
} }
if (!iterator && _.isEmpty(obj)) return -Infinity; var result = -Infinity, lastComputed = -Infinity;
var result = {computed : -Infinity, value: -Infinity};
each(obj, function(value, index, list) { each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value; var computed = iterator ? iterator.call(context, value, index, list) : value;
computed > result.computed && (result = {value : value, computed : computed}); if (computed > lastComputed) {
result = value;
lastComputed = computed;
}
}); });
return result.value; return result;
}; };
// Return the minimum element (or element-based computation). // Return the minimum element (or element-based computation).
@ -274,16 +271,18 @@
if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
return Math.min.apply(Math, obj); return Math.min.apply(Math, obj);
} }
if (!iterator && _.isEmpty(obj)) return Infinity; var result = Infinity, lastComputed = Infinity;
var result = {computed : Infinity, value: Infinity};
each(obj, function(value, index, list) { each(obj, function(value, index, list) {
var computed = iterator ? iterator.call(context, value, index, list) : value; var computed = iterator ? iterator.call(context, value, index, list) : value;
computed < result.computed && (result = {value : value, computed : computed}); if (computed < lastComputed) {
result = value;
lastComputed = computed;
}
}); });
return result.value; return result;
}; };
// Shuffle an array, using the modern version of the // Shuffle an array, using the modern version of the
// [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/FisherYates_shuffle). // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/FisherYates_shuffle).
_.shuffle = function(obj) { _.shuffle = function(obj) {
var rand; var rand;
@ -297,11 +296,12 @@
return shuffled; return shuffled;
}; };
// Sample **n** random values from an array. // Sample **n** random values from a collection.
// If **n** is not specified, returns a single random element from the array. // If **n** is not specified, returns a single random element.
// The internal `guard` argument allows it to work with `map`. // The internal `guard` argument allows it to work with `map`.
_.sample = function(obj, n, guard) { _.sample = function(obj, n, guard) {
if (arguments.length < 2 || guard) { if (n == null || guard) {
if (obj.length !== +obj.length) obj = _.values(obj);
return obj[_.random(obj.length - 1)]; return obj[_.random(obj.length - 1)];
} }
return _.shuffle(obj).slice(0, Math.max(0, n)); return _.shuffle(obj).slice(0, Math.max(0, n));
@ -309,12 +309,14 @@
// An internal function to generate lookup iterators. // An internal function to generate lookup iterators.
var lookupIterator = function(value) { var lookupIterator = function(value) {
return _.isFunction(value) ? value : function(obj){ return obj[value]; }; if (value == null) return _.identity;
if (_.isFunction(value)) return value;
return _.property(value);
}; };
// Sort the object's values by a criterion produced by an iterator. // Sort the object's values by a criterion produced by an iterator.
_.sortBy = function(obj, value, context) { _.sortBy = function(obj, iterator, context) {
var iterator = lookupIterator(value); iterator = lookupIterator(iterator);
return _.pluck(_.map(obj, function(value, index, list) { return _.pluck(_.map(obj, function(value, index, list) {
return { return {
value: value, value: value,
@ -334,9 +336,9 @@
// An internal function used for aggregate "group by" operations. // An internal function used for aggregate "group by" operations.
var group = function(behavior) { var group = function(behavior) {
return function(obj, value, context) { return function(obj, iterator, context) {
var result = {}; var result = {};
var iterator = value == null ? _.identity : lookupIterator(value); iterator = lookupIterator(iterator);
each(obj, function(value, index) { each(obj, function(value, index) {
var key = iterator.call(context, value, index, obj); var key = iterator.call(context, value, index, obj);
behavior(result, key, value); behavior(result, key, value);
@ -348,7 +350,7 @@
// Groups the object's values by a criterion. Pass either a string attribute // Groups the object's values by a criterion. Pass either a string attribute
// to group by, or a function that returns the criterion. // to group by, or a function that returns the criterion.
_.groupBy = group(function(result, key, value) { _.groupBy = group(function(result, key, value) {
(_.has(result, key) ? result[key] : (result[key] = [])).push(value); _.has(result, key) ? result[key].push(value) : result[key] = [value];
}); });
// Indexes the object's values by a criterion, similar to `groupBy`, but for // Indexes the object's values by a criterion, similar to `groupBy`, but for
@ -367,7 +369,7 @@
// Use a comparator function to figure out the smallest index at which // Use a comparator function to figure out the smallest index at which
// an object should be inserted so as to maintain order. Uses binary search. // an object should be inserted so as to maintain order. Uses binary search.
_.sortedIndex = function(array, obj, iterator, context) { _.sortedIndex = function(array, obj, iterator, context) {
iterator = iterator == null ? _.identity : lookupIterator(iterator); iterator = lookupIterator(iterator);
var value = iterator.call(context, obj); var value = iterator.call(context, obj);
var low = 0, high = array.length; var low = 0, high = array.length;
while (low < high) { while (low < high) {
@ -399,7 +401,9 @@
// allows it to work with `_.map`. // allows it to work with `_.map`.
_.first = _.head = _.take = function(array, n, guard) { _.first = _.head = _.take = function(array, n, guard) {
if (array == null) return void 0; if (array == null) return void 0;
return (n == null) || guard ? array[0] : slice.call(array, 0, n); if ((n == null) || guard) return array[0];
if (n < 0) return [];
return slice.call(array, 0, n);
}; };
// Returns everything but the last entry of the array. Especially useful on // Returns everything but the last entry of the array. Especially useful on
@ -414,11 +418,8 @@
// values in the array. The **guard** check allows it to work with `_.map`. // values in the array. The **guard** check allows it to work with `_.map`.
_.last = function(array, n, guard) { _.last = function(array, n, guard) {
if (array == null) return void 0; if (array == null) return void 0;
if ((n == null) || guard) { if ((n == null) || guard) return array[array.length - 1];
return array[array.length - 1]; return slice.call(array, Math.max(array.length - n, 0));
} else {
return slice.call(array, Math.max(array.length - n, 0));
}
}; };
// Returns everything but the first entry of the array. Aliased as `tail` and `drop`. // Returns everything but the first entry of the array. Aliased as `tail` and `drop`.
@ -459,6 +460,17 @@
return _.difference(array, slice.call(arguments, 1)); return _.difference(array, slice.call(arguments, 1));
}; };
// Split an array into two arrays: one whose elements all satisfy the given
// predicate, and one whose elements all do not satisfy the predicate.
_.partition = function(array, predicate, context) {
predicate = lookupIterator(predicate);
var pass = [], fail = [];
each(array, function(elem) {
(predicate.call(context, elem) ? pass : fail).push(elem);
});
return [pass, fail];
};
// Produce a duplicate-free version of the array. If the array has already // Produce a duplicate-free version of the array. If the array has already
// been sorted, you have the option of using a faster algorithm. // been sorted, you have the option of using a faster algorithm.
// Aliased as `unique`. // Aliased as `unique`.
@ -492,7 +504,7 @@
var rest = slice.call(arguments, 1); var rest = slice.call(arguments, 1);
return _.filter(_.uniq(array), function(item) { return _.filter(_.uniq(array), function(item) {
return _.every(rest, function(other) { return _.every(rest, function(other) {
return _.indexOf(other, item) >= 0; return _.contains(other, item);
}); });
}); });
}; };
@ -507,7 +519,7 @@
// Zip together multiple lists into a single array -- elements that share // Zip together multiple lists into a single array -- elements that share
// an index go together. // an index go together.
_.zip = function() { _.zip = function() {
var length = _.max(_.pluck(arguments, "length").concat(0)); var length = _.max(_.pluck(arguments, 'length').concat(0));
var results = new Array(length); var results = new Array(length);
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
results[i] = _.pluck(arguments, '' + i); results[i] = _.pluck(arguments, '' + i);
@ -613,19 +625,27 @@
}; };
// Partially apply a function by creating a version that has had some of its // Partially apply a function by creating a version that has had some of its
// arguments pre-filled, without changing its dynamic `this` context. // arguments pre-filled, without changing its dynamic `this` context. _ acts
// as a placeholder, allowing any combination of arguments to be pre-filled.
_.partial = function(func) { _.partial = function(func) {
var args = slice.call(arguments, 1); var boundArgs = slice.call(arguments, 1);
return function() { return function() {
return func.apply(this, args.concat(slice.call(arguments))); var position = 0;
var args = boundArgs.slice();
for (var i = 0, length = args.length; i < length; i++) {
if (args[i] === _) args[i] = arguments[position++];
}
while (position < arguments.length) args.push(arguments[position++]);
return func.apply(this, args);
}; };
}; };
// Bind all of an object's methods to that object. Useful for ensuring that // Bind a number of an object's methods to that object. Remaining arguments
// all callbacks defined on an object belong to it. // are the method names to be bound. Useful for ensuring that all callbacks
// defined on an object belong to it.
_.bindAll = function(obj) { _.bindAll = function(obj) {
var funcs = slice.call(arguments, 1); var funcs = slice.call(arguments, 1);
if (funcs.length === 0) throw new Error("bindAll must be passed function names"); if (funcs.length === 0) throw new Error('bindAll must be passed function names');
each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
return obj; return obj;
}; };
@ -664,12 +684,13 @@
var previous = 0; var previous = 0;
options || (options = {}); options || (options = {});
var later = function() { var later = function() {
previous = options.leading === false ? 0 : new Date; previous = options.leading === false ? 0 : _.now();
timeout = null; timeout = null;
result = func.apply(context, args); result = func.apply(context, args);
context = args = null;
}; };
return function() { return function() {
var now = new Date; var now = _.now();
if (!previous && options.leading === false) previous = now; if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous); var remaining = wait - (now - previous);
context = this; context = this;
@ -679,6 +700,7 @@
timeout = null; timeout = null;
previous = now; previous = now;
result = func.apply(context, args); result = func.apply(context, args);
context = args = null;
} else if (!timeout && options.trailing !== false) { } else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining); timeout = setTimeout(later, remaining);
} }
@ -692,24 +714,33 @@
// leading edge, instead of the trailing. // leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) { _.debounce = function(func, wait, immediate) {
var timeout, args, context, timestamp, result; var timeout, args, context, timestamp, result;
var later = function() {
var last = _.now() - timestamp;
if (last < wait) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
context = args = null;
}
}
};
return function() { return function() {
context = this; context = this;
args = arguments; args = arguments;
timestamp = new Date(); timestamp = _.now();
var later = function() {
var last = (new Date()) - timestamp;
if (last < wait) {
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if (!immediate) result = func.apply(context, args);
}
};
var callNow = immediate && !timeout; var callNow = immediate && !timeout;
if (!timeout) { if (!timeout) {
timeout = setTimeout(later, wait); timeout = setTimeout(later, wait);
} }
if (callNow) result = func.apply(context, args); if (callNow) {
result = func.apply(context, args);
context = args = null;
}
return result; return result;
}; };
}; };
@ -731,11 +762,7 @@
// allowing you to adjust arguments, run code before and after, and // allowing you to adjust arguments, run code before and after, and
// conditionally execute the original function. // conditionally execute the original function.
_.wrap = function(func, wrapper) { _.wrap = function(func, wrapper) {
return function() { return _.partial(wrapper, func);
var args = [func];
push.apply(args, arguments);
return wrapper.apply(this, args);
};
}; };
// Returns a function that is the composition of a list of functions, each // Returns a function that is the composition of a list of functions, each
@ -765,8 +792,9 @@
// Retrieve the names of an object's properties. // Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys` // Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = nativeKeys || function(obj) { _.keys = function(obj) {
if (obj !== Object(obj)) throw new TypeError('Invalid object'); if (!_.isObject(obj)) return [];
if (nativeKeys) return nativeKeys(obj);
var keys = []; var keys = [];
for (var key in obj) if (_.has(obj, key)) keys.push(key); for (var key in obj) if (_.has(obj, key)) keys.push(key);
return keys; return keys;
@ -921,7 +949,8 @@
// from different frames are. // from different frames are.
var aCtor = a.constructor, bCtor = b.constructor; var aCtor = a.constructor, bCtor = b.constructor;
if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
_.isFunction(bCtor) && (bCtor instanceof bCtor))) { _.isFunction(bCtor) && (bCtor instanceof bCtor))
&& ('constructor' in a && 'constructor' in b)) {
return false; return false;
} }
// Add the first object to the stack of traversed objects. // Add the first object to the stack of traversed objects.
@ -1061,6 +1090,30 @@
return value; return value;
}; };
_.constant = function(value) {
return function () {
return value;
};
};
_.property = function(key) {
return function(obj) {
return obj[key];
};
};
// Returns a predicate for checking whether an object has a given set of `key:value` pairs.
_.matches = function(attrs) {
return function(obj) {
if (obj === attrs) return true; //avoid comparing an object to itself.
for (var key in attrs) {
if (attrs[key] !== obj[key])
return false;
}
return true;
}
};
// Run a function **n** times. // Run a function **n** times.
_.times = function(n, iterator, context) { _.times = function(n, iterator, context) {
var accum = Array(Math.max(0, n)); var accum = Array(Math.max(0, n));
@ -1077,6 +1130,9 @@
return min + Math.floor(Math.random() * (max - min + 1)); return min + Math.floor(Math.random() * (max - min + 1));
}; };
// A (possibly faster) way to get the current timestamp as an integer.
_.now = Date.now || function() { return new Date().getTime(); };
// List of HTML entities for escaping. // List of HTML entities for escaping.
var entityMap = { var entityMap = {
escape: { escape: {
@ -1273,4 +1329,16 @@
}); });
// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
// practice for AMD registration is to be anonymous, underscore registers
// as a named module because, like jQuery, it is a base library that is
// popular enough to be bundled in a third party lib, but not be part of
// an AMD load request. Those cases could generate an error when an
// anonymous define() is called outside of a loader request.
if (typeof define === 'function' && define.amd) {
define('underscore', [], function() {
return _;
});
}
}).call(this); }).call(this);

View File

@ -368,6 +368,7 @@
.openerp .oe_left { .openerp .oe_left {
float: left; float: left;
margin-right: 8px; margin-right: 8px;
width: 305px;
} }
.openerp .oe_right { .openerp .oe_right {
float: right; float: right;
@ -456,11 +457,46 @@
background: #ed6f6a; background: #ed6f6a;
} }
.openerp .oe_button_box { .openerp .oe_button_box {
width: 270px; width: 400px;
text-align: right; text-align: left;
} }
.openerp .oe_button_box button { .openerp .oe_button_box .oe_stat_button:hover {
margin: 4px; background: #7c7bad;
color: white;
}
.openerp .oe_button_box .oe_stat_button:hover .fa {
color: white;
}
.openerp .oe_button_box .oe_stat_button {
font-weight: normal;
display: inline-table;
width: 33% !important;
height: 42px;
margin: 0px -1px -1px 0px;
padding: 0;
color: #666666;
border: 1px solid #dddddd;
border-radius: 0;
box-shadow: none;
background: white;
}
.openerp .oe_button_box .oe_stat_button > div {
display: table-cell;
vertical-align: middle;
text-align: left;
padding: 0;
line-height: 120%;
}
.openerp .oe_button_box .oe_stat_button .stat_button_icon {
color: #7c7bad;
font-size: 24px;
padding: 0px 3px;
width: 37px;
text-align: center;
}
.openerp .oe_button_box .oe_stat_button svg {
width: 38px;
height: 38px;
} }
.openerp .oe_avatar > img { .openerp .oe_avatar > img {
max-height: 90px; max-height: 90px;
@ -2339,10 +2375,9 @@
} }
.openerp .oe_form .oe_form_embedded_html { .openerp .oe_form .oe_form_embedded_html {
position: relative; position: relative;
width: 600px; width: 100%;
margin-left: 130px; margin: auto;
margin-top: 32px; overflow: auto;
margin-bottom: 32px;
text-align: justify; text-align: justify;
} }
.openerp .oe_form .oe_form_field_html .oe_input_icon { .openerp .oe_form .oe_form_field_html .oe_input_icon {

View File

@ -385,6 +385,7 @@ $sheet-padding: 16px
.oe_left .oe_left
float: left float: left
margin-right: 8px margin-right: 8px
width: 305px
.oe_right .oe_right
float: right float: right
margin-left: 8px margin-left: 8px
@ -429,10 +430,40 @@ $sheet-padding: 16px
&:hover &:hover
background: #ED6F6A background: #ED6F6A
.oe_button_box .oe_button_box
width: 270px width: 400px
text-align: right text-align: left
button .oe_stat_button:hover
margin: 4px background: #7c7bad
color: white
.fa
color: white
.oe_stat_button
font-weight: normal
display: inline-table
width: 33% !important
height: 42px
margin: 0px -1px -1px 0px
padding: 0
color: #666
border: 1px solid #dddddd
border-radius: 0
box-shadow: none
background: white
> div
display: table-cell
vertical-align: middle
text-align: left
padding: 0
line-height: 120%
.stat_button_icon
color: #7C7BAD
font-size: 24px
padding: 0px 3px
width: 37px
text-align: center
svg
width: 38px
height: 38px
.oe_avatar .oe_avatar
> img > img
max-height: 90px max-height: 90px
@ -1893,10 +1924,9 @@ $sheet-padding: 16px
overflow: hidden overflow: hidden
.oe_form_embedded_html .oe_form_embedded_html
position: relative position: relative
width: 600px width: 100%
margin-left: 130px margin: auto
margin-top: 32px overflow: auto
margin-bottom: 32px
text-align: justify text-align: justify
.oe_form_field_html .oe_input_icon .oe_form_field_html .oe_input_icon
float: right float: right

View File

@ -1337,12 +1337,13 @@ instance.web.WebClient = instance.web.Client.extend({
if (_.isEmpty(state) || state.action == "login") { if (_.isEmpty(state) || state.action == "login") {
self.menu.has_been_loaded.done(function() { self.menu.has_been_loaded.done(function() {
new instance.web.Model("res.users").call("read", [self.session.uid, ["action_id"]]).done(function(data) { new instance.web.Model("res.users").call("read", [self.session.uid, ["action_id"]]).done(function(data) {
var first_menu_id = self.menu.$el.find("a:first").data("menu");
if(first_menu_id)
self.menu.menu_click(first_menu_id);
if(data.action_id) { if(data.action_id) {
self.action_manager.do_action(data.action_id[0]); self.action_manager.do_action(data.action_id[0]);
self.menu.open_action(data.action_id[0]);
} else {
var first_menu_id = self.menu.$el.find("a:first").data("menu");
if(first_menu_id)
self.menu.menu_click(first_menu_id);
} }
}); });
}); });

View File

@ -221,11 +221,12 @@ instance.web.QueryGroup = instance.web.Class.extend({
{__context: {group_by: []}, __domain: []}, {__context: {group_by: []}, __domain: []},
read_group_group); read_group_group);
var raw_field = grouping_field && grouping_field.split(':')[0];
var aggregates = {}; var aggregates = {};
_(fixed_group).each(function (value, key) { _(fixed_group).each(function (value, key) {
if (key.indexOf('__') === 0 if (key.indexOf('__') === 0
|| key === grouping_field || key === raw_field
|| key === grouping_field + '_count') { || key === raw_field + '_count') {
return; return;
} }
aggregates[key] = value || 0; aggregates[key] = value || 0;
@ -234,7 +235,6 @@ instance.web.QueryGroup = instance.web.Class.extend({
this.model = new instance.web.Model( this.model = new instance.web.Model(
model, fixed_group.__context, fixed_group.__domain); model, fixed_group.__context, fixed_group.__domain);
var raw_field = grouping_field && grouping_field.split(':')[0];
var group_size = fixed_group[raw_field + '_count'] || fixed_group.__count || 0; var group_size = fixed_group[raw_field + '_count'] || fixed_group.__count || 0;
var leaf_group = fixed_group.__context.group_by.length === 0; var leaf_group = fixed_group.__context.group_by.length === 0;
@ -448,7 +448,8 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
* Read records. * Read records.
* *
* @param {Array} ids identifiers of the records to read * @param {Array} ids identifiers of the records to read
* @param {Array} fields fields to read and return, by default all fields are returned * @param {Array} [fields] fields to read and return, by default all fields are returned
* @param {Object} [options]
* @returns {$.Deferred} * @returns {$.Deferred}
*/ */
read_ids: function (ids, fields, options) { read_ids: function (ids, fields, options) {
@ -456,10 +457,20 @@ instance.web.DataSet = instance.web.Class.extend(instance.web.PropertiesMixin,
return $.Deferred().resolve([]); return $.Deferred().resolve([]);
options = options || {}; options = options || {};
// TODO: reorder results to match ids list
return this._model.call('read', return this._model.call('read',
[ids, fields || false], [ids, fields || false],
{context: this.get_context(options.context)}); {context: this.get_context(options.context)})
.then(function (records) {
if (records.length <= 1) { return records; }
var indexes = {};
for (var i = 0; i < ids.length; i++) {
indexes[ids[i]] = i;
}
records.sort(function (a, b) {
return indexes[a.id] - indexes[b.id];
});
return records;
});
}, },
/** /**
* Read a slice of the records represented by this DataSet, based on its * Read a slice of the records represented by this DataSet, based on its
@ -904,6 +915,10 @@ instance.web.BufferedDataSet = instance.web.DataSetStatic.extend({
sign = -1; sign = -1;
field = field.slice(1); field = field.slice(1);
} }
//m2o should be searched based on value[1] not based whole value(i.e. [id, value])
if(_.isArray(a[field]) && a[field].length == 2 && _.isString(a[field][1])){
return sign * compare(a[field][1], b[field][1]);
}
return sign * compare(a[field], b[field]); return sign * compare(a[field], b[field]);
}, 0); }, 0);
}); });

View File

@ -119,6 +119,7 @@ instance.web.DataExport = instance.web.Dialog.extend({
if (select_exp.val()) { if (select_exp.val()) {
self.exports.unlink([parseInt(select_exp.val(), 10)]); self.exports.unlink([parseInt(select_exp.val(), 10)]);
select_exp.remove(); select_exp.remove();
self.$el.find("#fields_list option").remove();
if (self.$el.find('#saved_export_list option').length <= 1) { if (self.$el.find('#saved_export_list option').length <= 1) {
self.$el.find('#ExistsExportList').hide(); self.$el.find('#ExistsExportList').hide();
} }
@ -166,18 +167,16 @@ instance.web.DataExport = instance.web.Dialog.extend({
export_fields: _(fields).map(function (field) { export_fields: _(fields).map(function (field) {
return [0, 0, {name: field}]; return [0, 0, {name: field}];
}) })
}, function (export_list_id) { }).then(function (export_list_id) {
if (!export_list_id.result) { if (!export_list_id) {
return; return;
} }
self.$el.find("#saved_export_list").append( if (!self.$el.find("#saved_export_list").length || self.$el.find("#saved_export_list").is(":hidden")) {
new Option(value, export_list_id.result));
if (self.$el.find("#saved_export_list").is(":hidden")) {
self.show_exports_list(); self.show_exports_list();
} }
self.$el.find("#saved_export_list").append( new Option(value, export_list_id) );
}); });
this.on_show_save_list(); this.on_show_save_list();
this.$el.find("#fields_list option").remove();
}, },
on_click: function(id, record) { on_click: function(id, record) {
var self = this; var self = this;

View File

@ -355,7 +355,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
} }
}, },
'autocompleteopen': function () { 'autocompleteopen': function () {
this.$el.autocomplete('widget').css('z-index', 1004); this.$el.autocomplete('widget').css('z-index', 9999);
}, },
}, },
/** /**
@ -677,6 +677,11 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
* @returns instance.web.search.Field * @returns instance.web.search.Field
*/ */
make_field: function (item, field, parent) { make_field: function (item, field, parent) {
// M2O combined with selection widget is pointless and broken in search views,
// but has been used in the past for unsupported hacks -> ignore it
if (field.type === "many2one" && item.attrs.widget === "selection"){
item.attrs.widget = undefined;
}
var obj = instance.web.search.fields.get_any( [item.attrs.widget, field.type]); var obj = instance.web.search.fields.get_any( [item.attrs.widget, field.type]);
if(obj) { if(obj) {
return new (obj) (item, field, parent || this); return new (obj) (item, field, parent || this);

View File

@ -1277,6 +1277,9 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
var defs = []; var defs = [];
_.each(this.to_replace, function(el) { _.each(this.to_replace, function(el) {
defs.push(el[0].replace(el[1])); defs.push(el[0].replace(el[1]));
if (el[1].children().length) {
el[0].$el.append(el[1].children());
}
}); });
this.to_replace = []; this.to_replace = [];
return $.when.apply($, defs); return $.when.apply($, defs);
@ -1304,7 +1307,7 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
var tagname = $tag[0].nodeName.toLowerCase(); var tagname = $tag[0].nodeName.toLowerCase();
if (this.tags_registry.contains(tagname)) { if (this.tags_registry.contains(tagname)) {
this.tags_to_init.push($tag); this.tags_to_init.push($tag);
return $tag; return (tagname === 'button') ? this.process_button($tag) : $tag;
} }
var fn = self['process_' + tagname]; var fn = self['process_' + tagname];
if (fn) { if (fn) {
@ -1321,6 +1324,13 @@ instance.web.form.FormRenderingEngine = instance.web.form.FormRenderingEngineInt
return $tag; return $tag;
} }
}, },
process_button: function ($button) {
var self = this;
$button.children().each(function() {
self.process($(this));
});
return $button;
},
process_widget: function($widget) { process_widget: function($widget) {
this.widgets_to_init.push($widget); this.widgets_to_init.push($widget);
return $widget; return $widget;
@ -1906,6 +1916,8 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({
template: 'WidgetButton', template: 'WidgetButton',
init: function(field_manager, node) { init: function(field_manager, node) {
node.attrs.type = node.attrs['data-button-type']; node.attrs.type = node.attrs['data-button-type'];
this.is_stat_button = /\boe_stat_button\b/.test(node.attrs['class']);
this.icon = node.attrs.icon && "<span class=\"fa " + node.attrs.icon + " fa-fw\"></span>";
this._super(field_manager, node); this._super(field_manager, node);
this.force_disabled = false; this.force_disabled = false;
this.string = (this.node.attrs.string || '').replace(/_/g, ''); this.string = (this.node.attrs.string || '').replace(/_/g, '');
@ -1976,7 +1988,6 @@ instance.web.form.WidgetButton = instance.web.form.FormWidget.extend({
var self = this; var self = this;
var context = this.build_context(); var context = this.build_context();
return this.view.do_execute_action( return this.view.do_execute_action(
_.extend({}, this.node.attrs, {context: context}), _.extend({}, this.node.attrs, {context: context}),
this.view.dataset, this.view.datarecord.id, function () { this.view.dataset, this.view.datarecord.id, function () {
@ -2805,6 +2816,50 @@ instance.web.form.FieldProgressBar = instance.web.form.AbstractField.extend({
} }
}); });
/**
The PercentPie field expect a float from 0 to 100.
*/
instance.web.form.FieldPercentPie = instance.web.form.AbstractField.extend({
template: 'FieldPercentPie',
render_value: function() {
var value = this.get('value'),
formatted_value = Math.round(value || 0) + '%',
svg = this.$('svg')[0];
svg.innerHTML = "";
nv.addGraph(function() {
var size=43;
var chart = nv.models.pieChart()
.width(size)
.height(size)
.margin({top: 0, right: 0, bottom: 0, left: 0})
.donut(true)
.showLegend(false)
.showLabels(false)
.tooltips(false)
.color(['#7C7BAD','#DDD'])
.donutRatio(0.62);
d3.select(svg)
.datum([{'x': 'value', 'y': value}, {'x': 'complement', 'y': 100 - value}])
.transition()
.call(chart)
.attr({width:size, height:size});
d3.select(svg)
.append("text")
.attr({x: size/2, y: size/2 + 3, 'text-anchor': 'middle'})
.style({"font-size": "10px", "font-weight": "bold"})
.text(formatted_value);
return chart;
});
}
});
instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, { instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, {
template: 'FieldSelection', template: 'FieldSelection',
@ -2835,9 +2890,7 @@ instance.web.form.FieldSelection = instance.web.form.AbstractField.extend(instan
var def; var def;
if (this.field.type === "many2one") { if (this.field.type === "many2one") {
var model = new openerp.Model(openerp.session, this.field.relation); var model = new openerp.Model(openerp.session, this.field.relation);
def = model.call("search", [this.get("domain")], {"context": this.build_context()}).then(function(record_ids) { def = model.call("name_search", ['', this.get("domain")], {"context": this.build_context()});
return model.call("name_get", [record_ids] , {"context": self.build_context()});
});
} else { } else {
var values = _.reject(this.field.selection, function (v) { return v[0] === false && v[1] === ''; }); var values = _.reject(this.field.selection, function (v) { return v[0] === false && v[1] === ''; });
def = $.when(values); def = $.when(values);
@ -3127,7 +3180,8 @@ instance.web.form.CompletionFieldMixin = {
if (self.options.quick_create === undefined || self.options.quick_create) { if (self.options.quick_create === undefined || self.options.quick_create) {
new instance.web.DataSet(this, this.field.relation, self.build_context()) new instance.web.DataSet(this, this.field.relation, self.build_context())
.name_create(name).done(function(data) { .name_create(name).done(function(data) {
self.add_id(data[0]); if (!self.get('effective_readonly'))
self.add_id(data[0]);
}).fail(function(error, event) { }).fail(function(error, event) {
event.preventDefault(); event.preventDefault();
slow_create(); slow_create();
@ -5007,7 +5061,7 @@ instance.web.form.SelectCreatePopup = instance.web.form.AbstractFormPopup.extend
this.searchview.on('search_data', self, function(domains, contexts, groupbys) { this.searchview.on('search_data', self, function(domains, contexts, groupbys) {
if (self.initial_ids) { if (self.initial_ids) {
self.do_search(domains.concat([[["id", "in", self.initial_ids]], self.domain]), self.do_search(domains.concat([[["id", "in", self.initial_ids]], self.domain]),
contexts, groupbys); contexts.concat(self.context), groupbys);
self.initial_ids = undefined; self.initial_ids = undefined;
} else { } else {
self.do_search(domains.concat([self.domain]), contexts.concat(self.context), groupbys); self.do_search(domains.concat([self.domain]), contexts.concat(self.context), groupbys);
@ -5852,6 +5906,26 @@ instance.web.form.X2ManyCounter = instance.web.form.AbstractField.extend(instanc
} }
}); });
/**
This widget is intended to be used on stat button numeric fields. It will display
the value many2many and one2many. It is a read-only field that will
display a simple string "<value of field> <label of the field>"
*/
instance.web.form.StatInfo = instance.web.form.AbstractField.extend({
init: function() {
this._super.apply(this, arguments);
this.set("value", 0);
},
render_value: function() {
var options = {
value: this.get("value") || 0,
text: this.string,
};
this.$el.html(QWeb.render("StatInfo", options));
},
});
/** /**
* Registry of form fields, called by :js:`instance.web.FormView`. * Registry of form fields, called by :js:`instance.web.FormView`.
* *
@ -5879,6 +5953,7 @@ instance.web.form.widgets = new instance.web.Registry({
'reference' : 'instance.web.form.FieldReference', 'reference' : 'instance.web.form.FieldReference',
'boolean' : 'instance.web.form.FieldBoolean', 'boolean' : 'instance.web.form.FieldBoolean',
'float' : 'instance.web.form.FieldFloat', 'float' : 'instance.web.form.FieldFloat',
'percentpie': 'instance.web.form.FieldPercentPie',
'integer': 'instance.web.form.FieldFloat', 'integer': 'instance.web.form.FieldFloat',
'float_time': 'instance.web.form.FieldFloat', 'float_time': 'instance.web.form.FieldFloat',
'progressbar': 'instance.web.form.FieldProgressBar', 'progressbar': 'instance.web.form.FieldProgressBar',
@ -5889,6 +5964,7 @@ instance.web.form.widgets = new instance.web.Registry({
'monetary': 'instance.web.form.FieldMonetary', 'monetary': 'instance.web.form.FieldMonetary',
'many2many_checkboxes': 'instance.web.form.FieldMany2ManyCheckBoxes', 'many2many_checkboxes': 'instance.web.form.FieldMany2ManyCheckBoxes',
'x2many_counter': 'instance.web.form.X2ManyCounter', 'x2many_counter': 'instance.web.form.X2ManyCounter',
'statinfo': 'instance.web.form.StatInfo',
}); });
/** /**

View File

@ -408,6 +408,9 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
if (total) { if (total) {
var range_start = this.page * limit + 1; var range_start = this.page * limit + 1;
var range_stop = range_start - 1 + limit; var range_stop = range_start - 1 + limit;
if (this.records.length) {
range_stop = range_start - 1 + this.records.length;
}
if (range_stop > total) { if (range_stop > total) {
range_stop = total; range_stop = total;
} }
@ -602,7 +605,17 @@ instance.web.ListView = instance.web.View.extend( /** @lends instance.web.ListVi
_(ids).each(function (id) { _(ids).each(function (id) {
self.records.remove(self.records.get(id)); self.records.remove(self.records.get(id));
}); });
self.configure_pager(self.dataset); if (self.records.length === 0 && self.dataset.size() > 0) {
//Trigger previous manually to navigate to previous page,
//If all records are deleted on current page.
self.$pager.find('ul li:first a').trigger('click');
} else if (self.dataset.size() == self.limit()) {
//Reload listview to update current page with next page records
//because pager going to be hidden if dataset.size == limit
self.reload();
} else {
self.configure_pager(self.dataset);
}
self.compute_aggregates(); self.compute_aggregates();
}); });
}, },

View File

@ -231,17 +231,24 @@
</div> </div>
<table align="center" class="db_option_table"> <table align="center" class="db_option_table">
<tr> <tr>
<td><label for="restore_db">File:</label></td> <td><label for="restore_pwd">Master Password:</label></td>
<td><input type="file" name="db_file" class="required" autofocus="autofocus"/></td> <td><input type="password" name="restore_pwd" class="required" autofocus="autofocus"/></td>
</tr> </tr>
<tr> <tr>
<td><label for="restore_pwd">Master Password:</label></td> <td><label for="restore_db">File:</label></td>
<td><input type="password" name="restore_pwd" class="required"/></td> <td><input type="file" name="db_file" class="required"/></td>
</tr> </tr>
<tr> <tr>
<td><label for="new_db">New database name:</label></td> <td><label for="new_db">New database name:</label></td>
<td><input type="text" name="new_db" class="required"/></td> <td><input type="text" name="new_db" class="required"/></td>
</tr> </tr>
<tr>
<td><label for="mode">Mode:</label></td>
<td><select name="mode" class="required">
<option value="restore">Backup Restore</option>
<option value="copy">Copy of an existing database</option>
</select></td>
</tr>
</table> </table>
</form> </form>
<form id="db_change_password" name="change_pwd_form" style="display: none;"> <form id="db_change_password" name="change_pwd_form" style="display: none;">
@ -1188,6 +1195,11 @@
<span></span> <span></span>
</span> </span>
</t> </t>
<t t-name="FieldPercentPie">
<span class="oe_form_field oe_form_field_percent_pie" t-att-style="widget.node.attrs.style">
<svg></svg>
</span>
</t>
<t t-name="FieldStatus"> <t t-name="FieldStatus">
<ul t-att-class="'oe_form_field_status ' + (widget.options.clickable ? 'oe_form_status_clickable' : 'oe_form_status')" t-att-style="widget.node.attrs.style"/> <ul t-att-class="'oe_form_field_status ' + (widget.options.clickable ? 'oe_form_status_clickable' : 'oe_form_status')" t-att-style="widget.node.attrs.style"/>
</t> </t>
@ -1351,13 +1363,15 @@
</div> </div>
</t> </t>
<t t-name="WidgetButton"> <t t-name="WidgetButton">
<button type="button" class="oe_button oe_form_button" <button type="button" t-att-class="widget.is_stat_button ? 'oe_stat_button btn btn-default' : 'oe_button oe_form_button'"
t-att-style="widget.node.attrs.style" t-att-style="widget.node.attrs.style"
t-att-tabindex="widget.node.attrs.tabindex" t-att-tabindex="widget.node.attrs.tabindex"
t-att-autofocus="widget.node.attrs.autofocus" t-att-autofocus="widget.node.attrs.autofocus"
t-att-accesskey="widget.node.attrs.accesskey"> t-att-accesskey="widget.node.attrs.accesskey">
<img t-if="widget.node.attrs.icon" t-att-src="_s + widget.node.attrs.icon" width="16" height="16"/> <img t-if="!widget.is_stat_button and widget.node.attrs.icon " t-att-src="_s + widget.node.attrs.icon" width="16" height="16"/>
<span t-if="widget.string"><t t-esc="widget.string"/></span> <div t-if="widget.is_stat_button" class="stat_button_icon"><t t-if="widget.icon" t-raw="widget.icon"/></div>
<span t-if="widget.string and !widget.is_stat_button"><t t-esc="widget.string"/></span>
<div t-if="widget.string and widget.is_stat_button"><t t-esc="widget.string"/></div>
</button> </button>
</t> </t>
<t t-name="WidgetButton.tooltip" t-extend="WidgetLabel.tooltip"> <t t-name="WidgetButton.tooltip" t-extend="WidgetLabel.tooltip">
@ -1930,4 +1944,6 @@
<t t-name="X2ManyCounter"> <t t-name="X2ManyCounter">
<a href="javascript:void(0)"><t t-esc="text"/></a> <a href="javascript:void(0)"><t t-esc="text"/></a>
</t> </t>
<t t-name="StatInfo">
<strong><t t-esc="value"/></strong><br/><t t-esc="text"/></t>
</templates> </templates>

View File

@ -1,3 +1,32 @@
openerp.testing.section('data.dataset', {
rpc: 'mock',
dependencies: ['web.data'],
}, function (test) {
test('read_ids', {asserts: 2}, function (instance, _, mock) {
var d = new instance.web.DataSet(null, 'foo');
mock('foo:read', function (args) {
var ids = args[0];
deepEqual(ids, [3, 1, 2]);
return [
{id: 1, a: 'bar'},
{id: 2, a: 'baz'},
{id: 3, a: 'foo'}
];
});
return d.read_ids([3, 1, 2]).then(function (records) {
deepEqual(
records,
[
{id: 3, a: 'foo'},
{id: 1, a: 'bar'},
{id: 2, a: 'baz'}
]
)
});
})
});
openerp.testing.section('data.model.group_by', { openerp.testing.section('data.model.group_by', {
rpc: 'mock', rpc: 'mock',
dependencies: ['web.data'], dependencies: ['web.data'],

View File

@ -1,152 +0,0 @@
(function() {
var ropenerp = window.openerp;
var openerp = ropenerp.declare($, _, QWeb2);
ropenerp.testing.section('jsonrpc', {},
function (test) {
test('basic-jsonrpc', {asserts: 1}, function () {
var session = new openerp.Session();
return session.rpc("/gen_session_id", {}).then(function(result) {
ok(result.length > 0, "Result returned by /gen_session_id");
});
});
test('basic-jsonprpc', {asserts: 1}, function () {
var session = new openerp.Session();
session.origin_server = false;
return session.rpc("/gen_session_id", {}).then(function(result) {
ok(result.length > 0, "Result returned by /gen_session_id");
});
});
// desactivated because the phantomjs runner crash
/*test('basic-jsonprpc2', {asserts: 1}, function () {
var session = new openerp.Session();
session.origin_server = false;
return session.rpc("/gen_session_id", {}, {force2step: true}).then(function(result) {
ok(result.length > 0, "Result returned by /gen_session_id");
});
});*/
test('session-jsonrpc', {asserts: 2}, function () {
var session = new openerp.Session();
var tmp = _.uniqueId("something");
return session.rpc("/web/tests/set_session_value", {value: tmp}).then(function() {
ok(true, "set_session returned");
return session.rpc("/web/tests/get_session_value", {});
}).then(function(result) {
equal(result, tmp, "Got the same value from the session");
});
});
test('session-jsonprpc', {asserts: 2}, function () {
var session = new openerp.Session();
session.origin_server = false;
var tmp = _.uniqueId("something");
return session.rpc("/web/tests/set_session_value", {value: tmp}).then(function() {
ok(true, "set_session returned");
return session.rpc("/web/tests/get_session_value", {});
}).then(function(result) {
equal(result, tmp, "Got the same value from the session");
});
});
// desactivated because the phantomjs runner crash
/*test('session-jsonprpc2', {asserts: 2}, function () {
var session = new openerp.Session();
session.origin_server = false;
var tmp = _.uniqueId("something");
return session.rpc("/web/tests/set_session_value", {value: tmp}, {force2step: true}).then(function() {
ok(true, "set_session returned");
return session.rpc("/web/tests/get_session_value", {}, {force2step: true});
}).then(function(result) {
equal(result, tmp, "Got the same value from the session");
});
});*/
test('overridesession-jsonrpc', {asserts: 4}, function () {
var origin_session = new openerp.Session();
var origin_tmp = _.uniqueId("something");
var session = new openerp.Session(null, null, {override_session: true});
var tmp = _.uniqueId("something_else");
return session.rpc("/web/tests/set_session_value", {value: tmp}).then(function() {
ok(true, "set_session returned");
return origin_session.rpc("/web/tests/set_session_value", {value: origin_tmp});
}).then(function(result) {
ok(true, "set_session on origin returned");
return session.rpc("/web/tests/get_session_value", {});
}).then(function(result) {
equal(result, tmp, "Got the same value from the session");
notEqual(result, origin_tmp, "Values in the different sessions should be different");
});
});
test('overridesession-jsonprpc', {asserts: 4}, function () {
var origin_session = new openerp.Session();
var origin_tmp = _.uniqueId("something");
var session = new openerp.Session(null, null, {override_session: true});
var tmp = _.uniqueId("something_else");
session.origin_server = false;
return session.rpc("/web/tests/set_session_value", {value: tmp}).then(function() {
ok(true, "set_session returned");
return origin_session.rpc("/web/tests/set_session_value", {value: origin_tmp});
}).then(function(result) {
ok(true, "set_session on origin returned");
return session.rpc("/web/tests/get_session_value", {});
}).then(function(result) {
equal(result, tmp, "Got the same value from the session");
notEqual(result, origin_tmp, "Values in the different sessions should be different");
});
});
// desactivated because the phantomjs runner crash
/*test('overridesession-jsonprpc2', {asserts: 4}, function () {
var origin_session = new openerp.Session();
var origin_tmp = _.uniqueId("something");
var session = new openerp.Session(null, null, {override_session: true});
var tmp = _.uniqueId("something_else");
session.origin_server = false;
return session.rpc("/web/tests/set_session_value", {value: tmp}, {force2step: true}).then(function() {
ok(true, "set_session returned");
return origin_session.rpc("/web/tests/set_session_value", {value: origin_tmp});
}).then(function(result) {
ok(true, "set_session on origin returned");
return session.rpc("/web/tests/get_session_value", {}, {force2step: true});
}).then(function(result) {
equal(result, tmp, "Got the same value from the session");
notEqual(result, origin_tmp, "Values in the different sessions should be different");
});
});*/
test('timeout-jsonrpc', {asserts: 1}, function () {
var session = new openerp.Session();
return session.rpc("/gen_session_id", {}, {timeout: 1}).then(function() {
ok(false, "the request incorrectly succeeded");
return $.when();
}, function(a, e) {
e.preventDefault();
ok(true, "the request correctly failed");
return $.when();
});
});
test('timeout-jsonprpc', {asserts: 1}, function () {
var session = new openerp.Session();
session.origin_server = false;
return session.rpc("/gen_session_id", {}, {timeout: 1}).then(function() {
ok(false, "the request incorrectly succeeded");
return $.when();
}, function(a, e) {
e.preventDefault();
ok(true, "the request correctly failed");
return $.when();
});
});
// desactivated because the phantomjs runner crash
/*test('timeout-jsonprpc2', {asserts: 1}, function () {
var session = new openerp.Session();
session.origin_server = false;
return session.rpc("/gen_session_id", {}, {force2step: true, timeout: 1}).then(function() {
ok(false, "the request incorrectly succeeded");
return $.when();
}, function(a, e) {
e.preventDefault();
ok(true, "the request correctly failed");
return $.when();
});
});*/
});
})();

View File

@ -102,7 +102,7 @@
<div class="form-group field-password"> <div class="form-group field-password">
<label for="password" class="control-label">Password</label> <label for="password" class="control-label">Password</label>
<input type="password" name="password" id="password" class="form-control" required="required"/> <input type="password" name="password" id="password" class="form-control" required="required" t-att-autofocus="'autofocus' if login else None"/>
</div> </div>
<p class="alert alert-danger" t-if="error"> <p class="alert alert-danger" t-if="error">

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
"X-Poedit-Language: Czech\n" "X-Poedit-Language: Czech\n"
#. module: web_calendar #. module: web_calendar

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:34+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:34+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:34+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:34+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:34+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -15,8 +15,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:34+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
"Language: es\n" "Language: es\n"
#. module: web_calendar #. module: web_calendar

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:34+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:34+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:34+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:34+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

View File

@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-02-26 06:33+0000\n" "X-Launchpad-Export-Date: 2014-04-01 06:09+0000\n"
"X-Generator: Launchpad (build 16935)\n" "X-Generator: Launchpad (build 16967)\n"
#. module: web_calendar #. module: web_calendar
#. openerp-web #. openerp-web

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