Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow the exclusion of certain JS libraries from being bundled when integrating Cypht with third-party software #1301

Merged
merged 3 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,6 @@ FANCY_LOGIN=false
#Windows CA certificates
#Get ON https://curl.se/ca/cacert.pem
#Depending on your PHP Directory, e.g. "c:\php\extras\ssl\cacert.pem"
WIN_CACERT_DIR=
WIN_CACERT_DIR=

JS_EXCLUDE_DEPS=
2 changes: 2 additions & 0 deletions config/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -1317,4 +1317,6 @@
| Use this setting switch between the legacy login page and the fancy one
*/
'fancy_login' => env('FANCY_LOGIN', false),

'js_exclude_deps' => env('JS_EXCLUDE_DEPS', ''),
];
1 change: 1 addition & 0 deletions lib/framework.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
require APP_PATH.'lib/servers.php';
require APP_PATH.'lib/api.php';
require APP_PATH.'lib/webdav_formats.php';
require APP_PATH.'lib/js_libs.php';

require_once APP_PATH.'modules/core/functions.php';

Expand Down
32 changes: 32 additions & 0 deletions lib/js_libs.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

define('JS_LIBS', [
'bootstrap' => 'vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js',
'cash' => 'third_party/cash.min.js',
'resumable' => 'third_party/resumable.min.js',
'ays-beforeunload-shim' => 'third_party/ays-beforeunload-shim.js',
'jquery-are-you-sure' => 'third_party/jquery.are-you-sure.js',
'sortable' => 'third_party/sortable.min.js'
]);

function get_js_libs($exclude_deps = []) {
$js_lib = '';

foreach (JS_LIBS as $dep) {
if (!in_array($dep, $exclude_deps)) {
$js_lib .= '<script type="text/javascript" src="'.WEB_ROOT.$dep.'"></script>';
}
}
return $js_lib;
}

function get_js_libs_content($exclude_deps = []) {
$js_lib = '';

foreach (JS_LIBS as $dep) {
if (!in_array($dep, $exclude_deps)) {
$js_lib .= file_get_contents(APP_PATH.$dep);
}
}
return $js_lib;
}
3 changes: 2 additions & 1 deletion lib/modules_exec.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ public function merge_response($request, $session, $page) {
'router_login_state' => $session->is_active(),
'router_url_path' => $request->path,
'router_module_list' => $this->site_config->get_modules(),
'router_app_name' => $this->site_config->get('app_name', 'HM3')
'router_app_name' => $this->site_config->get('app_name', 'HM3'),
'router_js_exclude_deps' => $this->site_config->get('js_exclude_deps'),
));
}
}
Expand Down
62 changes: 62 additions & 0 deletions modules/core/js_modules/[cash]/extend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* extend cash.js with some useful bits */
$.inArray = function(item, list) {
for (var i in list) {
if (list[i] === item) {
return i;
}
}
return -1;
};
$.isEmptyObject = function(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
return false;
}
}
return true;
};
$.fn.submit = function() { this[0].submit(); }
$.fn.focus = function() { this[0].focus(); };
$.fn.serializeArray = function() {
var parts;
var res = [];
var args = this.serialize().split('&');
for (var i in args) {
parts = args[i].split('=');
if (parts[0] && parts[1]) {
res.push({'name': parts[0], 'value': parts[1]});
}
}
return res.map(function(x) {return {name: x.name, value: decodeURIComponent(x.value.replace(/\+/g, " "))}});
};
$.fn.sort = function(sort_function) {
var list = [];
for (var i=0, len=this.length; i < len; i++) {
list.push(this[i]);
}
return $(list.sort(sort_function));
};
$.fn.fadeOut = function(timeout = 600) {
return this.css("opacity", 0)
.css("transition", `opacity ${timeout}ms`)
};
$.fn.fadeOutAndRemove = function(timeout = 600) {
this.fadeOut(timeout)
var tm = setTimeout(() => {
this.remove();
clearTimeout(tm)
}, timeout);
return this;
};

