diff --git a/src/octoprint/server/util/flask.py b/src/octoprint/server/util/flask.py index b443dfc5..175409e7 100644 --- a/src/octoprint/server/util/flask.py +++ b/src/octoprint/server/util/flask.py @@ -891,6 +891,13 @@ def collect_plugin_assets(enable_gcodeviewer=True, preferred_stylesheet="css"): less=[] ) assets["js"] = [ + 'js/app/bindings/allowbindings.js', + 'js/app/bindings/contextmenu.js', + 'js/app/bindings/invisible.js', + 'js/app/bindings/popover.js', + 'js/app/bindings/qrcode.js', + 'js/app/bindings/slimscrolledforeach.js', + 'js/app/bindings/togglecontent.js', 'js/app/viewmodels/appearance.js', 'js/app/viewmodels/connection.js', 'js/app/viewmodels/control.js', diff --git a/src/octoprint/static/intermediary.html b/src/octoprint/static/intermediary.html index 7e28c6ad..df09ed3b 100644 --- a/src/octoprint/static/intermediary.html +++ b/src/octoprint/static/intermediary.html @@ -46,6 +46,7 @@ .wrapper .outer .inner { display: table-cell; vertical-align: middle; + padding: 20px; } .wrapper .outer .inner .content { @@ -60,6 +61,10 @@ color: #990000; } + #message { + line-height: 1.3; + } + .pulsate3 { -webkit-animation: pulsate 3s ease-out; -webkit-animation-iteration-count: infinite; diff --git a/src/octoprint/static/js/app/bindings/allowbindings.js b/src/octoprint/static/js/app/bindings/allowbindings.js new file mode 100644 index 00000000..b1360215 --- /dev/null +++ b/src/octoprint/static/js/app/bindings/allowbindings.js @@ -0,0 +1,6 @@ +ko.bindingHandlers.allowBindings = { + init: function (elem, valueAccessor) { + return { controlsDescendantBindings: !valueAccessor() }; + } +}; +ko.virtualElements.allowedBindings.allowBindings = true; diff --git a/src/octoprint/static/js/app/bindings/contextmenu.js b/src/octoprint/static/js/app/bindings/contextmenu.js new file mode 100644 index 00000000..627a134a --- /dev/null +++ b/src/octoprint/static/js/app/bindings/contextmenu.js @@ -0,0 +1,12 @@ +ko.bindingHandlers.contextMenu = { + init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { + var val = ko.utils.unwrapObservable(valueAccessor()); + + $(element).contextMenu(val); + }, + update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { + var val = ko.utils.unwrapObservable(valueAccessor()); + + $(element).contextMenu(val); + } +}; diff --git a/src/octoprint/static/js/app/bindings/invisible.js b/src/octoprint/static/js/app/bindings/invisible.js new file mode 100644 index 00000000..ced9c235 --- /dev/null +++ b/src/octoprint/static/js/app/bindings/invisible.js @@ -0,0 +1,8 @@ +ko.bindingHandlers.invisible = { + init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { + if (!valueAccessor()) return; + ko.bindingHandlers.style.update(element, function() { + return { visibility: 'hidden' }; + }) + } +}; diff --git a/src/octoprint/static/js/app/bindings/popover.js b/src/octoprint/static/js/app/bindings/popover.js new file mode 100644 index 00000000..0571b128 --- /dev/null +++ b/src/octoprint/static/js/app/bindings/popover.js @@ -0,0 +1,16 @@ +ko.bindingHandlers.popover = { + init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { + var val = ko.utils.unwrapObservable(valueAccessor()); + + var options = { + title: val.title, + animation: val.animation, + placement: val.placement, + trigger: val.trigger, + delay: val.delay, + content: val.content, + html: val.html + }; + $(element).popover(options); + } +}; diff --git a/src/octoprint/static/js/app/bindings/qrcode.js b/src/octoprint/static/js/app/bindings/qrcode.js new file mode 100644 index 00000000..e0609d2d --- /dev/null +++ b/src/octoprint/static/js/app/bindings/qrcode.js @@ -0,0 +1,24 @@ +ko.bindingHandlers.qrcode = { + update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { + var val = ko.utils.unwrapObservable(valueAccessor()); + + var defaultOptions = { + text: "", + size: 200, + fill: "#000", + background: null, + label: "", + fontname: "sans", + fontcolor: "#000", + radius: 0, + ecLevel: "L" + }; + + var options = {}; + _.each(defaultOptions, function(value, key) { + options[key] = ko.utils.unwrapObservable(val[key]) || value; + }); + + $(element).empty().qrcode(options); + } +}; diff --git a/src/octoprint/static/js/app/bindings/slimscrolledforeach.js b/src/octoprint/static/js/app/bindings/slimscrolledforeach.js new file mode 100644 index 00000000..40755020 --- /dev/null +++ b/src/octoprint/static/js/app/bindings/slimscrolledforeach.js @@ -0,0 +1,17 @@ +ko.bindingHandlers.slimScrolledForeach = { + init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { + return ko.bindingHandlers.foreach.init(element, valueAccessor(), allBindings, viewModel, bindingContext); + }, + update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { + setTimeout(function() { + if (element.nodeName == "#comment") { + // foreach is bound to a virtual element + $(element.parentElement).slimScroll({scrollBy: 0}); + } else { + $(element).slimScroll({scrollBy: 0}); + } + }, 10); + return ko.bindingHandlers.foreach.update(element, valueAccessor(), allBindings, viewModel, bindingContext); + } +}; +ko.virtualElements.allowedBindings.slimScrolledForeach = true; diff --git a/src/octoprint/static/js/app/bindings/togglecontent.js b/src/octoprint/static/js/app/bindings/togglecontent.js new file mode 100644 index 00000000..6b0af579 --- /dev/null +++ b/src/octoprint/static/js/app/bindings/togglecontent.js @@ -0,0 +1,28 @@ +ko.bindingHandlers.toggleContent = { + init: function(element, valueAccessor) { + var $elm = $(element), + options = $.extend({ + class: null, + container: null, + parent: null, + onComplete: function() { + $(document).trigger("slideCompleted"); + } + }, valueAccessor()); + + $elm.on("click", function(e) { + e.preventDefault(); + if(options.class) { + $elm.children('[class^="icon-"]').toggleClass(options.class); + } + if(options.container) { + if(options.parent) { + $elm.parents(options.parent).find(options.container).stop().slideToggle('fast', options.onComplete); + } else { + $(options.container).stop().slideToggle('fast', options.onComplete); + } + } + + }); + } +}; diff --git a/src/octoprint/static/js/app/main.js b/src/octoprint/static/js/app/main.js index e7e2ae43..402933a6 100644 --- a/src/octoprint/static/js/app/main.js +++ b/src/octoprint/static/js/app/main.js @@ -304,97 +304,6 @@ $(function() { var dataUpdater = new DataUpdater(allViewModels); - //~~ Custom knockout.js bindings - - ko.bindingHandlers.popover = { - init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { - var val = ko.utils.unwrapObservable(valueAccessor()); - - var options = { - title: val.title, - animation: val.animation, - placement: val.placement, - trigger: val.trigger, - delay: val.delay, - content: val.content, - html: val.html - }; - $(element).popover(options); - } - }; - - ko.bindingHandlers.allowBindings = { - init: function (elem, valueAccessor) { - return { controlsDescendantBindings: !valueAccessor() }; - } - }; - ko.virtualElements.allowedBindings.allowBindings = true; - - ko.bindingHandlers.slimScrolledForeach = { - init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { - return ko.bindingHandlers.foreach.init(element, valueAccessor(), allBindings, viewModel, bindingContext); - }, - update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { - setTimeout(function() { - if (element.nodeName == "#comment") { - // foreach is bound to a virtual element - $(element.parentElement).slimScroll({scrollBy: 0}); - } else { - $(element).slimScroll({scrollBy: 0}); - } - }, 10); - return ko.bindingHandlers.foreach.update(element, valueAccessor(), allBindings, viewModel, bindingContext); - } - }; - ko.virtualElements.allowedBindings.slimScrolledForeach = true; - - ko.bindingHandlers.qrcode = { - update: function(element, valueAccessor, allBindings, viewModel, bindingContext) { - var val = ko.utils.unwrapObservable(valueAccessor()); - - var defaultOptions = { - text: "", - size: 200, - fill: "#000", - background: null, - label: "", - fontname: "sans", - fontcolor: "#000", - radius: 0, - ecLevel: "L" - }; - - var options = {}; - _.each(defaultOptions, function(value, key) { - options[key] = ko.utils.unwrapObservable(val[key]) || value; - }); - - $(element).empty().qrcode(options); - } - }; - - ko.bindingHandlers.invisible = { - init: function(element, valueAccessor, allBindings, viewModel, bindingContext) { - if (!valueAccessor()) return; - ko.bindingHandlers.style.update(element, function() { - return { visibility: 'hidden' }; - }) - } - }; - - ko.bindingHandlers.contextMenu = { - init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { - var val = ko.utils.unwrapObservable(valueAccessor()); - - $(element).contextMenu(val); - }, - update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { - var val = ko.utils.unwrapObservable(valueAccessor()); - - $(element).contextMenu(val); - } - }; - //~~ some additional hooks and initializations // make sure modals max out at the window height @@ -615,4 +524,3 @@ $(function() { .done(bindViewModels); } ); - diff --git a/src/octoprint/templates/dialogs/settings/appearance.jinja2 b/src/octoprint/templates/dialogs/settings/appearance.jinja2 index db3addff..48f7d60b 100644 --- a/src/octoprint/templates/dialogs/settings/appearance.jinja2 +++ b/src/octoprint/templates/dialogs/settings/appearance.jinja2 @@ -49,7 +49,7 @@
- +
diff --git a/src/octoprint/templates/dialogs/settings/serialconnection.jinja2 b/src/octoprint/templates/dialogs/settings/serialconnection.jinja2 index ad9a8433..dbeb1703 100644 --- a/src/octoprint/templates/dialogs/settings/serialconnection.jinja2 +++ b/src/octoprint/templates/dialogs/settings/serialconnection.jinja2 @@ -94,7 +94,7 @@
- +
diff --git a/src/octoprint/templates/dialogs/settings/webcam.jinja2 b/src/octoprint/templates/dialogs/settings/webcam.jinja2 index 74ddf291..9ee6e71d 100644 --- a/src/octoprint/templates/dialogs/settings/webcam.jinja2 +++ b/src/octoprint/templates/dialogs/settings/webcam.jinja2 @@ -12,7 +12,7 @@ {% include "_snippets/settings/webcam/ffmpegPath.jinja2" %} {% include "_snippets/settings/webcam/watermark.jinja2" %}
- +
{% include "_snippets/settings/webcam/ffmpegBitrate.jinja2" %} {% include "_snippets/settings/webcam/ffmpegThreads.jinja2" %} diff --git a/src/octoprint/templates/tabs/control.jinja2 b/src/octoprint/templates/tabs/control.jinja2 index f64db4f7..32fdd292 100644 --- a/src/octoprint/templates/tabs/control.jinja2 +++ b/src/octoprint/templates/tabs/control.jinja2 @@ -116,7 +116,7 @@ diff --git a/src/octoprint/templates/tabs/terminal.jinja2 b/src/octoprint/templates/tabs/terminal.jinja2 index 7ce48a13..89e74209 100644 --- a/src/octoprint/templates/tabs/terminal.jinja2 +++ b/src/octoprint/templates/tabs/terminal.jinja2 @@ -22,7 +22,7 @@
- +
{{ _("If acknowledgements (\"ok\"s) sent by the firmware get lost due to issues with the serial communication to your printer, OctoPrint's communication with it can become stuck. If that happens, this can help. Please be advised that such occurences hint at general communication issues with your printer which will probably negatively influence your printing results and which you should therefore try to resolve!") }}