mirror of
https://github.com/transmission/transmission.git
synced 2025-12-24 12:28:52 +00:00
(trunk web) #4979 "CSS Issues in Web Client" -- proposed fix. See ticket for more details.
This commit is contained in:
@@ -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, "<").replace(/>/g, ">");
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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​");
|
||||
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');
|
||||
|
||||
@@ -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>',
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user