$.fn.modal = function(action) {
const modalElement = this[0];
if (modalElement) {
const modal = new bootstrap.Modal(modalElement);
if (action === 'show') {
modal.show();
} else if (action === 'hide') {
modal.hide();
}
}
};
14 changes: 8 additions & 6 deletions modules/core/output_modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -541,12 +541,8 @@ class Hm_Output_page_js extends Hm_Output_Module {
protected function output() {
if (DEBUG_MODE) {
$res = '';
$js_lib = '<script type="text/javascript" src="'.WEB_ROOT.'vendor/twbs/bootstrap/dist/js/bootstrap.bundle.min.js"></script>';
$js_lib .= '<script type="text/javascript" src="'.WEB_ROOT.'third_party/cash.min.js"></script>';
$js_lib .= '<script type="text/javascript" src="'.WEB_ROOT.'third_party/resumable.min.js"></script>';
$js_lib .= '<script type="text/javascript" src="'.WEB_ROOT.'third_party/ays-beforeunload-shim.js"></script>';
$js_lib .= '<script type="text/javascript" src="'.WEB_ROOT.'third_party/jquery.are-you-sure.js"></script>';
$js_lib .= '<script type="text/javascript" src="'.WEB_ROOT.'third_party/sortable.min.js"></script>';
$js_exclude_dependencies = explode(',', $this->get('router_js_exclude_deps', ''));
$js_lib = get_js_libs($js_exclude_dependencies);
if ($this->get('encrypt_ajax_requests', '') || $this->get('encrypt_local_storage', '')) {
$js_lib .= '<script type="text/javascript" src="'.WEB_ROOT.'third_party/forge.min.js"></script>';
}
Expand All @@ -558,6 +554,12 @@ protected function output() {
if (in_array($mod, $mods, true)) {
$directoriesPattern = str_replace('/', DIRECTORY_SEPARATOR, "{*,*/*}");
foreach (glob($name.'js_modules' . DIRECTORY_SEPARATOR . $directoriesPattern . "*.js", GLOB_BRACE) as $js) {
if (preg_match('/\[(.+)\]/', $js, $matches)) {
$dep = $matches[1];
if (in_array($dep, $js_exclude_dependencies)) {
continue;
}
}
$res .= '<script type="text/javascript" src="'.WEB_ROOT.str_replace(APP_PATH, '', $js).'"></script>';
}

Expand Down
70 changes: 0 additions & 70 deletions modules/core/site.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,5 @@
'use strict';

/**
* NOTE: Tiki-Cypht integration dynamically removes everything from the begining of this file
* up to swipe_event function definition as it uses jquery (over cash.js) and has bootstrap
* framework already included. If you add code here that you wish to be included in Tiki-Cypht
* integration, add it below swipe_event function definition.
*/

/* extend cash.js with some useful bits */
$.inArray = function(item, list) {
for (var i in list) {
if (list[i] === item) {
return i;
}
}
return -1;
};
$.isEmptyObject = function(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
return false;
}
}
return true;
};
$.fn.submit = function() { this[0].submit(); }
$.fn.focus = function() { this[0].focus(); };
$.fn.serializeArray = function() {
var parts;
var res = [];
var args = this.serialize().split('&');
for (var i in args) {
parts = args[i].split('=');
if (parts[0] && parts[1]) {
res.push({'name': parts[0], 'value': parts[1]});
}
}
return res.map(function(x) {return {name: x.name, value: decodeURIComponent(x.value.replace(/\+/g, " "))}});
};
$.fn.sort = function(sort_function) {
var list = [];
for (var i=0, len=this.length; i < len; i++) {
list.push(this[i]);
}
return $(list.sort(sort_function));
};
$.fn.fadeOut = function(timeout = 600) {
return this.css("opacity", 0)
.css("transition", `opacity ${timeout}ms`)
};
$.fn.fadeOutAndRemove = function(timeout = 600) {
this.fadeOut(timeout)
var tm = setTimeout(() => {
this.remove();
clearTimeout(tm)
}, timeout);
return this;
};

$.fn.modal = function(action) {
const modalElement = this[0];
if (modalElement) {
const modal = new bootstrap.Modal(modalElement);
if (action === 'show') {
modal.show();
} else if (action === 'hide') {
modal.hide();
}
}
};

/* swipe event handler */
var swipe_event = function(el, callback, direction) {
var start_x, start_y, dist_x, dist_y, threshold = 150, restraint = 100,
Expand Down
13 changes: 8 additions & 5 deletions scripts/config_gen.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ function get_module_assignments($settings) {
$js = '';
$css = '';
$assets = array();
$js_exclude_dependencies = explode(',', ($settings['js_exclude_deps'] ?? ''));
$filters = array('allowed_output' => array(), 'allowed_get' => array(), 'allowed_cookie' => array(),
'allowed_post' => array(), 'allowed_server' => array(), 'allowed_pages' => array());

Expand All @@ -190,6 +191,12 @@ function get_module_assignments($settings) {
}
$directoriesPattern = str_replace('/', DIRECTORY_SEPARATOR, "{*,*/*}");
foreach (glob('modules' . DIRECTORY_SEPARATOR . $mod . DIRECTORY_SEPARATOR . 'js_modules' . DIRECTORY_SEPARATOR . $directoriesPattern . '*.js', GLOB_BRACE) as $js_module) {
if (preg_match('/\[(.+)\]/', $js_module, $matches)) {
$dep = $matches[1];
if (in_array($dep, $js_exclude_dependencies)) {
continue;
}
}
$js .= file_get_contents($js_module);
}
if (is_readable(sprintf("modules/%s/site.js", $mod))) {
Expand Down Expand Up @@ -255,7 +262,7 @@ function combine_includes($js, $js_compress, $css, $css_compress, $settings) {
}
if ($js) {
$mods = get_modules($settings);
$js_lib = file_get_contents(VENDOR_PATH . "twbs/bootstrap/dist/js/bootstrap.bundle.min.js");
$js_lib = get_js_libs_content(explode(',', $settings['js_exclude_deps']));
$js_lib .= file_get_contents("third_party/cash.min.js");
if (in_array('desktop_notifications', $mods, true)) {
$js_lib .= file_get_contents("third_party/push.min.js");
Expand All @@ -266,10 +273,6 @@ function combine_includes($js, $js_compress, $css, $css_compress, $settings) {
$settings['encrypt_local_storage'])) {
$js_lib .= file_get_contents("third_party/forge.min.js");
}
$js_lib .= file_get_contents("third_party/resumable.min.js");
$js_lib .= file_get_contents("third_party/ays-beforeunload-shim.js");
$js_lib .= file_get_contents("third_party/jquery.are-you-sure.js");
$js_lib .= file_get_contents("third_party/sortable.min.js");
file_put_contents('tmp.js', $js);
$js_out = $js_lib.compress($js, $js_compress, 'tmp.js');
$js_hash = build_integrity_hash($js_out);
Expand Down
2 changes: 2 additions & 0 deletions tests/phpunit/modules/core/output_modules_debug.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public function test_page_js_debug($given_router_module_list) {
$this->assertEquals(array($expected_output), $res->output_response);
}

// TODO: Add a test case excluding some js dependencies

static function router_module_list_provider() {
return [
'one module' => [['core']],
Expand Down