From 1b24931d6bfa667136a469b9ee513168ae2894cb Mon Sep 17 00:00:00 2001
From: Kathrin Osswald <kathrin.osswald@uni-ulm.de>
Date: Wed, 5 Jul 2017 09:36:03 +0200
Subject: [PATCH] Settings to be able to catch specific shortcuts to redefine
 the scrolling to bottom event.

---
 CHANGES.md                      |  1 +
 README.md                       | 15 +++++++
 amd/build/catchshortcuts.min.js |  1 +
 amd/src/catchshortcuts.js       | 75 +++++++++++++++++++++++++++++++++
 lang/en/theme_boost_campus.php  | 12 ++++++
 layout/columns2.php             | 16 ++++++-
 settings.php                    | 34 +++++++++++++++
 templates/columns2.mustache     |  3 ++
 version.php                     |  2 +-
 9 files changed, 157 insertions(+), 2 deletions(-)
 create mode 100644 amd/build/catchshortcuts.min.js
 create mode 100644 amd/src/catchshortcuts.js

diff --git a/CHANGES.md b/CHANGES.md
index 46fb8de..b6f94af 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -6,6 +6,7 @@ Changes
 
 ### Unreleased
 
+* 2017-07-04 - Settings to be able to catch specific shortcuts to redefine the scrolling to bottom event.
 * 2017-07-04 - Added modification hints to overridden layout files.
 * 2017-07-04 - Fix CSS selector for the footer separator lines.
 * 2017-07-03 - Minor improvements to the availability info for activities and resources.
diff --git a/README.md b/README.md
index eed4aed..46d4d21 100644
--- a/README.md
+++ b/README.md
@@ -91,6 +91,21 @@ This setting is already available in the Moodle core theme Boost. For more infor
 
 This setting is already available in the Moodle core theme Boost. For more information how to use it, please have a look at the official Moodle documentation: http://docs.moodle.org/en/Boost_theme
 
+#### Catch keyboard commands
+The following settings are intended to serve the needs for advanced users, especially if your Moodle instance has a large footer. Advanced users are likely to use keyboard shortcuts to navigate through the sites. They may use this for reaching the end of the page in the intention to get fast to the most recent topic in the course (for adding content or grading latest activities). If the footer is not quite small, they would need to scroll up again. With these settings you can enable that the following shortcuts are caught and would only scroll to the bottom of the main course content.
+
+##### End key
+
+This setting will catch the "End" key (should work on all main browsers and operating systems), prevent the default scrolling to the bottom of the web page and changes the behavior to scroll only to the bottom of the main course content.
+
+##### Cmd + Arrow down shortcut
+
+This setting will catch the "Cmd + Arrow down" shortcut (MAC), prevent the default scrolling to the bottom of the web page and changes the behavior to scroll only to the bottom of the main course content.
+
+##### Ctrl + Arrow down shortcut
+
+This setting will catch the "Ctrl + Arrow down" shortcut (Windows), prevent the default scrolling to the bottom of the web page and changes the behavior to scroll only to the bottom of the main course content.
+
 
 ### 3. Tab "Course Layout Settings"
 
