Conditions | 1 |
Paths | 32 |
Total Lines | 244 |
Lines | 0 |
Ratio | 0 % |
Changes | 1 | ||
Bugs | 0 | Features | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | /*! |
||
9 | (function () { |
||
|
|||
10 | |||
11 | // Global variables, accessible to Slimbox only |
||
12 | var state = 0, options, images, activeImage, prevImage, nextImage, top, fx, preload, preloadPrev = new Image(), preloadNext = new Image(), |
||
13 | // State values: 0 (closed or closing), 1 (open and ready), 2+ (open and busy with animation) |
||
14 | |||
15 | // DOM elements |
||
16 | overlay, center, image, prevLink, nextLink, bottomContainer, bottom, caption, number; |
||
17 | |||
18 | /* |
||
19 | Initialization |
||
20 | */ |
||
21 | |||
22 | window.addEvent("domready", function () { |
||
23 | // Append the Slimbox HTML code at the bottom of the document |
||
24 | $(document.body).adopt( |
||
25 | $$([ |
||
26 | overlay = new Element("div", {id: "lbOverlay"}).addEvent("click", close), |
||
27 | center = new Element("div", {id: "lbCenter"}), |
||
28 | bottomContainer = new Element("div", {id: "lbBottomContainer"}) |
||
29 | ]).setStyle("display", "none") |
||
30 | ); |
||
31 | |||
32 | image = new Element("div", {id: "lbImage"}).injectInside(center).adopt( |
||
33 | prevLink = new Element("a", {id: "lbPrevLink", href: "#"}).addEvent("click", previous), |
||
34 | nextLink = new Element("a", {id: "lbNextLink", href: "#"}).addEvent("click", next) |
||
35 | ); |
||
36 | |||
37 | bottom = new Element("div", {id: "lbBottom"}).injectInside(bottomContainer).adopt( |
||
38 | new Element("a", {id: "lbCloseLink", href: "#"}).addEvent("click", close), |
||
39 | caption = new Element("div", {id: "lbCaption"}), |
||
40 | number = new Element("div", {id: "lbNumber"}), |
||
41 | new Element("div", {styles: {clear: "both"}}) |
||
42 | ); |
||
43 | |||
44 | fx = { |
||
45 | overlay: new Fx.Tween(overlay, {property: "opacity", duration: 500}).set(0), |
||
46 | image: new Fx.Tween(image, {property: "opacity", duration: 500, onComplete: nextEffect}), |
||
47 | bottom: new Fx.Tween(bottom, {property: "margin-top", duration: 400}) |
||
48 | }; |
||
49 | }); |
||
50 | |||
51 | |||
52 | /* |
||
53 | API |
||
54 | */ |
||
55 | |||
56 | Slimbox = { |
||
57 | open: function (_images, startImage, _options) { |
||
58 | options = $extend({ |
||
59 | loop: false, // Allows to navigate between first and last images |
||
60 | overlayOpacity: 0.8, // 1 is opaque, 0 is completely transparent (change the color in the CSS file) |
||
61 | resizeDuration: 400, // Duration of each of the box resize animations (in milliseconds) |
||
62 | resizeTransition: false, // Default transition in mootools |
||
63 | initialWidth: 250, // Initial width of the box (in pixels) |
||
64 | initialHeight: 250, // Initial height of the box (in pixels) |
||
65 | animateCaption: true, |
||
66 | showCounter: true, // If true, a counter will only be shown if there is more than 1 image to display |
||
67 | counterText: "Image {x} of {y}" // Translate or change as you wish |
||
68 | }, _options || {}); |
||
69 | |||
70 | // The function is called for a single image, with URL and Title as first two arguments |
||
71 | if (typeof _images == "string") { |
||
72 | _images = [[_images, startImage]]; |
||
73 | startImage = 0; |
||
74 | } |
||
75 | |||
76 | images = _images; |
||
77 | options.loop = options.loop && (images.length > 1); |
||
78 | position(); |
||
79 | setup(true); |
||
80 | top = window.getScrollTop() + (window.getHeight() / 15); |
||
81 | fx.resize = new Fx.Morph(center, $extend({duration: options.resizeDuration, onComplete: nextEffect}, options.resizeTransition ? {transition: options.resizeTransition} : {})); |
||
82 | center.setStyles({top: top, width: options.initialWidth, height: options.initialHeight, marginLeft: -(options.initialWidth / 2), display: ""}); |
||
83 | fx.overlay.start(options.overlayOpacity); |
||
84 | state = 1; |
||
85 | return changeImage(startImage); |
||
86 | } |
||
87 | }; |
||
88 | |||
89 | Element.implement({ |
||
90 | slimbox: function (_options, linkMapper) { |
||
91 | // The processing of a single element is similar to the processing of a collection with a single element |
||
92 | $$(this).slimbox(_options, linkMapper); |
||
93 | |||
94 | return this; |
||
95 | } |
||
96 | }); |
||
97 | |||
98 | Elements.implement({ |
||
99 | /* |
||
100 | options: Optional options object, see Slimbox.open() |
||
101 | linkMapper: Optional function taking a link DOM element and an index as arguments and returning an array containing 2 elements: |
||
102 | the image URL and the image caption (may contain HTML) |
||
103 | linksFilter: Optional function taking a link DOM element and an index as arguments and returning true if the element is part of |
||
104 | the image collection that will be shown on click, false if not. "this" refers to the element that was clicked. |
||
105 | This function must always return true when the DOM element argument is "this". |
||
106 | */ |
||
107 | slimbox: function (_options, linkMapper, linksFilter) { |
||
108 | linkMapper = linkMapper || function (el) { |
||
109 | return [el.href, el.title]; |
||
110 | }; |
||
111 | |||
112 | linksFilter = linksFilter || function () { |
||
113 | return true; |
||
114 | }; |
||
115 | |||
116 | var links = this; |
||
117 | |||
118 | links.removeEvents("click").addEvent("click", function () { |
||
119 | // Build the list of images that will be displayed |
||
120 | var filteredLinks = links.filter(linksFilter, this); |
||
121 | return Slimbox.open(filteredLinks.map(linkMapper), filteredLinks.indexOf(this), _options); |
||
122 | }); |
||
123 | |||
124 | return links; |
||
125 | } |
||
126 | }); |
||
127 | |||
128 | |||
129 | /* |
||
130 | Internal functions |
||
131 | */ |
||
132 | |||
133 | function position() { |
||
134 | overlay.setStyles({top: window.getScrollTop(), height: window.getHeight()}); |
||
135 | } |
||
136 | |||
137 | function setup(open) { |
||
138 | ["object", Browser.Engine.trident ? "select" : "embed"].forEach(function (tag) { |
||
139 | Array.forEach(document.getElementsByTagName(tag), function (el) { |
||
140 | if (open) el._slimbox = el.style.visibility; |
||
141 | el.style.visibility = open ? "hidden" : el._slimbox; |
||
142 | }); |
||
143 | }); |
||
144 | |||
145 | overlay.style.display = open ? "" : "none"; |
||
146 | |||
147 | var fn = open ? "addEvent" : "removeEvent"; |
||
148 | window[fn]("scroll", position)[fn]("resize", position); |
||
149 | document[fn]("keydown", keyDown); |
||
150 | } |
||
151 | |||
152 | function keyDown(event) { |
||
153 | switch (event.code) { |
||
154 | case 27: // Esc |
||
155 | case 88: // 'x' |
||
156 | case 67: // 'c' |
||
157 | close(); |
||
158 | break; |
||
159 | case 37: // Left arrow |
||
160 | case 80: // 'p' |
||
161 | previous(); |
||
162 | break; |
||
163 | case 39: // Right arrow |
||
164 | case 78: // 'n' |
||
165 | next(); |
||
166 | } |
||
167 | // Prevent default keyboard action (like navigating inside the page) |
||
168 | return false; |
||
169 | } |
||
170 | |||
171 | function previous() { |
||
172 | return changeImage(prevImage); |
||
173 | } |
||
174 | |||
175 | function next() { |
||
176 | return changeImage(nextImage); |
||
177 | } |
||
178 | |||
179 | function changeImage(imageIndex) { |
||
180 | if ((state == 1) && (imageIndex >= 0)) { |
||
181 | state = 2; |
||
182 | activeImage = imageIndex; |
||
183 | prevImage = ((activeImage || !options.loop) ? activeImage : images.length) - 1; |
||
184 | nextImage = activeImage + 1; |
||
185 | if (nextImage == images.length) nextImage = options.loop ? 0 : -1; |
||
186 | |||
187 | $$(prevLink, nextLink, image, bottomContainer).setStyle("display", "none"); |
||
188 | fx.bottom.cancel().set(0); |
||
189 | fx.image.set(0); |
||
190 | center.className = "lbLoading"; |
||
191 | |||
192 | preload = new Image(); |
||
193 | preload.onload = nextEffect; |
||
194 | preload.src = images[imageIndex][0]; |
||
195 | } |
||
196 | |||
197 | return false; |
||
198 | } |
||
199 | |||
200 | function nextEffect() { |
||
201 | switch (state++) { |
||
202 | case 2: |
||
203 | center.className = ""; |
||
204 | image.setStyles({backgroundImage: "url(" + images[activeImage][0] + ")", display: ""}); |
||
205 | $$(image, bottom).setStyle("width", preload.width); |
||
206 | $$(image, prevLink, nextLink).setStyle("height", preload.height); |
||
207 | |||
208 | caption.set('html', images[activeImage][1] || ""); |
||
209 | number.set('html', (options.showCounter && (images.length > 1)) ? options.counterText.replace(/{x}/, activeImage + 1).replace(/{y}/, images.length) : ""); |
||
210 | |||
211 | if (prevImage >= 0) preloadPrev.src = images[prevImage][0]; |
||
212 | if (nextImage >= 0) preloadNext.src = images[nextImage][0]; |
||
213 | |||
214 | if (center.clientHeight != image.offsetHeight) { |
||
215 | fx.resize.start({height: image.offsetHeight}); |
||
216 | break; |
||
217 | } |
||
218 | state++; |
||
219 | case 3: |
||
220 | if (center.clientWidth != image.offsetWidth) { |
||
221 | fx.resize.start({width: image.offsetWidth, marginLeft: -image.offsetWidth / 2}); |
||
222 | break; |
||
223 | } |
||
224 | state++; |
||
225 | case 4: |
||
226 | bottomContainer.setStyles({top: top + center.clientHeight, marginLeft: center.style.marginLeft, visibility: "hidden", display: ""}); |
||
227 | fx.image.start(1); |
||
228 | break; |
||
229 | case 5: |
||
230 | if (prevImage >= 0) prevLink.style.display = ""; |
||
231 | if (nextImage >= 0) nextLink.style.display = ""; |
||
232 | if (options.animateCaption) { |
||
233 | fx.bottom.set(-bottom.offsetHeight).start(0); |
||
234 | } |
||
235 | bottomContainer.style.visibility = ""; |
||
236 | state = 1; |
||
237 | } |
||
238 | } |
||
239 | |||
240 | function close() { |
||
241 | if (state) { |
||
242 | state = 0; |
||
243 | preload.onload = $empty; |
||
244 | for (var f in fx) fx[f].cancel(); |
||
245 | $$(center, bottomContainer).setStyle("display", "none"); |
||
246 | fx.overlay.chain(setup).start(0); |
||
247 | } |
||
248 | |||
249 | return false; |
||
250 | } |
||
251 | |||
252 | })(); |
||
253 |