alchemy_cms 7.1.0.pre.b1 → 7.1.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -0
  3. data/Gemfile +1 -1
  4. data/README.md +2 -2
  5. data/alchemy_cms.gemspec +1 -1
  6. data/app/assets/config/alchemy_manifest.js +3 -4
  7. data/app/assets/images/alchemy/missing-image.svg +1 -1
  8. data/app/assets/javascripts/alchemy/admin.js +0 -4
  9. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +4 -4
  10. data/app/assets/javascripts/tinymce/icons/remixicons/icons.js +93 -0
  11. data/app/assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js +37 -18
  12. data/app/assets/stylesheets/alchemy/_variables.scss +11 -3
  13. data/app/assets/stylesheets/alchemy/archive.scss +5 -2
  14. data/app/assets/stylesheets/alchemy/buttons.scss +5 -4
  15. data/app/assets/stylesheets/alchemy/dialogs.scss +1 -1
  16. data/app/assets/stylesheets/alchemy/elements.scss +4 -5
  17. data/app/assets/stylesheets/alchemy/filter_field.scss +5 -0
  18. data/app/assets/stylesheets/tinymce/skins/content/alchemy/content.min.scss +69 -0
  19. data/app/assets/stylesheets/tinymce/skins/skintool.json +38 -0
  20. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.css +711 -0
  21. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.inline.css +705 -0
  22. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.inline.min.css +7 -0
  23. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.min.css +7 -0
  24. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.mobile.css +29 -0
  25. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/content.mobile.min.css +7 -0
  26. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/fonts/tinymce-mobile.woff +0 -0
  27. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/skin.min.scss +3803 -0
  28. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/skin.mobile.css +677 -0
  29. data/app/assets/stylesheets/tinymce/skins/ui/alchemy/skin.mobile.min.css +7 -0
  30. data/app/controllers/alchemy/admin/pages_controller.rb +9 -4
  31. data/app/helpers/alchemy/admin/base_helper.rb +23 -10
  32. data/app/helpers/alchemy/base_helper.rb +16 -1
  33. data/app/javascript/alchemy_admin/components/button.js +1 -1
  34. data/app/javascript/alchemy_admin/components/clipboard_button.js +27 -0
  35. data/app/javascript/alchemy_admin/components/element_editor.js +2 -2
  36. data/app/javascript/alchemy_admin/components/tinymce.js +9 -21
  37. data/app/javascript/alchemy_admin/picture_editors.js +4 -2
  38. data/app/javascript/alchemy_admin/utils/debounce.js +10 -0
  39. data/app/javascript/alchemy_admin/utils/max.js +3 -0
  40. data/app/javascript/alchemy_admin.js +4 -10
  41. data/app/models/alchemy/page/page_naming.rb +7 -0
  42. data/app/models/alchemy/page.rb +2 -2
  43. data/app/models/alchemy/picture_variant.rb +11 -2
  44. data/app/models/concerns/alchemy/picture_thumbnails.rb +1 -1
  45. data/app/views/alchemy/admin/attachments/show.html.erb +10 -19
  46. data/app/views/alchemy/admin/crop.html.erb +1 -1
  47. data/app/views/alchemy/admin/nodes/index.html.erb +1 -0
  48. data/app/views/alchemy/admin/partials/_toolbar_button.html.erb +0 -1
  49. data/app/views/alchemy/admin/pictures/_archive.html.erb +3 -3
  50. data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +16 -3
  51. data/app/views/alchemy/admin/pictures/_picture.html.erb +3 -5
  52. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -1
  53. data/app/views/alchemy/admin/resources/_filter.html.erb +1 -1
  54. data/app/views/alchemy/admin/resources/_per_page_select.html.erb +1 -1
  55. data/app/views/alchemy/admin/tinymce/_setup.html.erb +1 -2
  56. data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +2 -2
  57. data/app/views/layouts/alchemy/admin.html.erb +1 -1
  58. data/bundles/shoelace.js +10 -0
  59. data/bundles/tinymce.js +20 -0
  60. data/config/alchemy/config.yml +11 -10
  61. data/config/brakeman.ignore +0 -34
  62. data/config/importmap.rb +9 -14
  63. data/config/initializers/dragonfly.rb +1 -0
  64. data/config/locales/alchemy.en.yml +2 -0
  65. data/eslint.config.js +17 -0
  66. data/lib/alchemy/config.rb +24 -2
  67. data/lib/alchemy/engine.rb +2 -1
  68. data/lib/alchemy/forms/builder.rb +7 -0
  69. data/lib/alchemy/test_support/capybara_helpers.rb +1 -1
  70. data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +6 -6
  71. data/lib/alchemy/tinymce.rb +13 -2
  72. data/lib/alchemy/version.rb +1 -1
  73. data/package.json +20 -6
  74. data/rollup.config.mjs +65 -0
  75. data/vendor/assets/stylesheets/tinymce/skins/content/default/content.min.css +1 -0
  76. data/vendor/javascript/clipboard.min.js +7 -0
  77. data/vendor/javascript/flatpickr.min.js +1 -0
  78. data/vendor/javascript/keymaster.min.js +1 -0
  79. data/vendor/javascript/rails-ujs.min.js +1 -0
  80. data/vendor/javascript/shoelace.min.js +995 -0
  81. data/vendor/javascript/sortable.min.js +7 -0
  82. data/vendor/javascript/tinymce.min.js +1 -0
  83. data/vendor/javascript/ungap-custom-elements.min.js +3 -0
  84. metadata +31 -39
  85. data/.codeclimate.yml +0 -35
  86. data/.editorconfig +0 -23
  87. data/.github/FUNDING.yml +0 -4
  88. data/.github/ISSUE_TEMPLATE/Bug_report.md +0 -22
  89. data/.github/ISSUE_TEMPLATE/Feature_request.md +0 -17
  90. data/.github/PULL_REQUEST_TEMPLATE.md +0 -18
  91. data/.github/workflows/backport.yml +0 -36
  92. data/.github/workflows/brakeman-analysis.yml +0 -46
  93. data/.github/workflows/lint.yml +0 -37
  94. data/.github/workflows/stale.yml +0 -33
  95. data/.github/workflows/test.yml +0 -125
  96. data/.gitignore +0 -32
  97. data/.hound.yml +0 -9
  98. data/.localeapp/config.rb +0 -8
  99. data/.prettierrc +0 -6
  100. data/.rspec +0 -1
  101. data/.rubocop.yml +0 -7
  102. data/.standard.yml +0 -4
  103. data/.yardopts +0 -5
  104. data/app/assets/stylesheets/tinymce/skins/alchemy/content.min.css.scss +0 -94
  105. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.svg +0 -63
  106. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.ttf +0 -0
  107. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce-small.woff +0 -0
  108. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.svg +0 -129
  109. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.ttf +0 -0
  110. data/app/assets/stylesheets/tinymce/skins/alchemy/fonts/tinymce.woff +0 -0
  111. data/app/assets/stylesheets/tinymce/skins/alchemy/img/anchor.gif +0 -0
  112. data/app/assets/stylesheets/tinymce/skins/alchemy/img/loader.gif +0 -0
  113. data/app/assets/stylesheets/tinymce/skins/alchemy/img/object.gif +0 -0
  114. data/app/assets/stylesheets/tinymce/skins/alchemy/img/trans.gif +0 -0
  115. data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +0 -2077
  116. data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +0 -10
  117. data/vendor/assets/javascripts/clipboard.min.js +0 -7
  118. data/vendor/assets/javascripts/keymaster.js +0 -296
  119. data/vendor/assets/javascripts/requestAnimationFrame.js +0 -31
  120. data/vendor/assets/javascripts/tinymce/license.txt +0 -504
  121. data/vendor/assets/javascripts/tinymce/tinymce.min.js +0 -2
