slippery 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +15 -0
  2. data/.travis.yml +27 -0
  3. data/Gemfile +10 -0
  4. data/Gemfile.devtools +59 -0
  5. data/Gemfile.lock +220 -0
  6. data/LICENSE +9 -0
  7. data/README.md +122 -0
  8. data/Rakefile +2 -0
  9. data/assets/impress.js/css/impress-demo.css +703 -0
  10. data/assets/impress.js/js/impress.js +800 -0
  11. data/assets/reveal.js/css/print/paper.css +176 -0
  12. data/assets/reveal.js/css/print/pdf.css +190 -0
  13. data/assets/reveal.js/css/reveal.css +1616 -0
  14. data/assets/reveal.js/css/reveal.min.css +7 -0
  15. data/assets/reveal.js/css/theme/README.md +23 -0
  16. data/assets/reveal.js/css/theme/beige.css +142 -0
  17. data/assets/reveal.js/css/theme/default.css +142 -0
  18. data/assets/reveal.js/css/theme/moon.css +142 -0
  19. data/assets/reveal.js/css/theme/night.css +130 -0
  20. data/assets/reveal.js/css/theme/serif.css +132 -0
  21. data/assets/reveal.js/css/theme/simple.css +132 -0
  22. data/assets/reveal.js/css/theme/sky.css +139 -0
  23. data/assets/reveal.js/css/theme/solarized.css +142 -0
  24. data/assets/reveal.js/css/theme/source/beige.scss +50 -0
  25. data/assets/reveal.js/css/theme/source/default.scss +42 -0
  26. data/assets/reveal.js/css/theme/source/moon.scss +68 -0
  27. data/assets/reveal.js/css/theme/source/night.scss +35 -0
  28. data/assets/reveal.js/css/theme/source/serif.scss +35 -0
  29. data/assets/reveal.js/css/theme/source/simple.scss +38 -0
  30. data/assets/reveal.js/css/theme/source/sky.scss +46 -0
  31. data/assets/reveal.js/css/theme/source/solarized.scss +74 -0
  32. data/assets/reveal.js/css/theme/template/mixins.scss +29 -0
  33. data/assets/reveal.js/css/theme/template/settings.scss +33 -0
  34. data/assets/reveal.js/css/theme/template/theme.scss +163 -0
  35. data/assets/reveal.js/js/head.min.js +8 -0
  36. data/assets/reveal.js/js/reveal.js +2577 -0
  37. data/assets/reveal.js/js/reveal.min.js +8 -0
  38. data/assets/reveal.js/lib/css/zenburn.css +115 -0
  39. data/assets/reveal.js/lib/font/league_gothic-webfont.eot +0 -0
  40. data/assets/reveal.js/lib/font/league_gothic-webfont.svg +230 -0
  41. data/assets/reveal.js/lib/font/league_gothic-webfont.ttf +0 -0
  42. data/assets/reveal.js/lib/font/league_gothic-webfont.woff +0 -0
  43. data/assets/reveal.js/lib/font/league_gothic_license +2 -0
  44. data/assets/reveal.js/lib/js/classList.js +2 -0
  45. data/assets/reveal.js/lib/js/head.min.js +8 -0
  46. data/assets/reveal.js/lib/js/html5shiv.js +7 -0
  47. data/assets/reveal.js/plugin/highlight/highlight.js +31 -0
  48. data/assets/reveal.js/plugin/leap/leap.js +154 -0
  49. data/assets/reveal.js/plugin/markdown/example.html +97 -0
  50. data/assets/reveal.js/plugin/markdown/example.md +29 -0
  51. data/assets/reveal.js/plugin/markdown/markdown.js +190 -0
  52. data/assets/reveal.js/plugin/markdown/marked.js +37 -0
  53. data/assets/reveal.js/plugin/multiplex/client.js +13 -0
  54. data/assets/reveal.js/plugin/multiplex/index.js +56 -0
  55. data/assets/reveal.js/plugin/multiplex/master.js +50 -0
  56. data/assets/reveal.js/plugin/notes/notes.html +253 -0
  57. data/assets/reveal.js/plugin/notes/notes.js +100 -0
  58. data/assets/reveal.js/plugin/notes-server/client.js +57 -0
  59. data/assets/reveal.js/plugin/notes-server/index.js +59 -0
  60. data/assets/reveal.js/plugin/notes-server/notes.html +142 -0
  61. data/assets/reveal.js/plugin/postmessage/example.html +39 -0
  62. data/assets/reveal.js/plugin/postmessage/postmessage.js +42 -0
  63. data/assets/reveal.js/plugin/print-pdf/print-pdf.js +44 -0
  64. data/assets/reveal.js/plugin/remotes/remotes.js +39 -0
  65. data/assets/reveal.js/plugin/search/search.js +196 -0
  66. data/assets/reveal.js/plugin/zoom-js/zoom.js +256 -0
  67. data/config/flay.yml +3 -0
  68. data/config/flog.yml +2 -0
  69. data/config/mutant.yml +3 -0
  70. data/config/reek.yml +108 -0
  71. data/config/rubocop.yml +71 -0
  72. data/config/yardstick.yml +2 -0
  73. data/lib/slippery/converter.rb +130 -0
  74. data/lib/slippery/document.rb +20 -0
  75. data/lib/slippery/presentation.rb +36 -0
  76. data/lib/slippery/processor_helpers.rb +43 -0
  77. data/lib/slippery/processors/add_google_font.rb +27 -0
  78. data/lib/slippery/processors/graphviz_dot.rb +46 -0
  79. data/lib/slippery/processors/hr_to_sections.rb +36 -0
  80. data/lib/slippery/processors/impress_js/add_impress_js.rb +30 -0
  81. data/lib/slippery/processors/impress_js/auto_offsets.rb +25 -0
  82. data/lib/slippery/processors/reveal_js/add_reveal_js.rb +78 -0
  83. data/lib/slippery/processors/self_contained.rb +62 -0
  84. data/lib/slippery/version.rb +3 -0
  85. data/lib/slippery.rb +42 -0
  86. data/slippery.gemspec +25 -0
  87. data/spec/fixtures/blockquotes.md +6 -0
  88. data/spec/fixtures/code_blocks.md +9 -0
  89. data/spec/fixtures/definition_lists.md +2 -0
  90. data/spec/fixtures/header_and_paragraph.md +2 -0
  91. data/spec/fixtures/headers.md +13 -0
  92. data/spec/fixtures/ordered_list.md +3 -0
  93. data/spec/fixtures/unordered_list.md +3 -0
  94. data/spec/slippery/converter_spec.rb +67 -0
  95. data/spec/slippery_spec.rb +0 -0
  96. data/spec/spec_helper.rb +20 -0
  97. metadata +208 -0
