function ga_event(category, action, label, value) { if (typeof ga !== 'function') { console.warn('Could not track event (ga not defined): ' + category + ',' + action + ', ' + label + ', ' + value); return false; } try { ga('send', 'event', category, action, label, value); } catch (e) { console.warn('Could not track event: ' + e.message); return false; } return true; } window.onerror = function (msg, url, line, col) { if (typeof msg === 'object' && msg.originalEvent && !(url || line || col)) { line = msg.originalEvent.lineno; col = msg.originalEvent.colno; url = msg.originalEvent.filename; msg = msg.originalEvent.message; } if (!url && !line && !col) return false; if (url && !url.match(/^https?:\/\/([^\.\/]+\.)?sendspace\.com/)) return false; if (msg.match(/dealply/i)) return false; if (!url) url = '[h]' + location.href; ga_event('Error', 'JavaScript', url + ':' + line + ':' + (col ? col : '?') + ' - ' + msg); return false; }; var sendspace; // Fake console in case it's not available for the current browser if (typeof (console) === 'undefined') { var functionNames = ['info', 'error', 'warn', 'dir', 'trace', 'log', 'assert']; console = {}; for (var i = 0; i < functionNames.length; i++) { console[functionNames[i]] = function () { } } } function ga_pageView(page) { if (typeof ga !== 'function') { console.warn('Could not track page view (ga not defined): ' + page); return false; } try { ga('send', 'pageview', page); } catch (e) { console.warn('Could not track page view: ' + e.message); return false; } return true; } function toggle_parent_sons(a) { $(a).parent().parent().find("div").each(function () { $(this).toggle(); }); } function in_array(value, array) { for (var i in array) { if (array[i] == value) return true; } return false; } function remove_from_array(value, array) { var new_array = Array(); for (var i in array) { if (array[i] != value) { new_array.push(array[i]); } } return new_array; } function ss_ajax(method, path, data) { if (!data) data = {}; data.is_ajax = 1; // Wrap ajax call to handle response as generated // by ajax_response() in misc.inc.php var deferred = $.Deferred(); $.ajax({ dataType: 'json', type: method, url: path, data: data }) .done(function (result) { if (result.success) { deferred.resolve(result.data); } else { deferred.reject(result.error, result.data); } }) .fail(function (xhr) { // We don't know what we got back so don't send // back the responseText (as that could be a // complete HTML page and not an error message). console.warn(xhr.responseText); deferred.reject('Server error'); }); return deferred.promise(); } function ss_show_message_box(type, message) { // error, warning, information, success if (type == 'warn') type = 'warning'; if (type == 'info') type = 'information'; var $container = $('#ajax-message-container'); if (!$container.length) { console.warn('Ajax message container missing'); return; } var html = '
' + message + '
'; $container.html(html); } function ss_hide_message_box() { var $container = $('#ajax-message-container'); if (!$container.length) { console.warn('Ajax message container missing'); return; } $container.empty(); } var sendspaceClass = function () { var self = this; var is_ie7 = navigator.userAgent.match(/MSIE 7/); this.init = function () { self.assign_page_events(); }; this.assign_page_events = function () { // input focus event $("input:not(.noautosel)").focus(function () { this.select(); }); // login frame event var $login_frame = $("#login_frame"); $("a.login").click(function (e) { var rel = $(this).attr("rel"); if (rel === "open") { /* if ($.browser.msie) $login_frame.show(); else $login_frame.fadeIn("normal"); */ $login_frame.show(); $("#top_login_username").focus(); if ($('#mobile_upload_page').length) $('#login_frame ul.options li a').show(); self.overlay.show(); return false; } self.overlay.hide(); return false; }); this.overlay = new function () { var self = this; var $glass = $("#glass"); this.show = function () { if (!is_ie7) $glass.show(); }; this.hide = function () { if ($.browser.msie) $("div.overlay").hide(); else $("div.overlay").fadeOut("fast"); if (!is_ie7) $glass.hide(); if ($('.openid-popup').length) $('.openid-popup').hide(); }; $glass.click(function () { self.hide(); }); } // link copy event $("a.copy.selectable").click(function () { var $link = $("") .addClass("file_url") .attr({"type": "text", "readonly": "readonly"}) .val($("a.link").text()); $("a.link.selectable").replaceWith($link); self.assign_page_events(); $link.focus().select(); }); }; // Define uploader UI if ($("#progress_bar").length > 0) { this.progress = new function () { //focus var $progress = $("#progress_bar"); var w = $progress.find(".bar").width(); var $stats = $progress.find(".stats"); var backupTitle = ''; //parent.document.title; this.restoreTitle = function () { parent.document.title = backupTitle; }; this.update = function (params) { this.move(params[0]); this.stats(params); }; this.last_pos = 0; this.move = function (to) { try { to = parseInt(to, 10); if (to <= this.last_pos) return; this.last_pos = to; var to_bar = to >= 100 ? 99 : to; $progress .find(".fill") .css('width', to_bar + "%"); var w = $("#progress_bar").find(".bar").width(); var val = parseInt(w * to_bar / 100, 10); if (val > 0) { $progress .find(".tag") .text(to_bar + "%") .css('left', (val - 19) + "px"); } parent.document.title = 'Upload ' + to_bar + '% done'; } catch (e) { } }; this.stats = function (params) { try { $stats.find(".time_left").text(params[1]); $stats.find(".elapsed span").text(params[2]); $stats.find(".data").text(params[3]); $stats.find(".total").text(params[4]); //$stats.find(".kbps").text(((Math.round(params[5] * 1024 * 8)) / 1000) + 'kbps' + ' (' + params[5] + 'KB/s)'); $stats.find(".kbps").text(params[5] + '/s'); } catch (e) { } }; }; } ; }; function ss_toJson(o) { if (o === null) { return 'null'; } var pairs, k, name, val, type = $.type(o); if (type === 'undefined') { return undefined; } // Also covers instantiated Number and Boolean objects, // which are typeof 'object' but thanks to $.type, we // catch them here. I don't know whether it is right // or wrong that instantiated primitives are not // exported to JSON as an {"object":..}. // We choose this path because that's what the browsers did. if (type === 'number' || type === 'boolean') { return String(o); } if (type === 'string') { return ss_toJson_quoteString(o); } // if (typeof o.toJSON === 'function') { // return $.toJSON(o.toJSON()); // } if (type === 'date') { var month = o.getUTCMonth() + 1 , day = o.getUTCDate() , year = o.getUTCFullYear() , hours = o.getUTCHours() , minutes = o.getUTCMinutes() , seconds = o.getUTCSeconds() , milli = o.getUTCMilliseconds(); if (month < 10) { month = '0' + month; } if (day < 10) { day = '0' + day; } if (hours < 10) { hours = '0' + hours; } if (minutes < 10) { minutes = '0' + minutes; } if (seconds < 10) { seconds = '0' + seconds; } if (milli < 100) { milli = '0' + milli; } if (milli < 10) { milli = '0' + milli; } return '"' + year + '-' + month + '-' + day + 'T' + hours + ':' + minutes + ':' + seconds + '.' + milli + 'Z"'; } pairs = []; if ($.isArray(o)) { for (k = 0; k < o.length; k++) { pairs.push(ss_toJson(o[k]) || 'null'); } return '[' + pairs.join(',') + ']'; } // Any other object (plain object, RegExp, ..) // Need to do typeof instead of $.type, because we also // want to catch non-plain objects. if (typeof o === 'object') { for (k in o) { // Only include own properties, // Filter out inherited prototypes if (Object.prototype.hasOwnProperty.call(o, k)) { // Keys must be numerical or string. Skip others type = typeof k; if (type === 'number') { name = '"' + k + '"'; } else if (type === 'string') { name = ss_toJson_quoteString(k); } else { continue; } type = typeof o[k]; // Invalid values like these return undefined // from toJSON, however those object members // shouldn't be included in the JSON string at all. if (type !== 'function' && type !== 'undefined') { val = ss_toJson(o[k]); pairs.push(name + ':' + val); } } } return '{' + pairs.join(',') + '}'; } } function ss_toJson_quoteString(str) { if (str.match(escape)) { return '"' + str.replace(escape, function (a) { var c = meta[a]; if (typeof c === 'string') { return c; } c = a.charCodeAt(); return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16); }) + '"'; } return '"' + str + '"'; } (function ($) { $.fn.ss_tooltip = function () { this.off('mouseenter.tooltip,click.tooltip').bind('mouseenter.tooltip', function () { if (!this.title) return false; var tip = '' + this.title; if (tip.indexOf('*') !== -1) { tip = tip.split('*'); tip = ''; } var tooltip = $('
').css('opacity', 0) .html(tip) .appendTo('body'); this.title = ''; var target = $(this); var init_tooltip = function () { if ($(window).width() < tooltip.outerWidth() * 1.5) tooltip.css('max-width', $(window).width() / 2); else tooltip.css('max-width', 340); var pos_left = target.offset().left + (target.outerWidth() / 2) - (tooltip.outerWidth() / 2), pos_top = target.offset().top - tooltip.outerHeight() - 20; if (pos_left < 0) { pos_left = target.offset().left + target.outerWidth() / 2 - 20; tooltip.addClass('left'); } else tooltip.removeClass('left'); if (pos_left + tooltip.outerWidth() > $(window).width()) { pos_left = target.offset().left - tooltip.outerWidth() + target.outerWidth() / 2 + 20; tooltip.addClass('right'); } else tooltip.removeClass('right'); if (pos_top < 0) { var pos_top = target.offset().top + target.outerHeight(); tooltip.addClass('top'); } else tooltip.removeClass('top'); tooltip.css({left: pos_left, top: pos_top}) .animate({top: '+=10', opacity: 1}, 50); }; init_tooltip(); $(window).resize(init_tooltip); var remove_tooltip = function () { tooltip.animate({top: '-=10', opacity: 0}, 50, function () { $(this).remove(); }); target.attr('title', tip); }; target.bind('mouseleave.tooltip', remove_tooltip); tooltip.bind('click.tooltip', remove_tooltip); }); return this; }; }(jQuery)); $(function () { sendspace = new sendspaceClass(); sendspace.init(); if (document.domain.indexOf('sendspace.com') !== -1) document.domain = 'sendspace.com'; else document.domain = location.hostname.split('.').slice(-2).join('.'); $('.tooltip').ss_tooltip(); }); var ssmsg = { _returnto: $(document), bg: function () { if (!this._dlg_bg) this._dlg_bg = $('#ssmsg_bg'); return this._dlg_bg; }, dlg: function () { if (!this._dlg) { this._dlg = $('#ssmsg_msg').on('keydown', function (evt) { if (evt.which === 13) return true; if (evt.which === 27) return ssmsg.pop(); if (evt.shiftKey && evt.which !== 9) { evt.preventDefault(); return false; } if (!evt.which === 9) return ssmsg.pop(); evt.preventDefault(); var tabbable = $(this).find('div > div > *'); tabbable.eq(($(':focus').index() + (evt.shiftKey ? -1 : +1)) % tabbable.length).focus(); return true; }); } return this._dlg; }, /** * Please note, this is a non-blocking, use native alert() where needed * @param str msg Message to show * @param str title Optional title for the dialog * @returns false */ alert: function (msg, title) { this._returnto = $(':focus'); this.bg().show(); this.dlg().find('p').html(msg.replace(/\n/g, '
')) .end().find('h1').html(title).toggle(!!title) .end().show().addClass('fadeable'); this.setup_buttons({ title: title ? title : trn('Alert!', 'Alert!'), msg: msg, buttons: { ok: '' } }); return false; }, /** * Please note, this is a non-blocking, use native confirm() where needed * * @param mixed msg Either options or a string to use with callback param * @returns optional onok Assigns a handler for clicking the ok button * @returns false */ confirm: function (msg, onok) { var options = { msg: trn('Confirmation', 'Confirmation'), title: '', focus: 'ok', buttons: { //index => template ok: '