This commit is contained in:
djmaze 2021-09-01 12:21:08 +02:00
parent 53ece73da0
commit 010794fccb
9 changed files with 719 additions and 550 deletions

View file

@ -1,4 +1,4 @@
; SnappyMail Webmail configuration file ; SnappyMail configuration file
; Please don't add custom parameters here, those will be overwritten ; Please don't add custom parameters here, those will be overwritten
[webmail] [webmail]
@ -32,33 +32,19 @@ messages_per_page = 20
; File size limit (MB) for file upload on compose screen ; File size limit (MB) for file upload on compose screen
; 0 for unlimited. ; 0 for unlimited.
attachment_size_limit = 25 attachment_size_limit = 2
[interface] [interface]
show_attachment_thumbnail = On show_attachment_thumbnail = On
use_native_scrollbars = Off
new_move_to_folder_button = On new_move_to_folder_button = On
[branding]
login_logo = ""
login_background = ""
login_desc = ""
login_css = ""
user_css = ""
user_logo = ""
user_logo_title = ""
user_logo_message = ""
user_iframe_message = ""
welcome_page_url = ""
welcome_page_display = "none"
[contacts] [contacts]
; Enable contacts ; Enable contacts
enable = Off enable = Off
allow_sync = On allow_sync = Off
sync_interval = 20 sync_interval = 20
type = "sqlite" type = "sqlite"
pdo_dsn = "mysql:host=127.0.0.1;port=3306;dbname=snappymail" pdo_dsn = "host=127.0.0.1;port=3306;dbname=snappymail"
pdo_user = "root" pdo_user = "root"
pdo_password = "" pdo_password = ""
suggestions_limit = 30 suggestions_limit = 30
@ -67,23 +53,21 @@ suggestions_limit = 30
; Enable CSRF protection (http://en.wikipedia.org/wiki/Cross-site_request_forgery) ; Enable CSRF protection (http://en.wikipedia.org/wiki/Cross-site_request_forgery)
csrf_protection = On csrf_protection = On
custom_server_signature = "SnappyMail" custom_server_signature = "SnappyMail"
x_frame_options_header = "" x_frame_options_header = "DENY"
x_xss_protection_header = "1; mode=block" x_xss_protection_header = "1; mode=block"
openpgp = Off openpgp = Off
; Login and password for web admin panel ; Login and password for web admin panel
admin_login = "admin" admin_login = "admin"
admin_password = "12345" admin_password = ""
admin_totp = ""
; Access settings ; Access settings
allow_admin_panel = On allow_admin_panel = On
allow_two_factor_auth = Off hide_x_mailer_header = On
force_two_factor_auth = Off
hide_x_mailer_header = Off
admin_panel_host = "" admin_panel_host = ""
admin_panel_key = "admin" admin_panel_key = "admin"
content_security_policy = "" content_security_policy = ""
core_install_access_domain = ""
[ssl] [ssl]
; Require verification of SSL certificate used. ; Require verification of SSL certificate used.
@ -102,7 +86,6 @@ capath = ""
client_cert = "" client_cert = ""
[capa] [capa]
folders = On
composer = On composer = On
contacts = On contacts = On
settings = On settings = On
@ -111,7 +94,6 @@ help = On
reload = On reload = On
search = On search = On
search_adv = On search_adv = On
filters = On
x-templates = Off x-templates = Off
dangerous_actions = On dangerous_actions = On
message_actions = On message_actions = On
@ -125,10 +107,7 @@ default_domain = ""
allow_languages_on_login = On allow_languages_on_login = On
determine_user_language = On determine_user_language = On
determine_user_domain = Off determine_user_domain = Off
welcome_page = Off
hide_submit_button = On hide_submit_button = On
forgot_password_link_url = ""
registration_link_url = ""
login_lowercase = On login_lowercase = On
; This option allows webmail to remember the logged in user ; This option allows webmail to remember the logged in user
@ -177,9 +156,8 @@ write_on_timeout_only = 0
; Required for development purposes only. ; Required for development purposes only.
; Disabling this option is not recommended. ; Disabling this option is not recommended.
hide_passwords = On hide_passwords = On
time_offset = "0" time_zone = "UTC"
session_filter = "" session_filter = ""
sentry_dsn = ""
; Log filename. ; Log filename.
; For security reasons, some characters are removed from filename. ; For security reasons, some characters are removed from filename.
@ -207,6 +185,7 @@ sentry_dsn = ""
; filename = "log-{date:Y-m-d}.txt" ; filename = "log-{date:Y-m-d}.txt"
; filename = "{date:Y-m-d}/{user:domain}/{user:email}_{user:uid}.log" ; filename = "{date:Y-m-d}/{user:domain}/{user:email}_{user:uid}.log"
; filename = "{user:email}-{date:Y-m-d}.txt" ; filename = "{user:email}-{date:Y-m-d}.txt"
; filename = "syslog"
filename = "log-{date:Y-m-d}.txt" filename = "log-{date:Y-m-d}.txt"
; Enable auth logging in a separate file (for fail2ban) ; Enable auth logging in a separate file (for fail2ban)
@ -218,31 +197,6 @@ auth_logging_format = "[{date:Y-m-d H:i:s}] Auth failed: ip={request:ip} user={i
; Special option required for development purposes ; Special option required for development purposes
enable = Off enable = Off
[social]
; Google
google_enable = Off
google_enable_auth = Off
google_enable_auth_gmail = Off
google_enable_drive = Off
google_enable_preview = Off
google_client_id = ""
google_client_secret = ""
google_api_key = ""
; Facebook
fb_enable = Off
fb_app_id = ""
fb_app_secret = ""
; Twitter
twitter_enable = Off
twitter_consumer_key = ""
twitter_consumer_secret = ""
; Dropbox
dropbox_enable = Off
dropbox_api_key = ""
[cache] [cache]
; The section controls caching of the entire application. ; The section controls caching of the entire application.
; ;
@ -252,7 +206,7 @@ enable = On
; Additional caching key. If changed, cache is purged ; Additional caching key. If changed, cache is purged
index = "v1" index = "v1"
; Can be: files, APCU, memcache, redis (beta) ; Can be: files, APC, memcache, redis (beta)
fast_cache_driver = "files" fast_cache_driver = "files"
; Additional caching key. If changed, fast cache is purged ; Additional caching key. If changed, fast cache is purged
@ -268,27 +222,18 @@ http_expires = 3600
server_uids = On server_uids = On
[labs] [labs]
; Experimental settings. Handle with care.
;
allow_mobile_version = On
ignore_folders_subscription = Off
check_new_password_strength = On
update_channel = "stable" update_channel = "stable"
allow_gravatar = On
allow_prefetch = On allow_prefetch = On
allow_smart_html_links = On allow_smart_html_links = On
cache_system_data = On cache_system_data = On
date_from_headers = On date_from_headers = On
autocreate_system_folders = On autocreate_system_folders = On
allow_message_append = Off allow_message_append = Off
disable_iconv_if_mbstring_supported = Off
login_fault_delay = 1 login_fault_delay = 1
log_ajax_response_write_limit = 300 log_ajax_response_write_limit = 300
allow_html_editor_source_button = Off
allow_html_editor_biti_buttons = Off allow_html_editor_biti_buttons = Off
allow_ctrl_enter_on_compose = On allow_ctrl_enter_on_compose = On
try_to_detect_hidden_images = Off try_to_detect_hidden_images = Off
hide_dangerous_actions = Off
use_app_debug_js = Off use_app_debug_js = Off
use_mobile_version_for_tablets = Off use_mobile_version_for_tablets = Off
use_app_debug_css = Off use_app_debug_css = Off
@ -314,7 +259,6 @@ imap_use_auth_cram_md5 = Off
smtp_show_server_errors = Off smtp_show_server_errors = Off
smtp_use_auth_plain = On smtp_use_auth_plain = On
smtp_use_auth_cram_md5 = Off smtp_use_auth_cram_md5 = Off
sieve_allow_raw_script = Off
sieve_utf8_folder_name = On sieve_utf8_folder_name = On
sieve_auth_plain_initial = On sieve_auth_plain_initial = On
sieve_allow_fileinto_inbox = Off sieve_allow_fileinto_inbox = Off
@ -326,23 +270,16 @@ mail_func_clear_headers = On
mail_func_additional_parameters = Off mail_func_additional_parameters = Off
favicon_status = On favicon_status = On
folders_spec_limit = 50 folders_spec_limit = 50
owncloud_save_folder = "Attachments"
owncloud_suggestions = On
curl_proxy = "" curl_proxy = ""
curl_proxy_auth = "" curl_proxy_auth = ""
in_iframe = Off in_iframe = Off
force_https = Off force_https = Off
custom_login_link = ""
custom_logout_link = ""
allow_external_login = Off
allow_external_sso = Off
external_sso_key = ""
http_client_ip_check_proxy = Off http_client_ip_check_proxy = Off
fast_cache_memcache_host = "127.0.0.1" fast_cache_memcache_host = "127.0.0.1"
fast_cache_memcache_port = 11211 fast_cache_memcache_port = 11211
fast_cache_redis_host = "127.0.0.1" fast_cache_redis_host = "127.0.0.1"
fast_cache_redis_port = 6379 fast_cache_redis_port = 6379
use_local_proxy_for_external_images = Off use_local_proxy_for_external_images = On
detect_image_exif_orientation = On detect_image_exif_orientation = On
cookie_default_path = "" cookie_default_path = ""
cookie_default_secure = Off cookie_default_secure = Off
@ -350,10 +287,10 @@ check_new_messages = On
replace_env_in_configuration = "" replace_env_in_configuration = ""
startup_url = "" startup_url = ""
strict_html_parser = Off strict_html_parser = Off
allow_cmd = Off boundary_prefix = ""
dev_email = "" dev_email = ""
dev_password = "" dev_password = ""
[version] [version]
current = "1.14.0" current = "2.7.0"
saved = "Wed, 08 Apr 2020 16:37:27 +0000" saved = "Mon, 23 Aug 2021 07:55:13 +0000"

View file

@ -7,14 +7,15 @@
**Getting started** **Getting started**
1. Install node.js - `https://nodejs.org/download/` 1. Install PHP
2. Install yarn - `https://yarnpkg.com/en/docs/install` 2. Install node.js - `https://nodejs.org/download/`
3. Install gulp - `npm install gulp -g` 3. Install yarn - `https://yarnpkg.com/en/docs/install`
4. Fork snappymail from https://github.com/the-djmaze/snappymail 4. Install gulp - `npm install gulp -g`
5. Clone snappymail - `git clone git@github.com:USERNAME/snappymail.git snappymail` 5. Fork snappymail from https://github.com/the-djmaze/snappymail
6. `cd snappymail` 6. Clone snappymail - `git clone git@github.com:USERNAME/snappymail.git snappymail`
7. Install install all dependencies - `yarn install` 7. `cd snappymail`
8. Run gulp - `gulp` 8. Install all dependencies - `yarn install`
9. Run gulp - `gulp`
--- ---
@ -30,6 +31,17 @@
1. Edit data/\_data_/\_default_/configs/application.ini 1. Edit data/\_data_/\_default_/configs/application.ini
2. Set 'cache_system_data' to Off 2. Set 'cache_system_data' to Off
**Release**
1. Install gzip
2. Install brotli
3. php release.php
Options:
* `php release.php --aur` = Build Arch Linux package
* `php release.php --docker` = Build Docker instance
* `php release.php --plugins` = Build plugins
--- ---
If you have any questions, open an issue or email support@snappymail.eu. If you have any questions, open an issue or email support@snappymail.eu.

View file

@ -129,23 +129,23 @@ RainLoop 1.15 vs SnappyMail
|js/* |RainLoop |Snappy | |js/* |RainLoop |Snappy |
|--------------- |--------: |--------: | |--------------- |--------: |--------: |
|admin.js |2.158.025 | 91.050 | |admin.js |2.158.025 | 89.407 |
|app.js |4.215.733 | 451.709 | |app.js |4.215.733 | 447.836 |
|boot.js | 672.433 | 2.861 | |boot.js | 672.433 | 2.856 |
|libs.js | 647.679 | 214.458 | |libs.js | 647.679 | 214.458 |
|polyfills.js | 325.908 | 0 | |polyfills.js | 325.908 | 0 |
|serviceworker.js | 0 | 285 | |serviceworker.js | 0 | 285 |
|TOTAL |8.019.778 | 760.363 | |TOTAL |8.019.778 | 754.842 |
|js/min/* |RainLoop |Snappy |RL gzip |SM gzip |RL brotli |SM brotli | |js/min/* |RainLoop |Snappy |RL gzip |SM gzip |RL brotli |SM brotli |
|--------------- |--------: |--------: |------: |------: |--------: |--------: | |--------------- |--------: |--------: |------: |------: |--------: |--------: |
|admin.min.js | 255.514 | 47.330 | 73.899 | 14.216 | 60.674 | 12.715 | |admin.min.js | 255.514 | 46.428 | 73.899 | 14.039 | 60.674 | 12.575 |
|app.min.js | 516.000 | 232.217 |140.430 | 68.323 |110.657 | 57.830 | |app.min.js | 516.000 | 230.355 |140.430 | 67.980 |110.657 | 57.567 |
|boot.min.js | 66.456 | 1.621 | 22.553 | 968 | 20.043 | 810 | |boot.min.js | 66.456 | 1.648 | 22.553 | 986 | 20.043 | 822 |
|libs.min.js | 574.626 | 103.928 |177.280 | 37.795 |151.855 | 33.829 | |libs.min.js | 574.626 | 103.928 |177.280 | 37.795 |151.855 | 33.829 |
|polyfills.min.js | 32.608 | 0 | 11.315 | 0 | 10.072 | 0 | |polyfills.min.js | 32.608 | 0 | 11.315 | 0 | 10.072 | 0 |
|TOTAL |1.445.204 | 385.096 |425.477 |121.302 |353.301 |105.184 | |TOTAL |1.445.204 | 382.359 |425.477 |120.800 |353.301 |104.793 |
|TOTAL (no admin) |1.189.690 | 337.766 |351.061 |107.086 |292.627 | 92.469 | |TOTAL (no admin) |1.189.690 | 335.931 |351.061 |106.761 |292.627 | 92.218 |
For a user its around 68% smaller and faster than traditional RainLoop. For a user its around 68% smaller and faster than traditional RainLoop.
@ -184,12 +184,12 @@ For a user its around 68% smaller and faster than traditional RainLoop.
|css/* |RainLoop |Snappy |RL gzip |SM gzip |SM brotli | |css/* |RainLoop |Snappy |RL gzip |SM gzip |SM brotli |
|------------ |-------: |------: |------: |------: |--------: | |------------ |-------: |------: |------: |------: |--------: |
|app.css | 340.334 | 96.105 | 46,959 | 17.510 | 15.104 | |app.css | 340.334 | 94.785 | 46.959 | 17.381 | 15.006 |
|app.min.css | 274.791 | 78.371 | 39.618 | 15.671 | 13.804 | |app.min.css | 274.791 | 77.141 | 39.618 | 15.535 | 13.683 |
|boot.css | | 1.326 | | 664 | 545 | |boot.css | | 1.326 | | 664 | 545 |
|boot.min.css | | 1.071 | | 590 | 474 | |boot.min.css | | 1.071 | | 590 | 474 |
|admin.css | | 40.198 | | 8.442 | 7.371 | |admin.css | | 40.340 | | 8.507 | 7.434 |
|admin.min.css | | 31.756 | | 7.401 | 6.572 | |admin.min.css | | 31.824 | | 7.463 | 6.627 |
### Squire vs CKEditor ### Squire vs CKEditor
@ -202,7 +202,7 @@ Still TODO:
| | normal | min | gzip | min gzip | | | normal | min | gzip | min gzip |
|-------- |-------: |-------: |------: |--------: | |-------- |-------: |-------: |------: |--------: |
|squire | 128.826 | 47.074 | 33.671 | 15.596 | |squire | 122.321 | 41.906 | 31.867 | 14.330 |
|ckeditor | ? | 520.035 | ? | 155.916 | |ckeditor | ? | 520.035 | ? | 155.916 |
CKEditor including the 7 asset requests (css,language,plugins,icons) is 633.46 KB / 180.47 KB (gzip). CKEditor including the 7 asset requests (css,language,plugins,icons) is 633.46 KB / 180.47 KB (gzip).

View file

@ -1 +1 @@
2.6.2 2.7.0

View file

@ -4,7 +4,7 @@
<name>SnappyMail</name> <name>SnappyMail</name>
<summary>SnappyMail Webmail</summary> <summary>SnappyMail Webmail</summary>
<description>Simple, modern and fast web-based email client. After enabling in Nextcloud, go to Nextcloud admin panel, "Additionnal settings" and you will see a "SnappyMail webmail" section. There, click on the link to go to the SnappyMail admin panel. The default user/password is admin/12345. This version is based on SnappyMail 2.6.0 (2021-07).</description> <description>Simple, modern and fast web-based email client. After enabling in Nextcloud, go to Nextcloud admin panel, "Additionnal settings" and you will see a "SnappyMail webmail" section. There, click on the link to go to the SnappyMail admin panel. The default user/password is admin/12345. This version is based on SnappyMail 2.6.0 (2021-07).</description>
<version>2.6.2</version> <version>2.7.0</version>
<licence>agpl</licence> <licence>agpl</licence>
<author>SnappyMail Team, Nextgen-Networks, Tab Fitts, Nathan Kinkade, Pierre-Alain Bandinelli</author> <author>SnappyMail Team, Nextgen-Networks, Tab Fitts, Nathan Kinkade, Pierre-Alain Bandinelli</author>
<namespace>SnappyMail</namespace> <namespace>SnappyMail</namespace>

View file

@ -3,7 +3,7 @@
"title": "SnappyMail", "title": "SnappyMail",
"description": "Simple, modern & fast web-based email client", "description": "Simple, modern & fast web-based email client",
"private": true, "private": true,
"version": "2.6.2", "version": "2.7.0",
"homepage": "https://snappymail.eu", "homepage": "https://snappymail.eu",
"author": { "author": {
"name": "DJ Maze", "name": "DJ Maze",
@ -43,22 +43,22 @@
"readmeFilename": "README.md", "readmeFilename": "README.md",
"devDependencies": { "devDependencies": {
"babel-eslint": "10.1.0", "babel-eslint": "10.1.0",
"core-js": "^3.8.3", "core-js": "3.16.3",
"eslint": "6.8.0", "eslint": "7.32.0",
"gulp": "4.0.2", "gulp": "4.0.2",
"gulp-cached": "1.1.1", "gulp-cached": "1.1.1",
"gulp-clean-css": "4.3.0", "gulp-clean-css": "4.3.0",
"gulp-eol": "0.2.0", "gulp-eol": "0.2.0",
"gulp-eslint": "6.0.0", "gulp-eslint": "6.0.0",
"gulp-expect-file": "1.0.2", "gulp-expect-file": "2.0.0",
"gulp-filter": "6.0.0", "gulp-filter": "7.0.0",
"gulp-header": "2.0.9", "gulp-header": "2.0.9",
"gulp-less": "4.0.1", "gulp-less": "5.0.0",
"gulp-rename": "2.0.0", "gulp-rename": "2.0.0",
"gulp-replace": "1.0.0", "gulp-replace": "1.1.3",
"gulp-size": "3.0.0", "gulp-size": "4.0.1",
"gulp-stripbom": "1.0.5", "gulp-stripbom": "1.0.5",
"gulp-terser": "^1.4.0", "gulp-terser": "2.0.1",
"gulp-util": "3.0.8" "gulp-util": "3.0.8"
}, },
"dependencies": { "dependencies": {
@ -67,7 +67,7 @@
"gulp-concat": "^2.6.1", "gulp-concat": "^2.6.1",
"gulp-group-css-media-queries": "^1.2.2", "gulp-group-css-media-queries": "^1.2.2",
"gulp-rollup-2": "^1.2.1", "gulp-rollup-2": "^1.2.1",
"rollup": "^2.38.0", "rollup": "2.56.3",
"rollup-plugin-external-globals": "^0.6.1", "rollup-plugin-external-globals": "^0.6.1",
"rollup-plugin-html": "^0.2.1", "rollup-plugin-html": "^0.2.1",
"rollup-plugin-includepaths": "^0.2.4", "rollup-plugin-includepaths": "^0.2.4",

View file

@ -2,7 +2,7 @@
<?php <?php
chdir(__DIR__); chdir(__DIR__);
$options = getopt('', ['aur','docker','plugins']); $options = getopt('', ['aur','docker','plugins','set-version']);
if (isset($options['plugins'])) { if (isset($options['plugins'])) {
$destPath = "build/dist/releases/plugins/"; $destPath = "build/dist/releases/plugins/";
@ -85,14 +85,6 @@ if (!$gulp) {
exit('gulp not installed, run as root: npm install --global gulp-cli'); exit('gulp not installed, run as root: npm install --global gulp-cli');
} }
// Arch User Repository
// https://aur.archlinux.org/packages/snappymail/
$options['aur'] = isset($options['aur']);
// Docker build
$docker = trim(`which docker`);
$options['docker'] = isset($options['docker']) || (!$options['aur'] && $docker && strtoupper(readline("Build Docker image? (Y/N): ")) === "Y");
$package = json_decode(file_get_contents('package.json')); $package = json_decode(file_get_contents('package.json'));
// Update files that contain version // Update files that contain version
@ -101,6 +93,19 @@ $file = __DIR__ . '/integrations/nextcloud/snappymail/appinfo/info.xml';
file_put_contents($file, preg_replace('/<version>[^<]*</', "<version>{$package->version}<", file_get_contents($file))); file_put_contents($file, preg_replace('/<version>[^<]*</', "<version>{$package->version}<", file_get_contents($file)));
$file = __DIR__ . '/arch/PKGBUILD'; $file = __DIR__ . '/arch/PKGBUILD';
file_put_contents($file, preg_replace('/pkgver=[0-9.]+/', "pkgver={$package->version}", file_get_contents($file))); file_put_contents($file, preg_replace('/pkgver=[0-9.]+/', "pkgver={$package->version}", file_get_contents($file)));
$file = __DIR__ . '/.docker/release/files/usr/local/include/application.ini';
file_put_contents($file, preg_replace('/current = "[0-9.]+"/', "current = \"{$package->version}\"", file_get_contents($file)));
if (isset($options['set-version'])) {
exit;
}
// Arch User Repository
// https://aur.archlinux.org/packages/snappymail/
$options['aur'] = isset($options['aur']);
// Docker build
$docker = trim(`which docker`);
$options['docker'] = isset($options['docker']) || (!$options['aur'] && $docker && strtoupper(readline("Build Docker image? (Y/N): ")) === "Y");
$destPath = "build/dist/releases/webmail/{$package->version}/"; $destPath = "build/dist/releases/webmail/{$package->version}/";
is_dir($destPath) || mkdir($destPath, 0777, true); is_dir($destPath) || mkdir($destPath, 0777, true);

View file

@ -9,7 +9,7 @@ class Exception extends \Exception {};
* lessphp v0.3.9 * lessphp v0.3.9
* http://leafo.net/lessphp * http://leafo.net/lessphp
* *
* LESS css compiler, adapted from http://lesscss.org * LESS CSS compiler, adapted from http://lesscss.org
* *
* Copyright 2012, Leaf Corcoran <leafot@gmail.com> * Copyright 2012, Leaf Corcoran <leafot@gmail.com>
* Licensed under MIT or GPLv3, see LICENSE * Licensed under MIT or GPLv3, see LICENSE
@ -17,7 +17,7 @@ class Exception extends \Exception {};
/** /**
* The less compiler and parser. * The LESS compiler and parser.
* *
* Converting LESS to CSS is a three stage process. The incoming file is parsed * Converting LESS to CSS is a three stage process. The incoming file is parsed
* by `lessc_parser` into a syntax tree, then it is compiled into another tree * by `lessc_parser` into a syntax tree, then it is compiled into another tree
@ -44,6 +44,7 @@ class Exception extends \Exception {};
*/ */
class lessc { class lessc {
static public $VERSION = "v0.3.9"; static public $VERSION = "v0.3.9";
static protected $TRUE = array("keyword", "true"); static protected $TRUE = array("keyword", "true");
static protected $FALSE = array("keyword", "false"); static protected $FALSE = array("keyword", "false");
@ -85,12 +86,12 @@ class lessc {
return is_file($name); return is_file($name);
} }
static public function compressList($items, $delim) { public static function compressList($items, $delim) {
if (!isset($items[1]) && isset($items[0])) return $items[0]; if (!isset($items[1]) && isset($items[0])) return $items[0];
else return array('list', $delim, $items); else return array('list', $delim, $items);
} }
static public function preg_quote($what) { public static function preg_quote($what) {
return preg_quote($what, '/'); return preg_quote($what, '/');
} }
@ -353,8 +354,8 @@ class lessc {
protected function multiplyMedia($env, $childQueries = null) { protected function multiplyMedia($env, $childQueries = null) {
if (is_null($env) || if (is_null($env) ||
!empty($env->block->type) && $env->block->type != "media") !empty($env->block->type) && $env->block->type != "media"
{ ) {
return $childQueries; return $childQueries;
} }
@ -588,7 +589,9 @@ class lessc {
$value = $values[$i]; $value = $values[$i];
} elseif (isset($a[2])) { } elseif (isset($a[2])) {
$value = $a[2]; $value = $a[2];
} else $value = null; } else {
$value = null;
}
$value = $this->reduce($value); $value = $this->reduce($value);
$this->set($a[1], $value); $this->set($a[1], $value);
@ -659,8 +662,8 @@ class lessc {
if ($suffix !== null && if ($suffix !== null &&
$subProp[0] == "assign" && $subProp[0] == "assign" &&
is_string($subProp[1]) && is_string($subProp[1]) &&
$subProp[1][0] != $this->vPrefix) $subProp[1][0] != $this->vPrefix
{ ) {
$subProp[2] = array( $subProp[2] = array(
'list', ' ', 'list', ' ',
array($subProp[2], array('keyword', $suffix)) array($subProp[2], array('keyword', $suffix))
@ -687,7 +690,7 @@ class lessc {
case "comment": case "comment":
$out->lines[] = $prop[1]; $out->lines[] = $prop[1];
break; break;
case "import"; case "import":
list(, $importPath, $importId) = $prop; list(, $importPath, $importId) = $prop;
$importPath = $this->reduce($importPath); $importPath = $this->reduce($importPath);
@ -706,7 +709,9 @@ class lessc {
list(,$importId) = $prop; list(,$importId) = $prop;
$import = $this->env->imports[$importId]; $import = $this->env->imports[$importId];
if ($import[0] === false) { if ($import[0] === false) {
if (isset($import[1])) {
$out->lines[] = $import[1]; $out->lines[] = $import[1];
}
} else { } else {
list(, $bottom, $parser, $importDir) = $import; list(, $bottom, $parser, $importDir) = $import;
$this->compileImportedProps($bottom, $block, $out, $parser, $importDir); $this->compileImportedProps($bottom, $block, $out, $parser, $importDir);
@ -828,12 +833,16 @@ class lessc {
protected function lib_rgbahex($color) { protected function lib_rgbahex($color) {
$color = $this->coerceColor($color); $color = $this->coerceColor($color);
if (is_null($color)) if (is_null($color)) {
$this->throwError("color expected for rgbahex"); $this->throwError("color expected for rgbahex");
}
return sprintf("#%02x%02x%02x%02x", return sprintf("#%02x%02x%02x%02x",
isset($color[4]) ? $color[4]*255 : 255, isset($color[4]) ? $color[4]*255 : 255,
$color[1],$color[2], $color[3]); $color[1],
$color[2],
$color[3]
);
} }
protected function lib_argb($color){ protected function lib_argb($color){
@ -965,7 +974,9 @@ class lessc {
$hsl = $this->toHSL($color); $hsl = $this->toHSL($color);
$hsl[1] = $hsl[1] + $delta % 360; $hsl[1] = $hsl[1] + $delta % 360;
if ($hsl[1] < 0) $hsl[1] += 360; if ($hsl[1] < 0) {
$hsl[1] += 360;
}
return $this->toRGB($hsl); return $this->toRGB($hsl);
} }
@ -1095,14 +1106,18 @@ class lessc {
if ($min == $max) { if ($min == $max) {
$S = $H = 0; $S = $H = 0;
} else { } else {
if ($L < 0.5) if ($L < 0.5) {
$S = ($max - $min)/($max + $min); $S = ($max - $min)/($max + $min);
else } else {
$S = ($max - $min)/(2.0 - $max - $min); $S = ($max - $min)/(2.0 - $max - $min);
}
if ($r == $max) $H = ($g - $b)/($max - $min); if ($r == $max) {
elseif ($g == $max) $H = 2.0 + ($b - $r)/($max - $min); $H = ($g - $b)/($max - $min);
elseif ($b == $max) $H = 4.0 + ($r - $g)/($max - $min); } elseif ($g == $max) {
$H = 2.0 + ($b - $r)/($max - $min);
} elseif ($b == $max) {
$H = 4.0 + ($r - $g)/($max - $min);
}
} }
@ -1112,17 +1127,29 @@ class lessc {
$L * 100, $L * 100,
); );
if (count($color) > 4) $out[] = $color[4]; // copy alpha if (count($color) > 4) {
// copy alpha
$out[] = $color[4];
}
return $out; return $out;
} }
protected function toRGB_helper($comp, $temp1, $temp2) { protected function toRGB_helper($comp, $temp1, $temp2) {
if ($comp < 0) $comp += 1.0; if ($comp < 0) {
elseif ($comp > 1) $comp -= 1.0; $comp += 1.0;
} elseif ($comp > 1) {
$comp -= 1.0;
}
if (6 * $comp < 1) return $temp1 + ($temp2 - $temp1) * 6 * $comp; if (6 * $comp < 1) {
if (2 * $comp < 1) return $temp2; return $temp1 + ($temp2 - $temp1) * 6 * $comp;
if (3 * $comp < 2) return $temp1 + ($temp2 - $temp1)*((2/3) - $comp) * 6; }
if (2 * $comp < 1) {
return $temp2;
}
if (3 * $comp < 2) {
return $temp1 + ($temp2 - $temp1)*((2/3) - $comp) * 6;
}
return $temp1; return $temp1;
} }
@ -1132,7 +1159,9 @@ class lessc {
* Expects H to be in range of 0 to 360, S and L in 0 to 100 * Expects H to be in range of 0 to 360, S and L in 0 to 100
*/ */
protected function toRGB($color) { protected function toRGB($color) {
if ($color[0] == 'color') return $color; if ($color[0] === 'color') {
return $color;
}
$H = $color[1] / 360; $H = $color[1] / 360;
$S = $color[2] / 100; $S = $color[2] / 100;
@ -1154,7 +1183,10 @@ class lessc {
// $out = array('color', round($r*255), round($g*255), round($b*255)); // $out = array('color', round($r*255), round($g*255), round($b*255));
$out = array('color', $r*255, $g*255, $b*255); $out = array('color', $r*255, $g*255, $b*255);
if (count($color) > 4) $out[] = $color[4]; // copy alpha if (count($color) > 4) {
// copy alpha
$out[] = $color[4];
}
return $out; return $out;
} }
@ -1168,7 +1200,10 @@ class lessc {
*/ */
protected function funcToColor($func) { protected function funcToColor($func) {
$fname = $func[1]; $fname = $func[1];
if ($func[2][0] != 'list') return false; // need a list of arguments if ($func[2][0] != 'list') {
// need a list of arguments
return false;
}
$rawComponents = $func[2][2]; $rawComponents = $func[2][2];
if ($fname == 'hsl' || $fname == 'hsla') { if ($fname == 'hsl' || $fname == 'hsla') {
@ -1178,15 +1213,21 @@ class lessc {
$val = $this->reduce($c); $val = $this->reduce($c);
$val = isset($val[1]) ? floatval($val[1]) : 0; $val = isset($val[1]) ? floatval($val[1]) : 0;
if ($i == 0) $clamp = 360; if ($i == 0) {
elseif ($i < 3) $clamp = 100; $clamp = 360;
else $clamp = 1; } elseif ($i < 3) {
$clamp = 100;
} else {
$clamp = 1;
}
$hsl[] = $this->clamp($val, $clamp); $hsl[] = $this->clamp($val, $clamp);
$i++; $i++;
} }
while (count($hsl) < 4) $hsl[] = 0; while (count($hsl) < 4) {
$hsl[] = 0;
}
return $this->toRGB($hsl); return $this->toRGB($hsl);
} elseif ($fname == 'rgb' || $fname == 'rgba') { } elseif ($fname == 'rgb' || $fname == 'rgba') {
@ -1210,7 +1251,9 @@ class lessc {
$i++; $i++;
} }
while (count($components) < 3) $components[] = 0; while (count($components) < 3) {
$components[] = 0;
}
array_unshift($components, 'color'); array_unshift($components, 'color');
return $this->fixColor($components); return $this->fixColor($components);
} }
@ -1270,6 +1313,7 @@ class lessc {
list(, $name, $args) = $value; list(, $name, $args) = $value;
if ($name == "%") $name = "_sprintf"; if ($name == "%") $name = "_sprintf";
$f = isset($this->libFunctions[$name]) ? $f = isset($this->libFunctions[$name]) ?
$this->libFunctions[$name] : array($this, 'lib_'.$name); $this->libFunctions[$name] : array($this, 'lib_'.$name);
@ -1286,8 +1330,11 @@ class lessc {
} }
// convert to a typed value if the result is a php primitive // convert to a typed value if the result is a php primitive
if (is_numeric($ret)) $ret = array('number', $ret, ""); if (is_numeric($ret)) {
elseif (!is_array($ret)) $ret = array('keyword', $ret); $ret = array('number', $ret, "");
} elseif (!is_array($ret)) {
$ret = array('keyword', $ret);
}
return $ret; return $ret;
} }
@ -1350,9 +1397,9 @@ class lessc {
if (isset(self::$cssColors[$name])) { if (isset(self::$cssColors[$name])) {
$rgba = explode(',', self::$cssColors[$name]); $rgba = explode(',', self::$cssColors[$name]);
if(isset($rgba[3])) if (isset($rgba[3])) {
return array('color', $rgba[0], $rgba[1], $rgba[2], $rgba[3]); return array('color', $rgba[0], $rgba[1], $rgba[2], $rgba[3]);
}
return array('color', $rgba[0], $rgba[1], $rgba[2]); return array('color', $rgba[0], $rgba[1], $rgba[2]);
} }
return null; return null;
@ -1379,8 +1426,7 @@ class lessc {
} }
protected function toBool($a) { protected function toBool($a) {
if ($a) return self::$TRUE; return $a ? self::$TRUE : self::$FALSE;
else return self::$FALSE;
} }
// evaluate an expression // evaluate an expression
@ -1423,8 +1469,12 @@ class lessc {
// make the expression look it did before being parsed // make the expression look it did before being parsed
$paddedOp = $op; $paddedOp = $op;
if ($whiteBefore) $paddedOp = " " . $paddedOp; if ($whiteBefore) {
if ($whiteAfter) $paddedOp .= " "; $paddedOp = " " . $paddedOp;
}
if ($whiteAfter) {
$paddedOp .= " ";
}
return array("string", "", array($left, $paddedOp, $right)); return array("string", "", array($left, $paddedOp, $right));
} }
@ -1488,7 +1538,9 @@ class lessc {
$out[] = $lval % $rval; $out[] = $lval % $rval;
break; break;
case '/': case '/':
if ($rval == 0) $this->throwError("evaluate error: can't divide by zero"); if ($rval == 0) {
$this->throwError("evaluate error: can't divide by zero");
}
$out[] = $lval / $rval; $out[] = $lval / $rval;
break; break;
default: default:
@ -1610,12 +1662,13 @@ class lessc {
return array('list', ' ', $current->arguments); return array('list', ' ', $current->arguments);
} }
if (isset($current->store[$name])) if (isset($current->store[$name])) {
return $current->store[$name]; return $current->store[$name];
else {
$current = isset($current->storeParent) ?
$current->storeParent : $current->parent;
} }
$current = isset($current->storeParent) ?
$current->storeParent :
$current->parent;
} }
return $default; return $default;
@ -1626,7 +1679,9 @@ class lessc {
$this->pushEnv(); $this->pushEnv();
$parser = new lessc_parser($this, __METHOD__); $parser = new lessc_parser($this, __METHOD__);
foreach ($args as $name => $strValue) { foreach ($args as $name => $strValue) {
if ($name[0] != '@') $name = '@'.$name; if ($name[0] != '@') {
$name = '@' . $name;
}
$parser->count = 0; $parser->count = 0;
$parser->buffer = (string)$strValue; $parser->buffer = (string)$strValue;
if (!$parser->propertyValue($value)) { if (!$parser->propertyValue($value)) {
@ -1735,15 +1790,15 @@ class lessc {
if (is_string($in)) { if (is_string($in)) {
$root = $in; $root = $in;
} elseif (is_array($in) and isset($in['root'])) { } elseif (is_array($in) && isset($in['root'])) {
if ($force or ! isset($in['files'])) { if ($force || !isset($in['files'])) {
// If we are forcing a recompile or if for some reason the // If we are forcing a recompile or if for some reason the
// structure does not contain any file information we should // structure does not contain any file information we should
// specify the root to trigger a rebuild. // specify the root to trigger a rebuild.
$root = $in['root']; $root = $in['root'];
} elseif (isset($in['files']) and is_array($in['files'])) { } elseif (isset($in['files']) && is_array($in['files'])) {
foreach ($in['files'] as $fname => $ftime) { foreach ($in['files'] as $fname => $ftime) {
if (!file_exists($fname) or filemtime($fname) > $ftime) { if (!file_exists($fname) || filemtime($fname) > $ftime) {
// One of the files we knew about previously has changed // One of the files we knew about previously has changed
// so we should look at our incoming root again. // so we should look at our incoming root again.
$root = $in['root']; $root = $in['root'];
@ -2184,8 +2239,8 @@ class lessc_parser {
// setting a property // setting a property
if ($this->keyword($key) && $this->assign() && if ($this->keyword($key) && $this->assign() &&
$this->propertyValue($value, $key) && $this->end()) $this->propertyValue($value, $key) && $this->end()
{ ) {
$this->append(array('assign', $key, $value), $s); $this->append(array('assign', $key, $value), $s);
return true; return true;
} else { } else {
@ -2200,8 +2255,8 @@ class lessc_parser {
// media // media
if ($this->literal('@media')) { if ($this->literal('@media')) {
if (($this->mediaQueryList($mediaQueries) || true) if (($this->mediaQueryList($mediaQueries) || true)
&& $this->literal('{')) && $this->literal('{')
{ ) {
$media = $this->pushSpecialBlock("media"); $media = $this->pushSpecialBlock("media");
$media->queries = is_null($mediaQueries) ? array() : $mediaQueries; $media->queries = is_null($mediaQueries) ? array() : $mediaQueries;
return true; return true;
@ -2214,8 +2269,8 @@ class lessc_parser {
if ($this->literal("@", false) && $this->keyword($dirName)) { if ($this->literal("@", false) && $this->keyword($dirName)) {
if ($this->isDirective($dirName, $this->blockDirectives)) { if ($this->isDirective($dirName, $this->blockDirectives)) {
if (($this->openString("{", $dirValue, null, array(";")) || true) && if (($this->openString("{", $dirValue, null, array(";")) || true) &&
$this->literal("{")) $this->literal("{")
{ ) {
$dir = $this->pushSpecialBlock("directive"); $dir = $this->pushSpecialBlock("directive");
$dir->name = $dirName; $dir->name = $dirName;
if (isset($dirValue)) $dir->value = $dirValue; if (isset($dirValue)) $dir->value = $dirValue;
@ -2234,8 +2289,8 @@ class lessc_parser {
// setting a variable // setting a variable
if ($this->variable($var) && $this->assign() && if ($this->variable($var) && $this->assign() &&
$this->propertyValue($value) && $this->end()) $this->propertyValue($value) && $this->end()
{ ) {
$this->append(array('assign', $var, $value), $s); $this->append(array('assign', $var, $value), $s);
return true; return true;
} else { } else {
@ -2250,8 +2305,8 @@ class lessc_parser {
// opening parametric mixin // opening parametric mixin
if ($this->tag($tag, true) && $this->argumentDef($args, $isVararg) && if ($this->tag($tag, true) && $this->argumentDef($args, $isVararg) &&
($this->guards($guards) || true) && ($this->guards($guards) || true) &&
$this->literal('{')) $this->literal('{')
{ ) {
$block = $this->pushBlock($this->fixTags(array($tag))); $block = $this->pushBlock($this->fixTags(array($tag)));
$block->args = $args; $block->args = $args;
$block->isVararg = $isVararg; $block->isVararg = $isVararg;
@ -2311,8 +2366,8 @@ class lessc_parser {
// mixin // mixin
if ($this->mixinTags($tags) && if ($this->mixinTags($tags) &&
($this->argumentValues($argv) || true) && ($this->argumentValues($argv) || true) &&
($this->keyword($suffix) || true) && $this->end()) ($this->keyword($suffix) || true) && $this->end()
{ ) {
$tags = $this->fixTags($tags); $tags = $this->fixTags($tags);
$this->append(array('mixin', $tags, $argv, $suffix), $s); $this->append(array('mixin', $tags, $argv, $suffix), $s);
return true; return true;
@ -2467,8 +2522,8 @@ class lessc_parser {
$inParens = $this->inParens; $inParens = $this->inParens;
if ($this->literal("(") && if ($this->literal("(") &&
($this->inParens = true) && $this->expression($exp) && ($this->inParens = true) && $this->expression($exp) &&
$this->literal(")")) $this->literal(")")
{ ) {
$out = $exp; $out = $exp;
$this->inParens = $inParens; $this->inParens = $inParens;
return true; return true;
@ -2490,8 +2545,8 @@ class lessc_parser {
if ($this->literal("-", false) && if ($this->literal("-", false) &&
(($this->variable($inner) && $inner = array("variable", $inner)) || (($this->variable($inner) && $inner = array("variable", $inner)) ||
$this->unit($inner) || $this->unit($inner) ||
$this->parenValue($inner))) $this->parenValue($inner))
{ ) {
$value = array("unary", "-", $inner); $value = array("unary", "-", $inner);
return true; return true;
} else { } else {
@ -2597,8 +2652,8 @@ class lessc_parser {
if ($this->literal("(") && if ($this->literal("(") &&
$this->keyword($feature) && $this->keyword($feature) &&
($this->literal(":") && $this->expression($value) || true) && ($this->literal(":") && $this->expression($value) || true) &&
$this->literal(")")) $this->literal(")")
{ ) {
$out = array("mediaExp", $feature); $out = array("mediaExp", $feature);
if ($value) $out[] = $value; if ($value) $out[] = $value;
return true; return true;
@ -2738,8 +2793,8 @@ class lessc_parser {
$s = $this->seek(); $s = $this->seek();
if ($this->literal("@{") && if ($this->literal("@{") &&
$this->openString("}", $interp, null, array("'", '"', ";")) && $this->openString("}", $interp, null, array("'", '"', ";")) &&
$this->literal("}", false)) $this->literal("}", false)
{ ) {
$out = array("interpolate", $interp); $out = array("interpolate", $interp);
$this->eatWhiteDefault = $oldWhite; $this->eatWhiteDefault = $oldWhite;
if ($this->eatWhiteDefault) $this->whitespace(); if ($this->eatWhiteDefault) $this->whitespace();
@ -2808,7 +2863,9 @@ class lessc_parser {
// or at the end a ... or a variable named followed by ... // or at the end a ... or a variable named followed by ...
protected function argumentDef(&$args, &$isVararg, $delim = ',') { protected function argumentDef(&$args, &$isVararg, $delim = ',') {
$s = $this->seek(); $s = $this->seek();
if (!$this->literal('(')) return false; if (!$this->literal('(')) {
return false;
}
$values = array(); $values = array();
@ -2832,7 +2889,9 @@ class lessc_parser {
} }
} }
$values[] = $arg; $values[] = $arg;
if ($isVararg) break; if ($isVararg) {
break;
}
continue; continue;
} }
@ -2876,7 +2935,9 @@ class lessc_parser {
$this->literal(">"); $this->literal(">");
} }
if (count($tags) == 0) return false; if (!$tags) {
return false;
}
return true; return true;
} }
@ -2916,10 +2977,11 @@ class lessc_parser {
// a space separated list of selectors // a space separated list of selectors
protected function tag(&$tag, $simple = false) { protected function tag(&$tag, $simple = false) {
if ($simple) if ($simple) {
$chars = '^@,:;{}\][>\(\) "\''; $chars = '^@,:;{}\][>\(\) "\'';
else } else {
$chars = '^@,;{}["\''; $chars = '^@,;{}["\'';
}
$s = $this->seek(); $s = $this->seek();
@ -2929,7 +2991,9 @@ class lessc_parser {
$hasExpression = false; $hasExpression = false;
$parts = array(); $parts = array();
while ($this->tagBracket($first)) $parts[] = $first; while ($this->tagBracket($first)) {
$parts[] = $first;
}
$oldWhite = $this->eatWhiteDefault; $oldWhite = $this->eatWhiteDefault;
$this->eatWhiteDefault = false; $this->eatWhiteDefault = false;
@ -3031,8 +3095,8 @@ class lessc_parser {
protected function variable(&$name) { protected function variable(&$name) {
$s = $this->seek(); $s = $this->seek();
if ($this->literal($this->lessc->vPrefix, false) && if ($this->literal($this->lessc->vPrefix, false) &&
($this->variable($sub) || $this->keyword($name))) ($this->variable($sub) || $this->keyword($name))
{ ) {
if (!empty($sub)) { if (!empty($sub)) {
$name = array('variable', $sub); $name = array('variable', $sub);
} else { } else {
@ -3215,9 +3279,9 @@ class lessc_parser {
if ($this->writeComments) { if ($this->writeComments) {
$gotWhite = false; $gotWhite = false;
while (preg_match(self::$whitePattern, $this->buffer, $m, null, $this->count)) { while (preg_match(self::$whitePattern, $this->buffer, $m, null, $this->count)) {
if (isset($m[1]) && empty($this->commentsSeen[$this->count])) { if (isset($m[1]) && empty($this->seenComments[$this->count])) {
$this->append(array("comment", $m[1])); $this->append(array("comment", $m[1]));
$this->commentsSeen[$this->count] = true; $this->seenComments[$this->count] = true;
} }
$this->count += strlen($m[0]); $this->count += strlen($m[0]);
$gotWhite = true; $gotWhite = true;
@ -3475,5 +3539,3 @@ class lessc_formatter_lessjs extends lessc_formatter_classic {
public $assignSeparator = ": "; public $assignSeparator = ": ";
public $selectorSeparator = ","; public $selectorSeparator = ",";
} }

829
yarn.lock

File diff suppressed because it is too large Load diff