@@ -1,10 +0,0 @@
1
- <% if @pictures.empty? %>
2
- <%= render_message do %>
3
- <%= Alchemy.t(:no_images_in_archive) %>
4
- <% end %>
5
- <% else %>
6
- <%= render partial: 'picture_to_assign',
7
- collection: @pictures,
8
- locals: {size: @size} %>
9
- <%= paginate @pictures, theme: 'alchemy', remote: true, hide_per_page_select: true %>
10
- <% end %>
@@ -1,7 +0,0 @@
1
- /*!
2
- * clipboard.js v1.5.12
3
- * https://zenorocha.github.io/clipboard.js
4
- *
5
- * Licensed MIT © Zeno Rocha
6
- */
7
- !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,o){function i(a,c){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!c&&s)return s(a,!0);if(r)return r(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var u=n[a]={exports:{}};e[a][0].call(u.exports,function(t){var n=e[a][1][t];return i(n?n:t)},u,u.exports,t,e,n,o)}return n[a].exports}for(var r="function"==typeof require&&require,a=0;a<o.length;a++)i(o[a]);return i}({1:[function(t,e,n){var o=t("matches-selector");e.exports=function(t,e,n){for(var i=n?t:t.parentNode;i&&i!==document;){if(o(i,e))return i;i=i.parentNode}}},{"matches-selector":5}],2:[function(t,e,n){function o(t,e,n,o,r){var a=i.apply(this,arguments);return t.addEventListener(n,a,r),{destroy:function(){t.removeEventListener(n,a,r)}}}function i(t,e,n,o){return function(n){n.delegateTarget=r(n.target,e,!0),n.delegateTarget&&o.call(t,n)}}var r=t("closest");e.exports=o},{closest:1}],3:[function(t,e,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.fn=function(t){var e=Object.prototype.toString.call(t);return"[object Function]"===e}},{}],4:[function(t,e,n){function o(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!c.string(e))throw new TypeError("Second argument must be a String");if(!c.fn(n))throw new TypeError("Third argument must be a Function");if(c.node(t))return i(t,e,n);if(c.nodeList(t))return r(t,e,n);if(c.string(t))return a(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function i(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}function r(t,e,n){return Array.prototype.forEach.call(t,function(t){t.addEventListener(e,n)}),{destroy:function(){Array.prototype.forEach.call(t,function(t){t.removeEventListener(e,n)})}}}function a(t,e,n){return s(document.body,t,e,n)}var c=t("./is"),s=t("delegate");e.exports=o},{"./is":3,delegate:2}],5:[function(t,e,n){function o(t,e){if(r)return r.call(t,e);for(var n=t.parentNode.querySelectorAll(e),o=0;o<n.length;++o)if(n[o]==t)return!0;return!1}var i=Element.prototype,r=i.matchesSelector||i.webkitMatchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector;e.exports=o},{}],6:[function(t,e,n){function o(t){var e;if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName)t.focus(),t.setSelectionRange(0,t.value.length),e=t.value;else{t.hasAttribute("contenteditable")&&t.focus();var n=window.getSelection(),o=document.createRange();o.selectNodeContents(t),n.removeAllRanges(),n.addRange(o),e=n.toString()}return e}e.exports=o},{}],7:[function(t,e,n){function o(){}o.prototype={on:function(t,e,n){var o=this.e||(this.e={});return(o[t]||(o[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){function o(){i.off(t,o),e.apply(n,arguments)}var i=this;return o._=e,this.on(t,o,n)},emit:function(t){var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),o=0,i=n.length;for(o;i>o;o++)n[o].fn.apply(n[o].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),o=n[t],i=[];if(o&&e)for(var r=0,a=o.length;a>r;r++)o[r].fn!==e&&o[r].fn._!==e&&i.push(o[r]);return i.length?n[t]=i:delete n[t],this}},e.exports=o},{}],8:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","select"],r);else if("undefined"!=typeof o)r(n,e("select"));else{var a={exports:{}};r(a,i.select),i.clipboardAction=a.exports}}(this,function(t,e){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i=n(e),r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol?"symbol":typeof t},a=function(){function t(t,e){for(var n=0;n<e.length;n++){var o=e[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,n,o){return n&&t(e.prototype,n),o&&t(e,o),e}}(),c=function(){function t(e){o(this,t),this.resolveOptions(e),this.initSelection()}return t.prototype.resolveOptions=function t(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.action=e.action,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""},t.prototype.initSelection=function t(){this.text?this.selectFake():this.target&&this.selectTarget()},t.prototype.selectFake=function t(){var e=this,n="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=document.body.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[n?"right":"left"]="-9999px",this.fakeElem.style.top=(window.pageYOffset||document.documentElement.scrollTop)+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,document.body.appendChild(this.fakeElem),this.selectedText=(0,i.default)(this.fakeElem),this.copyText()},t.prototype.removeFake=function t(){this.fakeHandler&&(document.body.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(document.body.removeChild(this.fakeElem),this.fakeElem=null)},t.prototype.selectTarget=function t(){this.selectedText=(0,i.default)(this.target),this.copyText()},t.prototype.copyText=function t(){var e=void 0;try{e=document.execCommand(this.action)}catch(n){e=!1}this.handleResult(e)},t.prototype.handleResult=function t(e){e?this.emitter.emit("success",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)}):this.emitter.emit("error",{action:this.action,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})},t.prototype.clearSelection=function t(){this.target&&this.target.blur(),window.getSelection().removeAllRanges()},t.prototype.destroy=function t(){this.removeFake()},a(t,[{key:"action",set:function t(){var e=arguments.length<=0||void 0===arguments[0]?"copy":arguments[0];if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function t(){return this._action}},{key:"target",set:function t(e){if(void 0!==e){if(!e||"object"!==("undefined"==typeof e?"undefined":r(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function t(){return this._target}}]),t}();t.exports=c})},{select:6}],9:[function(e,n,o){!function(i,r){if("function"==typeof t&&t.amd)t(["module","./clipboard-action","tiny-emitter","good-listener"],r);else if("undefined"!=typeof o)r(n,e("./clipboard-action"),e("tiny-emitter"),e("good-listener"));else{var a={exports:{}};r(a,i.clipboardAction,i.tinyEmitter,i.goodListener),i.clipboard=a.exports}}(this,function(t,e,n,o){"use strict";function i(t){return t&&t.__esModule?t:{"default":t}}function r(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function a(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function c(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function s(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}var l=i(e),u=i(n),f=i(o),d=function(t){function e(n,o){r(this,e);var i=a(this,t.call(this));return i.resolveOptions(o),i.listenClick(n),i}return c(e,t),e.prototype.resolveOptions=function t(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText},e.prototype.listenClick=function t(e){var n=this;this.listener=(0,f.default)(e,"click",function(t){return n.onClick(t)})},e.prototype.onClick=function t(e){var n=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new l.default({action:this.action(n),target:this.target(n),text:this.text(n),trigger:n,emitter:this})},e.prototype.defaultAction=function t(e){return s("action",e)},e.prototype.defaultTarget=function t(e){var n=s("target",e);return n?document.querySelector(n):void 0},e.prototype.defaultText=function t(e){return s("text",e)},e.prototype.destroy=function t(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)},e}(u.default);t.exports=d})},{"./clipboard-action":8,"good-listener":4,"tiny-emitter":7}]},{},[9])(9)});
@@ -1,296 +0,0 @@
1
- // keymaster.js
2
- // (c) 2011-2013 Thomas Fuchs
3
- // keymaster.js may be freely distributed under the MIT license.
4
-
5
- ;(function(global){
6
- var k,
7
- _handlers = {},
8
- _mods = { 16: false, 18: false, 17: false, 91: false },
9
- _scope = 'all',
10
- // modifier keys
11
- _MODIFIERS = {
12
- '⇧': 16, shift: 16,
13
- '⌥': 18, alt: 18, option: 18,
14
- '⌃': 17, ctrl: 17, control: 17,
15
- '⌘': 91, command: 91
16
- },
17
- // special keys
18
- _MAP = {
19
- backspace: 8, tab: 9, clear: 12,
20
- enter: 13, 'return': 13,
21
- esc: 27, escape: 27, space: 32,
22
- left: 37, up: 38,
23
- right: 39, down: 40,
24
- del: 46, 'delete': 46,
25
- home: 36, end: 35,
26
- pageup: 33, pagedown: 34,
27
- ',': 188, '.': 190, '/': 191,
28
- '`': 192, '-': 189, '=': 187,
29
- ';': 186, '\'': 222,
30
- '[': 219, ']': 221, '\\': 220
31
- },
32
- code = function(x){
33
- return _MAP[x] || x.toUpperCase().charCodeAt(0);
34
- },
35
- _downKeys = [];
36
-
37
- for(k=1;k<20;k++) _MAP['f'+k] = 111+k;
38
-
39
- // IE doesn't support Array#indexOf, so have a simple replacement
40
- function index(array, item){
41
- var i = array.length;
42
- while(i--) if(array[i]===item) return i;
43
- return -1;
44
- }
45
-
46
- // for comparing mods before unassignment
47
- function compareArray(a1, a2) {
48
- if (a1.length != a2.length) return false;
49
- for (var i = 0; i < a1.length; i++) {
50
- if (a1[i] !== a2[i]) return false;
51
- }
52
- return true;
53
- }
54
-
55
- var modifierMap = {
56
- 16:'shiftKey',
57
- 18:'altKey',
58
- 17:'ctrlKey',
59
- 91:'metaKey'
60
- };
61
- function updateModifierKey(event) {
62
- for(k in _mods) _mods[k] = event[modifierMap[k]];
63
- };
64
-
65
- // handle keydown event
66
- function dispatch(event) {
67
- var key, handler, k, i, modifiersMatch, scope;
68
- key = event.keyCode;
69
-
70
- if (index(_downKeys, key) == -1) {
71
- _downKeys.push(key);
72
- }
73
-
74
- // if a modifier key, set the key.<modifierkeyname> property to true and return
75
- if(key == 93 || key == 224) key = 91; // right command on webkit, command on Gecko
76
- if(key in _mods) {
77
- _mods[key] = true;
78
- // 'assignKey' from inside this closure is exported to window.key
79
- for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = true;
80
- return;
81
- }
82
- updateModifierKey(event);
83
-
84
- // see if we need to ignore the keypress (filter() can can be overridden)
85
- // by default ignore key presses if a select, textarea, or input is focused
86
- if(!assignKey.filter.call(this, event)) return;
87
-
88
- // abort if no potentially matching shortcuts found
89
- if (!(key in _handlers)) return;
90
-
91
- scope = getScope();
92
-
93
- // for each potential shortcut
94
- for (i = 0; i < _handlers[key].length; i++) {
95
- handler = _handlers[key][i];
96
-
97
- // see if it's in the current scope
98
- if(handler.scope == scope || handler.scope == 'all'){
99
- // check if modifiers match if any
100
- modifiersMatch = handler.mods.length > 0;
101
- for(k in _mods)
102
- if((!_mods[k] && index(handler.mods, +k) > -1) ||
103
- (_mods[k] && index(handler.mods, +k) == -1)) modifiersMatch = false;
104
- // call the handler and stop the event if neccessary
105
- if((handler.mods.length == 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91]) || modifiersMatch){
106
- if(handler.method(event, handler)===false){
107
- if(event.preventDefault) event.preventDefault();
108
- else event.returnValue = false;
109
- if(event.stopPropagation) event.stopPropagation();
110
- if(event.cancelBubble) event.cancelBubble = true;
111
- }
112
- }
113
- }
114
- }
115
- };
116
-
117
- // unset modifier keys on keyup
118
- function clearModifier(event){
119
- var key = event.keyCode, k,
120
- i = index(_downKeys, key);
121
-
122
- // remove key from _downKeys
123
- if (i >= 0) {
124
- _downKeys.splice(i, 1);
125
- }
126
-
127
- if(key == 93 || key == 224) key = 91;
128
- if(key in _mods) {
129
- _mods[key] = false;
130
- for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = false;
131
- }
132
- };
133
-
134
- function resetModifiers() {
135
- for(k in _mods) _mods[k] = false;
136
- for(k in _MODIFIERS) assignKey[k] = false;
137
- };
138
-
139
- // parse and assign shortcut
140
- function assignKey(key, scope, method){
141
- var keys, mods;
142
- keys = getKeys(key);
143
- if (method === undefined) {
144
- method = scope;
145
- scope = 'all';
146
- }
147
-
148
- // for each shortcut
149
- for (var i = 0; i < keys.length; i++) {
150
- // set modifier keys if any
151
- mods = [];
152
- key = keys[i].split('+');
153
- if (key.length > 1){
154
- mods = getMods(key);
155
- key = [key[key.length-1]];
156
- }
157
- // convert to keycode and...
158
- key = key[0]
159
- key = code(key);
160
- // ...store handler
161
- if (!(key in _handlers)) _handlers[key] = [];
162
- _handlers[key].push({ shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods });
163
- }
164
- };
165
-
166
- // unbind all handlers for given key in current scope
167
- function unbindKey(key, scope) {
168
- var multipleKeys, keys,
169
- mods = [],
170
- i, j, obj;
171
-
172
- multipleKeys = getKeys(key);
173
-
174
- for (j = 0; j < multipleKeys.length; j++) {
175
- keys = multipleKeys[j].split('+');
176
-
177
- if (keys.length > 1) {
178
- mods = getMods(keys);
179
- key = keys[keys.length - 1];
180
- }
181
-
182
- key = code(key);
183
-
184
- if (scope === undefined) {
185
- scope = getScope();
186
- }
187
- if (!_handlers[key]) {
188
- return;
189
- }
190
- for (i in _handlers[key]) {
191
- obj = _handlers[key][i];
192
- // only clear handlers if correct scope and mods match
193
- if (obj.scope === scope && compareArray(obj.mods, mods)) {
194
- _handlers[key][i] = {};
195
- }
196
- }
197
- }
198
- };
199
-
200
- // Returns true if the key with code 'keyCode' is currently down
201
- // Converts strings into key codes.
202
- function isPressed(keyCode) {
203
- if (typeof(keyCode)=='string') {
204
- keyCode = code(keyCode);
205
- }
206
- return index(_downKeys, keyCode) != -1;
207
- }
208
-
209
- function getPressedKeyCodes() {
210
- return _downKeys.slice(0);
211
- }
212
-
213
- function filter(event){
214
- var tagName = (event.target || event.srcElement).tagName;
215
- // ignore keypressed in any elements that support keyboard data input
216
- return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA');
217
- }
218
-
219
- // initialize key.<modifier> to false
220
- for(k in _MODIFIERS) assignKey[k] = false;
221
-
222
- // set current scope (default 'all')
223
- function setScope(scope){ _scope = scope || 'all' };
224
- function getScope(){ return _scope || 'all' };
225
-
226
- // delete all handlers for a given scope
227
- function deleteScope(scope){
228
- var key, handlers, i;
229
-
230
- for (key in _handlers) {
231
- handlers = _handlers[key];
232
- for (i = 0; i < handlers.length; ) {
233
- if (handlers[i].scope === scope) handlers.splice(i, 1);
234
- else i++;
235
- }
236
- }
237
- };
238
-
239
- // abstract key logic for assign and unassign
240
- function getKeys(key) {
241
- var keys;
242
- key = key.replace(/\s/g, '');
243
- keys = key.split(',');
244
- if ((keys[keys.length - 1]) == '') {
245
- keys[keys.length - 2] += ',';
246
- }
247
- return keys;
248
- }
249
-
250
- // abstract mods logic for assign and unassign
251
- function getMods(key) {
252
- var mods = key.slice(0, key.length - 1);
253
- for (var mi = 0; mi < mods.length; mi++)
254
- mods[mi] = _MODIFIERS[mods[mi]];
255
- return mods;
256
- }
257
-
258
- // cross-browser events
259
- function addEvent(object, event, method) {
260
- if (object.addEventListener)
261
- object.addEventListener(event, method, false);
262
- else if(object.attachEvent)
263
- object.attachEvent('on'+event, function(){ method(window.event) });
264
- };
265
-
266
- // set the handlers globally on document
267
- addEvent(document, 'keydown', function(event) { dispatch(event) }); // Passing _scope to a callback to ensure it remains the same by execution. Fixes #48
268
- addEvent(document, 'keyup', clearModifier);
269
-
270
- // reset modifiers to false whenever the window is (re)focused.
271
- addEvent(window, 'focus', resetModifiers);
272
-
273
- // store previously defined key
274
- var previousKey = global.key;
275
-
276
- // restore previously defined key and return reference to our key object
277
- function noConflict() {
278
- var k = global.key;
279
- global.key = previousKey;
280
- return k;
281
- }
282
-
283
- // set window.key and window.key.set/get/deleteScope, and the default filter
284
- global.key = assignKey;
285
- global.key.setScope = setScope;
286
- global.key.getScope = getScope;
287
- global.key.deleteScope = deleteScope;
288
- global.key.filter = filter;
289
- global.key.isPressed = isPressed;
290
- global.key.getPressedKeyCodes = getPressedKeyCodes;
291
- global.key.noConflict = noConflict;
292
- global.key.unbind = unbindKey;
293
-
294
- if(typeof module !== 'undefined') module.exports = key;
295
-
296
- })(this);
@@ -1,31 +0,0 @@
1
- // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
2
- // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
3
-
4
- // requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
5
-
6
- // MIT license
7
-
8
- (function() {
9
- var lastTime = 0;
10
- var vendors = ['ms', 'moz', 'webkit', 'o'];
11
- for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
12
- window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
13
- window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
14
- || window[vendors[x]+'CancelRequestAnimationFrame'];
15
- }
16
-
17
- if (!window.requestAnimationFrame)
18
- window.requestAnimationFrame = function(callback, element) {
19
- var currTime = new Date().getTime();
20
- var timeToCall = Math.max(0, 16 - (currTime - lastTime));
21
- var id = window.setTimeout(function() { callback(currTime + timeToCall); },
22
- timeToCall);
23
- lastTime = currTime + timeToCall;
24
- return id;
25
- };
26
-
27
- if (!window.cancelAnimationFrame)
28
- window.cancelAnimationFrame = function(id) {
29
- clearTimeout(id);
30
- };
31
- }());