mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
v2.7.0
This commit is contained in:
parent
53ece73da0
commit
010794fccb
9 changed files with 719 additions and 550 deletions
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
28
README.md
28
README.md
|
|
@ -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).
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
2.6.2
|
2.7.0
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
20
package.json
20
package.json
|
|
@ -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",
|
||||||
|
|
|
||||||
23
release.php
23
release.php
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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,34 +1106,50 @@ 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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$out = array('hsl',
|
$out = array('hsl',
|
||||||
($H < 0 ? $H + 6 : $H)*60,
|
($H < 0 ? $H + 6 : $H)*60,
|
||||||
$S*100,
|
$S * 100,
|
||||||
$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;
|
||||||
|
|
@ -1142,7 +1171,7 @@ class lessc {
|
||||||
$r = $g = $b = $L;
|
$r = $g = $b = $L;
|
||||||
} else {
|
} else {
|
||||||
$temp2 = $L < 0.5 ?
|
$temp2 = $L < 0.5 ?
|
||||||
$L*(1.0 + $S) :
|
$L * (1.0 + $S) :
|
||||||
$L + $S - $L * $S;
|
$L + $S - $L * $S;
|
||||||
|
|
||||||
$temp1 = 2.0 * $L - $temp2;
|
$temp1 = 2.0 * $L - $temp2;
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
@ -1329,7 +1376,7 @@ class lessc {
|
||||||
|
|
||||||
// coerce a value for use in color operation
|
// coerce a value for use in color operation
|
||||||
protected function coerceColor($value) {
|
protected function coerceColor($value) {
|
||||||
switch($value[0]) {
|
switch ($value[0]) {
|
||||||
case 'color': return $value;
|
case 'color': return $value;
|
||||||
case 'raw_color':
|
case 'raw_color':
|
||||||
$c = array("color", 0, 0, 0);
|
$c = array("color", 0, 0, 0);
|
||||||
|
|
@ -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 = ",";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue