]> granicus.if.org Git - transmission/commitdiff
(trunk web) #4979 "CSS Issues in Web Client" -- proposed fix. See ticket for more...
authorJordan Lee <jordan@transmissionbt.com>
Fri, 20 Jul 2012 17:37:50 +0000 (17:37 +0000)
committerJordan Lee <jordan@transmissionbt.com>
Fri, 20 Jul 2012 17:37:50 +0000 (17:37 +0000)
web/javascript/common.js
web/javascript/dialog.js
web/javascript/file-row.js
web/javascript/inspector.js
web/javascript/torrent-row.js

index 0e5631a030cdd339c2e6c064a4ebb6f3dc13a740..59070fdec2774de95e91ca7660033555bdf5ab7a 100644 (file)
@@ -79,9 +79,7 @@ $(document).ready(function() {
 });
 
 /**
- * "innerHTML = html" is pretty slow in FF.  Happily a lot of our innerHTML
- * changes are triggered by periodic refreshes on torrents whose state hasn't
- * changed since the last update, so even this simple test helps a lot.
+ * Checks to see if the content actually changed before poking the DOM.
  */
 function setInnerHTML(e, html)
 {
@@ -98,6 +96,22 @@ function setInnerHTML(e, html)
        }
 };
 
+function sanitizeText(text)
+{
+       return text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
+};
+
+/**
+ * Many of our text changes are triggered by periodic refreshes
+ * on torrents whose state hasn't changed since the last update,
+ * so see if the text actually changed before poking the DOM.
+ */
+function setTextContent(e, text)
+{
+       if (e && (e.textContent != text))
+               e.textContent = text;
+};
+
 /*
  *   Given a numerator and denominator, return a ratio string
  */
