narou 1.7.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of narou might be problematic. Click here for more details.

Files changed (100) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +1 -0
  3. data/ChangeLog.md +35 -0
  4. data/Gemfile +3 -0
  5. data/LICENSE.txt +100 -0
  6. data/README.md +28 -39
  7. data/lib/color.rb +0 -2
  8. data/lib/command.rb +1 -0
  9. data/lib/command/convert.rb +33 -4
  10. data/lib/command/diff.rb +5 -4
  11. data/lib/command/download.rb +9 -1
  12. data/lib/command/flag.rb +2 -2
  13. data/lib/command/list.rb +1 -1
  14. data/lib/command/mail.rb +3 -3
  15. data/lib/command/remove.rb +2 -1
  16. data/lib/command/send.rb +7 -6
  17. data/lib/command/setting.rb +39 -95
  18. data/lib/command/tag.rb +25 -13
  19. data/lib/command/update.rb +6 -1
  20. data/lib/command/version.rb +5 -1
  21. data/lib/command/web.rb +111 -0
  22. data/lib/commandbase.rb +5 -2
  23. data/lib/commandline.rb +16 -0
  24. data/lib/converterbase.rb +20 -14
  25. data/lib/device.rb +5 -4
  26. data/lib/downloader.rb +68 -39
  27. data/lib/eventable.rb +72 -0
  28. data/lib/helper.rb +105 -37
  29. data/lib/ini.rb +2 -1
  30. data/lib/input.rb +68 -0
  31. data/lib/inventory.rb +4 -0
  32. data/lib/kindlestrip.rb +2 -2
  33. data/lib/logger.rb +41 -19
  34. data/lib/narou.rb +10 -0
  35. data/lib/narou/api.rb +1 -1
  36. data/lib/novelconverter.rb +8 -21
  37. data/lib/novelsetting.rb +79 -4
  38. data/lib/version.rb +1 -1
  39. data/lib/web/all.rb +12 -0
  40. data/lib/web/appserver.rb +612 -0
  41. data/lib/web/helper4web.rb +15 -0
  42. data/lib/web/progressbar4web.rb +32 -0
  43. data/lib/web/public/favicon.ico +0 -0
  44. data/lib/web/public/resources/bootbox.min.js +6 -0
  45. data/lib/web/public/resources/common.ui.js +143 -0
  46. data/lib/web/public/resources/dataTables.colVis.js +1113 -0
  47. data/lib/web/public/resources/help/rect_select.png +0 -0
  48. data/lib/web/public/resources/help/ssmain.png +0 -0
  49. data/lib/web/public/resources/help/tag.png +0 -0
  50. data/lib/web/public/resources/jquery.moveto.js +44 -0
  51. data/lib/web/public/resources/jquery.outerclick.js +60 -0
  52. data/lib/web/public/resources/jquery.slidenavbar.js +89 -0
  53. data/lib/web/public/resources/narou.library.js +815 -0
  54. data/lib/web/public/resources/narou.ui.js +993 -0
  55. data/lib/web/public/resources/perfect-scrollbar.min.css +5 -0
  56. data/lib/web/public/resources/perfect-scrollbar.min.js +4 -0
  57. data/lib/web/public/resources/shortcut.js +223 -0
  58. data/lib/web/public/resources/sort_asc.png +0 -0
  59. data/lib/web/public/resources/sort_desc.png +0 -0
  60. data/lib/web/public/resources/toggle-switch.css +322 -0
  61. data/lib/web/public/robots.txt +3 -0
  62. data/lib/web/public/test/jquery.outerclick.html +72 -0
  63. data/lib/web/pushserver.rb +110 -0
  64. data/lib/web/settingmessages.rb +14 -0
  65. data/lib/web/streaminginput.rb +103 -0
  66. data/lib/web/streaminglogger.rb +52 -0
  67. data/lib/web/views/about.haml +11 -0
  68. data/lib/web/views/help.haml +105 -0
  69. data/lib/web/views/index.haml +245 -0
  70. data/lib/web/views/js/widget.erb +74 -0
  71. data/lib/web/views/layout.haml +49 -0
  72. data/lib/web/views/novels/setting.haml +177 -0
  73. data/lib/web/views/settings.haml +115 -0
  74. data/lib/web/views/style.scss +737 -0
  75. data/lib/web/views/widget.haml +39 -0
  76. data/lib/web/web-socket-ruby/.gitignore +1 -0
  77. data/lib/web/web-socket-ruby/README.txt +75 -0
  78. data/lib/web/web-socket-ruby/lib/web_socket.rb +601 -0
  79. data/lib/web/web-socket-ruby/samples/chat_server.rb +58 -0
  80. data/lib/web/web-socket-ruby/samples/echo_server.rb +33 -0
  81. data/lib/web/web-socket-ruby/samples/stdio_client.rb +25 -0
  82. data/lib/web/worker.rb +87 -0
  83. data/narou.gemspec +36 -3
  84. data/narou.rb +8 -6
  85. data/preset/ncode.syosetu.com/n8725k/converter.rb +2 -1
  86. data/spec/data/convert_test/replace/correct_test_replace.txt +1 -1
  87. data/spec/data/convert_test/replace/test_replace.txt +1 -1
  88. data/spec/data/convert_test/ruby/correct_test_ruby.txt +18 -1
  89. data/spec/data/convert_test/ruby/test_ruby.txt +18 -0
  90. data/spec/downloader_spec.rb +37 -0
  91. data/spec/eventable_spec.rb +172 -0
  92. data/spec/exit_code_spec.rb +67 -0
  93. data/spec/helper_spec.rb +72 -0
  94. data/spec/input_spec.rb +76 -0
  95. data/spec/logger_spec.rb +53 -0
  96. data/spec/novelsetting_spec.rb +35 -0
  97. data/spec/worker_spec.rb +56 -0
  98. data/template/ibunko_novel.txt.erb +2 -2
  99. data/template/novel.txt.erb +2 -2
  100. metadata +213 -29