diff --git a/amd/build/catchshortcuts.min.js b/amd/build/catchshortcuts.min.js
new file mode 100644
index 0000000..abc970c
--- /dev/null
+++ b/amd/build/catchshortcuts.min.js
@@ -0,0 +1 @@
+define(["jquery"],function(a){"use strict";function b(b){"end"==b&&a(document).keydown(function(a){35==a.keyCode&&c(a)}),navigator.appVersion.indexOf("Mac")!=-1&&"cmdarrowdown"==b&&a(document).keydown(function(a){40==a.keyCode&&a.metaKey&&c(a)}),navigator.appVersion.indexOf("Win")!=-1&&"ctrlarrowdown"==b&&a(document).keydown(function(a){40==a.keyCode&&a.ctrlKey&&c(a)})}function c(b){b.preventDefault(),a("html, body").animate({scrollTop:a("#page-footer").offset().top-a(window).height()+50},500)}return{init:function(a){for(var c=0,d=a.length;c<d;c++)b(a[c])}}});
\ No newline at end of file
diff --git a/amd/src/catchshortcuts.js b/amd/src/catchshortcuts.js
new file mode 100644
index 0000000..265b7a7
--- /dev/null
+++ b/amd/src/catchshortcuts.js
@@ -0,0 +1,75 @@
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Theme Boost Campus - JS code for catching pressed keys.
+ *
+ * @package    theme_boost_campus
+ * @copyright  2017 Kathrin Osswald, Ulm University <kathrin.osswald@uni-ulm.de>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+define(['jquery'], function($) {
+    "use strict";
+
+    function initcatchshortcuts(value) {
+        if (value == 'end') {
+            // Catch the end key to be able to change the behavior.
+            $(document).keydown(function(e) {
+                if(e.keyCode == 35) {
+                    // Scroll only to the bottom of the course content.
+                    scrollToBottomOfCourse(e);
+                }
+            });
+        }
+        // This shortcut is only relevant for users operating on MacOS.
+        if (navigator.appVersion.indexOf("Mac") != -1 && value == 'cmdarrowdown') {
+            // Bind the cmd + arrow down shortcut to be able to change the behavior.
+            $(document).keydown(function(e) {
+                if(e.keyCode == 40 && e.metaKey) {
+                    // Scroll only to the bottom of the course content.
+                    scrollToBottomOfCourse(e);
+                }
+            });
+        }
+        // This shortcut is only relevant for users operating on Windows.
+        if (navigator.appVersion.indexOf("Win") != -1 && value == 'ctrlarrowdown') {
+            // Bind the ctrl + arrow down shortcut to be able to change the behavior.
+            $(document).keydown(function(e) {
+                if(e.keyCode == 40 && e.ctrlKey) {
+                    // Scroll only to the bottom of the course content.
+                    scrollToBottomOfCourse(e);
+                }
+            });
+        }
+    }
+
+    function scrollToBottomOfCourse(event) {
+        // Prevent default behavior.
+        event.preventDefault();
+        // Scroll only to the bottom of the course content.
+        $('html, body').animate({
+            scrollTop: $('#page-footer').offset().top - $(window).height() + 50
+        }, 500);
+    }
+
+    return {
+        init: function(params) {
+            for (var i = 0, len = params.length; i < len; i++) {
+                initcatchshortcuts(params[i]);
+            }
+        }
+    };
+});
diff --git a/lang/en/theme_boost_campus.php b/lang/en/theme_boost_campus.php
index 43a7da5..bfa471b 100644
--- a/lang/en/theme_boost_campus.php
+++ b/lang/en/theme_boost_campus.php
@@ -48,6 +48,18 @@ $string['faviconheadingsetting'] = 'Favicon';
 $string['faviconsetting'] = 'Favicon';
 $string['faviconsetting_desc'] = 'You can upload one image (.ico or .png format) that the browser will show as the favicon of your Moodle website.';
 
+// Advanced settings.
+// ... Catch keyboard commands.
+$string['catchkeyboardcommandsheadingsetting'] = 'Catch keyboard commands';
+$string['catchkeyboardcommandsheadingsetting_desc'] = 'The following settings are intended to serve the needs for advanced users, especially if your Moodle instance has a large footer. Advanced users are likely to use keyboard shortcuts to navigate through the sites. They may use this for reaching the end of the page in the intention to get fast to the most recent topic in the course (for adding content or grading latest activities). If the footer is not quite small, they would need to scroll up again. With these settings you can enable that the following shortcuts are caught and would only scroll to the bottom of the main course content.';
+$string['catchendkeysetting'] = 'End key';
+$string['catchendkeysetting_desc'] = 'This setting will catch the "End" key (should work on all main browsers and operating systems), ';
+$string['catchcmdarrowdownsetting'] = 'Cmd + Arrow down shortcut';
+$string['catchcmdarrowdownsetting_desc'] = 'This setting will catch the "Cmd + Arrow down" shortcut (MAC),';
+$string['catchctrlarrowdownsetting'] = 'Ctrl + Arrow down shortcut';
+$string['catchctrlarrowdownsetting_desc'] = 'This setting will catch the "Ctrl + Arrow down" shortcut (Windows),';
+$string['catchkeys_desc_addition'] = 'prevent the default scrolling to the bottom of the web page and changes the behavior to scroll only to the bottom of the main course content.';
+
 // Course layout settings.
 $string['courselayoutsettings'] = 'Course Layout Settings';
 // ...Section 0.
diff --git a/layout/columns2.php b/layout/columns2.php
index c152685..44ddcac 100644
--- a/layout/columns2.php
+++ b/layout/columns2.php
@@ -41,6 +41,19 @@ $bodyattributes = $OUTPUT->body_attributes($extraclasses);
 $blockshtml = $OUTPUT->blocks('side-pre');
 $hasblocks = strpos($blockshtml, 'data-block=') !== false;
 $regionmainsettingsmenu = $OUTPUT->region_main_settings_menu();