index 026d54f20c06fd76b0a640c70228bb9fdf5961fe..f937104e4526158138646e103dc483a66cad4e79 100644 (file)
@@ -76,10 +76,10 @@ Dialog.prototype = {
        {
                if (!isMobileDevice)
                        $('.dialog_container').hide();
-               setInnerHTML(this._heading[0], dialog_heading);
-               setInnerHTML(this._message[0], dialog_message);
-               setInnerHTML(this._cancel_button[0], cancel_button_label || 'Cancel');
-               setInnerHTML(this._confirm_button[0], confirm_button_label);
+               setTextContent(this._heading[0], dialog_heading);
+               setTextContent(this._message[0], dialog_message);
+               setTextContent(this._cancel_button[0], cancel_button_label || 'Cancel');
+               setTextContent(this._confirm_button[0], confirm_button_label);
                this._confirm_button.show();
                this._callback_function = callback_function;
                this._callback_data = callback_data;
@@ -96,11 +96,11 @@ Dialog.prototype = {
        alert: function(dialog_heading, dialog_message, cancel_button_label) {
                if (!isMobileDevice)
                        $('.dialog_container').hide();
-               setInnerHTML(this._heading[0], dialog_heading);
-               setInnerHTML(this._message[0], dialog_message);
+               setTextContent(this._heading[0], dialog_heading);
+               setTextContent(this._message[0], dialog_message);
                // jquery::hide() doesn't work here in Safari for some odd reason
                this._confirm_button.css('display', 'none');
-               setInnerHTML(this._cancel_button[0], cancel_button_label);
+               setTextContent(this._cancel_button[0], cancel_button_label);
                // Just in case
                $('#upload_container').hide();
                $('body').addClass('dialog_showing');
index 03ea07d70b9e814e3b70db6b86a9093b4b548134..20e8abdd112b06b8a9acf4e64c319352c55f4dbc 100644 (file)
@@ -73,7 +73,7 @@ function FileRow(torrent, i)
                          ' (',
                          Transmission.fmt.percentString(pct),
                          '%)' ].join('');
-               setInnerHTML(elements.progress, c);
+               setTextContent(elements.progress, c);
        },
        refreshHTML = function() {
                if (fields.isDirty) {
@@ -140,7 +140,7 @@ function FileRow(torrent, i)
                name = name.replace(/([\/_\.])/g, "$1&#8203;");
                e = document.createElement('div');
                e.className = "inspector_torrent_file_list_entry_name";
-               e.innerHTML = name;
+               setTextContent(e, name);
                root.appendChild(e);
 
                e = document.createElement('div');
index 6c8bc97f53b97c064b490d95b674fb31e1f8aa40..320df186b44c0ff8d3b33e26a90088bcc7e3cab9 100644 (file)
@@ -65,7 +65,7 @@ function Inspector(controller) {
             name = torrents[0].getName();
         else
             name = '' + torrents.length+' Transfers Selected';
-        setInnerHTML(e.name_lb, name || na);
+        setTextContent(e.name_lb, name || na);
 
         // update the visible page
         if ($(e.info_page).is(':visible'))
@@ -146,7 +146,7 @@ function Inspector(controller) {
             else
                 str = torrents[0].getStateString();
         }
-        setInnerHTML(e.state_lb, str);
+        setTextContent(e.state_lb, str);
         stateString = str;
 
         //
@@ -180,7 +180,7 @@ function Inspector(controller) {
             else
                 str = fmt.size(haveVerified) + ' of ' + fmt.size(sizeWhenDone) + ' (' + str +'%), ' + fmt.size(haveUnverified) + ' Unverified';
         }
-        setInnerHTML(e.have_lb, str);
+        setTextContent(e.have_lb, str);
 
         //
         //  availability_lb
@@ -192,7 +192,7 @@ function Inspector(controller) {
             str = none;
         else
             str = '' + fmt.percentString( ( 100.0 * available ) / sizeWhenDone ) +  '%';
-        setInnerHTML(e.availability_lb, str);
+        setTextContent(e.availability_lb, str);
 
         //
         //  downloaded_lb
@@ -211,7 +211,7 @@ function Inspector(controller) {
             else
                 str = fmt.size(d);
         }
-        setInnerHTML(e.downloaded_lb, str);
+        setTextContent(e.downloaded_lb, str);
 
         //
         //  uploaded_lb
@@ -236,7 +236,7 @@ function Inspector(controller) {
                        }
             str = fmt.size(u) + ' (Ratio: ' + fmt.ratioString( Math.ratio(u,d))+')';
         }
-        setInnerHTML(e.uploaded_lb, str);
+        setTextContent(e.uploaded_lb, str);
 
         //
         // running time
@@ -260,7 +260,7 @@ function Inspector(controller) {
             else
                 str = fmt.timeInterval(now/1000 - baseline);
         }
-        setInnerHTML(e.running_time_lb, str);
+        setTextContent(e.running_time_lb, str);
 
         //
         // remaining time
@@ -284,7 +284,7 @@ function Inspector(controller) {
             else
                 str = fmt.timeInterval(baseline);
         }
-        setInnerHTML(e.remaining_time_lb, str);
+        setTextContent(e.remaining_time_lb, str);
 
         //
         // last activity
@@ -308,7 +308,7 @@ function Inspector(controller) {
             else
                 str = fmt.timeInterval(d) + ' ago';
         }
-        setInnerHTML(e.last_activity_lb, str);
+        setTextContent(e.last_activity_lb, str);
 
         //
         // error
@@ -325,7 +325,7 @@ function Inspector(controller) {
                 }
             }
         }
-        setInnerHTML(e.error_lb, str || none);
+        setTextContent(e.error_lb, str || none);
 
         //
         // size
@@ -350,7 +350,7 @@ function Inspector(controller) {
             else
                 str = fmt.size(size) + ' (' + pieces.toStringWithCommas() + ' pieces)';
         }
-        setInnerHTML(e.size_lb, str);
+        setTextContent(e.size_lb, str);
 
         //
         //  hash
@@ -367,7 +367,7 @@ function Inspector(controller) {
                 }
             }
         }
-        setInnerHTML(e.hash_lb, str);
+        setTextContent(e.hash_lb, str);
 
         //
         //  privacy
@@ -385,7 +385,7 @@ function Inspector(controller) {
                 }
             }
         }
-        setInnerHTML(e.privacy_lb, str);
+        setTextContent(e.privacy_lb, str);
 
         //
         //  comment
@@ -404,7 +404,7 @@ function Inspector(controller) {
         }
         if(!str)
             str = none;  
-        setInnerHTML(e.comment_lb, str.replace(/(https?|ftp):\/\/([\w\-]+(\.[\w\-]+)*(\.[a-z]{2,4})?)(\d{1,5})?(\/([^<>\s]*))?/g, '<a target="_blank" href="$&">$&</a>'));
+        setTextContent(e.comment_lb, str.replace(/(https?|ftp):\/\/([\w\-]+(\.[\w\-]+)*(\.[a-z]{2,4})?)(\d{1,5})?(\/([^<>\s]*))?/g, '<a target="_blank" href="$&">$&</a>'));
 
         //
         //  origin
