X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=js%2Futil.js;h=56ecdbcb830d8cfbb0007eb69f0fed59e57ba528;hb=99db745f9d8746e3170bf779746d855c44f0b951;hp=2c79c1db668050faaa301b07a0b33f879c107e87;hpb=532178e3ee455218338b619c6cd35089db16ade5;p=quix0rs-gnu-social.git diff --git a/js/util.js b/js/util.js index 2c79c1db66..56ecdbcb83 100644 --- a/js/util.js +++ b/js/util.js @@ -241,6 +241,26 @@ var SN = { // StatusNet SN.U.Counter(form); }, + /** + * Helper function to rewrite default HTTP form action URLs to HTTPS + * so we can actually fetch them when on an SSL page in ssl=sometimes + * mode. + * + * It would be better to output URLs that didn't hardcode protocol + * and hostname in the first place... + * + * @param {String} url + * @return string + */ + RewriteAjaxAction: function(url) { + // Quick hack: rewrite AJAX submits to HTTPS if they'd fail otherwise. + if (document.location.protocol == 'https:' && url.substr(0, 5) == 'http:') { + return url.replace(/^http:\/\/[^:\/]+/, 'https://' + document.location.host); + } else { + return url; + } + }, + /** * Grabs form data and submits it asynchronously, with 'ajax=1' * parameter added to the rest. @@ -261,7 +281,7 @@ var SN = { // StatusNet $.ajax({ type: 'POST', dataType: 'xml', - url: form.attr('action'), + url: SN.U.RewriteAjaxAction(form.attr('action')), data: form.serialize() + '&ajax=1', beforeSend: function(xhr) { form @@ -316,6 +336,9 @@ var SN = { // StatusNet SN.C.I.NoticeDataGeo = {}; form.append(''); + // Make sure we don't have a mixed HTTP/HTTPS submission... + form.attr('action', SN.U.RewriteAjaxAction(form.attr('action'))); + /** * Show a response feedback bit under the new-notice dialog. * @@ -695,8 +718,16 @@ var SN = { // StatusNet */ NoticeDataAttach: function() { NDA = $('#'+SN.C.S.NoticeDataAttach); - NDA.change(function() { - S = '
'+$(this).val()+'
'; + NDA.change(function(event) { + var filename = $(this).val(); + if (!filename) { + // No file -- we've been tricked! + $('#'+SN.C.S.NoticeDataAttachSelected).remove(); + return false; + } + + // @fixme appending filename straight in is potentially unsafe + S = '
'+filename+'
'; NDAS = $('#'+SN.C.S.NoticeDataAttachSelected); if (NDAS.length > 0) { NDAS.replaceWith(S); @@ -719,6 +750,22 @@ var SN = { // StatusNet }); }, + /** + * Get PHP's MAX_FILE_SIZE setting for this form; + * used to apply client-side file size limit checks. + * + * @param {jQuery} form + * @return int max size in bytes; 0 or negative means no limit + */ + maxFileSize: function(form) { + var max = $(form).find('input[name=MAX_FILE_SIZE]').attr('value'); + if (max) { + return parseInt(max); + } else { + return 0; + } + }, + /** * For browsers with FileAPI support: make a thumbnail if possible, * and append it into the attachment display widget. @@ -1194,6 +1241,32 @@ var SN = { // StatusNet SN.U.StatusNetInstance.Set({Nickname: $('#form_login #nickname').val()}); return true; }); + }, + + /** + * Add logic to any file upload forms to handle file size limits, + * on browsers that support basic FileAPI. + */ + UploadForms: function () { + $('input[type=file]').change(function(event) { + if (typeof this.files == "object" && this.files.length > 0) { + var size = 0; + for (var i = 0; i < this.files.length; i++) { + size += this.files[i].size; + } + + var max = SN.U.maxFileSize($(this.form)); + if (max > 0 && size > max) { + var msg = 'File too large: maximum upload size is %d bytes.'; + alert(msg.replace('%d', max)); + + // Clear the files. + $(this).val(''); + event.preventDefault(); + return false; + } + } + }); } } }; @@ -1206,6 +1279,7 @@ var SN = { // StatusNet * don't start them loading until after DOM-ready time! */ $(document).ready(function(){ + SN.Init.UploadForms(); if ($('.'+SN.C.S.FormNotice).length > 0) { SN.Init.NoticeForm(); } @@ -1219,272 +1293,3 @@ $(document).ready(function(){ SN.Init.Login(); } }); - -// Formerly in xbImportNode.js -// @fixme put it back there -- since we're minifying we can concat in the makefile now - -/* is this stuff defined? */ -if (!document.ELEMENT_NODE) { - document.ELEMENT_NODE = 1; - document.ATTRIBUTE_NODE = 2; - document.TEXT_NODE = 3; - document.CDATA_SECTION_NODE = 4; - document.ENTITY_REFERENCE_NODE = 5; - document.ENTITY_NODE = 6; - document.PROCESSING_INSTRUCTION_NODE = 7; - document.COMMENT_NODE = 8; - document.DOCUMENT_NODE = 9; - document.DOCUMENT_TYPE_NODE = 10; - document.DOCUMENT_FRAGMENT_NODE = 11; - document.NOTATION_NODE = 12; -} - -document._importNode = function(node, allChildren) { - /* find the node type to import */ - switch (node.nodeType) { - case document.ELEMENT_NODE: - /* create a new element */ - var newNode = document.createElement(node.nodeName); - /* does the node have any attributes to add? */ - if (node.attributes && node.attributes.length > 0) - /* add all of the attributes */ - for (var i = 0, il = node.attributes.length; i < il;) { - if (node.attributes[i].nodeName == 'class') { - newNode.className = node.getAttribute(node.attributes[i++].nodeName); - } else { - newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i++].nodeName)); - } - } - /* are we going after children too, and does the node have any? */ - if (allChildren && node.childNodes && node.childNodes.length > 0) - /* recursively get all of the child nodes */ - for (var i = 0, il = node.childNodes.length; i < il;) - newNode.appendChild(document._importNode(node.childNodes[i++], allChildren)); - return newNode; - break; - case document.TEXT_NODE: - case document.CDATA_SECTION_NODE: - case document.COMMENT_NODE: - return document.createTextNode(node.nodeValue); - break; - } -}; - -// @fixme put this next bit back too -- since we're minifying we can concat in the makefile now -// A shim to implement the W3C Geolocation API Specification using Gears or the Ajax API -if (typeof navigator.geolocation == "undefined" || navigator.geolocation.shim ) { (function(){ - -// -- BEGIN GEARS_INIT -(function() { - // We are already defined. Hooray! - if (window.google && google.gears) { - return; - } - - var factory = null; - - // Firefox - if (typeof GearsFactory != 'undefined') { - factory = new GearsFactory(); - } else { - // IE - try { - factory = new ActiveXObject('Gears.Factory'); - // privateSetGlobalObject is only required and supported on WinCE. - if (factory.getBuildInfo().indexOf('ie_mobile') != -1) { - factory.privateSetGlobalObject(this); - } - } catch (e) { - // Safari - if ((typeof navigator.mimeTypes != 'undefined') && navigator.mimeTypes["application/x-googlegears"]) { - factory = document.createElement("object"); - factory.style.display = "none"; - factory.width = 0; - factory.height = 0; - factory.type = "application/x-googlegears"; - document.documentElement.appendChild(factory); - } - } - } - - // *Do not* define any objects if Gears is not installed. This mimics the - // behavior of Gears defining the objects in the future. - if (!factory) { - return; - } - - // Now set up the objects, being careful not to overwrite anything. - // - // Note: In Internet Explorer for Windows Mobile, you can't add properties to - // the window object. However, global objects are automatically added as - // properties of the window object in all browsers. - if (!window.google) { - google = {}; - } - - if (!google.gears) { - google.gears = {factory: factory}; - } -})(); -// -- END GEARS_INIT - -var GearsGeoLocation = (function() { - // -- PRIVATE - var geo = google.gears.factory.create('beta.geolocation'); - - var wrapSuccess = function(callback, self) { // wrap it for lastPosition love - return function(position) { - callback(position); - self.lastPosition = position; - }; - }; - - // -- PUBLIC - return { - shim: true, - - type: "Gears", - - lastPosition: null, - - getCurrentPosition: function(successCallback, errorCallback, options) { - var self = this; - var sc = wrapSuccess(successCallback, self); - geo.getCurrentPosition(sc, errorCallback, options); - }, - - watchPosition: function(successCallback, errorCallback, options) { - geo.watchPosition(successCallback, errorCallback, options); - }, - - clearWatch: function(watchId) { - geo.clearWatch(watchId); - }, - - getPermission: function(siteName, imageUrl, extraMessage) { - geo.getPermission(siteName, imageUrl, extraMessage); - } - - }; -}); - -var AjaxGeoLocation = (function() { - // -- PRIVATE - var loading = false; - var loadGoogleLoader = function() { - if (!hasGoogleLoader() && !loading) { - loading = true; - var s = document.createElement('script'); - s.src = (document.location.protocol == "https:"?"https://":"http://") + 'www.google.com/jsapi?callback=_google_loader_apiLoaded'; - s.type = "text/javascript"; - document.getElementsByTagName('body')[0].appendChild(s); - } - }; - - var queue = []; - var addLocationQueue = function(callback) { - queue.push(callback); - }; - - var runLocationQueue = function() { - if (hasGoogleLoader()) { - while (queue.length > 0) { - var call = queue.pop(); - call(); - } - } - }; - - window['_google_loader_apiLoaded'] = function() { - runLocationQueue(); - }; - - var hasGoogleLoader = function() { - return (window['google'] && google['loader']); - }; - - var checkGoogleLoader = function(callback) { - if (hasGoogleLoader()) { return true; } - - addLocationQueue(callback); - - loadGoogleLoader(); - - return false; - }; - - loadGoogleLoader(); // start to load as soon as possible just in case - - // -- PUBLIC - return { - shim: true, - - type: "ClientLocation", - - lastPosition: null, - - getCurrentPosition: function(successCallback, errorCallback, options) { - var self = this; - if (!checkGoogleLoader(function() { - self.getCurrentPosition(successCallback, errorCallback, options); - })) { return; } - - if (google.loader.ClientLocation) { - var cl = google.loader.ClientLocation; - - var position = { - coords: { - latitude: cl.latitude, - longitude: cl.longitude, - altitude: null, - accuracy: 43000, // same as Gears accuracy over wifi? - altitudeAccuracy: null, - heading: null, - speed: null - }, - // extra info that is outside of the bounds of the core API - address: { - city: cl.address.city, - country: cl.address.country, - country_code: cl.address.country_code, - region: cl.address.region - }, - timestamp: new Date() - }; - - successCallback(position); - - this.lastPosition = position; - } else if (errorCallback === "function") { - errorCallback({ code: 3, message: "Using the Google ClientLocation API and it is not able to calculate a location."}); - } - }, - - watchPosition: function(successCallback, errorCallback, options) { - this.getCurrentPosition(successCallback, errorCallback, options); - - var self = this; - var watchId = setInterval(function() { - self.getCurrentPosition(successCallback, errorCallback, options); - }, 10000); - - return watchId; - }, - - clearWatch: function(watchId) { - clearInterval(watchId); - }, - - getPermission: function(siteName, imageUrl, extraMessage) { - // for now just say yes :) - return true; - } - - }; -}); - -// If you have Gears installed use that, else use Ajax ClientLocation -navigator.geolocation = (window.google && google.gears) ? GearsGeoLocation() : AjaxGeoLocation(); - -})(); -}