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 @@