1/*! 2 * Nas 3 * Project Website: http://nas.pimmey.com 4 * @version 1.0 5 * @author Yegor Borisenco <[email protected]> 6 */ 7 8'use strict'; 9 10var App = {}; 11 12App = { 13 /* 14 * Injecting the data from config.js 15 * */ 16 CONFIG: CONFIG === 'undefined' ? console.error('Missing config file') : CONFIG, 17 18 /* 19 * Global variables used throughout the app 20 * */ 21 GLOBAL: { 22 activeToasts: 0, 23 $pace: $('.pace'), 24 progress: { 25 show: function show () { 26 App.GLOBAL.$pace.show().css('visibility', 'visible'); 27 }, 28 hide: function hide () { 29 App.GLOBAL.$pace.hide().css('visibility', 'hidden'); 30 } 31 }, 32 isTouch: function isTouch () { 33 return (('ontouchstart' in window) || (navigator.MaxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)); 34 }, 35 $nav: $('nav') 36 }, 37 38 /* 39 * Initialising Google Maps 40 * More information: https://developers.google.com/maps/documentation/javascript/ 41 * */ 42 initMap: function initMap () { 43 var map = new google.maps.Map(document.getElementById('map'), { 44 center: { 45 lat: App.CONFIG.map.lat, 46 lng: App.CONFIG.map.lng 47 }, 48 zoom: 14, 49 disableDefaultUI: true, 50 styles: App.CONFIG.map.styles 51 }); 52 53 var marker = new google.maps.Marker({ 54 position: { 55 lat: App.CONFIG.map.lat, 56 lng: App.CONFIG.map.lng 57 }, 58 map: map, 59 icon: App.CONFIG.map.markerIcon, 60 title: 'Nas' 61 }); 62 }, 63 64 /* 65 * Loader handling 66 * */ 67 onLoad: function onLoad () { 68 window.onload = function () { 69 $('#loading-overlay').fadeOut(); 70 App.GLOBAL.progress.hide(); 71 }; 72 }, 73 74 /* 75 Contact form handling 76 @param String suffix helps differentiate between human and classic form modes 77 Constricted to human and classic 78 */ 79 initContactForm: function initContactForm () { 80 var $name = $('#name'); 81 var $email = $('#email'); 82 var $message = $('#message'); 83 var $sendButton = $('#send-message'); 84 var initialMessage = $message.html(); 85 86 $sendButton.on('click', function (e) { 87 e.preventDefault(); 88 App._sendMessage($name, $email, $message, initialMessage, $sendButton); 89 }); 90 }, 91 92 /* 93 A private function that sends the message, once everything is cool 94 @param Obj $name the object that contains name value 95 Obj $email the object that contains contact value 96 Obj $message the object that contains message value 97 String initialMessage initial message value 98 Obj $sendButton the button that submits the form 99 */ 100 _sendMessage: function _sendMessage ($name, $email, $message, initialMessage, $sendButton) { 101 // Creating the conditions of the form's validity 102 var isNameValid = App._verifyField($name, App.CONFIG.toastMessages.nameMissing); 103 var isEmailValid = App._verifyField($email, App.CONFIG.toastMessages.contactMissing); 104 var isMessageValid = App._verifyField($message, App.CONFIG.toastMessages.messageMissing, initialMessage); 105 106 if (isNameValid && isEmailValid && isMessageValid) { 107 App.GLOBAL.progress.show(); 108 109 // Disabling the button while we're waiting for the response 110 $sendButton.attr('disabled', true); 111 $.ajax({ 112 url: '/mailer/mailer.php', 113 type: 'POST', 114 data: { 115 name: $name.html() || $name.val(), 116 email: $email.html() || $email.val(), 117 message: $message.html() || $message.val() 118 } 119 }).done(function (res) { 120 // res should return 1, if PHPMailer has done its job right 121 if (res === '200') { 122 Materialize.toast(App.CONFIG.toastMessages.messageSent, App.CONFIG.toastSpeed, 'success'); 123 124 // Resetting the form 125 $name.html('') && $name.val(''); 126 $email.html('') && $email.val(''); 127 $message.html(initialMessage) && $message.val(initialMessage); 128 129 // Removing active class from label 130 $name.next().removeClass('active'); 131 $email.next().removeClass('active'); 132 $message.next().removeClass('active'); 133 } else { 134 Materialize.toast(App.CONFIG.toastMessages.somethingWrong + res, App.CONFIG.toastSpeed, 'error'); 135 } 136 }).error(function (error) { 137 console.error(error); 138 Materialize.toast(App.CONFIG.toastMessages.somethingWrong + error, App.CONFIG.toastSpeed, 'error'); 139 }).complete(function () { 140 App.GLOBAL.progress.hide(); 141 142 // Re-enabling the button on request complete 143 $sendButton.attr('disabled', false); 144 }); 145 } 146 }, 147 148 /* 149 A private function that handles field verifying 150 @param Obj $field the object that contains selected field 151 String errorMessage error message relevant to the selected field 152 String initialMessage initial message value 153 */ 154 _verifyField: function _verifyField ($field, errorMessage, initialMessage) { 155 var fieldValue = $field.html() || $field.val(); 156 var isFieldInvalid; 157 var isFieldLengthInvalid = fieldValue.length === 0; 158 159 if (initialMessage !== 'undefined') { 160 isFieldInvalid = isFieldLengthInvalid || (fieldValue === initialMessage); 161 } else { 162 isFieldInvalid = isFieldLengthInvalid; 163 } 164 165 if ($field.attr('type') === 'email' && ! /.+\@.+\..+/.test(fieldValue)) { 166 Materialize.toast(App.CONFIG.toastMessages.enterValidEmail, App.CONFIG.toastSpeed, 'error', function () { 167 App.GLOBAL.activeToasts--; 168 }); 169 App.GLOBAL.activeToasts++; 170 return false;
171 } 172 173 if (isFieldInvalid) { 174 Materialize.toast(errorMessage, App.CONFIG.toastSpeed, 'error', function () { 175 App.GLOBAL.activeToasts--; 176 }); 177 App.GLOBAL.activeToasts++; 178 return false; 179 } else { 180 return true; 181 } 182 }, 183 184 /* 185 * A function that handles stories hovers 186 * */ 187 initPostsHovers: function initPostHovers () { 188 if ( ! this.GLOBAL.isTouch()) { 189 var $postLinks = $('.posts a'); 190 var $postCoverImages = $('.posts-covers > div'); 191 var $navbar = $('.navbar-fixed'); 192 193 $(document).on('mouseenter', '.posts a', function () { 194 var slug = $(this).data('slug'); 195 $navbar.css('z-index', 0); 196 $postLinks.addClass('opacity'); 197 $postCoverImages.removeClass('active zoom'); 198 $('.' + slug).addClass('active'); 199 setTimeout(function () { 200 $('.' + slug).addClass('zoom'); 201 }, 1); 202 }).on('mouseleave', '.posts a', function () { 203 $navbar.css('z-index', ''); 204 $postLinks.removeClass('opacity'); 205 $postCoverImages.removeClass('active'); 206 }); 207 } 208 }, 209 210 211 /* 212 * Handling nav color scheme, depending on scroll position 213 * */ 214 initNavColorChange: function initNavColorChange () { 215 var $trianglesHeight = $('#triangles').height() || 720; 216 $(document).on('scroll ready', function () { 217 App._switchNavColorSchemes($trianglesHeight); 218 }); 219 }, 220 221 /* 222 * A private function that toggles .dark class for nav element 223 * */ 224 _switchNavColorSchemes: function _switchNavColorSchemes ($trianglesHeight) { 225 if ($(window).scrollTop() > $trianglesHeight) { 226 App.GLOBAL.$nav.addClass('dark'); 227 } else { 228 App.GLOBAL.$nav.removeClass('dark'); 229 } 230 }, 231 232 /* 233 * Initialising parallax 234 * http://materializecss.com/parallax.html 235 * */ 236 initParallax: function initParallax () { 237 $('.parallax').parallax(); 238 }, 239 240 /* 241 * Initialising slider 242 * http://materializecss.com/media.html#slider 243 * */ 244 initSlider: function initSlider () { 245 $('.slider').slider({ 246 full_width: true, 247 height: 720 248 }); 249 }, 250 251 /* 252 * Handling modals behaviour 253 * http://materializecss.com/modals.html 254 * */ 255 initModal: function initModal () { 256 if (window.location.hash.length > 0 && window.location.hash !== '#!') { 257 $(window.location.hash).openModal({ 258 complete: function () { 259 history.replaceState('', document.title, window.location.pathname); 260 } 261 }); 262 } 263 264 $('.modal-trigger').leanModal({ 265 opacity: .5, 266 ready: function () { 267 268 }, 269 complete: function () { 270 history.replaceState('', document.title, window.location.pathname); 271 } 272 }).on('click', function () { 273 var href = $(this).attr('href'); 274 setTimeout(function () { 275 window.location.hash = href; 276 }, 400); 277 }); 278 }, 279 280 /* 281 * A function that handles modal navigation 282 * */ 283 initModalNav: function initModalNav () { 284 var $links = $('.modal-nav'); 285 286 $links.on('click', function (e) { 287 e.preventDefault(); 288 289 var $this = $(this); 290 var current = window.location.hash; 291 var next = $this.data('next-modal'); 292 var prev = $this.data('previous-modal'); 293 294 $(current).closeModal(); 295 296 if (typeof prev !== 'undefined') { 297 $('#' + prev).openModal({ 298 ready: function () { 299 $('.modal').scrollTop(0); 300 window.location.hash = prev; 301 }, 302 complete: function () { 303 history.replaceState('', document.title, window.location.pathname); 304 } 305 }); 306 } 307 308 if (typeof next !== 'undefined') {
309 $('#' + next).openModal({ 310 ready: function () { 311 $('.modal').scrollTop(0); 312 window.location.hash = next; 313 }, 314 complete: function () { 315 history.replaceState('', document.title, window.location.pathname); 316 } 317 }); 318 } 319 }); 320 }, 321 322 /* 323 * Textillate effect on hover of .block elements 324 * */ 325 initTextillate: function initTextillate () { 326 var $tlt = $('.tlt'); 327 328 if ($tlt) { 329 $tlt.textillate({ 330 loop: false, 331 minDisplayTime: 0, 332 initialDelay: 0, 333 autoStart: false, 334 'in': { 335 effect: 'fadeIn', 336 delay: 15 337 }, 338 out: { 339 effect: 'fadeOut', 340 delay: 15 341 } 342 }); 343 344 $('.block').on({ 345 'mouseenter': function () { 346 $(this).find('.tlt').textillate('in'); 347 }, 348 'mouseleave': function () { 349 $(this).find('.tlt').textillate('out'); 350 } 351 }); 352 } 353 } 354}; 355 356$(document).on('ready', function () { 357 App.onLoad(); 358 App.initPostsHovers(); 359 App.initNavColorChange(); 360});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.