Parcourir la source

New Build System: Rollup (#5010)

* JS build working

* Css build working!

* Uglify JS in production

* fix codacy

* Add frappe.commands.popen

* FIx ESLint errors

* Add socket.io to package.json

* ignore subprocess warnings

* Add babel-runtime

* sleep 20 after bench start

* remove set -e

* [FIX] non-shell subprocess call

* [FIX] use shell = False

* split commands
version-14
Faris Ansari il y a 7 ans
committed by GitHub
Parent
révision
92e8856588
Aucune clé connue n'a été trouvée dans la base pour cette signature ID de la clé GPG: 4AEE18F83AFDEB23
43 fichiers modifiés avec 2727 ajouts et 573 suppressions
  1. +21
    -17
      .eslintrc
  2. +3
    -3
      .travis.yml
  3. +26
    -0
      frappe-html-plugin.js
  4. +7
    -25
      frappe/build.py
  5. +21
    -0
      frappe/commands/__init__.py
  6. +1
    -1
      frappe/commands/utils.py
  7. +24
    -25
      frappe/public/build.json
  8. +3
    -3
      frappe/public/js/docs.js
  9. +187
    -183
      frappe/public/js/frappe/chat.js
  10. +61
    -62
      frappe/public/js/frappe/class.js
  11. +36
    -37
      frappe/public/js/frappe/desk.js
  12. +2
    -2
      frappe/public/js/frappe/list/list_factory.js
  13. +9
    -11
      frappe/public/js/frappe/misc/common.js
  14. +16
    -0
      frappe/public/js/frappe/misc/number_format.js
  15. +11
    -8
      frappe/public/js/frappe/misc/pretty_date.js
  16. +4
    -2
      frappe/public/js/frappe/misc/tools.js
  17. +9
    -2
      frappe/public/js/frappe/model/perm.js
  18. +4
    -5
      frappe/public/js/frappe/model/sync.js
  19. +1
    -1
      frappe/public/js/frappe/request.js
  20. +3
    -2
      frappe/public/js/frappe/router.js
  21. +7
    -8
      frappe/public/js/frappe/ui/dialog.js
  22. +1
    -1
      frappe/public/js/frappe/ui/keyboard.js
  23. +2
    -2
      frappe/public/js/frappe/views/container.js
  24. +11
    -11
      frappe/public/js/frappe/views/pageview.js
  25. +1
    -1
      frappe/public/js/frappe/views/treeview.js
  26. +93
    -83
      frappe/public/js/legacy/client_script_helpers.js
  27. +19
    -0
      frappe/public/js/legacy/datatype.js
  28. +9
    -9
      frappe/public/js/legacy/globals.js
  29. +10
    -5
      frappe/public/js/legacy/handler.js
  30. +1
    -1
      frappe/public/js/legacy/layout.js
  31. +1
    -1
      frappe/public/js/lib/microtemplate.js
  32. +1
    -1
      frappe/public/js/lib/slickgrid/slick-default-theme.css
  33. +2
    -2
      frappe/public/js/lib/slickgrid/slick.grid.css
  34. +2
    -2
      frappe/templates/includes/comments/comments.html
  35. +3
    -3
      frappe/templates/includes/login/login.js
  36. +2
    -2
      frappe/templates/includes/search_box.html
  37. +41
    -30
      frappe/website/js/website.js
  38. +5
    -5
      frappe/www/feedback.html
  39. +3
    -3
      frappe/www/update-password.html
  40. +16
    -14
      package.json
  41. +172
    -0
      rollup.config.js
  42. +56
    -0
      rollup.utils.js
  43. +1820
    -0
      yarn.lock

+ 21
- 17
.eslintrc Voir le fichier

@@ -4,6 +4,10 @@
"node": true,
"es6": true
},
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module"
},
"extends": "eslint:recommended",
"rules": {
"indent": [
@@ -56,21 +60,6 @@
"root": true,
"globals": {
"frappe": true,
"$": true,
"jQuery": true,
"moment": true,
"hljs": true,
"Awesomplete": true,
"Sortable": true,
"Showdown": true,
"Taggle": true,
"Gantt": true,
"Slick": true,
"Webcam": true,
"PhotoSwipe": true,
"PhotoSwipeUI_Default": true,
"fluxify": true,
"io": true,
"__": true,
"_p": true,
"_f": true,
@@ -94,7 +83,6 @@
"format_number": true,
"format_currency": true,
"comment_when": true,
"replace_newlines": true,
"open_url_post": true,
"toTitle": true,
"lstrip": true,
@@ -103,7 +91,6 @@
"replace_all": true,
"flt": true,
"precision": true,
"md5": true,
"CREATE": true,
"AMEND": true,
"CANCEL": true,
@@ -129,6 +116,23 @@
"getCookie": true,
"getCookies": true,
"get_url_arg": true,

"md5": true,
"$": true,
"jQuery": true,
"moment": true,
"hljs": true,
"Awesomplete": true,
"Sortable": true,
"Showdown": true,
"Taggle": true,
"Gantt": true,
"Slick": true,
"Webcam": true,
"PhotoSwipe": true,
"PhotoSwipeUI_Default": true,
"fluxify": true,
"io": true,
"QUnit": true,
"JsBarcode": true,
"L": true,


+ 3
- 3
.travis.yml Voir le fichier

@@ -15,7 +15,7 @@ install:
- sudo apt-get purge -y mysql-common mysql-server mysql-client
- nvm install v7.10.0
- wget https://raw.githubusercontent.com/frappe/bench/master/playbooks/install.py
- sudo python install.py --develop --user travis --without-bench-setup
- sudo pip install -e ~/bench

@@ -35,8 +35,8 @@ before_script:
- bench setup-help
- bench scheduler disable
- bench start &
- sleep 10
- sleep 20

script:
- set -e
# - set -e
- bench run-tests

+ 26
- 0
frappe-html-plugin.js Voir le fichier

@@ -0,0 +1,26 @@
const path = require('path');

function scrub_html_template(content) {
content = content.replace(/\s/g, ' ');
content = content.replace(/(<!--.*?-->)/g, '');
return content.replace("'", "\'"); // eslint-disable-line
}

module.exports = function frappe_html() {
return {
name: 'frappe-html',
transform(code, id) {
if (!id.endsWith('.html')) return null;

var filepath = path.basename(id).split('.');
filepath.splice(-1);

var key = filepath.join(".");
var content = scrub_html_template(code);

return `
frappe.templates['${key}'] = '${content}';
`;
}
};
};

+ 7
- 25
frappe/build.py Voir le fichier

@@ -3,10 +3,10 @@

from __future__ import unicode_literals, print_function
from frappe.utils.minify import JavascriptMinify
import subprocess
import warnings

from six import iteritems, text_type
import subprocess

"""
Build the `public` folders and setup languages
@@ -28,36 +28,18 @@ def bundle(no_compress, make_copy=False, restore=False, verbose=False):
"""concat / minify js files"""
# build js files
setup()

make_asset_dirs(make_copy=make_copy, restore=restore)

# new nodejs build system
command = 'node --use_strict ../apps/frappe/frappe/build.js --build'
if not no_compress:
command += ' --minify'
subprocess.call(command.split(' '))

# build(no_compress, verbose)
command = 'yarn run build' if no_compress else 'yarn run production'
frappe_app_path = os.path.abspath(os.path.join(app_paths[0], '..'))
subprocess.call(command.split(" "), cwd=frappe_app_path)

def watch(no_compress):
"""watch and rebuild if necessary"""
setup()

# new nodejs file watcher
command = 'node --use_strict ../apps/frappe/frappe/build.js --watch'
subprocess.call(command.split(' '))

# setup()

# import time
# compile_less()
# build(no_compress=True)

# while True:
# compile_less()
# if files_dirty():
# build(no_compress=True)

# time.sleep(3)
frappe_app_path = os.path.abspath(os.path.join(app_paths[0], '..'))
subprocess.call('yarn run watch'.split(" "), cwd = frappe_app_path)

def make_asset_dirs(make_copy=False, restore=False):
# don't even think of making assets_path absolute - rm -rf ahead.


+ 21
- 0
frappe/commands/__init__.py Voir le fichier

@@ -8,6 +8,7 @@ import cProfile
import pstats
import frappe
import frappe.utils
import subprocess # nosec
from functools import wraps
from six import StringIO

@@ -46,6 +47,26 @@ def get_site(context):
print('Please specify --site sitename')
sys.exit(1)

def popen(command, *args, **kwargs):
output = kwargs.get('output', True)
cwd = kwargs.get('cwd')
shell = kwargs.get('shell', True)
raise_err = kwargs.get('raise_err')

proc = subprocess.Popen(command,
stdout = None if output else subprocess.PIPE,
stderr = None if output else subprocess.PIPE,
shell = shell,
cwd = cwd
)

return_ = proc.wait()

if raise_err:
raise subprocess.CalledProcessError(return_, command)

return return_

def call_command(cmd, context):
return click.Context(cmd, obj=context).forward(cmd)



+ 1
- 1
frappe/commands/utils.py Voir le fichier

@@ -328,7 +328,7 @@ def console(context):
frappe.connect()
frappe.local.lang = frappe.db.get_default("lang")
import IPython
IPython.embed()
IPython.embed(disable_banner = True)

@click.command('run-tests')
@click.option('--app', help="For App")


+ 24
- 25
frappe/public/build.json Voir le fichier

@@ -2,8 +2,8 @@
"css/frappe-web.css": [
"public/css/font-awesome.css",
"public/css/octicons/octicons.css",
"public/css/website.css",
"public/css/avatar.css"
"public/less/website.less",
"public/less/avatar.less"
],
"js/frappe-web.min.js": [
"public/js/frappe/class.js",
@@ -111,20 +111,20 @@
"public/css/bootstrap.css",
"public/css/font-awesome.css",
"public/css/octicons/octicons.css",
"public/css/desk.css",
"public/css/flex.css",
"public/css/indicator.css",
"public/css/avatar.css",
"public/css/navbar.css",
"public/css/sidebar.css",
"public/css/page.css",
"public/css/tree.css",
"public/css/desktop.css",
"public/css/form.css",
"public/css/mobile.css",
"public/css/kanban.css",
"public/css/controls.css",
"public/css/chat.css"
"public/less/desk.less",
"public/less/flex.less",
"public/less/indicator.less",
"public/less/avatar.less",
"public/less/navbar.less",
"public/less/sidebar.less",
"public/less/page.less",
"public/less/tree.less",
"public/less/desktop.less",
"public/less/form.less",
"public/less/mobile.less",
"public/less/kanban.less",
"public/less/controls.less",
"public/less/chat.less"
],
"css/frappe-rtl.css": [
"public/css/bootstrap-rtl.css",
@@ -140,7 +140,6 @@
"public/js/lib/moment/moment-with-locales.min.js",
"public/js/lib/moment/moment-timezone-with-data.min.js",
"public/js/lib/socket.io.min.js",
"public/js/lib/markdown.js",
"public/js/lib/jSignature.min.js",
"public/js/frappe/translate.js",
"public/js/lib/datepicker/datepicker.min.js",
@@ -255,10 +254,10 @@
"public/js/frappe/chat.js"
],
"css/module.min.css": [
"public/css/module.css"
"public/less/module.less"
],
"css/form.min.css": [
"public/css/form_grid.css"
"public/less/form_grid.less"
],
"js/form.min.js": [
"public/js/frappe/form/templates/grid_form.html",
@@ -299,10 +298,10 @@
"public/js/frappe/form/quick_entry.js"
],
"css/list.min.css": [
"public/css/list.css",
"public/css/calendar.css",
"public/css/role_editor.css",
"public/css/gantt.css"
"public/less/list.less",
"public/less/calendar.less",
"public/less/role_editor.less",
"public/less/gantt.less"
],
"js/list.min.js": [
"public/js/frappe/ui/listing.html",
@@ -351,9 +350,9 @@
"public/js/frappe/views/kanban/kanban_card.html"
],
"css/report.min.css": [
"public/css/report.css",
"public/less/report.less",
"public/css/tree_grid.css",
"public/css/frappe-datatable.css",
"public/less/frappe-datatable.less",

"public/js/lib/slickgrid/slick.grid.css",
"public/js/lib/slickgrid/slick-default-theme.css",


+ 3
- 3
frappe/public/js/docs.js Voir le fichier

@@ -1,7 +1,7 @@
// used in documenation site built via document generator

$(function() {
if(hljs) {
if(window.hljs) {
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
@@ -10,7 +10,7 @@ $(function() {
// search
$('.sidebar-navbar-items .octicon-search, .navbar .octicon-search').parent().on("click", function() {
var modal = frappe.get_modal("Search",
'<p><input class="search-input form-control" type="text" placeholder="Search text..." tabindex="1"></p>\
'<p><input class="search-input form-control" type="text" placeholder="Search text..." tabindex="1"></p>\
<p><a class="btn btn-sm btn-default btn-search" href="#" target="_blank" tabindex="2">Search via Google</a></p>');
modal.find(".search-input").on("keyup", function(e) {
if(e.which===13) {
@@ -49,4 +49,4 @@ frappe = {

return modal;
},
}
};

+ 187
- 183
frappe/public/js/frappe/chat.js
Fichier diff supprimé car celui-ci est trop grand
Voir le fichier


+ 61
- 62
frappe/public/js/frappe/class.js Voir le fichier

@@ -13,72 +13,71 @@ To subclass, use:
})

*/
// https://stackoverflow.com/a/15052240/5353542

/* Simple JavaScript Inheritance
* By John Resig http://ejohn.org/
/* Simple JavaScript Inheritance for ES 5.1
* based on http://ejohn.org/blog/simple-javascript-inheritance/
* (inspired by base2 and Prototype)
* MIT Licensed.
*/
// Inspired by base2 and Prototype
(function(global) {
"use strict";
var fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

; /* otherwise causes a concat bug? */

(function(){
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function(){};
function Class(){}

// Create a new Class that inherits from this class
Class.extend = function(prop) {
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
return function() {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) :
prop[name];
}
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
this._type = "instance";
if ( !initializing && this.init )
this.init.apply(this, arguments);
}
// Populate our constructed prototype object
Class.prototype = prototype;
Class._type = "class";
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;

// And make this class extendable
Class.extend = arguments.callee;
return Class;
Class.extend = function(props) {
var _super = this.prototype;

// Set up the prototype to inherit from the base class
// (but without running the init constructor)
var proto = Object.create(_super);

// Copy the properties over onto the new prototype
for (var name in props) {
// Check if we're overwriting an existing function
proto[name] = typeof props[name] === "function" &&
typeof _super[name] == "function" && fnTest.test(props[name])
? (function(name, fn){
return function() {
var tmp = this._super;

// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];

// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;

return ret;
};
})(name, props[name])
: props[name];
}

// The new constructor
var newClass = typeof proto.init === "function"
? proto.hasOwnProperty("init")
? proto.init // All construction is actually done in the init method
: function SubClass(){ _super.init.apply(this, arguments); }
: function EmptyClass(){};

// Populate our constructed prototype object
newClass.prototype = proto;

// Enforce the constructor to be what we expect
proto.constructor = newClass;

// And make this class extendable
newClass.extend = Class.extend;

return newClass;
};
})();

// export
global.Class = Class;
})(this);

+ 36
- 37
frappe/public/js/frappe/desk.js Voir le fichier

@@ -1,5 +1,6 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
/* eslint-disable no-console */

frappe.start_app = function() {
if(!frappe.Application)
@@ -7,7 +8,7 @@ frappe.start_app = function() {
frappe.assets.check();
frappe.provide('frappe.app');
frappe.app = new frappe.Application();
}
};

$(document).ready(function() {
if(!frappe.utils.supportsES6) {
@@ -35,7 +36,7 @@ frappe.Application = Class.extend({
this.startup();
},
startup: function() {
frappe.socketio.init()
frappe.socketio.init();
frappe.model.init();

if(frappe.boot.status==='failed') {
@@ -43,7 +44,7 @@ frappe.Application = Class.extend({
message: frappe.boot.error,
title: __('Session Start Failed'),
indicator: 'red',
})
});
throw 'boot failed';
}

@@ -109,20 +110,20 @@ frappe.Application = Class.extend({
var email_list = frappe.sys_defaults.email_user_password.split(',');
for (var u in email_list) {
if (email_list[u]===frappe.user.name){
this.set_password(email_list[u])
this.set_password(email_list[u]);
}
}
}

},
set_password: function (user) {
var me=this
set_password: function(user) {
var me=this;
frappe.call({
method: 'frappe.core.doctype.user.user.get_email_awaiting',
args: {
"user": user
},
callback: function (email_account) {
callback: function(email_account) {
email_account = email_account["message"];
if (email_account) {
var i = 0;
@@ -135,7 +136,7 @@ frappe.Application = Class.extend({
},

email_password_prompt: function(email_account,user,i) {
var me = this
var me = this;
var d = new frappe.ui.Dialog({
title: __('Email Account setup please enter your password for: '+email_account[i]["email_id"]),
fields: [
@@ -160,7 +161,7 @@ frappe.Application = Class.extend({
"fieldname": "checking"
}]
});
s.fields_dict.checking.$wrapper.html('<i class="fa fa-spinner fa-spin fa-4x"></i>')
s.fields_dict.checking.$wrapper.html('<i class="fa fa-spinner fa-spin fa-4x"></i>');
s.show();
frappe.call({
method: 'frappe.core.doctype.user.user.set_email_password',
@@ -169,21 +170,16 @@ frappe.Application = Class.extend({
"user": user,
"password": d.get_value("password")
},
callback: function (passed)
{
callback: function(passed) {
s.hide();
d.hide();//hide waiting indication
if (!passed["message"])
{
if (!passed["message"]) {
frappe.show_alert("Login Failed please try again", 5);
me.email_password_prompt(email_account, user, i)
}
else
{
if (i + 1 < email_account.length)
{
me.email_password_prompt(email_account, user, i);
} else {
if (i + 1 < email_account.length) {
i = i + 1;
me.email_password_prompt(email_account, user, i)
me.email_password_prompt(email_account, user, i);
}
}

@@ -195,7 +191,9 @@ frappe.Application = Class.extend({
load_bootinfo: function() {
if(frappe.boot) {
frappe.modules = {};
frappe.boot.desktop_icons.forEach(function(m) { frappe.modules[m.module_name]=m; });
frappe.boot.desktop_icons.forEach(function(m) {
frappe.modules[m.module_name]=m;
});
frappe.model.sync(frappe.boot.docs);
$.extend(frappe._messages, frappe.boot.__messages);
this.check_metadata_cache_status();
@@ -234,7 +232,7 @@ frappe.Application = Class.extend({
// refresh notifications if user is back after sometime
$(document).on("session_alive", function() {
me.refresh_notifications();
})
});
},

refresh_notifications: function() {
@@ -377,7 +375,7 @@ frappe.Application = Class.extend({
}
me.redirect_to_login();
}
})
});
},
handle_session_expired: function() {
if(!frappe.app.session_expired_dialog) {
@@ -439,7 +437,7 @@ frappe.Application = Class.extend({
},

trigger_primary_action: function() {
if(cur_dialog && cur_dialog.display) {
if(window.cur_dialog && cur_dialog.display) {
// trigger primary
cur_dialog.get_primary_btn().trigger("click");
} else if(cur_frm && cur_frm.page.btn_primary.is(':visible')) {
@@ -449,13 +447,13 @@ frappe.Application = Class.extend({
}
},

set_rtl: function () {
set_rtl: function() {
if (["ar", "he", "fa"].indexOf(frappe.boot.lang) >= 0) {
var ls = document.createElement('link');
ls.rel="stylesheet";
ls.href= "assets/css/frappe-rtl.css";
document.getElementsByTagName('head')[0].appendChild(ls);
$('body').addClass('frappe-rtl')
$('body').addClass('frappe-rtl');
}
},

@@ -509,9 +507,9 @@ frappe.Application = Class.extend({
// next note
me.show_notes();

}
};
}
})
});
}
},
});
@@ -567,17 +565,17 @@ frappe.get_desktop_icons = function(show_hidden, show_global) {
var out = [];

var add_to_out = function(module) {
var module = frappe.get_module(module.module_name, module);
module = frappe.get_module(module.module_name, module);
module.app_icon = frappe.ui.app_icon.get_html(module);
out.push(module);
}
};

var show_module = function(m) {
var out = true;
if(m.type==="page") {
out = m.link in frappe.boot.page_info;
} else if(m._report) {
out = m._report in frappe.boot.user.all_reports
out = m._report in frappe.boot.user.all_reports;
} else if(m._doctype) {
//out = frappe.model.can_read(m._doctype);
out = frappe.boot.user.can_read.includes(m._doctype);
@@ -588,7 +586,7 @@ frappe.get_desktop_icons = function(show_hidden, show_global) {
} else if(m.module_name==='Setup' && frappe.user.has_role('System Manager')) {
out = true;
} else {
out = frappe.boot.user.allow_modules.indexOf(m.module_name) !== -1
out = frappe.boot.user.allow_modules.indexOf(m.module_name) !== -1;
}
}
if(m.hidden && !show_hidden) {
@@ -598,22 +596,23 @@ frappe.get_desktop_icons = function(show_hidden, show_global) {
out = false;
}
return out;
}
};

let m;
for (var i=0, l=frappe.boot.desktop_icons.length; i < l; i++) {
var m = frappe.boot.desktop_icons[i];
m = frappe.boot.desktop_icons[i];
if ((['Setup', 'Core'].indexOf(m.module_name) === -1) && show_module(m)) {
add_to_out(m);
}
}

if(frappe.user_roles.includes('System Manager')) {
var m = frappe.get_module('Setup');
m = frappe.get_module('Setup');
if(show_module(m)) add_to_out(m);
}

if(frappe.user_roles.includes('Administrator')) {
var m = frappe.get_module('Core');
m = frappe.get_module('Core');
if(show_module(m)) add_to_out(m);
}

@@ -636,4 +635,4 @@ frappe.add_to_desktop = function(label, doctype, report) {
}
}
});
}
};

+ 2
- 2
frappe/public/js/frappe/list/list_factory.js Voir le fichier

@@ -3,7 +3,7 @@

frappe.provide('frappe.views.list_view');

cur_list = null;
window.cur_list = null;
frappe.views.ListFactory = frappe.views.Factory.extend({
make: function (route) {
var me = this;
@@ -89,7 +89,7 @@ frappe.views.ListFactory = frappe.views.Factory.extend({
cur_list = frappe.views.list_view[page_name];
if (cur_list && cur_list.doctype !== route[1]) {
// changing...
cur_list = null;
window.cur_list = null;
}
}
});

+ 9
- 11
frappe/public/js/frappe/misc/common.js Voir le fichier

@@ -94,7 +94,7 @@ frappe.get_gravatar = function(email_id, size = 0) {

// string commons

function repl(s, dict) {
window.repl =function repl(s, dict) {
if(s==null)return '';
for(var key in dict) {
s = s.split("%("+key+")s").join(dict[key]);
@@ -102,15 +102,15 @@ function repl(s, dict) {
return s;
}

function replace_all(s, t1, t2) {
window.replace_all = function(s, t1, t2) {
return s.split(t1).join(t2);
}

function strip_html(txt) {
window.strip_html = function(txt) {
return txt.replace(/<[^>]*>/g, "");
}

var strip = function(s, chars) {
window.strip = function(s, chars) {
if (s) {
var s= lstrip(s, chars)
s = rstrip(s, chars);
@@ -118,7 +118,7 @@ var strip = function(s, chars) {
}
}

var lstrip = function(s, chars) {
window.lstrip = function lstrip(s, chars) {
if(!chars) chars = ['\n', '\t', ' '];
// strip left
var first_char = s.substr(0,1);
@@ -129,7 +129,7 @@ var lstrip = function(s, chars) {
return s;
}

var rstrip = function(s, chars) {
window.rstrip = function(s, chars) {
if(!chars) chars = ['\n', '\t', ' '];
var last_char = s.substr(s.length-1);
while(in_list(chars, last_char)) {
@@ -139,13 +139,11 @@ var rstrip = function(s, chars) {
return s;
}

function getCookie(name) {
return getCookies()[name];
frappe.get_cookie = function getCookie(name) {
return frappe.get_cookies()[name];
}

frappe.get_cookie = getCookie;

function getCookies() {
frappe.get_cookies = function getCookies() {
var c = document.cookie, v = 0, cookies = {};
if (document.cookie.match(/^\s*\$Version=(?:"1"|1);\s*(.*)/)) {
c = RegExp.$1;


+ 16
- 0
frappe/public/js/frappe/misc/number_format.js Voir le fichier

@@ -240,3 +240,19 @@ function round_based_on_smallest_currency_fraction(value, currency, precision) {
}
return value;
}

Object.assign(window, {
flt,
cint,
strip_number_groups,
format_currency,
get_currency_symbol,
get_number_format,
get_number_format_info,
_round,
roundNumber,
precision,
remainder,
round_based_on_smallest_currency_fraction,
in_list
});

+ 11
- 8
frappe/public/js/frappe/misc/pretty_date.js Voir le fichier

@@ -5,10 +5,11 @@ function prettyDate(time, mini) {
time = new Date();
}
if (moment) {
let ret;
if (frappe.sys_defaults && frappe.sys_defaults.time_zone) {
var ret = moment.tz(time, frappe.sys_defaults.time_zone).locale(frappe.boot.lang).fromNow(mini);
ret = moment.tz(time, frappe.sys_defaults.time_zone).locale(frappe.boot.lang).fromNow(mini);
} else {
var ret = moment(time).locale(frappe.boot.lang).fromNow(mini);
ret = moment(time).locale(frappe.boot.lang).fromNow(mini);
}
if (mini) {
if (ret === moment().locale(frappe.boot.lang).fromNow(mini)) {
@@ -30,7 +31,7 @@ function prettyDate(time, mini) {
}
return ret;
} else {
if (!time) return ''
if (!time) return '';
var date = time;
if (typeof (time) == "string")
date = new Date((time || "").replace(/-/g, "/").replace(/[TZ]/g, " ").replace(/\.[0-9]*/, ""));
@@ -58,7 +59,7 @@ function prettyDate(time, mini) {
}


var comment_when = function (datetime, mini) {
window.comment_when = function(datetime, mini) {
var timestamp = frappe.datetime.str_to_user ?
frappe.datetime.str_to_user(datetime) : datetime;
return '<span class="frappe-timestamp '
@@ -68,12 +69,14 @@ var comment_when = function (datetime, mini) {
};

frappe.provide("frappe.datetime");
frappe.datetime.refresh_when = function () {
frappe.datetime.refresh_when = function() {
if (jQuery) {
$(".frappe-timestamp").each(function () {
$(".frappe-timestamp").each(function() {
$(this).html(prettyDate($(this).attr("data-timestamp"), $(this).hasClass("mini")));
});
}
}
};

setInterval(function () { frappe.datetime.refresh_when() }, 60000); // refresh every minute
setInterval(function() {
frappe.datetime.refresh_when();
}, 60000); // refresh every minute

+ 4
- 2
frappe/public/js/frappe/misc/tools.js Voir le fichier

@@ -1,6 +1,8 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt

import showdown from 'showdown';

frappe.provide("frappe.tools");

frappe.tools.downloadify = function(data, roles, title) {
@@ -34,7 +36,7 @@ frappe.tools.downloadify = function(data, roles, title) {

frappe.markdown = function(txt) {
if(!frappe.md2html) {
frappe.md2html = new Showdown.converter();
frappe.md2html = new showdown.Converter();
}

while(txt.substr(0,1)==="\n") {
@@ -77,7 +79,7 @@ frappe.slickgrid_tools = {
get_filtered_items: function(dataView) {
var data = [];
for (var i=0, len=dataView.getLength(); i<len; i++) {
// remove single quotes at start and end of total labels when print/pdf
// remove single quotes at start and end of total labels when print/pdf
var obj = dataView.getItem(i);
for (var item in obj) {
if(obj.hasOwnProperty(item) && typeof(obj[item]) == "string"


+ 9
- 2
frappe/public/js/frappe/model/perm.js Voir le fichier

@@ -4,8 +4,15 @@
frappe.provide("frappe.perm");

// backward compatibilty
var READ = "read", WRITE = "write", CREATE = "create", DELETE = "delete";
var SUBMIT = "submit", CANCEL = "cancel", AMEND = "amend";
Object.assign(window, {
READ: "read",
WRITE: "write",
CREATE: "create",
DELETE: "delete",
SUBMIT: "submit",
CANCEL: "cancel",
AMEND: "amend",
});

$.extend(frappe.perm, {
rights: ["read", "write", "create", "delete", "submit", "cancel", "amend",


+ 4
- 5
frappe/public/js/frappe/model/sync.js Voir le fichier

@@ -15,7 +15,6 @@ $.extend(frappe.model, {
if(isPlain) r.docs = [r.docs];

if(r.docs) {
var last_parent_name = null;

for(var i=0, l=r.docs.length; i<l; i++) {
var d = r.docs[i];
@@ -51,11 +50,11 @@ $.extend(frappe.model, {

// set docinfo (comments, assign, attachments)
if(r.docinfo) {
var doc;
if(r.docs) {
var doc = r.docs[0];
doc = r.docs[0];
} else {
if(cur_frm)
var doc = cur_frm.doc;
if(cur_frm) doc = cur_frm.doc;
}
if(doc) {
if(!frappe.model.docinfo[doc.doctype])
@@ -89,7 +88,7 @@ $.extend(frappe.model, {
for (var x=0, y=value.length; x < y; x++) {
var d = value[x];

if(!d.parent)
if(typeof d=='object' && !d.parent)
d.parent = doc.name;

frappe.model.add_to_locals(d);


+ 1
- 1
frappe/public/js/frappe/request.js Voir le fichier

@@ -369,7 +369,7 @@ frappe.request.report_error = function(xhr, request_opts) {

request_opts = frappe.request.cleanup_request_opts(request_opts);

msg_dialog = frappe.msgprint({message:error_message, indicator:'red'});
window.msg_dialog = frappe.msgprint({message:error_message, indicator:'red'});

msg_dialog.msg_area.find(".report-btn")
.toggle(error_report_email ? true : false)


+ 3
- 2
frappe/public/js/frappe/router.js Voir le fichier

@@ -72,7 +72,7 @@ frappe.get_route = function(route) {
var parts = route[route.length - 1].split("?");
route[route.length - 1] = parts[0];
if (parts.length > 1) {
var query_params = get_query_params(parts[1]);
var query_params = frappe.utils.get_query_params(parts[1]);
frappe.route_options = $.extend(frappe.route_options || {}, query_params);
}

@@ -133,6 +133,7 @@ frappe.set_route = function() {
frappe.route_options = a;
return null;
} else {
a = String(a);
if (a && a.match(/[%'"]/)) {
// if special chars, then encode
a = encodeURIComponent(a);
@@ -170,7 +171,7 @@ $(window).on('hashchange', function() {
return;

// hide open dialog
if(cur_dialog && cur_dialog.hide_on_page_refresh) {
if(window.cur_dialog && cur_dialog.hide_on_page_refresh) {
cur_dialog.hide();
}



+ 7
- 8
frappe/public/js/frappe/ui/dialog.js Voir le fichier

@@ -3,7 +3,7 @@

frappe.provide('frappe.ui');

var cur_dialog;
window.cur_dialog = null;

frappe.ui.open_dialogs = [];
frappe.ui.Dialog = frappe.ui.FieldGroup.extend({
@@ -49,9 +49,9 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({
if(frappe.ui.open_dialogs[frappe.ui.open_dialogs.length-1]===me) {
frappe.ui.open_dialogs.pop();
if(frappe.ui.open_dialogs.length) {
cur_dialog = frappe.ui.open_dialogs[frappe.ui.open_dialogs.length-1];
window.cur_dialog = frappe.ui.open_dialogs[frappe.ui.open_dialogs.length-1];
} else {
cur_dialog = null;
window.cur_dialog = null;
}
}
me.onhide && me.onhide();
@@ -60,7 +60,7 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({
.on("shown.bs.modal", function() {
// focus on first input
me.display = true;
cur_dialog = me;
window.cur_dialog = me;
frappe.ui.open_dialogs.push(me);
me.focus_on_first_input();
me.on_page_show && me.on_page_show();
@@ -100,7 +100,6 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({
this.get_primary_btn().removeClass('disabled');
},
make_head: function() {
var me = this;
this.set_title(this.title);
},
set_title: function(t) {
@@ -109,15 +108,15 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({
show: function() {
// show it
if ( this.animate ) {
this.$wrapper.addClass('fade')
this.$wrapper.addClass('fade');
} else {
this.$wrapper.removeClass('fade')
this.$wrapper.removeClass('fade');
}
this.$wrapper.modal("show");
this.primary_action_fulfilled = false;
this.is_visible = true;
},
hide: function(from_event) {
hide: function() {
this.$wrapper.modal("hide");
this.is_visible = false;
},


+ 1
- 1
frappe/public/js/frappe/ui/keyboard.js Voir le fichier

@@ -69,7 +69,7 @@ frappe.ui.keys.on('esc', function(e) {
});

frappe.ui.keys.on('enter', function(e) {
if(cur_dialog && cur_dialog.confirm_dialog) {
if(window.cur_dialog && cur_dialog.confirm_dialog) {
cur_dialog.get_primary_btn().trigger('click');
}
});


+ 2
- 2
frappe/public/js/frappe/views/container.js Voir le fichier

@@ -5,7 +5,7 @@
frappe.provide('frappe.pages');
frappe.provide('frappe.views');

var cur_page = null;
window.cur_page = null;
frappe.views.Container = Class.extend({
_intro: "Container contains pages inside `#container` and manages \
page creation, switching",
@@ -59,7 +59,7 @@ frappe.views.Container = Class.extend({
}

// hide dialog
if(cur_dialog && cur_dialog.display && !cur_dialog.keep_open) {
if(window.cur_dialog && cur_dialog.display && !cur_dialog.keep_open) {
cur_dialog.hide();
}



+ 11
- 11
frappe/public/js/frappe/views/pageview.js Voir le fichier

@@ -52,10 +52,10 @@ frappe.views.pageview = {
});
});
}
}
};

frappe.views.Page = Class.extend({
init: function(name, wrapper) {
init: function(name) {
this.name = name;
var me = this;
// web home page
@@ -85,7 +85,7 @@ frappe.views.Page = Class.extend({

// set events
$(this.wrapper).on('show', function() {
cur_frm = null;
window.cur_frm = null;
me.trigger_page_event('on_page_show');
me.trigger_page_event('refresh');
});
@@ -96,7 +96,7 @@ frappe.views.Page = Class.extend({
me.wrapper[eventname](me.wrapper);
}
}
})
});

frappe.show_not_found = function(page_name) {
frappe.show_message_page({
@@ -104,7 +104,7 @@ frappe.show_not_found = function(page_name) {
message: __("Sorry! I could not find what you were looking for."),
img: "/assets/frappe/images/ui/bubble-tea-sorry.svg"
});
}
};

frappe.show_not_permitted = function(page_name) {
frappe.show_message_page({
@@ -113,7 +113,7 @@ frappe.show_not_permitted = function(page_name) {
img: "/assets/frappe/images/ui/bubble-tea-sorry.svg",
// icon: "octicon octicon-circle-slash"
});
}
};

frappe.show_message_page = function(opts) {
// opts can include `page_name`, `message`, `icon` or `img`
@@ -136,11 +136,11 @@ frappe.show_message_page = function(opts) {
<a class="btn btn-default btn-sm btn-home" href="#">%(home)s</a>\
</div>\
</div>', {
img: opts.img || "",
message: opts.message || "",
home: __("Home")
})
img: opts.img || "",
message: opts.message || "",
home: __("Home")
})
);

frappe.container.change_to(opts.page_name);
}
};

+ 1
- 1
frappe/public/js/frappe/views/treeview.js Voir le fichier

@@ -3,7 +3,7 @@

frappe.provide("frappe.treeview_settings");
frappe.provide('frappe.views.trees');
cur_tree = null;
window.cur_tree = null;

frappe.views.TreeFactory = frappe.views.Factory.extend({
make: function(route) {


+ 93
- 83
frappe/public/js/legacy/client_script_helpers.js Voir le fichier

@@ -1,33 +1,34 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
/* eslint-disable no-console */

window.get_server_fields = function(method, arg, table_field, doc, dt, dn, allow_edit, call_back) {
console.warn("This function 'get_server_fields' has been deprecated and will be removed soon.");
frappe.dom.freeze();
if($.isPlainObject(arg)) arg = JSON.stringify(arg);
return $c('runserverobj', {'method': method, 'docs': JSON.stringify(doc), 'arg': arg },
function(r, rt) {
frappe.dom.unfreeze();
if (r.message) {
var d = locals[dt][dn];
var field_dict = r.message;
for(var key in field_dict) {
d[key] = field_dict[key];
if (table_field)
refresh_field(key, d.name, table_field);
else
refresh_field(key);
function(r) {
frappe.dom.unfreeze();
if (r.message) {
var d = locals[dt][dn];
var field_dict = r.message;
for(var key in field_dict) {
d[key] = field_dict[key];
if (table_field)
refresh_field(key, d.name, table_field);
else
refresh_field(key);
}
}
}
if(call_back){
doc = locals[doc.doctype][doc.name];
call_back(doc, dt, dn);
}
});
}
if(call_back){
doc = locals[doc.doctype][doc.name];
call_back(doc, dt, dn);
}
});
};


window.set_multiple = function (dt, dn, dict, table_field) {
window.set_multiple = function(dt, dn, dict, table_field) {
var d = locals[dt][dn];
for(var key in dict) {
d[key] = dict[key];
@@ -36,16 +37,16 @@ window.set_multiple = function (dt, dn, dict, table_field) {
else
refresh_field(key);
}
}
};

window.refresh_many = function (flist, dn, table_field) {
window.refresh_many = function(flist, dn, table_field) {
for(var i in flist) {
if (table_field)
refresh_field(flist[i], dn, table_field);
else
refresh_field(flist[i]);
}
}
};

window.set_field_tip = function(n,txt) {
var df = frappe.meta.get_docfield(cur_frm.doctype, n, cur_frm.docname);
@@ -53,13 +54,13 @@ window.set_field_tip = function(n,txt) {

if(cur_frm && cur_frm.fields_dict) {
if(cur_frm.fields_dict[n])
cur_frm.fields_dict[n].comment_area.innerHTML = replace_newlines(txt);
cur_frm.fields_dict[n].comment_area.innerHTML = window.replace_newlines(txt);
else
console.log('[set_field_tip] Unable to set field tip: ' + n);
}
}
};

refresh_field = function(n, docname, table_field) {
window.refresh_field = function(n, docname, table_field) {
// multiple
if(typeof n==typeof [])
refresh_many(n, docname, table_field);
@@ -78,50 +79,53 @@ refresh_field = function(n, docname, table_field) {
}
}
} else if(cur_frm) {
cur_frm.refresh_field(n)
cur_frm.refresh_field(n);
}
}
};

window.set_field_options = function(n, txt) {
cur_frm.set_df_property(n, 'options', txt)
}
cur_frm.set_df_property(n, 'options', txt);
};

window.set_field_permlevel = function(n, level) {
cur_frm.set_df_property(n, 'permlevel', level)
}
cur_frm.set_df_property(n, 'permlevel', level);
};

toggle_field = function(n, hidden) {
window.toggle_field = function(n, hidden) {
var df = frappe.meta.get_docfield(cur_frm.doctype, n, cur_frm.docname);
if(df) {
df.hidden = hidden;
refresh_field(n);
}
else {
} else {
console.log((hidden ? "hide_field" : "unhide_field") + " cannot find field " + n);
}
}
};

hide_field = function(n) {
window.hide_field = function(n) {
if(cur_frm) {
if(n.substr) toggle_field(n, 1);
else { for(var i in n) toggle_field(n[i], 1) }
else {
for(var i in n) toggle_field(n[i], 1);
}
}
}
};

unhide_field = function(n) {
window.unhide_field = function(n) {
if(cur_frm) {
if(n.substr) toggle_field(n, 0);
else { for(var i in n) toggle_field(n[i], 0) }
else {
for(var i in n) toggle_field(n[i], 0);
}
}
}
};

get_field_obj = function(fn) {
window.get_field_obj = function(fn) {
return cur_frm.fields_dict[fn];
}
};

_f.Frm.prototype.get_doc = function() {
return locals[this.doctype][this.docname];
}
};

_f.Frm.prototype.set_currency_labels = function(fields_list, currency, parentfield) {
// To set the currency in the label
@@ -129,13 +133,13 @@ _f.Frm.prototype.set_currency_labels = function(fields_list, currency, parentfie

var me = this;
var doctype = parentfield ? this.fields_dict[parentfield].grid.doctype : this.doc.doctype;
var field_label_map = {}
var grid_field_label_map = {}
var field_label_map = {};
var grid_field_label_map = {};

$.each(fields_list, function(i, fname) {
var docfield = frappe.meta.docfield_map[doctype][fname];
if(docfield) {
var label = __(docfield.label || "").replace(/\([^\)]*\)/g, "");
var label = __(docfield.label || "").replace(/\([^\)]*\)/g, ""); // eslint-disable-line
if(parentfield) {
grid_field_label_map[doctype + "-" + fname] =
label.trim() + " (" + __(currency) + ")";
@@ -154,7 +158,7 @@ _f.Frm.prototype.set_currency_labels = function(fields_list, currency, parentfie
var df = frappe.meta.get_docfield(fname[0], fname[1], me.doc.name);
if(df) df.label = label;
});
}
};

_f.Frm.prototype.field_map = function(fnames, fn) {
if(typeof fnames==='string') {
@@ -172,7 +176,7 @@ _f.Frm.prototype.field_map = function(fnames, fn) {
this.refresh_field(fieldname);
}
}
}
};

_f.Frm.prototype.get_docfield = function(fieldname1, fieldname2) {
if(fieldname2) {
@@ -183,45 +187,51 @@ _f.Frm.prototype.get_docfield = function(fieldname1, fieldname2) {
// for parent
return frappe.meta.get_docfield(this.doctype, fieldname1, this.docname);
}
}
};

_f.Frm.prototype.set_df_property = function(fieldname, property, value, docname, table_field) {
var df;
if (!docname && !table_field){
var df = this.get_docfield(fieldname);
df = this.get_docfield(fieldname);
} else {
var grid = this.fields_dict[table_field].grid,
fname = frappe.utils.filter_dict(grid.docfields, {'fieldname': fieldname});
if (fname && fname.length)
var df = frappe.meta.get_docfield(fname[0].parent, fieldname, docname);
df = frappe.meta.get_docfield(fname[0].parent, fieldname, docname);
}
if(df && df[property] != value) {
df[property] = value;
refresh_field(fieldname, table_field);
}
}
};

_f.Frm.prototype.toggle_enable = function(fnames, enable) {
this.field_map(fnames, function(field) {
field.read_only = enable ? 0 : 1; });
}
field.read_only = enable ? 0 : 1;
});
};

_f.Frm.prototype.toggle_reqd = function(fnames, mandatory) {
this.field_map(fnames, function(field) { field.reqd = mandatory ? true : false; });
}
this.field_map(fnames, function(field) {
field.reqd = mandatory ? true : false;
});
};

_f.Frm.prototype.toggle_display = function(fnames, show) {
this.field_map(fnames, function(field) { field.hidden = show ? 0 : 1; });
}
this.field_map(fnames, function(field) {
field.hidden = show ? 0 : 1;
});
};

_f.Frm.prototype.call_server = function(method, args, callback) {
return $c_obj(this.doc, method, args, callback);
}
};

_f.Frm.prototype.get_files = function() {
return this.attachments
? frappe.utils.sort(this.attachments.get_attachments(), "file_name", "string")
: [] ;
}
};

_f.Frm.prototype.set_query = function(fieldname, opt1, opt2) {
if(opt2) {
@@ -235,15 +245,15 @@ _f.Frm.prototype.set_query = function(fieldname, opt1, opt2) {
this.fields_dict[fieldname].get_query = opt1;
}
}
}
};

_f.Frm.prototype.set_value_if_missing = function(field, value) {
return this.set_value(field, value, true);
}
};

_f.Frm.prototype.clear_table = function(fieldname) {
frappe.model.clear_table(this.doc, fieldname);
}
};

_f.Frm.prototype.add_child = function(fieldname, values) {
var doc = frappe.model.add_child(this.doc, frappe.meta.get_docfield(this.doctype, fieldname).options, fieldname);
@@ -261,7 +271,7 @@ _f.Frm.prototype.add_child = function(fieldname, values) {
$.extend(doc, d);
}
return doc;
}
};

_f.Frm.prototype.set_value = function(field, value, if_missing) {
var me = this;
@@ -290,10 +300,10 @@ _f.Frm.prototype.set_value = function(field, value, if_missing) {
frappe.msgprint(__("Field {0} not found.",[f]));
throw "frm.set_value";
}
}
};

if(typeof field=="string") {
return _set(field, value)
return _set(field, value);
} else if($.isPlainObject(field)) {
let tasks = [];
for (let f in field) {
@@ -304,7 +314,7 @@ _f.Frm.prototype.set_value = function(field, value, if_missing) {
}
return frappe.run_serially(tasks);
}
}
};

_f.Frm.prototype.call = function(opts, args, callback) {
var me = this;
@@ -341,18 +351,18 @@ _f.Frm.prototype.call = function(opts, args, callback) {
}
}
opts.original_callback && opts.original_callback(r);
}
};
} else {
opts.original_callback = opts.callback;
opts.callback = function(r) {
if(!r.exc) me.refresh_fields();

opts.original_callback && opts.original_callback(r);
}
};

}
return frappe.call(opts);
}
};

_f.Frm.prototype.get_field = function(field) {
return this.fields_dict[field];
@@ -367,7 +377,7 @@ _f.Frm.prototype.set_read_only = function() {
perm[p.permlevel || 0] = {read:1, print:1, cancel:1};
}
this.perm = perm;
}
};

_f.Frm.prototype.trigger = function(event) {
return this.script_manager.trigger(event);
@@ -377,15 +387,15 @@ _f.Frm.prototype.get_formatted = function(fieldname) {
return frappe.format(this.doc[fieldname],
frappe.meta.get_docfield(this.doctype, fieldname, this.docname),
{no_icon:true}, this.doc);
}
};

_f.Frm.prototype.open_grid_row = function() {
return frappe.ui.form.get_open_grid_form();
}
};

_f.Frm.prototype.is_new = function() {
return this.doc.__islocal;
}
};

_f.Frm.prototype.get_title = function() {
if(this.meta.title_field) {
@@ -393,7 +403,7 @@ _f.Frm.prototype.get_title = function() {
} else {
return this.doc.name;
}
}
};

_f.Frm.prototype.get_selected = function() {
// returns list of children that are selected. returns [parentfield, name] for each
@@ -405,7 +415,7 @@ _f.Frm.prototype.get_selected = function() {
}
});
return selected;
}
};

_f.Frm.prototype.has_mapper = function() {
// hackalert!
@@ -415,7 +425,7 @@ _f.Frm.prototype.has_mapper = function() {
true: false;
}
return this._has_mapper;
}
};

_f.Frm.prototype.set_indicator_formatter = function(fieldname, get_color, get_text) {
// get doctype from parent
@@ -430,7 +440,7 @@ _f.Frm.prototype.set_indicator_formatter = function(fieldname, get_color, get_te
} else {
return true;
}
})
});
}

frappe.meta.docfield_map[doctype][fieldname].formatter =
@@ -446,7 +456,7 @@ _f.Frm.prototype.set_indicator_formatter = function(fieldname, get_color, get_te
return '';
}
};
}
};

_f.Frm.prototype.can_create = function(doctype) {
// return true or false if the user can make a particlar doctype
@@ -472,7 +482,7 @@ _f.Frm.prototype.can_create = function(doctype) {
return true;
}
}
}
};

_f.Frm.prototype.make_new = function(doctype) {
// make new doctype from the current form
@@ -498,7 +508,7 @@ _f.Frm.prototype.make_new = function(doctype) {
// frappe.set_route('Form', doctype, new_doc.name);
});
}
}
};

_f.Frm.prototype.update_in_all_rows = function(table_fieldname, fieldname, value) {
// update the child value in all tables where it is missing
@@ -508,4 +518,4 @@ _f.Frm.prototype.update_in_all_rows = function(table_fieldname, fieldname, value
if(!cl[i][fieldname]) cl[i][fieldname] = value;
}
refresh_field("items");
}
};

+ 19
- 0
frappe/public/js/legacy/datatype.js Voir le fichier

@@ -108,3 +108,22 @@ function remove_from_list(list, val) {
}
return list
}

Object.assign(window, {
fmt_money,
toTitle,
is_null,
set_value_in,
copy_dict,
replace_newlines,
validate_email,
validate_spl_chars,
cstr,
nth,
esc_quotes,
has_words,
has_common,
add_lists,
docstring,
remove_from_list,
});

+ 9
- 9
frappe/public/js/legacy/globals.js Voir le fichier

@@ -18,10 +18,10 @@ frappe.provide("frappe.listview_parent_route");
frappe.settings.no_history = 1;

// constants
var NEWLINE = '\n';
var TAB = 9;
var UP_ARROW = 38;
var DOWN_ARROW = 40;
window.NEWLINE = '\n';
window.TAB = 9;
window.UP_ARROW = 38;
window.DOWN_ARROW = 40;

// proxy for user globals defined in desk.js

@@ -29,10 +29,10 @@ var DOWN_ARROW = 40;
// ============

// form
var _f = {};
var _p = {};
var _r = {};
window._f = {};
window._p = {};
window._r = {};

// API globals
var frms={};
var cur_frm=null;
window.frms={};
window.cur_frm=null;

+ 10
- 5
frappe/public/js/legacy/handler.js Voir le fichier

@@ -1,5 +1,6 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
/* eslint-disable no-console */

function $c(command, args, callback, error, no_spinner, freeze_msg, btn) {
console.warn("This function '$c' has been deprecated and will be removed soon.");
@@ -11,7 +12,7 @@ function $c(command, args, callback, error, no_spinner, freeze_msg, btn) {
btn: btn,
freeze: freeze_msg,
show_spinner: !no_spinner
})
});
}

// For calling an object
@@ -29,7 +30,7 @@ function $c_obj(doc, method, arg, callback, no_spinner, freeze_msg, btn) {
if(typeof doc=='string') {
args.doctype = doc;
} else {
args.docs = doc
args.docs = doc;
}

return frappe.request.call({
@@ -47,7 +48,7 @@ function $c_obj_csv(doc, method, arg) {
console.warn("This function '$c_obj_csv' has been deprecated and will be removed soon.");
// single

var args = {}
var args = {};
args.cmd = 'runserverobj';
args.as_csv = 1;
args.method = method;
@@ -62,7 +63,7 @@ function $c_obj_csv(doc, method, arg) {
open_url_post(frappe.request.url, args);
}

function open_url_post(URL, PARAMS, new_window) {
window.open_url_post = function open_url_post(URL, PARAMS, new_window) {
if (window.cordova) {
let url = URL + 'api/method/' + PARAMS.cmd + frappe.utils.make_query_string(PARAMS, false);
window.location.href = url;
@@ -70,7 +71,7 @@ function open_url_post(URL, PARAMS, new_window) {
// call a url as POST
_open_url_post(URL, PARAMS, new_window);
}
}
};

function _open_url_post(URL, PARAMS, new_window) {
var temp=document.createElement("form");
@@ -94,3 +95,7 @@ function _open_url_post(URL, PARAMS, new_window) {
temp.submit();
return temp;
}

Object.assign(window, {
$c, $c_obj, $c_obj_csv
});

+ 1
- 1
frappe/public/js/legacy/layout.js Voir le fichier

@@ -14,7 +14,7 @@
+ subrows

*/
function Layout(parent, width) {
window.Layout = function Layout(parent, width) {
if(parent&&parent.substr) { parent = $i(parent); }

this.wrapper = $a(parent, 'div', '', {display:'none'});


+ 1
- 1
frappe/public/js/lib/microtemplate.js Voir le fichier

@@ -39,7 +39,7 @@ frappe.template.compile = function(str, name) {
// {% endif %} --> {% } %}
str = str.replace(/{%\s?endfor\s?%}/g, "{% }; %}");

fn_str = "var _p=[],print=function(){_p.push.apply(_p,arguments)};" +
var fn_str = "var _p=[],print=function(){_p.push.apply(_p,arguments)};" +

// Introduce the data as local variables using with(){}
"with(obj){\n_p.push('" +


+ 1
- 1
frappe/public/js/lib/slickgrid/slick-default-theme.css Voir le fichier

@@ -96,7 +96,7 @@ classes should alter those!

.slick-row.loading {
opacity: 0.5;
filter: alpha(opacity = 50);
/* filter: alpha(opacity = 50); */
}

.slick-cell.invalid {


+ 2
- 2
frappe/public/js/lib/slickgrid/slick.grid.css Voir le fichier

@@ -138,7 +138,7 @@ classes should alter those!
display: inline-block;
background: blue;
opacity: 0.15;
filter: alpha(opacity = 15);
/* filter: alpha(opacity = 15); */
cursor: move;
}

@@ -147,7 +147,7 @@ classes should alter those!
height: 2px;
background: blue;
opacity: 0.7;
filter: alpha(opacity = 70);
/* filter: alpha(opacity = 70); */
}

.slick-selection {


+ 2
- 2
frappe/templates/includes/comments/comments.html Voir le fichier

@@ -71,8 +71,8 @@
$("#comment-form").toggle();
var full_name = "", user_id = "";
if(frappe.is_user_logged_in()) {
full_name = getCookie("full_name");
user_id = getCookie("user_id");
full_name = frappe.get_cookie("full_name");
user_id = frappe.get_cookie("user_id");
if(user_id != "Guest") {
$("[name='comment_by']").val(user_id);
$("[name='comment_by_fullname']").val(full_name);


+ 3
- 3
frappe/templates/includes/login/login.js Voir le fichier

@@ -33,7 +33,7 @@ login.bind_events = function() {
var args = {};
args.cmd = "frappe.core.doctype.user.user.sign_up";
args.email = ($("#signup_email").val() || "").trim();
args.redirect_to = get_url_arg("redirect-to") || '';
args.redirect_to = frappe.utils.get_url_arg("redirect-to") || '';
args.full_name = ($("#signup_fullname").val() || "").trim();
if(!args.email || !valid_email(args.email) || !args.full_name) {
login.set_indicator("{{ _("Valid email and name required") }}", 'red');
@@ -161,13 +161,13 @@ login.login_handlers = (function() {
200: function(data) {
if(data.message == 'Logged In'){
login.set_indicator("{{ _("Success") }}", 'green');
window.location.href = get_url_arg("redirect-to") || data.home_page;
window.location.href = frappe.utils.get_url_arg("redirect-to") || data.home_page;
} else if(data.message=="No App") {
login.set_indicator("{{ _("Success") }}", 'green');
if(localStorage) {
var last_visited =
localStorage.getItem("last_visited")
|| get_url_arg("redirect-to");
|| frappe.utils.get_url_arg("redirect-to");
localStorage.removeItem("last_visited");
}



+ 2
- 2
frappe/templates/includes/search_box.html Voir le fichier

@@ -14,8 +14,8 @@

<script>
frappe.ready(function() {
if(get_url_arg("search")) {
var txt = get_url_arg("search");
if(frappe.utils.get_url_arg("search")) {
var txt = frappe.utils.get_url_arg("search");
$(".item-search-results").html("{{ _('Search results for') }}: " + encodeURIComponent(txt));
$(".item-search").toggle(false);
$(".clear").toggle(true);


+ 41
- 30
frappe/website/js/website.js Voir le fichier

@@ -1,9 +1,10 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// MIT License. See license.txt
/* eslint-disable no-console */

frappe.provide("website");
frappe.provide("frappe.awesome_bar_path");
cur_frm = null;
window.cur_frm = null;

$.extend(frappe, {
boot: {
@@ -17,10 +18,11 @@ $.extend(frappe, {
async: false,
dataType: "text",
success: function(data) {
var el;
if(url.split(".").splice(-1) == "js") {
var el = document.createElement('script');
el = document.createElement('script');
} else {
var el = document.createElement('style');
el = document.createElement('style');
}
el.appendChild(document.createTextNode(data));
document.getElementsByTagName('head')[0].appendChild(el);
@@ -28,13 +30,15 @@ $.extend(frappe, {
}
});
},
hide_message: function(text) {
hide_message: function() {
$('.message-overlay').remove();
},
call: function(opts) {
// opts = {"method": "PYTHON MODULE STRING", "args": {}, "callback": function(r) {}}
frappe.prepare_call(opts);
if(opts.freeze) { frappe.freeze(); }
if(opts.freeze) {
frappe.freeze();
}
return $.ajax({
type: opts.type || "POST",
url: "/",
@@ -42,13 +46,13 @@ $.extend(frappe, {
dataType: "json",
headers: { "X-Frappe-CSRF-Token": frappe.csrf_token },
statusCode: opts.statusCode || {
404: function(xhr) {
404: function() {
frappe.msgprint(__("Not found"));
},
403: function(xhr) {
403: function() {
frappe.msgprint(__("Not permitted"));
},
200: function(data, xhr) {
200: function(data) {
if(opts.callback)
opts.callback(data);
if(opts.success)
@@ -160,7 +164,7 @@ $.extend(frappe, {
+text+'</div>').appendTo(document.body);
},
get_sid: function() {
var sid = getCookie("sid");
var sid = frappe.get_cookie("sid");
return sid && sid !== "Guest";
},
get_modal: function(title, body_html) {
@@ -183,7 +187,7 @@ $.extend(frappe, {
msgprint: function(html, title) {
if(html.substr(0,1)==="[") html = JSON.parse(html);
if($.isArray(html)) {
html = html.join("<hr>")
html = html.join("<hr>");
}

return frappe.get_modal(title || "Message", html).modal("show");
@@ -205,7 +209,9 @@ $.extend(frappe, {
args: {doctype: doctype, docname: docname, perm_type: perm_type},
callback: function(r) {
if(!r.exc && r.message.has_permission) {
if(callback) { return callback(r); }
if(callback) {
return callback(r);
}
}
}
});
@@ -233,7 +239,9 @@ $.extend(frappe, {
freeze.html(repl('<div class="freeze-message-container"><div class="freeze-message">%(msg)s</div></div>',
{msg: msg || ""}));

setTimeout(function() { freeze.addClass("in") }, 1);
setTimeout(function() {
freeze.addClass("in");
}, 1);

} else {
$("#freeze").addClass("in");
@@ -246,7 +254,9 @@ $.extend(frappe, {
if(!frappe.freeze_count) {
var freeze = $('#freeze').removeClass("in");
setTimeout(function() {
if(!frappe.freeze_count) { freeze.remove(); }
if(!frappe.freeze_count) {
freeze.remove();
}
}, 150);
}
},
@@ -258,7 +268,7 @@ $.extend(frappe, {
},

highlight_code_blocks: function() {
if(hljs) {
if(window.hljs) {
$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
@@ -282,7 +292,7 @@ $.extend(frappe, {
});

window.location.href = location.pathname + "?" + $.param(args);
}
};

$(".filter").on("change", function() {
search();
@@ -316,7 +326,7 @@ $.extend(frappe, {
$(this).addClass("active");
return false;
}
})
});
},
get_navbar_search: function() {
return $(".navbar .search, .sidebar .search");
@@ -333,28 +343,29 @@ $.extend(frappe, {
// Utility functions

function valid_email(id) {
// eslint-disable-next-line
return (id.toLowerCase().search("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?")==-1) ? 0 : 1;
}

var validate_email = valid_email;
window.validate_email = valid_email;

function cstr(s) {
return s==null ? '' : s+'';
}

function is_null(v) {
window.is_null = function is_null(v) {
if(v===null || v===undefined || cstr(v).trim()==="") return true;
}
};

function is_html(txt) {
window.is_html = function is_html(txt) {
if(txt.indexOf("<br>")==-1 && txt.indexOf("<p")==-1
&& txt.indexOf("<img")==-1 && txt.indexOf("<div")==-1) {
return false;
}
return true;
}
};

function ask_to_login() {
window.ask_to_login = function ask_to_login() {
if(!frappe.is_user_logged_in()) {
if(localStorage) {
localStorage.setItem("last_visited",
@@ -362,12 +373,12 @@ function ask_to_login() {
}
window.location.href = "login";
}
}
};

// check if logged in?
$(document).ready(function() {
window.full_name = getCookie("full_name");
var logged_in = getCookie("sid") && getCookie("sid") !== "Guest";
window.full_name = frappe.get_cookie("full_name");
var logged_in = frappe.get_cookie("sid") && frappe.get_cookie("sid") !== "Guest";
$("#website-login").toggleClass("hide", logged_in ? true : false);
$("#website-post-login").toggleClass("hide", logged_in ? false : true);
$(".logged-in").toggleClass("hide", logged_in ? false : true);
@@ -375,7 +386,7 @@ $(document).ready(function() {
frappe.bind_navbar_search();

// switch to app link
if(getCookie("system_user")==="yes" && logged_in) {
if(frappe.get_cookie("system_user")==="yes" && logged_in) {
frappe.add_switch_to_desk();
}

@@ -389,12 +400,12 @@ $(document).on("page-change", function() {
$('.dropdown-toggle').dropdown();

//multilevel dropdown fix
$('.dropdown-menu .dropdown-submenu .dropdown-toggle').on('click', function (e) {
$('.dropdown-menu .dropdown-submenu .dropdown-toggle').on('click', function(e) {
e.stopPropagation();
$(this).parent().parent().parent().addClass('open');
})
});

$.extend(frappe, getCookies());
$.extend(frappe, frappe.get_cookies());
frappe.session = {'user': frappe.user_id};

frappe.datetime.refresh_when();
@@ -410,7 +421,7 @@ $(document).on("page-change", function() {
});


$(document).ready(function ( ) {
$(document).ready(function( ) {
// frappe.Chat
// const chat = new frappe.Chat();
// chat.render();


+ 5
- 5
frappe/www/feedback.html Voir le fichier

@@ -55,11 +55,11 @@
init: function() {
var me = this;

this.key = get_url_arg("key");
this.reference_name = get_url_arg("reference_name");
this.reference_doctype = get_url_arg("reference_doctype");
this.sender = get_url_arg("email");
this.rating = get_url_arg("rating") || 0;
this.key = frappe.utils.get_url_arg("key");
this.reference_name = frappe.utils.get_url_arg("reference_name");
this.reference_doctype = frappe.utils.get_url_arg("reference_doctype");
this.sender = frappe.utils.get_url_arg("email");
this.rating = frappe.utils.get_url_arg("rating") || 0;

// set ratings
this.set_ratings_icon(this.rating)


+ 3
- 3
frappe/www/update-password.html Voir le fichier

@@ -40,7 +40,7 @@
<script>

frappe.ready(function() {
if(get_url_arg("key")) {
if(frappe.utils.get_url_arg("key")) {
$("#old_password").parent().toggle(false);
}

@@ -54,7 +54,7 @@ frappe.ready(function() {

$("#update").click(function() {
var args = {
key: get_url_arg("key") || "",
key: frappe.utils.get_url_arg("key") || "",
old_password: $("#old_password").val(),
new_password: $("#new_password").val(),
logout_all_sessions: +($("#logout_all_sessions").is(":checked"))
@@ -110,7 +110,7 @@ frappe.ready(function() {
window.timout_password_strength = null;

var args = {
key: get_url_arg("key") || "",
key: frappe.utils.get_url_arg("key") || "",
old_password: $("#old_password").val(),
new_password: $("#new_password").val()
}


+ 16
- 14
package.json Voir le fichier

@@ -1,7 +1,9 @@
{
"name": "frappe",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"build": "rollup -c",
"production": "FRAPPE_ENV=production rollup -c",
"watch": "rollup -c -w --silent"
},
"repository": {
"type": "git",
@@ -15,20 +17,20 @@
"homepage": "https://frappe.io",
"dependencies": {
"cookie": "^0.3.1",
"express": "^4.15.3",
"redis": "^2.7.1",
"socket.io": "^2.0.1",
"superagent": "^3.5.2",
"touch": "^3.1.0"
"express": "^4.16.2",
"redis": "^2.8.0",
"showdown": "^1.8.6",
"socket.io": "^2.0.4",
"superagent": "^3.8.2"
},
"devDependencies": {
"babel-core": "^6.26.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.0",
"babel-preset-minify": "^0.2.0",
"chokidar": "^1.7.0",
"chromedriver": "^2.32.3",
"less": "^2.7.2",
"nightwatch": "^0.9.16"
"babel-runtime": "^6.26.0",
"rollup": "^0.55.3",
"rollup-plugin-buble": "^0.19.2",
"rollup-plugin-commonjs": "^8.3.0",
"rollup-plugin-less": "^0.1.3",
"rollup-plugin-multi-entry": "^2.0.2",
"rollup-plugin-node-resolve": "^3.0.2",
"rollup-plugin-uglify": "^3.0.0"
}
}

+ 172
- 0
rollup.config.js Voir le fichier

@@ -0,0 +1,172 @@
const path = require('path');
const fs = require('fs');

const {
get_build_json_path,
get_app_path,
apps_list,
assets_path,
get_public_path,
bench_path
} = require('./rollup.utils');

const less = require('rollup-plugin-less');
const multi_entry = require('rollup-plugin-multi-entry');
const commonjs = require('rollup-plugin-commonjs');
const node_resolve = require('rollup-plugin-node-resolve');
const buble = require('rollup-plugin-buble');
const uglify = require('rollup-plugin-uglify');
const frappe_html = require('./frappe-html-plugin');

const production = process.env.FRAPPE_ENV === 'production';

make_js_css_dirs();
build_libs();

function get_app_config(app) {
const build_map = get_build_json(app);
if (!build_map) return [];

const js_config = Object.keys(build_map)
.filter(output_file =>
output_file.endsWith('.js') &&
// libs is built separately (to be deprecated)
!output_file.endsWith('libs.min.js')
)
.map(output_file => {

const input_files = build_map[output_file].map(
// make paths absolute
input_path => path.resolve(get_app_path(app), input_path)
);

return get_js_config(output_file, input_files);
});

const less_config = Object.keys(build_map)
.filter(output_file =>
output_file.endsWith('.css')
)
.map(output_file => {

const input_files = build_map[output_file].map(
input_path => path.resolve(get_app_path(app), input_path)
);

return get_css_config(output_file, input_files);
});

return [].concat(js_config, less_config);
}

function get_js_config(output_file, input_files) {

const plugins = [
// enables array of inputs
multi_entry(),
// .html -> .js
frappe_html(),
// ES6 -> ES5
buble({
objectAssign: 'Object.assign',
transforms: {
dangerousForOf: true
}
}),
commonjs(),
node_resolve(),
production && uglify()
];

return {
input: input_files,
plugins: plugins,
output: {
file: path.resolve(assets_path, output_file),
format: 'iife',
name: 'Rollup',
globals: {
'sortablejs': 'window.Sortable',
'clusterize.js': 'window.Clusterize'
}
},
context: 'window',
onwarn: (e) => {
if (e.code === 'EVAL') return;
},
external: ['jquery']
};
}

function get_css_config(output_file, input_files) {

const plugins = [
// enables array of inputs
multi_entry(),
// less -> css
less({
output: path.resolve(assets_path, output_file),
option: {
// so that other .less files can import variables.less from frappe directly
paths: [path.resolve(get_public_path('frappe'), 'less')],
compress: production
},
include: [path.resolve(bench_path, '**/*.less'), path.resolve(bench_path, '**/*.css')]
})
];

return {
input: input_files,
plugins: plugins,
output: {
// this file is always empty, remove it later?
file: path.resolve(assets_path, `css/rollup.manifest.css`),
format: 'cjs',
}
};
}

function make_js_css_dirs() {
const paths = [
path.resolve(assets_path, 'js'),
path.resolve(assets_path, 'css')
];
paths.forEach(path => {
if (!fs.existsSync(path)) {
fs.mkdirSync(path);
}
});
}

function build_libs() {
const libs_path = 'js/libs.min.js';
const input_files = get_build_json('frappe')[libs_path];

const libs_content = input_files.map(file_name => {
const full_path = path.resolve(get_app_path('frappe'), file_name);
return `/* ${file_name} */\n` + fs.readFileSync(full_path);
}).join('\n\n');

const target_path = path.resolve(assets_path, libs_path);
fs.writeFileSync(target_path, libs_content);
console.log('✨ Built libs.min.js'); // eslint-disable-line
}

function get_all_apps_config() {
let configs = [];
apps_list.forEach(app => {
configs = configs.concat(get_app_config(app));
});
return configs;
}

function get_build_json(app) {
try {
return require(get_build_json_path(app));
} catch (e) {
// build.json does not exist
return null;
}
}

module.exports = get_all_apps_config();

+ 56
- 0
rollup.utils.js Voir le fichier

@@ -0,0 +1,56 @@
const path = require('path');
const fs = require('fs');

const frappe_path = process.cwd();
const bench_path = path.resolve(frappe_path, '..', '..');
const sites_path = path.resolve(bench_path, 'sites');
const apps_list =
fs.readFileSync(
path.resolve(sites_path, 'apps.txt'), { encoding: 'utf-8' }
).split('\n').filter(Boolean);
const assets_path = path.resolve(sites_path, 'assets');

const app_paths = apps_list.reduce((out, app) => {
out[app] = path.resolve(bench_path, 'apps', app, app)
return out;
}, {});
const public_paths = apps_list.reduce((out, app) => {
out[app] = path.resolve(app_paths[app], 'public');
return out;
}, {});
const public_js_paths = apps_list.reduce((out, app) => {
out[app] = path.resolve(app_paths[app], 'public/js');
return out;
}, {});

const bundle_map = apps_list.reduce((out, app) => {
const public_js_path = public_js_paths[app];
if ( fs.existsSync(public_js_path) ) {
const all_files = fs.readdirSync(public_js_path);
const js_files = all_files.filter(file => file.endsWith('.js'));

for (let js_file of js_files) {
const filename = path.basename(js_file).split('.')[0];
out[path.join(app, 'js', filename)] = path.resolve(public_js_path, js_file);
}
}

return out;
}, {});

const get_public_path = app => public_paths[app];

const get_build_json_path = app => path.resolve(get_public_path(app), 'build.json');

const get_app_path = app => app_paths[app];

module.exports = {
sites_path,
bundle_map,
get_public_path,
get_build_json_path,
get_app_path,
apps_list,
assets_path,
bench_path
};

+ 1820
- 0
yarn.lock
Fichier diff supprimé car celui-ci est trop grand
Voir le fichier


Chargement…
Annuler
Enregistrer