From 66285a525ba8c78b73c7c7fd340a314757624c50 Mon Sep 17 00:00:00 2001 From: Mike Gelfand Date: Tue, 12 Apr 2016 19:03:01 +0000 Subject: [PATCH] Web UI: main() refactoring (patch by skybon @ GH-9) Less jQuery, more Web API. Moved main() away from common. --- web/index.html | 2 + web/javascript/Makefile.am | 2 + web/javascript/common.js | 65 +--------------------------- web/javascript/main.js | 52 +++++++++++++++++++++++ web/javascript/polyfill.js | 87 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 144 insertions(+), 64 deletions(-) create mode 100644 web/javascript/main.js create mode 100644 web/javascript/polyfill.js diff --git a/web/index.html b/web/index.html index 06a5c81c0..86e462cb3 100755 --- a/web/index.html +++ b/web/index.html @@ -23,6 +23,7 @@ + @@ -34,6 +35,7 @@ + Transmission Web Interface diff --git a/web/javascript/Makefile.am b/web/javascript/Makefile.am index 8ac9dfaa5..16e932ac9 100644 --- a/web/javascript/Makefile.am +++ b/web/javascript/Makefile.am @@ -6,7 +6,9 @@ dist_data_DATA = \ file-row.js \ formatter.js \ inspector.js \ + main.js \ notifications.js \ + polyfill.js \ prefs-dialog.js \ remote.js \ torrent.js \ diff --git a/web/javascript/common.js b/web/javascript/common.js index fd7913dc3..27e4cf47a 100644 --- a/web/javascript/common.js +++ b/web/javascript/common.js @@ -1,5 +1,5 @@ /** - * Copyright © Dave Perrett and Malcolm Jarvis + * Copyright © Dave Perrett, Malcolm Jarvis and Artem Vorotnikov * * This file is licensed under the GPLv2. * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html @@ -10,18 +10,6 @@ var transmission, isMobileDevice = RegExp("(iPhone|iPod|Android)").test(navigator.userAgent), scroll_timeout; -if (!Array.indexOf) { - Array.prototype.indexOf = function (obj) { - var i, len; - for (i = 0, len = this.length; i < len; i++) { - if (this[i] == obj) { - return i; - }; - }; - return -1; - }; -}; - // http://forum.jquery.com/topic/combining-ui-dialog-and-tabs $.fn.tabbedDialog = function (dialog_opts) { this.tabs({ @@ -44,57 +32,6 @@ $.fn.tabbedDialog = function (dialog_opts) { tabul.addClass('ui-dialog-titlebar'); } -$(document).ready(function () { - - // IE8 and below don’t support ES5 Date.now() - if (!Date.now) { - Date.now = function () { - return +new Date(); - }; - }; - - // IE specific fixes here - if ($.browser.msie) { - try { - document.execCommand("BackgroundImageCache", false, true); - } catch (err) {}; - $('.dialog_container').css('height', $(window).height() + 'px'); - }; - - if ($.browser.safari) { - // Move search field's margin down for the styled input - $('#torrent_search').css('margin-top', 3); - }; - - if (isMobileDevice) { - window.onload = function () { - setTimeout(function () { - window.scrollTo(0, 1); - }, 500); - }; - window.onorientationchange = function () { - setTimeout(function () { - window.scrollTo(0, 1); - }, 100); - }; - if (window.navigator.standalone) { - // Fix min height for isMobileDevice when run in full screen mode from home screen - // so the footer appears in the right place - $('body div#torrent_container').css('min-height', '338px'); - }; - $("label[for=torrent_upload_url]").text("URL: "); - } else { - // Fix for non-Safari-3 browsers: dark borders to replace shadows. - $('div.dialog_container div.dialog_window').css('border', '1px solid #777'); - }; - - // Initialise the dialog controller - dialog = new Dialog(); - - // Initialise the main Transmission controller - transmission = new Transmission(); -}); - /** * Checks to see if the content actually changed before poking the DOM. */ diff --git a/web/javascript/main.js b/web/javascript/main.js new file mode 100644 index 000000000..376706bc7 --- /dev/null +++ b/web/javascript/main.js @@ -0,0 +1,52 @@ +/** + * Copyright © Dave Perrett, Malcolm Jarvis and Artem Vorotnikov + * + * This file is licensed under the GPLv2. + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + */ + +function main() { + // IE specific fixes here + if (jQuery.browser.msie) { + try { + document.execCommand("BackgroundImageCache", false, true); + } catch (err) {}; + }; + + if (jQuery.browser.safari) { + // Move search field's margin down for the styled input + document.getElementById("torrent_search").style["margin-top"] = 3; + }; + + if (isMobileDevice) { + window.onload = function () { + setTimeout(function () { + window.scrollTo(0, 1); + }, 500); + }; + window.onorientationchange = function () { + setTimeout(function () { + window.scrollTo(0, 1); + }, 100); + }; + if (window.navigator.standalone) { + // Fix min height for isMobileDevice when run in full screen mode from home screen + // so the footer appears in the right place + document.getElementById("torrent_container").style["min-height"] = "338px"; + }; + document.querySelector("label[for=torrent_upload_url]").textContent("URL: "); + } else { + // Fix for non-Safari-3 browsers: dark borders to replace shadows. + Array.from(document.getElementsByClassName("dialog_window")).forEach(function (e) { + e.style["border"] = "1px solid #777"; + }); + }; + + // Initialise the dialog controller + dialog = new Dialog(); + + // Initialise the main Transmission controller + transmission = new Transmission(); +}; + +document.addEventListener("DOMContentLoaded", main); diff --git a/web/javascript/polyfill.js b/web/javascript/polyfill.js new file mode 100644 index 000000000..c77197dd6 --- /dev/null +++ b/web/javascript/polyfill.js @@ -0,0 +1,87 @@ +/** + * Copyright © Dave Perrett, Malcolm Jarvis and Artem Vorotnikov + * + * This file is licensed under the GPLv2. + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + */ + +if (!Array.from) { + Array.from = (function () { + var toStr = Object.prototype.toString; + var isCallable = function (fn) { + return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; + }; + var toInteger = function (value) { + var number = Number(value); + if (isNaN(number)) { + return 0; + } + if (number === 0 || !isFinite(number)) { + return number; + } + return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); + }; + var maxSafeInteger = Math.pow(2, 53) - 1; + var toLength = function (value) { + var len = toInteger(value); + return Math.min(Math.max(len, 0), maxSafeInteger); + }; + + // The length property of the from method is 1. + return function from(arrayLike /*, mapFn, thisArg */ ) { + // 1. Let C be the this value. + var C = this; + + // 2. Let items be ToObject(arrayLike). + var items = Object(arrayLike); + + // 3. ReturnIfAbrupt(items). + if (arrayLike == null) { + throw new TypeError("Array.from requires an array-like object - not null or undefined"); + } + + // 4. If mapfn is undefined, then let mapping be false. + var mapFn = arguments.length > 1 ? arguments[1] : void undefined; + var T; + if (typeof mapFn !== 'undefined') { + // 5. else + // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. + if (!isCallable(mapFn)) { + throw new TypeError('Array.from: when provided, the second argument must be a function'); + } + + // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. + if (arguments.length > 2) { + T = arguments[2]; + } + } + + // 10. Let lenValue be Get(items, "length"). + // 11. Let len be ToLength(lenValue). + var len = toLength(items.length); + + // 13. If IsConstructor(C) is true, then + // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len. + // 14. a. Else, Let A be ArrayCreate(len). + var A = isCallable(C) ? Object(new C(len)) : new Array(len); + + // 16. Let k be 0. + var k = 0; + // 17. Repeat, while k < len… (also steps a - h) + var kValue; + while (k < len) { + kValue = items[k]; + if (mapFn) { + A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); + } else { + A[k] = kValue; + } + k += 1; + } + // 18. Let putStatus be Put(A, "length", len, true). + A.length = len; + // 20. Return A. + return A; + }; + }()); +}