diff --git a/cronplus.html b/cronplus.html index 6d6d569..dc3aa95 100644 --- a/cronplus.html +++ b/cronplus.html @@ -353,6 +353,31 @@ let map, mapPopup, selectedLocation, selectedLocationInput const filesAdded = [] // list of files already added + function toggleFullscreen(selector, callback) { + callback = callback || function () {} + const el = document.querySelector(selector || "#node-cronplus-tab-static-schedules"); + const $el = $(el) + if (!document.fullscreenElement) { + el.requestFullscreen().then(() => { + $el.addClass('cron-plus-fullscreen-element').removeClass('cron-plus-expanded-element') + callback() + }).catch((err) => { + if (callback) { + callback(err) + } else { + alert( `Unable to get fullscreen mode: ${err.message}`, ); + } + }); + } else { + $el.removeClass('cron-plus-fullscreen-element').removeClass('cron-plus-expanded-element') + try { + document.exitFullscreen(); + } finally { + callback() + } + } + } + function checkLoadJsCssFile (filename, filetype, callback) { if (filesAdded.indexOf(filename) === -1) { loadJsCssFile(filename, filetype, function () { @@ -644,7 +669,14 @@ } function updateEditorLayout () { + onSchedulesExpandCompress() + if (RED._cron_plus_debug) console.log('cronplus-updateEditorLayout') + const scheduleList = $('#node-cronplus-tab-static-schedules') + const scheduleListFullScreen = scheduleList.css('position') === 'fixed' || document.fullscreenElement + if (scheduleListFullScreen) { + return // don't update layout if schedules are fullscreen + } const dlg = $('#dialog-form') let height = dlg.height() - 5 const expandRow = dlg.find('.form-row-auto-height') @@ -1748,7 +1780,7 @@ const container = $('
  • ') // const container = $('
  • ', { style: 'max-width: 600px' }) - // control buttons + // row buttons const controlsContainer = $('', { style: controlsContainerStyle }).appendTo(container) const deleteButton = $('', { href: '#', class: 'editor-button editor-button-small', style: '' }).appendTo(controlsContainer) $('', { class: 'fa fa-remove' }).appendTo(deleteButton) @@ -1943,9 +1975,9 @@ offsetField.prop('title', 'Minutes Offset +/- 1439') // init tooltips - initTooltip(offsetField, 'solar', { my: 'right top', at: 'right bottom+5', of: cell2Solar, collision: 'flipfit' }) - initTooltip(locationField, 'solar', { my: 'right top', at: 'right bottom+5', of: cell2Solar, collision: 'flipfit' }) - initTooltip(expressionField, 'cron', { my: 'right top', at: 'right bottom+5', of: cell2Cron, collision: 'flipfit' }) + initTooltip(offsetField, 'solar', { my: 'middle top', at: 'middle bottom+5', of: cell2Solar, collision: 'flipfit' }) + initTooltip(locationField, 'solar', { my: 'middle top', at: 'middle bottom+5', of: cell2Solar, collision: 'flipfit' }) + initTooltip(expressionField, 'cron', { my: 'middle top', at: 'middle bottom+5', of: cell2Cron, collision: 'flipfit' }) // locationField.keyup(function () { // const f = $(this) @@ -1982,8 +2014,7 @@ }) deleteButton.click(function () { - container.css({ background: '#fee' }) - container.fadeOut(300, function () { + container.fadeOut(200, function () { $(this).remove() }) }) @@ -2018,12 +2049,45 @@ $('#node-input-add-option').click(function () { generateOption($('#node-input-option-container').children().length, {}) $('#node-input-option-container-div').scrollTop($('#node-input-option-container-div').get(0).scrollHeight) + // focus the input with class .node-input-option-name in the last li added + $('#node-input-option-container').children().last().find('.node-input-option-name').focus().select() }) $('#node-input-show-dynamic').click(function () { $('#cron-plus-dynamic-nodes-dialog').dialog('open') }) + removeEventListener("fullscreenchange", onSchedulesExpandCompress); + addEventListener("fullscreenchange", onSchedulesExpandCompress) + + $('#cronplus-expand-schedules-button').click(function (evt) { + const selector = '#node-cronplus-tab-static-schedules' + if (evt) { + // prevent the default behaviour - we will handle it + evt.preventDefault() + evt.stopImmediatePropagation() + } + + // if shift key or middle mouse button or already full screen then toggle full screen + if (evt.shiftKey || evt.button === 1 /* middle button */ || document.fullscreenElement) { + toggleFullscreen(selector, function (err) { + updateEditorLayout() + }) + } else { + //CSS expansion/contraction + const el = $(selector) + const isSmall = el.css('position') !== 'fixed' && !document.fullscreenElement; + if (isSmall) { + // is small - make it big + el.addClass('cron-plus-expanded-element').removeClass('cron-plus-fullscreen-element') + } else { + // is big - make it small + el.removeClass('cron-plus-expanded-element').removeClass('cron-plus-fullscreen-element') + } + updateEditorLayout() + } + }) + for (let i = 0; i < this.options.length; i++) { const option = this.options[i] try { @@ -2052,9 +2116,11 @@ setTimeout(function () { $('#node-cronplus-tab-static-schedules').css('max-width', '') }, 200) + }, oneditsave: function () { if (RED._cron_plus_debug) { console.log('oneditsave - cronplus') } + removeEventListener("fullscreenchange", onSchedulesExpandCompress); const node = this const options = $('#node-input-option-container').children() delete node.persistDynamic // remove deprecated property @@ -2096,6 +2162,12 @@ $('#node-input-timeZone').off() $('#node-input-crontab').off() }, + oneditcancel: function() { + if (RED._cron_plus_debug) { console.log('oneditcancel - cronplus') } + removeEventListener("fullscreenchange", onSchedulesExpandCompress); + $('#node-input-timeZone').off() + $('#node-input-crontab').off() + }, button: { visible: function () { if (this.options && this.options.length === 1) { @@ -2240,6 +2312,23 @@

    cron-plus

    'width=800,height=600' ) } + +function onSchedulesExpandCompress () { + const selector = '#node-cronplus-tab-static-schedules' + const el = $(selector) + const $buttonExpandIcon = $('#cronplus-expand-schedules-button').find('i.fa') + const isBig = el.css('position') === 'fixed' || document.fullscreenElement; + if (isBig) { + // is big - set the icon to compress & hide certain elements + $buttonExpandIcon.removeClass('fa-expand').addClass('fa-compress') + $('#node-input-show-dynamic').addClass('cron-plus-vanish-element') + } else { + // is small - set the icon to expand & show elements + $buttonExpandIcon.removeClass('fa-compress').addClass('fa-expand') + $('#node-input-show-dynamic').removeClass('cron-plus-vanish-element') + } +} + diff --git a/package.json b/package.json index b122d7a..008dd4a 100644 --- a/package.json +++ b/package.json @@ -1,70 +1,70 @@ { - "name": "node-red-contrib-cron-plus", - "version": "2.0.1", - "description": "A flexible scheduler (cron, solar events, fixed dates) node for Node-RED with full dynamic control and time zone support", - "main": "cronplus.js", - "scripts": { - "test": "mocha \"test/**/*_spec.js\"", - "publish": "npm publish" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/Steve-Mcl/node-red-contrib-cron-plus.git" - }, - "keywords": [ - "node-red", - "scheduler", - "timer", - "cron", - "cronplus", - "cron plus", - "cron-plus", - "crontab", - "timer", - "suntime", - "sunrise", - "sunset" - ], - "node-red": { - "version": ">=1.0.0", - "nodes": { - "cronplus": "cronplus.js" - } - }, - "engines": { - "node": ">=8.0.0" - }, - "author": { - "name": "Steve-Mcl" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/Steve-Mcl/node-red-contrib-cron-plus/issues" - }, - "homepage": "https://github.com/Steve-Mcl/node-red-contrib-cron-plus#readme", - "dependencies": { - "coord-parser": "^1.0.0", - "cronosjs": "^1.7.1", - "cronstrue": "^2.28.0", - "pretty-ms": "7.0.1", - "suncalc2": "^1.8.1" - }, - "devDependencies": { - "eslint": "^8.45.0", - "eslint-config-standard": "^17.1.0", - "eslint-plugin-html": "^7.1.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-standard": "^5.0.0", - "install": "^0.13.0", - "mocha": "^10.2.0", - "node-red-node-test-helper": "^0.3.2", - "npm": "^9.8.1", - "should": "^13.2.3" - }, - "maintainers": [ - { - "name": "Steve-Mcl", - "email": "44235289+Steve-Mcl@users.noreply.github.com" - } - ] -} + "name": "node-red-contrib-cron-plus", + "version": "2.1.0", + "description": "A flexible scheduler (cron, solar events, fixed dates) node for Node-RED with full dynamic control and time zone support", + "main": "cronplus.js", + "scripts": { + "test": "mocha \"test/**/*_spec.js\"", + "publish": "npm publish" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Steve-Mcl/node-red-contrib-cron-plus.git" + }, + "keywords": [ + "node-red", + "scheduler", + "timer", + "cron", + "cronplus", + "cron plus", + "cron-plus", + "crontab", + "timer", + "suntime", + "sunrise", + "sunset" + ], + "node-red": { + "version": ">=1.0.0", + "nodes": { + "cronplus": "cronplus.js" + } + }, + "engines": { + "node": ">=8.0.0" + }, + "author": { + "name": "Steve-Mcl" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/Steve-Mcl/node-red-contrib-cron-plus/issues" + }, + "homepage": "https://github.com/Steve-Mcl/node-red-contrib-cron-plus#readme", + "dependencies": { + "coord-parser": "^1.0.0", + "cronosjs": "^1.7.1", + "cronstrue": "^2.28.0", + "pretty-ms": "7.0.1", + "suncalc2": "^1.8.1" + }, + "devDependencies": { + "eslint": "^8.45.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-html": "^7.1.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-standard": "^5.0.0", + "install": "^0.13.0", + "mocha": "^10.2.0", + "node-red-node-test-helper": "^0.3.2", + "npm": "^9.8.1", + "should": "^13.2.3" + }, + "maintainers": [ + { + "name": "Steve-Mcl", + "email": "44235289+Steve-Mcl@users.noreply.github.com" + } + ] +} \ No newline at end of file