+$catchshortcuts = array();
+$catchendkey = get_config('theme_boost_campus', 'catchendkey');
+if (isset($catchendkey) && $catchendkey == true) {
+    $catchshortcuts[] = 'end';
+}
+$catchcmdarrowdown = get_config('theme_boost_campus', 'catchcmdarrowdown');
+if (isset($catchcmdarrowdown) && $catchcmdarrowdown == true) {
+    $catchshortcuts[] = 'cmdarrowdown';
+}
+$catchctrlarrowdown = get_config('theme_boost_campus', 'catchctrlarrowdown');
+if (isset($catchctrlarrowdown) && $catchctrlarrowdown == true) {
+    $catchshortcuts[] = 'ctrlarrowdown';
+}
 $templatecontext = [
     'sitename' => format_string($SITE->shortname, true, ['context' => context_course::instance(SITEID), "escape" => false]),
     'output' => $OUTPUT,
@@ -49,7 +62,8 @@ $templatecontext = [
     'bodyattributes' => $bodyattributes,
     'navdraweropen' => $navdraweropen,
     'regionmainsettingsmenu' => $regionmainsettingsmenu,
-    'hasregionmainsettingsmenu' => !empty($regionmainsettingsmenu)
+    'hasregionmainsettingsmenu' => !empty($regionmainsettingsmenu),
+    'catchshortcuts' => json_encode($catchshortcuts)
 ];
 
 $templatecontext['flatnavigation'] = $PAGE->flatnav;
diff --git a/settings.php b/settings.php
index 983b04f..5d64ce0 100644
--- a/settings.php
+++ b/settings.php
@@ -159,6 +159,40 @@ if ($ADMIN->fulltree) {
     $setting->set_updatedcallback('theme_reset_all_caches');
     $page->add($setting);
 
+    // Settings title for the catching keybaord commands.
+    $name = 'theme_boost_campus/catchkeyboardcommandsheading';
+    $title = get_string('catchkeyboardcommandsheadingsetting', 'theme_boost_campus', null, true);
+    $description = get_string('catchkeyboardcommandsheadingsetting_desc', 'theme_boost_campus', null, true);
+    $setting = new admin_setting_heading($name, $title, $description);
+    $page->add($setting);
+
+    // Setting for catching the end key.
+    $name = 'theme_boost_campus/catchendkey';
+    $title = get_string('catchendkeysetting', 'theme_boost_campus', null, true);
+    $description = get_string('catchendkeysetting_desc', 'theme_boost_campus', null, true) . ' ' .
+        get_string('catchkeys_desc_addition', 'theme_boost_campus', null, true);
+    $setting = new admin_setting_configcheckbox($name, $title, $description, 0);
+    $setting->set_updatedcallback('theme_reset_all_caches');
+    $page->add($setting);
+
+    // Setting for catching the cmd + arrow down keys.
+    $name = 'theme_boost_campus/catchcmdarrowdown';
+    $title = get_string('catchcmdarrowdownsetting', 'theme_boost_campus', null, true);
+    $description = get_string('catchcmdarrowdownsetting_desc', 'theme_boost_campus', null, true) . ' ' .
+        get_string('catchkeys_desc_addition', 'theme_boost_campus', null, true);
+    $setting = new admin_setting_configcheckbox($name, $title, $description, 0);
+    $setting->set_updatedcallback('theme_reset_all_caches');
+    $page->add($setting);
+
+    // Setting for catching the strg + arrow down keys.
+    $name = 'theme_boost_campus/catchctrlarrowdown';
+    $title = get_string('catchctrlarrowdownsetting', 'theme_boost_campus', null, true);
+    $description = get_string('catchctrlarrowdownsetting_desc', 'theme_boost_campus', null, true) . ' ' .
+        get_string('catchkeys_desc_addition', 'theme_boost_campus', null, true);
+    $setting = new admin_setting_configcheckbox($name, $title, $description, 0);
+    $setting->set_updatedcallback('theme_reset_all_caches');
+    $page->add($setting);
+
     // Add tab to settings page.
     $settings->add($page);
 
diff --git a/templates/columns2.mustache b/templates/columns2.mustache
index b08137a..1391e36 100644
--- a/templates/columns2.mustache
+++ b/templates/columns2.mustache
@@ -109,4 +109,7 @@ require(['theme_boost/drawer'], function(mod) {
     mod.init();
 });
 require(['theme_boost_campus/backtotop']);
+require(['theme_boost_campus/catchshortcuts'], function(mod) {
+    mod.init({{{catchshortcuts}}});
+});
 {{/js}}
diff --git a/version.php b/version.php
index 62af3b9..050aed2 100644
--- a/version.php
+++ b/version.php
@@ -25,7 +25,7 @@
 defined('MOODLE_INTERNAL') || die();
 
 $plugin->component = 'theme_boost_campus';
-$plugin->version = 2017061200;
+$plugin->version = 2017063001;
 $plugin->release = 'v3.2-r1';
 $plugin->requires = 2016070700;
 $plugin->maturity = MATURITY_STABLE;
-- 
GitLab