@@ -432,7 +432,7 @@ function Inspector(controller) {
             else
                 str = 'Created by ' + creator + ' on ' + (new Date(date*1000)).toDateString();
         }
-        setInnerHTML(e.origin_lb, str);
+        setTextContent(e.origin_lb, str);
 
         //
         //  foldername
@@ -449,7 +449,7 @@ function Inspector(controller) {
                 }
             }
         }
-        setInnerHTML(e.foldername_lb, str);
+        setTextContent(e.foldername_lb, str);
     },
 
     /****
@@ -535,7 +535,7 @@ function Inspector(controller) {
             peers = tor.getPeers();
             html.push('<div class="inspector_group">');
             if (torrents.length > 1) {
-                html.push('<div class="inspector_torrent_label">', tor.getName(), '</div>');
+                html.push('<div class="inspector_torrent_label">', sanitizeText(tor.getName()), '</div>');
             }
             if (!peers || !peers.length) {
                 html.push('<br></div>'); // firefox won't paint the top border if the div is empty
@@ -560,8 +560,8 @@ function Inspector(controller) {
                        '<td>', (peer.rateToClient ? fmt.speedBps(peer.rateToClient) : ''), '</td>',
                        '<td class="percentCol">', Math.floor(peer.progress*100), '%', '</td>',
                        '<td>', fmt.peerStatus(peer.flagStr), '</td>',
-                       '<td>', peer.address, '</td>',
-                       '<td class="clientCol">', peer.clientName, '</td>',
+                       '<td>', sanitizeText(peer.address), '</td>',
+                       '<td class="clientCol">', sanitizeText(peer.clientName), '</td>',
                        '</tr>');
             }
             html.push('</table></div>');
@@ -676,8 +676,8 @@ function Inspector(controller) {
                 announceState = getAnnounceState(tracker);
                 lastScrapeStatusHash = lastScrapeStatus(tracker);
                 parity = (j%2) ? 'odd' : 'even';
-                html.push('<li class="inspector_tracker_entry ', parity, '"><div class="tracker_host" title="', tracker.announce, '">',
-                      tracker.host, '</div>',
+                html.push('<li class="inspector_tracker_entry ', parity, '"><div class="tracker_host" title="', sanitizeText(tracker.announce), '">',
+                      sanitizeText(tracker.host), '</div>',
                       '<div class="tracker_activity">',
                       '<div>', lastAnnounceStatusHash['label'], ': ', lastAnnounceStatusHash['value'], '</div>',
                       '<div>', announceState, '</div>',
@@ -694,7 +694,7 @@ function Inspector(controller) {
             html.push('</div>'); // inspector_group
         }
 
-        setInnerHTML(trackers_list, html.join(''));
+        setInnerHTML (trackers_list, html.join(''));
     },
 
     initialize = function (controller) {
index 2a8096cea0e5b0b4685df16e0f04988f94a691c4..41c619df2d1504558bf01069259265ad91e0477e 100644 (file)
@@ -230,7 +230,7 @@ TorrentRendererFull.prototype =
        render: function(controller, t, root)
        {
                // name
-               setInnerHTML(root._name_container, t.getName());
+               setTextContent(root._name_container, t.getName());
 
                // progressbar
                TorrentRendererHelper.renderProgressbar(controller, t, root._progressbar);
@@ -239,11 +239,11 @@ TorrentRendererFull.prototype =
                var has_error = t.getError() !== Torrent._ErrNone;
                var e = root._peer_details_container;
                $(e).toggleClass('error',has_error);
-               setInnerHTML(e, this.getPeerDetails(t));
+               setTextContent(e, this.getPeerDetails(t));
 
                // progress details
                e = root._progress_details_container;
-               setInnerHTML(e, this.getProgressDetails(controller, t));
+               setTextContent(e, this.getProgressDetails(controller, t));
 
                // pause/resume button
                var is_stopped = t.isStopped();
@@ -319,13 +319,13 @@ TorrentRendererCompact.prototype =
                var is_stopped = t.isStopped();
                var e = root._name_container;
                $(e).toggleClass('paused', is_stopped);
-               setInnerHTML(e, t.getName());
+               setTextContent(e, t.getName());
 
                // peer details
                var has_error = t.getError() !== Torrent._ErrNone;
                e = root._details_container;
                $(e).toggleClass('error', has_error);
-               setInnerHTML(e, this.getPeerDetails(t));
+               setTextContent(e, this.getPeerDetails(t));
 
                // progressbar
                TorrentRendererHelper.renderProgressbar(controller, t, root._progressbar);