@@ -0,0 +1,196 @@
1
+ /*
2
+ * Handles finding a text string anywhere in the slides and showing the next occurrence to the user
3
+ * by navigatating to that slide and highlighting it.
4
+ *
5
+ * By Jon Snyder <snyder.jon@gmail.com>, February 2013
6
+ */
7
+
8
+ var RevealSearch = (function() {
9
+
10
+ var matchedSlides;
11
+ var currentMatchedIndex;
12
+ var searchboxDirty;
13
+ var myHilitor;
14
+
15
+ // Original JavaScript code by Chirp Internet: www.chirp.com.au
16
+ // Please acknowledge use of this code by including this header.
17
+ // 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
18
+
19
+ function Hilitor(id, tag)
20
+ {
21
+
22
+ var targetNode = document.getElementById(id) || document.body;
23
+ var hiliteTag = tag || "EM";
24
+ var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM|SPAN)$");
25
+ var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
26
+ var wordColor = [];
27
+ var colorIdx = 0;
28
+ var matchRegex = "";
29
+ var matchingSlides = [];
30
+
31
+ this.setRegex = function(input)
32
+ {
33
+ input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
34
+ matchRegex = new RegExp("(" + input + ")","i");
35
+ }
36
+
37
+ this.getRegex = function()
38
+ {
39
+ return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
40
+ }
41
+
42
+ // recursively apply word highlighting
43
+ this.hiliteWords = function(node)
44
+ {
45
+ if(node == undefined || !node) return;
46
+ if(!matchRegex) return;
47
+ if(skipTags.test(node.nodeName)) return;
48
+
49
+ if(node.hasChildNodes()) {
50
+ for(var i=0; i < node.childNodes.length; i++)
51
+ this.hiliteWords(node.childNodes[i]);
52
+ }
53
+ if(node.nodeType == 3) { // NODE_TEXT
54
+ if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
55
+ //find the slide's section element and save it in our list of matching slides
56
+ var secnode = node.parentNode;
57
+ while (secnode.nodeName != 'SECTION') {
58
+ secnode = secnode.parentNode;
59
+ }
60
+
61
+ var slideIndex = Reveal.getIndices(secnode);
62
+ var slidelen = matchingSlides.length;
63
+ var alreadyAdded = false;
64
+ for (var i=0; i < slidelen; i++) {
65
+ if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
66
+ alreadyAdded = true;
67
+ }
68
+ }
69
+ if (! alreadyAdded) {
70
+ matchingSlides.push(slideIndex);
71
+ }
72
+
73
+ if(!wordColor[regs[0].toLowerCase()]) {
74
+ wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
75
+ }
76
+
77
+ var match = document.createElement(hiliteTag);
78
+ match.appendChild(document.createTextNode(regs[0]));
79
+ match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
80
+ match.style.fontStyle = "inherit";
81
+ match.style.color = "#000";
82
+
83
+ var after = node.splitText(regs.index);
84
+ after.nodeValue = after.nodeValue.substring(regs[0].length);
85
+ node.parentNode.insertBefore(match, after);
86
+ }
87
+ }
88
+ };
89
+
90
+ // remove highlighting
91
+ this.remove = function()
92
+ {
93
+ var arr = document.getElementsByTagName(hiliteTag);
94
+ while(arr.length && (el = arr[0])) {
95
+ el.parentNode.replaceChild(el.firstChild, el);
96
+ }
97
+ };
98
+
99
+ // start highlighting at target node
100
+ this.apply = function(input)
101
+ {
102
+ if(input == undefined || !input) return;
103
+ this.remove();
104
+ this.setRegex(input);
105
+ this.hiliteWords(targetNode);
106
+ return matchingSlides;
107
+ };
108
+
109
+ }
110
+
111
+ function openSearch() {
112
+ //ensure the search term input dialog is visible and has focus:
113
+ var inputbox = document.getElementById("searchinput");
114
+ inputbox.style.display = "inline";
115
+ inputbox.focus();
116
+ inputbox.select();
117
+ }
118
+
119
+ function toggleSearch() {
120
+ var inputbox = document.getElementById("searchinput");
121
+ if (inputbox.style.display !== "inline") {
122
+ openSearch();
123
+ }
124
+ else {
125
+ inputbox.style.display = "none";
126
+ myHilitor.remove();
127
+ }
128
+ }
129
+
130
+ function doSearch() {
131
+ //if there's been a change in the search term, perform a new search:
132
+ if (searchboxDirty) {
133
+ var searchstring = document.getElementById("searchinput").value;
134
+
135
+ //find the keyword amongst the slides
136
+ myHilitor = new Hilitor("slidecontent");
137
+ matchedSlides = myHilitor.apply(searchstring);
138
+ currentMatchedIndex = 0;
139
+ }
140
+
141
+ //navigate to the next slide that has the keyword, wrapping to the first if necessary
142
+ if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
143
+ currentMatchedIndex = 0;
144
+ }
145
+ if (matchedSlides.length > currentMatchedIndex) {
146
+ Reveal.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
147
+ currentMatchedIndex++;
148
+ }
149
+ }
150
+
151
+ var dom = {};
152
+ dom.wrapper = document.querySelector( '.reveal' );
153
+
154
+ if( !dom.wrapper.querySelector( '.searchbox' ) ) {
155
+ var searchElement = document.createElement( 'div' );
156
+ searchElement.id = "searchinputdiv";
157
+ searchElement.classList.add( 'searchdiv' );
158
+ searchElement.style.position = 'absolute';
159
+ searchElement.style.top = '10px';
160
+ searchElement.style.left = '10px';
161
+ //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
162
+ searchElement.innerHTML = '<span><input type="search" id="searchinput" class="searchinput" style="vertical-align: top;"/><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJiSURBVHjatFZNaxNBGH5md+Mmu92NVdKDRipSAyqCghgQD4L4cRe86UUtAQ+eFCxoa4/25EXBFi8eBE+eRPoDhB6KgiiixdAPCEkx2pjvTXadd9yNsflwuyUDD/O+u8PzzDPvzOwyx3EwyCZhwG3gAkp7MnpjgbopjsltcD4gjuXZZKeAR348MYLYTm3LzOs/y3j3JTfZxgXWXmTuwPHIc4VmoOmv5IrI53+AO2DdHLjkDWQ3GoEEVFXtXQOvkSnPWcyUceviLhwbDYv8/XIVj97kse7TodLvZXxYxrPUHkQ1ufXs3FEdybEIxucySOesoNvUgWU1cP3MkCBfTFdw9fGaAMVmRELq7LBw2Q3/FaAxxWIRpw+ZIr/7IouPqzUBiqmdHAv7EuhRAwf1er2Vy4x1jW3b2d5Jfvu5IPp7l2LYbcgCFFNb+FoJ7oBqEAqFMPNqFcmEgVMJDfMT+1tvN0pNjERlMS6QA5pFOKxiKVPFhakPeL3It+WGJUDxt2wFR+JhzI7v5ctkd8DXOZAkCYYxhO+lKm4+Xfqz/rIixBuNBl7eOYzkQQNzqX249mRl6zUgEcYkaJrGhUwBinVdh6IouPzwE6/DL5w4oLkH8y981aDf+uq6hlKpJESiUdNfDZi7/ehG9K6KfiA3pml0PLcsq+cSMTj2NL9ukc4UOmz7AZ3+crkC4mHujFvXNaMFB3bEr8xPS6p5O+jXxq4VZtaen7/PwzrntjcLUE0iHPS1Ud1cdiEJl/8WivZk0wXd7zWOMkeF8s0CcAmkNrC2nvXZDbbbN73ccYnZoH9bfgswAFzAe9/h3dbKAAAAAElFTkSuQmCC" id="searchbutton" class="searchicon" style="vertical-align: top; margin-top: -1px;"/></span>';
163
+ dom.wrapper.appendChild( searchElement );
164
+ }
165
+
166
+ document.getElementById("searchbutton").addEventListener( 'click', function(event) {
167
+ doSearch();
168
+ }, false );
169
+
170
+ document.getElementById("searchinput").addEventListener( 'keyup', function( event ) {
171
+ switch (event.keyCode) {
172
+ case 13:
173
+ event.preventDefault();
174
+ doSearch();
175
+ searchboxDirty = false;
176
+ break;
177
+ default:
178
+ searchboxDirty = true;
179
+ }
180
+ }, false );
181
+
182
+ // Open the search when the 's' key is hit (yes, this conflicts with the notes plugin, disabling for now)
183
+ /*
184
+ document.addEventListener( 'keydown', function( event ) {
185
+ // Disregard the event if the target is editable or a
186
+ // modifier is present
187
+ if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
188
+
189
+ if( event.keyCode === 83 ) {
190
+ event.preventDefault();
191
+ openSearch();
192
+ }
193
+ }, false );
194
+ */
195
+ return { open: openSearch };
196
+ })();
@@ -0,0 +1,256 @@
1
+ // Custom reveal.js integration
2
+ (function(){
3
+ var isEnabled = true;
4
+
5
+ document.querySelector( '.reveal' ).addEventListener( 'mousedown', function( event ) {
6
+ if( event.altKey && isEnabled ) {
7
+ event.preventDefault();
8
+ zoom.to({ element: event.target, pan: false });
9
+ }
10
+ } );
11
+
12
+ Reveal.addEventListener( 'overviewshown', function() { isEnabled = false; } );
13
+ Reveal.addEventListener( 'overviewhidden', function() { isEnabled = true; } );
14
+ })();
15
+
16
+ /*!
17
+ * zoom.js 0.2 (modified version for use with reveal.js)
18
+ * http://lab.hakim.se/zoom-js
19
+ * MIT licensed
20
+ *
21
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
22
+ */
23
+ var zoom = (function(){
24
+
25
+ // The current zoom level (scale)
26
+ var level = 1;
27
+
28
+ // The current mouse position, used for panning
29
+ var mouseX = 0,
30
+ mouseY = 0;
31
+
32
+ // Timeout before pan is activated
33
+ var panEngageTimeout = -1,
34
+ panUpdateInterval = -1;
35
+
36
+ var currentOptions = null;
37
+
38
+ // Check for transform support so that we can fallback otherwise
39
+ var supportsTransforms = 'WebkitTransform' in document.body.style ||
40
+ 'MozTransform' in document.body.style ||
41
+ 'msTransform' in document.body.style ||
42
+ 'OTransform' in document.body.style ||
43
+ 'transform' in document.body.style;
44
+
45
+ if( supportsTransforms ) {
46
+ // The easing that will be applied when we zoom in/out
47
+ document.body.style.transition = 'transform 0.8s ease';
48
+ document.body.style.OTransition = '-o-transform 0.8s ease';
49
+ document.body.style.msTransition = '-ms-transform 0.8s ease';
50
+ document.body.style.MozTransition = '-moz-transform 0.8s ease';
51
+ document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
52
+ }
53
+
54
+ // Zoom out if the user hits escape
55
+ document.addEventListener( 'keyup', function( event ) {
56
+ if( level !== 1 && event.keyCode === 27 ) {
57
+ zoom.out();
58
+ }
59
+ }, false );
60
+
61
+ // Monitor mouse movement for panning
62
+ document.addEventListener( 'mousemove', function( event ) {
63
+ if( level !== 1 ) {
64
+ mouseX = event.clientX;
65
+ mouseY = event.clientY;
66
+ }
67
+ }, false );
68
+
69
+ /**
70
+ * Applies the CSS required to zoom in, prioritizes use of CSS3
71
+ * transforms but falls back on zoom for IE.
72
+ *
73
+ * @param {Number} pageOffsetX
74
+ * @param {Number} pageOffsetY
75
+ * @param {Number} elementOffsetX
76
+ * @param {Number} elementOffsetY
77
+ * @param {Number} scale
78
+ */
79
+ function magnify( pageOffsetX, pageOffsetY, elementOffsetX, elementOffsetY, scale ) {
80
+
81
+ if( supportsTransforms ) {
82
+ var origin = pageOffsetX +'px '+ pageOffsetY +'px',
83
+ transform = 'translate('+ -elementOffsetX +'px,'+ -elementOffsetY +'px) scale('+ scale +')';
84
+
85
+ document.body.style.transformOrigin = origin;
86
+ document.body.style.OTransformOrigin = origin;
87
+ document.body.style.msTransformOrigin = origin;
88
+ document.body.style.MozTransformOrigin = origin;
89
+ document.body.style.WebkitTransformOrigin = origin;
90
+
91
+ document.body.style.transform = transform;
92
+ document.body.style.OTransform = transform;
93
+ document.body.style.msTransform = transform;
94
+ document.body.style.MozTransform = transform;
95
+ document.body.style.WebkitTransform = transform;
96
+ }
97
+ else {
98
+ // Reset all values
99
+ if( scale === 1 ) {
100
+ document.body.style.position = '';
101
+ document.body.style.left = '';
102
+ document.body.style.top = '';
103
+ document.body.style.width = '';
104
+ document.body.style.height = '';
105
+ document.body.style.zoom = '';
106
+ }
107
+ // Apply scale
108
+ else {
109
+ document.body.style.position = 'relative';
110
+ document.body.style.left = ( - ( pageOffsetX + elementOffsetX ) / scale ) + 'px';
111
+ document.body.style.top = ( - ( pageOffsetY + elementOffsetY ) / scale ) + 'px';
112
+ document.body.style.width = ( scale * 100 ) + '%';
113
+ document.body.style.height = ( scale * 100 ) + '%';
114
+ document.body.style.zoom = scale;
115
+ }
116
+ }
117
+
118
+ level = scale;
119
+
120
+ if( level !== 1 && document.documentElement.classList ) {
121
+ document.documentElement.classList.add( 'zoomed' );
122
+ }
123
+ else {
124
+ document.documentElement.classList.remove( 'zoomed' );
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Pan the document when the mosue cursor approaches the edges
130
+ * of the window.
131
+ */
132
+ function pan() {
133
+ var range = 0.12,
134
+ rangeX = window.innerWidth * range,
135
+ rangeY = window.innerHeight * range,
136
+ scrollOffset = getScrollOffset();
137
+
138
+ // Up
139
+ if( mouseY < rangeY ) {
140
+ window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) );
141
+ }
142
+ // Down
143
+ else if( mouseY > window.innerHeight - rangeY ) {
144
+ window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) );
145
+ }
146
+
147
+ // Left
148
+ if( mouseX < rangeX ) {
149
+ window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y );
150
+ }
151
+ // Right
152
+ else if( mouseX > window.innerWidth - rangeX ) {
153
+ window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y );
154
+ }
155
+ }
156
+
157
+ function getScrollOffset() {
158
+ return {
159
+ x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
160
+ y: window.scrollY !== undefined ? window.scrollY : window.pageXYffset
161
+ }
162
+ }
163
+
164
+ return {
165
+ /**
166
+ * Zooms in on either a rectangle or HTML element.
167
+ *
168
+ * @param {Object} options
169
+ * - element: HTML element to zoom in on
170
+ * OR
171
+ * - x/y: coordinates in non-transformed space to zoom in on
172
+ * - width/height: the portion of the screen to zoom in on
173
+ * - scale: can be used instead of width/height to explicitly set scale
174
+ */
175
+ to: function( options ) {
176
+ // Due to an implementation limitation we can't zoom in
177
+ // to another element without zooming out first
178
+ if( level !== 1 ) {
179
+ zoom.out();
180
+ }
181
+ else {
182
+ options.x = options.x || 0;
183
+ options.y = options.y || 0;
184
+
185
+ // If an element is set, that takes precedence
186
+ if( !!options.element ) {
187
+ // Space around the zoomed in element to leave on screen
188
+ var padding = 20;
189
+
190
+ options.width = options.element.getBoundingClientRect().width + ( padding * 2 );
191
+ options.height = options.element.getBoundingClientRect().height + ( padding * 2 );
192
+ options.x = options.element.getBoundingClientRect().left - padding;
193
+ options.y = options.element.getBoundingClientRect().top - padding;
194
+ }
195
+
196
+ // If width/height values are set, calculate scale from those values
197
+ if( options.width !== undefined && options.height !== undefined ) {
198
+ options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 );
199
+ }
200
+
201
+ if( options.scale > 1 ) {
202
+ options.x *= options.scale;
203
+ options.y *= options.scale;
204
+
205
+ var scrollOffset = getScrollOffset();
206
+
207
+ if( options.element ) {
208
+ scrollOffset.x -= ( window.innerWidth - ( options.width * options.scale ) ) / 2;
209
+ }
210
+
211
+ magnify( scrollOffset.x, scrollOffset.y, options.x, options.y, options.scale );
212
+
213
+ if( options.pan !== false ) {
214
+
215
+ // Wait with engaging panning as it may conflict with the
216
+ // zoom transition
217
+ panEngageTimeout = setTimeout( function() {
218
+ panUpdateInterval = setInterval( pan, 1000 / 60 );
219
+ }, 800 );
220
+
221
+ }
222
+ }
223
+
224
+ currentOptions = options;
225
+ }
226
+ },
227
+
228
+ /**
229
+ * Resets the document zoom state to its default.
230
+ */
231
+ out: function() {
232
+ clearTimeout( panEngageTimeout );
233
+ clearInterval( panUpdateInterval );
234
+
235
+ var scrollOffset = getScrollOffset();
236
+
237
+ if( currentOptions && currentOptions.element ) {
238
+ scrollOffset.x -= ( window.innerWidth - ( currentOptions.width * currentOptions.scale ) ) / 2;
239
+ }
240
+
241
+ magnify( scrollOffset.x, scrollOffset.y, 0, 0, 1 );
242
+
243
+ level = 1;
244
+ },
245
+
246
+ // Alias
247
+ magnify: function( options ) { this.to( options ) },
248
+ reset: function() { this.out() },
249
+
250
+ zoomLevel: function() {
251
+ return level;
252
+ }
253
+ }
254
+
255
+ })();
256
+
data/config/flay.yml ADDED
@@ -0,0 +1,3 @@
1
+ ---
2
+ threshold: 3
3
+ total_score: 13
data/config/flog.yml ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ threshold: 11.0
data/config/mutant.yml ADDED
@@ -0,0 +1,3 @@
1
+ name: devtools
2
+ namespace: Devtools
3
+ strategy: --rspec-dm2
data/config/reek.yml ADDED
@@ -0,0 +1,108 @@
1
+ ---
2
+ Attribute:
3
+ enabled: false
4
+ exclude:
5
+ - Devtools::Config
6
+ - Devtools::Project
7
+ BooleanParameter:
8
+ enabled: true
9
+ exclude: []
10
+ ClassVariable:
11
+ enabled: true
12
+ exclude: []
13
+ ControlParameter:
14
+ enabled: true
15
+ exclude: []
16
+ DataClump:
17
+ enabled: true
18
+ exclude: []
19
+ max_copies: 0
20
+ min_clump_size: 1
21
+ DuplicateMethodCall:
22
+ enabled: true
23
+ exclude:
24
+ - Devtools::Project#self.timeout_unit_tests
25
+ max_calls: 1
26
+ allow_calls: []
27
+ FeatureEnvy:
28
+ enabled: true
29
+ exclude: []
30
+ IrresponsibleModule:
31
+ enabled: true
32
+ exclude: []
33
+ LongParameterList:
34
+ enabled: true
35
+ exclude:
36
+ - Devtools::Config#self.attribute
37
+ - Devtools::Project#self.assert_within_timeout
38
+ - Devtools::Project#self.setup_rspec
39
+ max_params: 1
40
+ overrides: {}
41
+ LongYieldList:
42
+ enabled: true
43
+ exclude: []
44
+ max_params: 0
45
+ NestedIterators:
46
+ enabled: true
47
+ exclude:
48
+ - Devtools::Project#self.timeout_unit_tests
49
+ max_allowed_nesting: 1
50
+ ignore_iterators: []
51
+ NilCheck:
52
+ enabled: true
53
+ exclude: []
54
+ RepeatedConditional:
55
+ enabled: true
56
+ exclude: []
57
+ max_ifs: 1
58
+ TooManyInstanceVariables:
59
+ enabled: true
60
+ exclude: []
61
+ max_instance_variables: 13 # no adamantium ;)
62
+ TooManyMethods:
63
+ enabled: true
64
+ exclude: []
65
+ max_methods: 15
66
+ TooManyStatements:
67
+ enabled: true
68
+ exclude:
69
+ - Devtools::Project#self.setup_rspec
70
+ max_statements: 5
71
+ UncommunicativeMethodName:
72
+ enabled: true
73
+ exclude: []
74
+ reject:
75
+ - !ruby/regexp /^[a-z]$/
76
+ - !ruby/regexp /[0-9]$/
77
+ - !ruby/regexp /[A-Z]/
78
+ accept: []
79
+ UncommunicativeModuleName:
80
+ enabled: true
81
+ exclude: []
82
+ reject:
83
+ - !ruby/regexp /^.$/
84
+ - !ruby/regexp /[0-9]$/
85
+ accept: []
86
+ UncommunicativeParameterName:
87
+ enabled: true
88
+ exclude: []
89
+ reject:
90
+ - !ruby/regexp /^.$/
91
+ - !ruby/regexp /[0-9]$/
92
+ - !ruby/regexp /[A-Z]/
93
+ accept: []
94
+ UncommunicativeVariableName:
95
+ enabled: true
96
+ exclude: []
97
+ reject:
98
+ - !ruby/regexp /^.$/
99
+ - !ruby/regexp /[0-9]$/
100
+ - !ruby/regexp /[A-Z]/
101
+ accept: []
102
+ UnusedParameters:
103
+ enabled: true
104
+ exclude: []
105
+ UtilityFunction:
106
+ enabled: true
107
+ exclude: []
108
+ max_helper_calls: 0
@@ -0,0 +1,71 @@
1
+ AllCops:
2
+ Includes:
3
+ - '**/*.rake'
4
+ - 'Gemfile'
5
+ - 'Gemfile.devtools'
6
+ Excludes:
7
+ - '**/vendor/**'
8
+
9
+ # Avoid parameter lists longer than five parameters.
10
+ ParameterLists:
11
+ Max: 3
12
+ CountKeywordArgs: true
13
+
14
+ # Avoid more than `Max` levels of nesting.
15
+ BlockNesting:
16
+ Max: 3
17
+
18
+ # Align with the style guide.
19
+ CollectionMethods:
20
+ PreferredMethods:
21
+ collect: 'map'
22
+ inject: 'reduce'
23
+ find: 'detect'
24
+ find_all: 'select'
25
+
26
+ # Do not force public/protected/private keyword to be indented at the same
27
+ # level as the def keyword. My personal preference is to outdent these keywords
28
+ # because I think when scanning code it makes it easier to identify the
29
+ # sections of code and visually separate them. When the keyword is at the same
30
+ # level I think it sort of blends in with the def keywords and makes it harder
31
+ # to scan the code and see where the sections are.
32
+ AccessControl:
33
+ Enabled: false
34
+
35
+ LineLength:
36
+ Enabled: true
37
+ Max: 80
38
+
39
+ # Avoid methods longer than 30 lines of code
40
+ MethodLength:
41
+ Max: 3
42
+
43
+ # Rubocop doesn't allow fine grained per method/class disabling of checks.
44
+ # so I'm disabling all the ones that disagree with me *somewhere*
45
+
46
+ # I mostly agree with this cop, except that { |arg| ... } looks very wrong to
47
+ # me. I prefer {|arg| ... } in that case .
48
+ SpaceAroundBraces:
49
+ Enabled: false
50
+
51
+ # Align the parameters of a method call if they span more than one line.
52
+ AlignParameters:
53
+ Enabled: false
54
+
55
+ # Checks for uses of Module#attr.
56
+ #
57
+ # This is also triggered by instance methods named attr
58
+ Attr:
59
+ Enabled: false
60
+
61
+ # Document classes and non-namespace modules.
62
+ #
63
+ # The Slippery module is repeated many times, but only documented in slippery.rb
64
+ Documentation:
65
+ Enabled: false
66
+
67
+ # The use of eval represents a serious security risk.
68
+ #
69
+ # Eval is used in the Gemfile to load Devtools
70
+ Eval:
71
+ Enabled: false
@@ -0,0 +1,2 @@
1
+ ---
2
+ threshold: 86.3