iframify main interface, numerous javascript cleanups

This commit is contained in:
Andrew Dolgov 2005-09-05 13:02:00 +01:00
parent 4f0d779c36
commit f0601b870c
7 changed files with 376 additions and 245 deletions

View File

@ -194,13 +194,11 @@
WHERE id = '$id'");
if ($addheader) {
print "<html>
<head>
print "<html><head>
<title>Tiny Tiny RSS : Article $id</title>
<link rel=\"stylesheet\" href=\"tt-rss.css\" type=\"text/css\">
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
</head><body>";
</head><body>";
}
if ($result) {
@ -250,11 +248,22 @@
$skip = $_GET["skip"];
$subop = $_GET["subop"];
$view_mode = $_GET["view"];
$addheader = $_GET["addheader"];
if (!$skip) $skip = 0;
if ($subop == "undefined") $subop = "";
if ($addheader) {
print "<html><head>
<title>Tiny Tiny RSS : Article $id</title>
<link rel=\"stylesheet\" href=\"tt-rss.css\" type=\"text/css\">
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
<script type=\"text/javascript\" src=\"functions.js\"></script>
<script type=\"text/javascript\" src=\"viewfeed.js\"></script>
</head><body>";
}
// FIXME: check for null value here
$result = pg_query("SELECT *,SUBSTRING(last_updated,1,16) as last_updated,
@ -265,11 +274,11 @@
$line = pg_fetch_assoc($result);
if ($subop == "ForceUpdate" ||
(!$subop && $line["update_timeout"] > MIN_UPDATE_TIME)) {
update_rss_feed($link, $line["feed_url"], $feed);
if ($subop == "ForceUpdate") {
// (!$subop && $line["update_timeout"] > MIN_UPDATE_TIME)) {
update_rss_feed($link, $line["feed_url"], $feed);
} else {
if ($subop == "MarkAllRead") {
@ -284,22 +293,26 @@
$feed_last_updated = "Updated: " . $line["last_updated"];
print "<tr><td class=\"search\" colspan=\"4\">
Search: <input id=\"searchbox\"
onblur=\"javascript:enableHotkeys()\" onfocus=\"javascript:disableHotkeys()\"
onchange=\"javascript:search($feed);\"> ";
if (!$addheader) {
print " <a class=\"button\" href=\"javascript:resetSearch()\">Reset</a>";
print "&nbsp;&nbsp;View: ";
print_select("viewbox", $view_mode, array("All Posts", "Starred"),
"onchange=\"javascript:viewfeed('$feed', '0', '');\"");
print "<tr><td class=\"search\" colspan=\"4\">
Search: <input id=\"searchbox\"
onblur=\"javascript:enableHotkeys()\" onfocus=\"javascript:disableHotkeys()\"
onchange=\"javascript:search($feed);\"> ";
print "</td></tr>";
print " <a class=\"button\" href=\"javascript:resetSearch()\">Reset</a>";
print "&nbsp;&nbsp;View: ";
print_select("viewbox", $view_mode, array("All Posts", "Starred"),
"onchange=\"javascript:viewfeed('$feed', '0', '');\"");
print "</td></tr>";
print "<tr>
<td colspan=\"4\" class=\"title\">" . $line["title"] . "</td></tr>";
print "<tr>
<td colspan=\"4\" class=\"title\">" . $line["title"] . "</td></tr>";
}
$search = $_GET["search"];
@ -323,6 +336,10 @@
$total_entries = pg_fetch_result($result, 0, "total_entries");
if (!$addheader) {
$limit_query_part = "LIMIT ".HEADLINES_PER_PAGE." OFFSET $skip";
}
$result = pg_query("SELECT
id,title,updated,unread,feed_id,marked,
EXTRACT(EPOCH FROM last_read) AS last_read_ts,
@ -332,7 +349,8 @@
WHERE
$search_query_part
$view_query_part
feed_id = '$feed' ORDER BY updated DESC LIMIT ".HEADLINES_PER_PAGE." OFFSET $skip");
feed_id = '$feed' ORDER BY updated DESC
$limit_query_part");
$lnum = 0;
@ -396,45 +414,49 @@
// start unholy navbar block
print "<tr><td colspan=\"4\" class=\"headlineToolbar\">";
$next_skip = $skip + HEADLINES_PER_PAGE;
$prev_skip = $skip - HEADLINES_PER_PAGE;
if (!$addheader) {
print "Navigate: ";
if ($prev_skip >= 0) {
print "<a class=\"button\"
href=\"javascript:viewfeed($feed, $prev_skip);\">Previous Page</a>";
} else {
print "<a class=\"disabledButton\">Previous Page</a>";
}
print "&nbsp;";
if ($next_skip < $total_entries) {
print "<a class=\"button\"
href=\"javascript:viewfeed($feed, $next_skip);\">Next Page</a>";
} else {
print "<a class=\"disabledButton\">Next Page</a>";
}
print "&nbsp;&nbsp;Feed: ";
print "<a class=\"button\"
href=\"javascript:viewfeed($feed, 0, 'ForceUpdate');\">Update</a>";
print "&nbsp;&nbsp;Mark as read: ";
if ($num_unread > 0) {
print "<a class=\"button\" id=\"btnCatchupPage\"
href=\"javascript:catchupPage($feed);\">This Page</a>";
print "&nbsp;";
} else {
print "<a class=\"disabledButton\">This Page</a>";
print "&nbsp;";
}
print "<tr><td colspan=\"4\" class=\"headlineToolbar\">";
$next_skip = $skip + HEADLINES_PER_PAGE;
$prev_skip = $skip - HEADLINES_PER_PAGE;
print "<a class=\"button\"
href=\"javascript:viewfeed($feed, $skip, 'MarkAllRead');\">All Posts</a>";
print "Navigate: ";
if ($prev_skip >= 0) {
print "<a class=\"button\"
href=\"javascript:viewfeed($feed, $prev_skip);\">Previous Page</a>";
} else {
print "<a class=\"disabledButton\">Previous Page</a>";
}
print "&nbsp;";
if ($next_skip < $total_entries) {
print "<a class=\"button\"
href=\"javascript:viewfeed($feed, $next_skip);\">Next Page</a>";
} else {
print "<a class=\"disabledButton\">Next Page</a>";
}
print "&nbsp;&nbsp;Feed: ";
print "<a class=\"button\"
href=\"javascript:viewfeed($feed, 0, 'ForceUpdate');\">Update</a>";
print "&nbsp;&nbsp;Mark as read: ";
if ($num_unread > 0) {
print "<a class=\"button\" id=\"btnCatchupPage\"
href=\"javascript:catchupPage($feed);\">This Page</a>";
print "&nbsp;";
} else {
print "<a class=\"disabledButton\">This Page</a>";
print "&nbsp;";
}
print "<a class=\"button\"
href=\"javascript:viewfeed($feed, $skip, 'MarkAllRead');\">All Posts</a>";
}
/* print "&nbsp;&nbsp;Unmark: ";
@ -464,6 +486,10 @@
print "<div class=\"invisible\" id=\"FTOTAL\">$total</div>";
print "<div class=\"invisible\" id=\"FUNREAD\">$unread</div>";
if ($addheader) {
print "</body></html>";
}
}
if ($op == "pref-rpc") {

View File

@ -23,8 +23,5 @@
define(ENABLE_PREFS_CATCHUP_UNCATCHUP, false);
// enable "Mark as read/unread" buttons in preferences dialog
define(ENABLE_CONTENT_IFRAME, true);
// show article in an iframe to mitigate scrolling UI issues
?>

View File

@ -54,6 +54,8 @@ function notify(msg) {
var n = document.getElementById("notify");
if (!n) return;
n.innerHTML = msg;
if (msg.length == 0) {
@ -65,8 +67,7 @@ function notify(msg) {
}
function printLockingError() {
notify("Please wait until operation finishes");
}
notify("Please wait until operation finishes");}
var seq = "";
@ -102,5 +103,76 @@ function hotkey_handler(e) {
}
function cleanSelected(element) {
var content = document.getElementById(element);
var rows = new Array();
for (i = 0; i < content.rows.length; i++) {
content.rows[i].className = content.rows[i].className.replace("Selected", "");
}
}
function getVisibleUnreadHeadlines() {
var content = document.getElementById("headlinesList");
var rows = new Array();
for (i = 0; i < content.rows.length; i++) {
var row_id = content.rows[i].id.replace("RROW-", "");
if (row_id.length > 0 && content.rows[i].className.match("Unread")) {
rows.push(row_id);
}
}
return rows;
}
function getVisibleHeadlineIds() {
var content = document.getElementById("headlinesList");
var rows = new Array();
for (i = 0; i < content.rows.length; i++) {
var row_id = content.rows[i].id.replace("RROW-", "");
if (row_id.length > 0) {
rows.push(row_id);
}
}
return rows;
}
function getFirstVisibleHeadlineId() {
var rows = getVisibleHeadlineIds();
return rows[0];
}
function getLastVisibleHeadlineId() {
var rows = getVisibleHeadlineIds();
return rows[rows.length-1];
}
function markHeadline(id) {
var row = document.getElementById("RROW-" + id);
if (row) {
row.className = row.className + "Selected";
}
}
function getFeedIds() {
var content = document.getElementById("feedsList");
var rows = new Array();
for (i = 0; i < content.rows.length; i++) {
var id = content.rows[i].id.replace("FEEDR-", "");
if (id.length > 0) {
rows.push(id);
}
}
return rows;
}

View File

@ -42,10 +42,6 @@ table.feedOverview {
font-size : small;
}
td.headlineToolbar {
padding-top : 10px;
}
table.feeds {
font-size : small;
}
@ -67,7 +63,17 @@ table.headlinesList td.search {
padding-bottom : 3px; */
}
table.headlinesList td.title {
td.headlinesToolbar {
padding : 10px;
}
td.headlinesTitle {
text-align : right;
font-size : large;
font-weight : bold;
}
table.headlinesList td.title, table.headlinesHeader td.title {
font-weight : bold;
font-size : large;
border-width : 0px 0px 1px 0px;
@ -135,13 +141,18 @@ table.main td.feeds {
padding : 10px;
}
table.main td.headlines {
height : 10%;
padding : 10px;
div.headlineToolbar {
border-width : 1px 0px 0px 0px;
border-color : #c0c0c0;
border-style : solid;
padding : 10px;
}
table.main td.headlines {
height : 25%;
border-width : 1px 0px 0px 0px;
border-color : #c0c0c0;
border-style : solid;
overflow : scroll;
}
table.main td.prefContent {
@ -152,6 +163,14 @@ table.main td.prefContent {
}
table.main td.headlinesToolbarBox {
padding : 0px;
height : 20px;
border-width : 1px 0px 0px 0px;
border-color : #c0c0c0;
border-style : solid;
}
table.main td.content {
padding : 0px;
border-width : 1px 0px 0px 0px;
@ -375,10 +394,11 @@ div.expPane {
margin : 15px;
}
iframe.contentFrame {
iframe.contentFrame, iframe.headlinesFrame {
width : 100%;
border-width : 0px;
padding : 0px;
margin : 0px;
height : 100%;
}

218
tt-rss.js
View File

@ -16,12 +16,6 @@ var active_offset = false;
var total_feed_entries = false;
var _viewfeed_autoselect_first = false;
var _viewfeed_autoselect_last = false;
var _update_ids;
var _update_num_ids;
var search_query = "";
/*@cc_on @*/
@ -63,14 +57,7 @@ function feedlist_callback() {
}
}
function feed_update_callback() {
if (xmlhttp_rpc.readyState == 4) {
var result = xmlhttp_rpc.responseText;
notify(_update_ids);
updateFeed(_update_ids.shift());
}
}
/*
function viewfeed_callback() {
var container = document.getElementById('headlines');
if (xmlhttp.readyState == 4) {
@ -121,15 +108,7 @@ function viewfeed_callback() {
notify("");
}
}
function view_callback() {
var container = document.getElementById('content');
if (xmlhttp_view.readyState == 4) {
container.innerHTML=xmlhttp_view.responseText;
markHeadline(active_post_id);
}
}
} */
function refetch_callback() {
@ -155,16 +134,6 @@ function updateFeed(feed_id) {
}
function scheduleSepFeedUpdate(force) {
notify("Updating feeds in background (M2)...");
_update_ids = getFeedIds();
_update_num_ids = _update_ids.length;
updateFeed(_update_ids.pop());
}
function scheduleFeedUpdate(force) {
notify("Updating feeds in background...");
@ -207,6 +176,7 @@ function updateFeedList(silent, fetch) {
}
}
/*
function catchupPage(feed) {
if (!xmlhttp_ready(xmlhttp)) {
@ -266,7 +236,7 @@ function catchupPage(feed) {
notify("No unread items on this page.");
}
}
} */
function catchupAllFeeds() {
@ -284,6 +254,12 @@ function catchupAllFeeds() {
}
function viewCurrentFeed(skip, subop) {
if (active_feed_id) {
viewfeed(active_feed_id, skip, subop);
}
}
function viewfeed(feed, skip, subop) {
enableHotkeys();
@ -306,11 +282,6 @@ function viewfeed(feed, skip, subop) {
view_mode = "All Posts";
}
/* if (active_feed_id == feed && subop != "ForceUpdate") {
notify("This feed is currently selected.");
return;
} */
if (skip < 0 || skip > total_feed_entries) {
return;
}
@ -327,6 +298,19 @@ function viewfeed(feed, skip, subop) {
active_feed_id = feed;
active_offset = skip;
if (subop == "MarkAllRead") {
var feedr = document.getElementById("FEEDR-" + feed);
var feedt = document.getElementById("FEEDT-" + feed);
var feedu = document.getElementById("FEEDU-" + feed);
feedu.innerHTML = "0";
if (feedr.className.match("Unread")) {
feedr.className = feedr.className.replace("Unread", "");
}
}
var query = "backend.php?op=viewfeed&feed=" + param_escape(feed) +
"&skip=" + param_escape(skip) + "&subop=" + param_escape(subop) +
"&view=" + param_escape(view_mode);
@ -335,47 +319,25 @@ function viewfeed(feed, skip, subop) {
query = query + "&search=" + param_escape(search_query);
}
xmlhttp.open("GET", query, true);
xmlhttp.onreadystatechange=viewfeed_callback;
xmlhttp.send(null);
var headlines_frame = document.getElementById("headlines-frame");
headlines_frame.src = query + "&addheader=true";
notify("Loading headlines...");
}
function markHeadline(id) {
var row = document.getElementById("RROW-" + id);
if (row) {
row.className = row.className + "Selected";
}
}
function getFeedIds() {
var content = document.getElementById("feedsList");
var rows = new Array();
for (i = 0; i < content.rows.length; i++) {
var id = content.rows[i].id.replace("FEEDR-", "");
if (id.length > 0) {
rows.push(id);
}
}
return rows;
}
function cleanSelected(element) {
var content = document.getElementById(element);
var rows = new Array();
for (i = 0; i < content.rows.length; i++) {
content.rows[i].className = content.rows[i].className.replace("Selected", "");
}
var feedr = document.getElementById("FEEDR-" + feed);
cleanSelected("feedsList");
feedr.className = feedr.className + "Selected";
var ftitle_d = document.getElementById("headlinesTitle");
var ftitle_s = document.getElementById("FEEDN-" + feed);
ftitle_d.innerHTML = ftitle_s.innerHTML;
notify("");
}
/*
function view(id,feed_id) {
enableHotkeys();
@ -425,15 +387,11 @@ function view(id,feed_id) {
var content = document.getElementById("content-frame");
if (content) {
content.src = "backend.php?op=view&addheader=true&id=" + param_escape(id);
markHeadline(active_post_id);
} else {
xmlhttp_view.open("GET", "backend.php?op=view&id=" + param_escape(id), true);
xmlhttp_view.onreadystatechange=view_callback;
xmlhttp_view.send(null);
}
content.src = "backend.php?op=view&addheader=true&id=" + param_escape(id);
markHeadline(active_post_id);
}
*/
function timeout() {
scheduleFeedUpdate(true);
@ -445,8 +403,12 @@ function resetSearch() {
viewfeed(active_feed_id, 0, "");
}
function search(feed) {
viewfeed(feed, 0, "");
function search() {
if (active_feed_id) {
viewfeed(active_feed_id, 0, "");
} else {
notify("Please select some feed first.");
}
}
function localPiggieFunction(enable) {
@ -462,53 +424,7 @@ function localPiggieFunction(enable) {
}
}
function relativeid_callback() {
if (xmlhttp_rpc.readyState == 4) {
notify(xmlhttp_rpc.responseText);
}
}
function getVisibleUnreadHeadlines() {
var content = document.getElementById("headlinesList");
var rows = new Array();
for (i = 0; i < content.rows.length; i++) {
var row_id = content.rows[i].id.replace("RROW-", "");
if (row_id.length > 0 && content.rows[i].className.match("Unread")) {
rows.push(row_id);
}
}
return rows;
}
function getVisibleHeadlineIds() {
var content = document.getElementById("headlinesList");
var rows = new Array();
for (i = 0; i < content.rows.length; i++) {
var row_id = content.rows[i].id.replace("RROW-", "");
if (row_id.length > 0) {
rows.push(row_id);
}
}
return rows;
}
function getFirstVisibleHeadlineId() {
var rows = getVisibleHeadlineIds();
return rows[0];
}
function getLastVisibleHeadlineId() {
var rows = getVisibleHeadlineIds();
return rows[rows.length-1];
}
/*
function moveToPost(mode) {
var rows = getVisibleHeadlineIds();
@ -547,16 +463,17 @@ function moveToPost(mode) {
}
}
*/
function localHotkeyHandler(keycode) {
if (keycode == 78) {
/* if (keycode == 78) {
return moveToPost('next');
}
if (keycode == 80) {
return moveToPost('prev');
}
} */
if (keycode == 82) {
return scheduleFeedUpdate(true);
@ -570,37 +487,6 @@ function localHotkeyHandler(keycode) {
}
function toggleMark(id, toggle) {
// notify("Toggle mark: " + id + ", " + toggle);
if (!xmlhttp_ready(xmlhttp_rpc)) {
printLockingError();
return;
}
var mark_img = document.getElementById("FMARKPIC-" + id);
var query = "backend.php?op=rpc&id=" + id + "&subop=mark";
if (toggle == true) {
mark_img.src = "images/mark_set.png";
mark_img.alt = "Reset mark";
mark_img.setAttribute('onclick', 'javascript:toggleMark('+id+', false)');
query = query + "&mark=1";
} else {
mark_img.src = "images/mark_unset.png";
mark_img.alt = "Set mark";
mark_img.setAttribute('onclick', 'javascript:toggleMark('+id+', true)');
query = query + "&mark=0";
}
xmlhttp_rpc.open("GET", query, true);
xmlhttp_rpc.onreadystatechange=rpc_notify_callback;
xmlhttp_rpc.send(null);
}
function init() {
// IE kludge

View File

@ -28,7 +28,7 @@
</td>
</tr>
<tr>
<td valign="top" rowspan="2" class="feeds">
<td valign="top" rowspan="3" class="feeds">
<div id="feeds">&nbsp;</div>
@ -41,14 +41,41 @@
href="javascript:catchupAllFeeds()">Mark as read</a></p>
</td>
<td valign="top" class="headlinesToolbarBox">
<table width="100%">
<!-- <tr><td id="headlinesTitle" class="headlinesTitle">
&nbsp;
</td></tr> -->
<tr><td class="headlinesToolbar">
Search: <input id="searchbox"
onblur="javascript:enableHotkeys()" onfocus="javascript:disableHotkeys()"
onchange="javascript:search()">
<a class="button" href="javascript:resetSearch()">Reset</a>
&nbsp;View:
<select id="viewbox" onchange="javascript:viewCurrentFeed(0, '')">
<option>All Posts</option>
<option>Starred</option>
</select>
&nbsp;Feed: <a class="button"
href="javascript:viewCurrentFeed(0, 'ForceUpdate')">Update</a>
<a class="button"
href="javascript:viewCurrentFeed(0, 'MarkAllRead')">Mark as read</a>
</td></tr>
</table>
</td>
</tr><tr>
<td id="headlines" class="headlines" valign="top">
Please select the feed.
<iframe name="headlines-frame"
id="headlines-frame" class="headlinesFrame"> </iframe>
</td>
</tr>
<td class="content" id="content" valign="top">
<? if (ENABLE_CONTENT_IFRAME) { ?>
<iframe id="content-frame" class="contentFrame"> </iframe>
<? } ?>
<iframe name="content-frame" id="content-frame" class="contentFrame"> </iframe>
</td>
</tr>
<tr>

103
viewfeed.js Normal file
View File

@ -0,0 +1,103 @@
var active_post_id;
var total_unread = 0;
var xmlhttp_rpc = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
// JScript gives us Conditional compilation, we can cope with old IE versions.
// and security blocked creation of the objects.
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp_rpc = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp_rpc = false;
}
}
@end @*/
if (!xmlhttp_rpc && typeof XMLHttpRequest!='undefined') {
xmlhttp_rpc = new XMLHttpRequest();
}
function view(id,feed_id) {
enableHotkeys();
var crow = document.getElementById("RROW-" + id);
if (crow.className.match("Unread")) {
var umark = parent.document.getElementById("FEEDU-" + feed_id);
umark.innerHTML = umark.innerHTML - 1;
crow.className = crow.className.replace("Unread", "");
if (umark.innerHTML == "0") {
var feedr = parent.document.getElementById("FEEDR-" + feed_id);
feedr.className = feedr.className.replace("Unread", "");
}
total_unread--;
}
cleanSelected("headlinesList");
var upd_img_pic = document.getElementById("FUPDPIC-" + id);
if (upd_img_pic) {
upd_img_pic.innerHTML = "";
}
var unread_rows = getVisibleUnreadHeadlines();
if (unread_rows.length == 0) {
var button = document.getElementById("btnCatchupPage");
if (button) {
button.className = "disabledButton";
button.href = "";
}
}
active_post_id = id;
var content = parent.document.getElementById("content-frame");
if (content) {
content.src = "backend.php?op=view&addheader=true&id=" + param_escape(id);
markHeadline(active_post_id);
}
}
function toggleMark(id, toggle) {
// notify("Toggle mark: " + id + ", " + toggle);
if (!xmlhttp_ready(xmlhttp_rpc)) {
printLockingError();
return;
}
var mark_img = document.getElementById("FMARKPIC-" + id);
var query = "backend.php?op=rpc&id=" + id + "&subop=mark";
if (toggle == true) {
mark_img.src = "images/mark_set.png";
mark_img.alt = "Reset mark";
mark_img.setAttribute('onclick', 'javascript:toggleMark('+id+', false)');
query = query + "&mark=1";
} else {
mark_img.src = "images/mark_unset.png";
mark_img.alt = "Set mark";
mark_img.setAttribute('onclick', 'javascript:toggleMark('+id+', true)');
query = query + "&mark=0";
}
xmlhttp_rpc.open("GET", query, true);
xmlhttp_rpc.onreadystatechange=rpc_notify_callback;
xmlhttp_rpc.send(null);
}