@@ -0,0 +1,5 @@
1
+ /*! perfect-scrollbar - v0.5.8
2
+ * http://noraesae.github.com/perfect-scrollbar/
3
+ * Copyright (c) 2014 Hyunje Alex Jun; Licensed MIT */
4
+
5
+ .ps-container.ps-active-x>.ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;border-radius:4px;opacity:0;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;bottom:3px;height:8px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#aaa;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;border-radius:4px;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;bottom:0;height:8px}.ps-container>.ps-scrollbar-x-rail.in-scrolling{background-color:#eee;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;border-radius:4px;opacity:0;-ms-filter:"alpha(Opacity=0)";filter:alpha(opacity=0);-webkit-transition:background-color .2s linear,opacity .2s linear;-moz-transition:background-color .2s linear,opacity .2s linear;-o-transition:background-color .2s linear,opacity .2s linear;transition:background-color .2s linear,opacity .2s linear;right:3px;width:8px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#aaa;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;border-radius:4px;-webkit-transition:background-color .2s linear;-moz-transition:background-color .2s linear;-o-transition:background-color .2s linear;transition:background-color .2s linear;right:0;width:8px}.ps-container>.ps-scrollbar-y-rail.in-scrolling{background-color:#eee;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6;-ms-filter:"alpha(Opacity=60)";filter:alpha(opacity=60)}.ps-container:hover>.ps-scrollbar-x-rail.in-scrolling,.ps-container:hover>.ps-scrollbar-y-rail.in-scrolling{background-color:#eee;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail:hover{background-color:#eee;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:#eee;opacity:.9;-ms-filter:"alpha(Opacity=90)";filter:alpha(opacity=90)}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999}
@@ -0,0 +1,4 @@
1
+ /*! perfect-scrollbar - v0.5.8
2
+ * http://noraesae.github.com/perfect-scrollbar/
3
+ * Copyright (c) 2014 Hyunje Alex Jun; Licensed MIT */
4
+ (function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof exports?e(require("jquery")):e(jQuery)})(function(e){"use strict";function t(e){return"string"==typeof e?parseInt(e,10):~~e}var o={wheelSpeed:1,wheelPropagation:!1,swipePropagation:!0,minScrollbarLength:null,maxScrollbarLength:null,useBothWheelAxes:!1,useKeyboard:!0,suppressScrollX:!1,suppressScrollY:!1,scrollXMarginOffset:0,scrollYMarginOffset:0,includePadding:!1},n=0,r=function(){var e=n++;return function(t){var o=".perfect-scrollbar-"+e;return t===void 0?o:t+o}},l="WebkitAppearance"in document.documentElement.style;e.fn.perfectScrollbar=function(n,i){return this.each(function(){function a(e,o){var n=e+o,r=D-R;j=0>n?0:n>r?r:n;var l=t(j*(Y-D)/(D-R));M.scrollTop(l)}function s(e,o){var n=e+o,r=E-k;W=0>n?0:n>r?r:n;var l=t(W*(C-E)/(E-k));M.scrollLeft(l)}function c(e){return P.minScrollbarLength&&(e=Math.max(e,P.minScrollbarLength)),P.maxScrollbarLength&&(e=Math.min(e,P.maxScrollbarLength)),e}function u(){var e={width:I};e.left=B?M.scrollLeft()+E-C:M.scrollLeft(),N?e.bottom=_-M.scrollTop():e.top=Q+M.scrollTop(),H.css(e);var t={top:M.scrollTop(),height:A};Z?t.right=B?C-M.scrollLeft()-V-J.outerWidth():V-M.scrollLeft():t.left=B?M.scrollLeft()+2*E-C-$-J.outerWidth():$+M.scrollLeft(),G.css(t),U.css({left:W,width:k-z}),J.css({top:j,height:R-et})}function d(){M.removeClass("ps-active-x"),M.removeClass("ps-active-y"),E=P.includePadding?M.innerWidth():M.width(),D=P.includePadding?M.innerHeight():M.height(),C=M.prop("scrollWidth"),Y=M.prop("scrollHeight"),!P.suppressScrollX&&C>E+P.scrollXMarginOffset?(X=!0,I=E-F,k=c(t(I*E/C)),W=t(M.scrollLeft()*(I-k)/(C-E))):(X=!1,k=0,W=0,M.scrollLeft(0)),!P.suppressScrollY&&Y>D+P.scrollYMarginOffset?(O=!0,A=D-tt,R=c(t(A*D/Y)),j=t(M.scrollTop()*(A-R)/(Y-D))):(O=!1,R=0,j=0,M.scrollTop(0)),W>=I-k&&(W=I-k),j>=A-R&&(j=A-R),u(),X&&M.addClass("ps-active-x"),O&&M.addClass("ps-active-y")}function p(){var t,o,n=function(e){s(t,e.pageX-o),d(),e.stopPropagation(),e.preventDefault()},r=function(){H.removeClass("in-scrolling"),e(q).unbind(K("mousemove"),n)};U.bind(K("mousedown"),function(l){o=l.pageX,t=U.position().left,H.addClass("in-scrolling"),e(q).bind(K("mousemove"),n),e(q).one(K("mouseup"),r),l.stopPropagation(),l.preventDefault()}),t=o=null}function f(){var t,o,n=function(e){a(t,e.pageY-o),d(),e.stopPropagation(),e.preventDefault()},r=function(){G.removeClass("in-scrolling"),e(q).unbind(K("mousemove"),n)};J.bind(K("mousedown"),function(l){o=l.pageY,t=J.position().top,G.addClass("in-scrolling"),e(q).bind(K("mousemove"),n),e(q).one(K("mouseup"),r),l.stopPropagation(),l.preventDefault()}),t=o=null}function v(e,t){var o=M.scrollTop();if(0===e){if(!O)return!1;if(0===o&&t>0||o>=Y-D&&0>t)return!P.wheelPropagation}var n=M.scrollLeft();if(0===t){if(!X)return!1;if(0===n&&0>e||n>=C-E&&e>0)return!P.wheelPropagation}return!0}function g(e,t){var o=M.scrollTop(),n=M.scrollLeft(),r=Math.abs(e),l=Math.abs(t);if(l>r){if(0>t&&o===Y-D||t>0&&0===o)return!P.swipePropagation}else if(r>l&&(0>e&&n===C-E||e>0&&0===n))return!P.swipePropagation;return!0}function b(){function e(e){var t=e.originalEvent.deltaX,o=-1*e.originalEvent.deltaY;return(t===void 0||o===void 0)&&(t=-1*e.originalEvent.wheelDeltaX/6,o=e.originalEvent.wheelDeltaY/6),e.originalEvent.deltaMode&&1===e.originalEvent.deltaMode&&(t*=10,o*=10),t!==t&&o!==o&&(t=0,o=e.originalEvent.wheelDelta),[t,o]}function t(t){if(l||!(M.find("select:focus").length>0)){var n=e(t),r=n[0],i=n[1];o=!1,P.useBothWheelAxes?O&&!X?(i?M.scrollTop(M.scrollTop()-i*P.wheelSpeed):M.scrollTop(M.scrollTop()+r*P.wheelSpeed),o=!0):X&&!O&&(r?M.scrollLeft(M.scrollLeft()+r*P.wheelSpeed):M.scrollLeft(M.scrollLeft()-i*P.wheelSpeed),o=!0):(M.scrollTop(M.scrollTop()-i*P.wheelSpeed),M.scrollLeft(M.scrollLeft()+r*P.wheelSpeed)),d(),o=o||v(r,i),o&&(t.stopPropagation(),t.preventDefault())}}var o=!1;window.onwheel!==void 0?M.bind(K("wheel"),t):window.onmousewheel!==void 0&&M.bind(K("mousewheel"),t)}function h(){var t=!1;M.bind(K("mouseenter"),function(){t=!0}),M.bind(K("mouseleave"),function(){t=!1});var o=!1;e(q).bind(K("keydown"),function(n){if((!n.isDefaultPrevented||!n.isDefaultPrevented())&&t){for(var r=document.activeElement?document.activeElement:q.activeElement;r.shadowRoot;)r=r.shadowRoot.activeElement;if(!e(r).is(":input,[contenteditable]")){var l=0,i=0;switch(n.which){case 37:l=-30;break;case 38:i=30;break;case 39:l=30;break;case 40:i=-30;break;case 33:i=90;break;case 32:case 34:i=-90;break;case 35:i=n.ctrlKey?-Y:-D;break;case 36:i=n.ctrlKey?M.scrollTop():D;break;default:return}M.scrollTop(M.scrollTop()-i),M.scrollLeft(M.scrollLeft()+l),o=v(l,i),o&&n.preventDefault()}}})}function w(){function e(e){e.stopPropagation()}J.bind(K("click"),e),G.bind(K("click"),function(e){var o=t(R/2),n=e.pageY-G.offset().top-o,r=D-R,l=n/r;0>l?l=0:l>1&&(l=1),M.scrollTop((Y-D)*l)}),U.bind(K("click"),e),H.bind(K("click"),function(e){var o=t(k/2),n=e.pageX-H.offset().left-o,r=E-k,l=n/r;0>l?l=0:l>1&&(l=1),M.scrollLeft((C-E)*l)})}function m(){function t(){var e=window.getSelection?window.getSelection():document.getSlection?document.getSlection():{rangeCount:0};return 0===e.rangeCount?null:e.getRangeAt(0).commonAncestorContainer}function o(){r||(r=setInterval(function(){return x()?(M.scrollTop(M.scrollTop()+l.top),M.scrollLeft(M.scrollLeft()+l.left),d(),void 0):(clearInterval(r),void 0)},50))}function n(){r&&(clearInterval(r),r=null),H.removeClass("in-scrolling"),G.removeClass("in-scrolling")}var r=null,l={top:0,left:0},i=!1;e(q).bind(K("selectionchange"),function(){e.contains(M[0],t())?i=!0:(i=!1,n())}),e(window).bind(K("mouseup"),function(){i&&(i=!1,n())}),e(window).bind(K("mousemove"),function(e){if(i){var t={x:e.pageX,y:e.pageY},r=M.offset(),a={left:r.left,right:r.left+M.outerWidth(),top:r.top,bottom:r.top+M.outerHeight()};t.x<a.left+3?(l.left=-5,H.addClass("in-scrolling")):t.x>a.right-3?(l.left=5,H.addClass("in-scrolling")):l.left=0,t.y<a.top+3?(l.top=5>a.top+3-t.y?-5:-20,G.addClass("in-scrolling")):t.y>a.bottom-3?(l.top=5>t.y-a.bottom+3?5:20,G.addClass("in-scrolling")):l.top=0,0===l.top&&0===l.left?n():o()}})}function T(t,o){function n(e,t){M.scrollTop(M.scrollTop()-t),M.scrollLeft(M.scrollLeft()-e),d()}function r(){h=!0}function l(){h=!1}function i(e){return e.originalEvent.targetTouches?e.originalEvent.targetTouches[0]:e.originalEvent}function a(e){var t=e.originalEvent;return t.targetTouches&&1===t.targetTouches.length?!0:t.pointerType&&"mouse"!==t.pointerType&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE?!0:!1}function s(e){if(a(e)){w=!0;var t=i(e);p.pageX=t.pageX,p.pageY=t.pageY,f=(new Date).getTime(),null!==b&&clearInterval(b),e.stopPropagation()}}function c(e){if(!h&&w&&a(e)){var t=i(e),o={pageX:t.pageX,pageY:t.pageY},r=o.pageX-p.pageX,l=o.pageY-p.pageY;n(r,l),p=o;var s=(new Date).getTime(),c=s-f;c>0&&(v.x=r/c,v.y=l/c,f=s),g(r,l)&&(e.stopPropagation(),e.preventDefault())}}function u(){!h&&w&&(w=!1,clearInterval(b),b=setInterval(function(){return x()?.01>Math.abs(v.x)&&.01>Math.abs(v.y)?(clearInterval(b),void 0):(n(30*v.x,30*v.y),v.x*=.8,v.y*=.8,void 0):(clearInterval(b),void 0)},10))}var p={},f=0,v={},b=null,h=!1,w=!1;t&&(e(window).bind(K("touchstart"),r),e(window).bind(K("touchend"),l),M.bind(K("touchstart"),s),M.bind(K("touchmove"),c),M.bind(K("touchend"),u)),o&&(window.PointerEvent?(e(window).bind(K("pointerdown"),r),e(window).bind(K("pointerup"),l),M.bind(K("pointerdown"),s),M.bind(K("pointermove"),c),M.bind(K("pointerup"),u)):window.MSPointerEvent&&(e(window).bind(K("MSPointerDown"),r),e(window).bind(K("MSPointerUp"),l),M.bind(K("MSPointerDown"),s),M.bind(K("MSPointerMove"),c),M.bind(K("MSPointerUp"),u)))}function y(){M.bind(K("scroll"),function(){d()})}function L(){M.unbind(K()),e(window).unbind(K()),e(q).unbind(K()),M.data("perfect-scrollbar",null),M.data("perfect-scrollbar-update",null),M.data("perfect-scrollbar-destroy",null),U.remove(),J.remove(),H.remove(),G.remove(),M=H=G=U=J=X=O=E=D=C=Y=k=W=_=N=Q=R=j=V=Z=$=B=K=null}function S(){d(),y(),p(),f(),w(),m(),b(),(ot||nt)&&T(ot,nt),P.useKeyboard&&h(),M.data("perfect-scrollbar",M),M.data("perfect-scrollbar-update",d),M.data("perfect-scrollbar-destroy",L)}var P=e.extend(!0,{},o),M=e(this),x=function(){return!!M};if("object"==typeof n?e.extend(!0,P,n):i=n,"update"===i)return M.data("perfect-scrollbar-update")&&M.data("perfect-scrollbar-update")(),M;if("destroy"===i)return M.data("perfect-scrollbar-destroy")&&M.data("perfect-scrollbar-destroy")(),M;if(M.data("perfect-scrollbar"))return M.data("perfect-scrollbar");M.addClass("ps-container");var E,D,C,Y,X,k,W,I,O,R,j,A,B="rtl"===M.css("direction"),K=r(),q=this.ownerDocument||document,H=e("<div class='ps-scrollbar-x-rail'>").appendTo(M),U=e("<div class='ps-scrollbar-x'>").appendTo(H),_=t(H.css("bottom")),N=_===_,Q=N?null:t(H.css("top")),z=t(H.css("borderLeftWidth"))+t(H.css("borderRightWidth")),F=t(H.css("marginLeft"))+t(H.css("marginRight")),G=e("<div class='ps-scrollbar-y-rail'>").appendTo(M),J=e("<div class='ps-scrollbar-y'>").appendTo(G),V=t(G.css("right")),Z=V===V,$=Z?null:t(G.css("left")),et=t(G.css("borderTopWidth"))+t(G.css("borderBottomWidth")),tt=t(G.css("marginTop"))+t(G.css("marginBottom")),ot="ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch,nt=null!==window.navigator.msMaxTouchPoints;return S(),M})}});
@@ -0,0 +1,223 @@
1
+ /**
2
+ * http://www.openjs.com/scripts/events/keyboard_shortcuts/
3
+ * Version : 2.01.B
4
+ * By Binny V A
5
+ * License : BSD
6
+ */
7
+ shortcut = {
8
+ 'all_shortcuts':{},//All the shortcuts are stored in this array
9
+ 'add': function(shortcut_combination,callback,opt) {
10
+ //Provide a set of default options
11
+ var default_options = {
12
+ 'type':'keydown',
13
+ 'propagate':false,
14
+ 'disable_in_input':false,
15
+ 'target':document,
16
+ 'keycode':false
17
+ }
18
+ if(!opt) opt = default_options;
19
+ else {
20
+ for(var dfo in default_options) {
21
+ if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
22
+ }
23
+ }
24
+
25
+ var ele = opt.target;
26
+ if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
27
+ var ths = this;
28
+ shortcut_combination = shortcut_combination.toLowerCase();
29
+
30
+ //The function to be called at keypress
31
+ var func = function(e) {
32
+ e = e || window.event;
33
+
34
+ if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
35
+ var element;
36
+ if(e.target) element=e.target;
37
+ else if(e.srcElement) element=e.srcElement;
38
+ if(element.nodeType==3) element=element.parentNode;
39
+
40
+ if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
41
+ }
42
+
43
+ //Find Which key is pressed
44
+ if (e.keyCode) code = e.keyCode;
45
+ else if (e.which) code = e.which;
46
+ var character = String.fromCharCode(code).toLowerCase();
47
+
48
+ if(code == 188) character=","; //If the user presses , when the type is onkeydown
49
+ if(code == 190) character="."; //If the user presses , when the type is onkeydown
50
+
51
+ var keys = shortcut_combination.split("+");
52
+ //Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
53
+ var kp = 0;
54
+
55
+ //Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
56
+ var shift_nums = {
57
+ "`":"~",
58
+ "1":"!",
59
+ "2":"@",
60
+ "3":"#",
61
+ "4":"$",
62
+ "5":"%",
63
+ "6":"^",
64
+ "7":"&",
65
+ "8":"*",
66
+ "9":"(",
67
+ "0":")",
68
+ "-":"_",
69
+ "=":"+",
70
+ ";":":",
71
+ "'":"\"",
72
+ ",":"<",
73
+ ".":">",
74
+ "/":"?",
75
+ "\\":"|"
76
+ }
77
+ //Special Keys - and their codes
78
+ var special_keys = {
79
+ 'esc':27,
80
+ 'escape':27,
81
+ 'tab':9,
82
+ 'space':32,
83
+ 'return':13,
84
+ 'enter':13,
85
+ 'backspace':8,
86
+
87
+ 'scrolllock':145,
88
+ 'scroll_lock':145,
89
+ 'scroll':145,
90
+ 'capslock':20,
91
+ 'caps_lock':20,
92
+ 'caps':20,
93
+ 'numlock':144,
94
+ 'num_lock':144,
95
+ 'num':144,
96
+
97
+ 'pause':19,
98
+ 'break':19,
99
+
100
+ 'insert':45,
101
+ 'home':36,
102
+ 'delete':46,
103
+ 'end':35,
104
+
105
+ 'pageup':33,
106
+ 'page_up':33,
107
+ 'pu':33,
108
+
109
+ 'pagedown':34,
110
+ 'page_down':34,
111
+ 'pd':34,
112
+
113
+ 'left':37,
114
+ 'up':38,
115
+ 'right':39,
116
+ 'down':40,
117
+
118
+ 'f1':112,
119
+ 'f2':113,
120
+ 'f3':114,
121
+ 'f4':115,
122
+ 'f5':116,
123
+ 'f6':117,
124
+ 'f7':118,
125
+ 'f8':119,
126
+ 'f9':120,
127
+ 'f10':121,
128
+ 'f11':122,
129
+ 'f12':123
130
+ }
131
+
132
+ var modifiers = {
133
+ shift: { wanted:false, pressed:false},
134
+ ctrl : { wanted:false, pressed:false},
135
+ alt : { wanted:false, pressed:false},
136
+ meta : { wanted:false, pressed:false} //Meta is Mac specific
137
+ };
138
+
139
+ if(e.ctrlKey) modifiers.ctrl.pressed = true;
140
+ if(e.shiftKey) modifiers.shift.pressed = true;
141
+ if(e.altKey) modifiers.alt.pressed = true;
142
+ if(e.metaKey) modifiers.meta.pressed = true;
143
+
144
+ for(var i=0; k=keys[i],i<keys.length; i++) {
145
+ //Modifiers
146
+ if(k == 'ctrl' || k == 'control') {
147
+ kp++;
148
+ modifiers.ctrl.wanted = true;
149
+
150
+ } else if(k == 'shift') {
151
+ kp++;
152
+ modifiers.shift.wanted = true;
153
+
154
+ } else if(k == 'alt') {
155
+ kp++;
156
+ modifiers.alt.wanted = true;
157
+ } else if(k == 'meta') {
158
+ kp++;
159
+ modifiers.meta.wanted = true;
160
+ } else if(k.length > 1) { //If it is a special key
161
+ if(special_keys[k] == code) kp++;
162
+
163
+ } else if(opt['keycode']) {
164
+ if(opt['keycode'] == code) kp++;
165
+
166
+ } else { //The special keys did not match
167
+ if(character == k) kp++;
168
+ else {
169
+ if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
170
+ character = shift_nums[character];
171
+ if(character == k) kp++;
172
+ }
173
+ }
174
+ }
175
+ }
176
+
177
+ if(kp == keys.length &&
178
+ modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
179
+ modifiers.shift.pressed == modifiers.shift.wanted &&
180
+ modifiers.alt.pressed == modifiers.alt.wanted &&
181
+ modifiers.meta.pressed == modifiers.meta.wanted) {
182
+ callback(e);
183
+
184
+ if(!opt['propagate']) { //Stop the event
185
+ //e.cancelBubble is supported by IE - this will kill the bubbling process.
186
+ e.cancelBubble = true;
187
+ e.returnValue = false;
188
+
189
+ //e.stopPropagation works in Firefox.
190
+ if (e.stopPropagation) {
191
+ e.stopPropagation();
192
+ e.preventDefault();
193
+ }
194
+ return false;
195
+ }
196
+ }
197
+ }
198
+ this.all_shortcuts[shortcut_combination] = {
199
+ 'callback':func,
200
+ 'target':ele,
201
+ 'event': opt['type']
202
+ };
203
+ //Attach the function with the event
204
+ if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
205
+ else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
206
+ else ele['on'+opt['type']] = func;
207
+ },
208
+
209
+ //Remove the shortcut - just specify the shortcut and I will remove the binding
210
+ 'remove':function(shortcut_combination) {
211
+ shortcut_combination = shortcut_combination.toLowerCase();
212
+ var binding = this.all_shortcuts[shortcut_combination];
213
+ delete(this.all_shortcuts[shortcut_combination])
214
+ if(!binding) return;
215
+ var type = binding['event'];
216
+ var ele = binding['target'];
217
+ var callback = binding['callback'];
218
+
219
+ if(ele.detachEvent) ele.detachEvent('on'+type, callback);
220
+ else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
221
+ else ele['on'+type] = false;
222
+ }
223
+ }
@@ -0,0 +1,322 @@
1
+ /*
2
+ * CSS TOGGLE SWITCHES
3
+ * Unlicense
4
+ *
5
+ * Ionuț Colceriu - ghinda.net
6
+ * https://github.com/ghinda/css-toggle-switch
7
+ *
8
+ */
9
+ /* Supported values are px, rem-calc, em-calc */
10
+ /* Functions */
11
+ /* Toggle Switches */
12
+ /* Shared */
13
+ /* Checkbox
14
+ */
15
+ /* Radio Switch
16
+ */
17
+ /* Hide by default
18
+ */
19
+ .switch-toggle a, .switch-light span span {
20
+ display: none; }
21
+
22
+ /* We can't test for a specific feature,
23
+ * so we only target browsers with support for media queries.
24
+ */
25
+ @media only screen {
26
+ /* Checkbox switch
27
+ */
28
+ .switch-light {
29
+ display: block;
30
+ min-height: 1.875em;
31
+ /* Outline the toggles when the inputs are focused
32
+ */
33
+ position: relative;
34
+ overflow: visible;
35
+ padding: 0;
36
+ margin-left: 6.25em;
37
+ /* Position the label over all the elements, except the slide-button (<a>)
38
+ * Clicking anywhere on the label will change the switch-state
39
+ */
40
+ /* Don't hide the input from screen-readers and keyboard access
41
+ */ }
42
+ .switch-light * {
43
+ -webkit-box-sizing: border-box;
44
+ -moz-box-sizing: border-box;
45
+ box-sizing: border-box; }
46
+ .switch-light a {
47
+ display: block;
48
+ -webkit-transition: all 0.2s ease-out;
49
+ -moz-transition: all 0.2s ease-out;
50
+ transition: all 0.2s ease-out; }
51
+ .switch-light label, .switch-light > span {
52
+ line-height: 1.875em;
53
+ vertical-align: middle; }
54
+ .switch-light input:focus ~ a, .switch-light input:focus + label {
55
+ outline: 1px dotted #888; }
56
+ .switch-light label {
57
+ position: relative;
58
+ z-index: 3;
59
+ display: block;
60
+ width: 100%; }
61
+ .switch-light input {
62
+ position: absolute;
63
+ opacity: 0;
64
+ z-index: 5; }
65
+ .switch-light input:checked ~ a {
66
+ right: 0%; }
67
+ .switch-light > span {
68
+ position: absolute;
69
+ left: -6.25em;
70
+ width: 100%;
71
+ margin: 0;
72
+ padding-right: 6.25em;
73
+ text-align: left; }
74
+ .switch-light > span span {
75
+ position: absolute;
76
+ top: 0;
77
+ left: 0;
78
+ z-index: 5;
79
+ display: block;
80
+ width: 50%;
81
+ margin-left: 6.25em;
82
+ text-align: center; }
83
+ .switch-light > span span:last-child {
84
+ left: 50%; }
85
+ .switch-light a {
86
+ position: absolute;
87
+ right: 50%;
88
+ top: 0;
89
+ z-index: 4;
90
+ display: block;
91
+ width: 50%;
92
+ height: 100%;
93
+ padding: 0; }
94
+
95
+ /* Radio switch
96
+ */
97
+ .switch-toggle {
98
+ display: block;
99
+ min-height: 1.875em;
100
+ /* Outline the toggles when the inputs are focused
101
+ */
102
+ position: relative;
103
+ display: table;
104
+ table-layout: fixed;
105
+ /* For callout panels in foundation
106
+ */
107
+ padding: 0 !important;
108
+ /* Generate styles for the multiple states */ }
109
+ .switch-toggle * {
110
+ -webkit-box-sizing: border-box;
111
+ -moz-box-sizing: border-box;
112
+ box-sizing: border-box; }
113
+ .switch-toggle a {
114
+ display: block;
115
+ -webkit-transition: all 0.2s ease-out;
116
+ -moz-transition: all 0.2s ease-out;
117
+ transition: all 0.2s ease-out; }
118
+ .switch-toggle label, .switch-toggle > span {
119
+ line-height: 1.875em;
120
+ vertical-align: middle; }
121
+ .switch-toggle input:focus ~ a, .switch-toggle input:focus + label {
122
+ outline: 1px dotted #888; }
123
+ .switch-toggle * {
124
+ font-size: 1em; }
125
+ .switch-toggle input {
126
+ position: absolute;
127
+ opacity: 0; }
128
+ .switch-toggle input + label {
129
+ position: relative;
130
+ z-index: 2;
131
+ display: table-cell;
132
+ width: 50%;
133
+ padding: 0 0.5em;
134
+ margin: 0;
135
+ text-align: center; }
136
+ .switch-toggle a {
137
+ position: absolute;
138
+ top: 0;
139
+ left: 0;
140
+ padding: 0;
141
+ z-index: 1;
142
+ width: 50%;
143
+ height: 100%; }
144
+ .switch-toggle input:last-of-type:checked ~ a {
145
+ left: 50%; }
146
+ .switch-toggle.switch-3 label, .switch-toggle.switch-3 a {
147
+ width: 33.3333333333%; }
148
+ .switch-toggle.switch-3 input:checked:nth-of-type(2) ~ a {
149
+ left: 33.3333333333%; }
150
+ .switch-toggle.switch-3 input:checked:last-of-type ~ a {
151
+ left: 66.6666666667%; }
152
+ .switch-toggle.switch-4 label, .switch-toggle.switch-4 a {
153
+ width: 25%; }
154
+ .switch-toggle.switch-4 input:checked:nth-of-type(2) ~ a {
155
+ left: 25%; }
156
+ .switch-toggle.switch-4 input:checked:nth-of-type(3) ~ a {
157
+ left: 50%; }
158
+ .switch-toggle.switch-4 input:checked:last-of-type ~ a {
159
+ left: 75%; }
160
+ .switch-toggle.switch-5 label, .switch-toggle.switch-5 a {
161
+ width: 20%; }
162
+ .switch-toggle.switch-5 input:checked:nth-of-type(2) ~ a {
163
+ left: 20%; }
164
+ .switch-toggle.switch-5 input:checked:nth-of-type(3) ~ a {
165
+ left: 40%; }
166
+ .switch-toggle.switch-5 input:checked:nth-of-type(4) ~ a {
167
+ left: 60%; }
168
+ .switch-toggle.switch-5 input:checked:last-of-type ~ a {
169
+ left: 80%; }
170
+
171
+ /* Standalone Themes */
172
+ /* Candy Theme
173
+ * Based on the "Sort Switches / Toggles (PSD)" by Ormal Clarck
174
+ * http://www.premiumpixels.com/freebies/sort-switches-toggles-psd/
175
+ */
176
+ .switch-candy {
177
+ background-color: #2d3035;
178
+ border-radius: 3px;
179
+ color: #fff;
180
+ font-weight: bold;
181
+ text-align: center;
182
+ text-shadow: 1px 1px 1px #191b1e;
183
+ box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.3), 0 1px 0 rgba(255, 255, 255, 0.2); }
184
+ .switch-candy label {
185
+ color: #fff;
186
+ -webkit-transition: color 0.2s ease-out;
187
+ -moz-transition: color 0.2s ease-out;
188
+ transition: color 0.2s ease-out; }
189
+ .switch-candy input:checked + label {
190
+ color: #333;
191
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); }
192
+ .switch-candy a {
193
+ border: 1px solid #333;
194
+ background-color: #70c66b;
195
+ border-radius: 3px;
196
+ background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0));
197
+ background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.2), rgba(0, 0, 0, 0));
198
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), inset 0 1px 1px rgba(255, 255, 255, 0.45); }
199
+ .switch-candy > span {
200
+ color: #333;
201
+ text-shadow: none; }
202
+ .switch-candy span {
203
+ color: #fff; }
204
+ .switch-candy.switch-candy-blue a {
205
+ background-color: #38a3d4; }
206
+ .switch-candy.switch-candy-yellow a {
207
+ background-color: #f5e560; }
208
+
209
+ /* Android Theme
210
+ */
211
+ .switch-android {
212
+ background-color: #464747;
213
+ border-radius: 1px;
214
+ box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0;
215
+ color: #fff;
216
+ /* Selected ON switch-light
217
+ */ }
218
+ .switch-android label {
219
+ color: #fff; }
220
+ .switch-android > span span {
221
+ opacity: 0;
222
+ margin-left: 7.1875em;
223
+ -webkit-transition: all 0.1s;
224
+ -moz-transition: all 0.1s;
225
+ transition: all 0.1s; }
226
+ .switch-android > span span:first-of-type {
227
+ opacity: 1; }
228
+ .switch-android > span span, .switch-android input + label {
229
+ font-size: 85%;
230
+ line-height: 2.15625em; }
231
+ .switch-android a {
232
+ background-color: #666;
233
+ border-radius: 1px;
234
+ box-shadow: inset rgba(255, 255, 255, 0.2) 0 1px 0, inset rgba(0, 0, 0, 0.3) 0 -1px 0; }
235
+ .switch-android.switch-light input:checked ~ a {
236
+ background-color: #0E88B1; }
237
+ .switch-android.switch-light input:checked ~ span span:first-of-type {
238
+ opacity: 0; }
239
+ .switch-android.switch-light input:checked ~ span span:last-of-type {
240
+ opacity: 1; }
241
+ .switch-android.switch-toggle, .switch-android > span span {
242
+ text-transform: uppercase; }
243
+
244
+ /* iOS Theme
245
+ */
246
+ .switch-ios.switch-light {
247
+ color: #868686; }
248
+ .switch-ios.switch-light a {
249
+ left: 0;
250
+ width: 1.875em;
251
+ background-color: #fff;
252
+ border: 1px solid #d3d3d3;
253
+ border-radius: 100%;
254
+ -webkit-transition: all 0.3s ease-out;
255
+ -moz-transition: all 0.3s ease-out;
256
+ transition: all 0.3s ease-out;
257
+ box-shadow: inset 0 -3px 3px rgba(0, 0, 0, 0.025), 0 1px 4px rgba(0, 0, 0, 0.15), 0 4px 4px rgba(0, 0, 0, 0.1); }
258
+ .switch-ios.switch-light > span span {
259
+ width: 100%;
260
+ left: 0;
261
+ opacity: 0; }
262
+ .switch-ios.switch-light > span span:first-of-type {
263
+ opacity: 1;
264
+ padding-left: 1.875em; }
265
+ .switch-ios.switch-light > span span:last-of-type {
266
+ padding-right: 1.875em; }
267
+ .switch-ios.switch-light > span:before {
268
+ content: '';
269
+ display: block;
270
+ width: 100%;
271
+ height: 100%;
272
+ position: absolute;
273
+ left: 6.25em;
274
+ top: 0;
275
+ background-color: #fafafa;
276
+ border: 1px solid #d3d3d3;
277
+ border-radius: 30px;
278
+ -webkit-transition: all 0.5s ease-out;
279
+ -moz-transition: all 0.5s ease-out;
280
+ transition: all 0.5s ease-out;
281
+ box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; }
282
+ .switch-ios.switch-light input:checked ~ a {
283
+ left: 100%;
284
+ margin-left: -1.875em; }
285
+ .switch-ios.switch-light input:checked ~ span:before {
286
+ border-color: #53d76a;
287
+ box-shadow: inset 0 0 0 30px #53d76a; }
288
+ .switch-ios.switch-light input:checked ~ span span:first-of-type {
289
+ opacity: 0; }
290
+ .switch-ios.switch-light input:checked ~ span span:last-of-type {
291
+ opacity: 1;
292
+ color: #fff; }
293
+ .switch-ios.switch-toggle {
294
+ background-color: #fafafa;
295
+ border: 1px solid #d3d3d3;
296
+ border-radius: 30px;
297
+ box-shadow: inset rgba(0, 0, 0, 0.1) 0 1px 0; }
298
+ .switch-ios.switch-toggle a {
299
+ background-color: #53d76a;
300
+ border-radius: 25px;
301
+ -webkit-transition: all 0.3s ease-out;
302
+ -moz-transition: all 0.3s ease-out;
303
+ transition: all 0.3s ease-out; }
304
+ .switch-ios.switch-toggle label {
305
+ color: #868686; }
306
+ .switch-ios input:checked + label {
307
+ color: #3a3a3a; }
308
+ }
309
+
310
+ /* Bugfix for older Webkit, including mobile Webkit. Adapted from
311
+ * http://css-tricks.com/webkit-sibling-bug/
312
+ */
313
+ @media only screen and (-webkit-max-device-pixel-ratio: 2) and (max-device-width: 80em) {
314
+ .switch-light, .switch-toggle {
315
+ -webkit-animation: webkitSiblingBugfix infinite 1s; } }
316
+
317
+ @-webkit-keyframes webkitSiblingBugfix {
318
+ from {
319
+ -webkit-transform: translate3d(0, 0, 0); }
320
+
321
+ to {
322
+ -webkit-transform: translate3d(0, 0, 0); } }