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,9 +194,7 @@
WHERE id = '$id'"); WHERE id = '$id'");
if ($addheader) { if ($addheader) {
print "<html><head>
print "<html>
<head>
<title>Tiny Tiny RSS : Article $id</title> <title>Tiny Tiny RSS : Article $id</title>
<link rel=\"stylesheet\" href=\"tt-rss.css\" type=\"text/css\"> <link rel=\"stylesheet\" href=\"tt-rss.css\" type=\"text/css\">
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
@ -250,11 +248,22 @@
$skip = $_GET["skip"]; $skip = $_GET["skip"];
$subop = $_GET["subop"]; $subop = $_GET["subop"];
$view_mode = $_GET["view"]; $view_mode = $_GET["view"];
$addheader = $_GET["addheader"];
if (!$skip) $skip = 0; if (!$skip) $skip = 0;
if ($subop == "undefined") $subop = ""; 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 // FIXME: check for null value here
$result = pg_query("SELECT *,SUBSTRING(last_updated,1,16) as last_updated, $result = pg_query("SELECT *,SUBSTRING(last_updated,1,16) as last_updated,
@ -265,8 +274,8 @@
$line = pg_fetch_assoc($result); $line = pg_fetch_assoc($result);
if ($subop == "ForceUpdate" || if ($subop == "ForceUpdate") {
(!$subop && $line["update_timeout"] > MIN_UPDATE_TIME)) { // (!$subop && $line["update_timeout"] > MIN_UPDATE_TIME)) {
update_rss_feed($link, $line["feed_url"], $feed); update_rss_feed($link, $line["feed_url"], $feed);
@ -284,6 +293,8 @@
$feed_last_updated = "Updated: " . $line["last_updated"]; $feed_last_updated = "Updated: " . $line["last_updated"];
if (!$addheader) {
print "<tr><td class=\"search\" colspan=\"4\"> print "<tr><td class=\"search\" colspan=\"4\">
Search: <input id=\"searchbox\" Search: <input id=\"searchbox\"
onblur=\"javascript:enableHotkeys()\" onfocus=\"javascript:disableHotkeys()\" onblur=\"javascript:enableHotkeys()\" onfocus=\"javascript:disableHotkeys()\"
@ -301,6 +312,8 @@
print "<tr> print "<tr>
<td colspan=\"4\" class=\"title\">" . $line["title"] . "</td></tr>"; <td colspan=\"4\" class=\"title\">" . $line["title"] . "</td></tr>";
}
$search = $_GET["search"]; $search = $_GET["search"];
if ($search) { if ($search) {
@ -323,6 +336,10 @@
$total_entries = pg_fetch_result($result, 0, "total_entries"); $total_entries = pg_fetch_result($result, 0, "total_entries");
if (!$addheader) {
$limit_query_part = "LIMIT ".HEADLINES_PER_PAGE." OFFSET $skip";
}
$result = pg_query("SELECT $result = pg_query("SELECT
id,title,updated,unread,feed_id,marked, id,title,updated,unread,feed_id,marked,
EXTRACT(EPOCH FROM last_read) AS last_read_ts, EXTRACT(EPOCH FROM last_read) AS last_read_ts,
@ -332,7 +349,8 @@
WHERE WHERE
$search_query_part $search_query_part
$view_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; $lnum = 0;
@ -396,6 +414,8 @@
// start unholy navbar block // start unholy navbar block
if (!$addheader) {
print "<tr><td colspan=\"4\" class=\"headlineToolbar\">"; print "<tr><td colspan=\"4\" class=\"headlineToolbar\">";
$next_skip = $skip + HEADLINES_PER_PAGE; $next_skip = $skip + HEADLINES_PER_PAGE;
@ -436,6 +456,8 @@
print "<a class=\"button\" print "<a class=\"button\"
href=\"javascript:viewfeed($feed, $skip, 'MarkAllRead');\">All Posts</a>"; href=\"javascript:viewfeed($feed, $skip, 'MarkAllRead');\">All Posts</a>";
}
/* print "&nbsp;&nbsp;Unmark: "; /* print "&nbsp;&nbsp;Unmark: ";
print "<a class=\"button\" print "<a class=\"button\"
@ -464,6 +486,10 @@
print "<div class=\"invisible\" id=\"FTOTAL\">$total</div>"; print "<div class=\"invisible\" id=\"FTOTAL\">$total</div>";
print "<div class=\"invisible\" id=\"FUNREAD\">$unread</div>"; print "<div class=\"invisible\" id=\"FUNREAD\">$unread</div>";
if ($addheader) {
print "</body></html>";
}
} }
if ($op == "pref-rpc") { if ($op == "pref-rpc") {

View File

@ -23,8 +23,5 @@
define(ENABLE_PREFS_CATCHUP_UNCATCHUP, false); define(ENABLE_PREFS_CATCHUP_UNCATCHUP, false);
// enable "Mark as read/unread" buttons in preferences dialog // 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"); var n = document.getElementById("notify");
if (!n) return;
n.innerHTML = msg; n.innerHTML = msg;
if (msg.length == 0) { if (msg.length == 0) {
@ -65,8 +67,7 @@ function notify(msg) {
} }
function printLockingError() { function printLockingError() {
notify("Please wait until operation finishes"); notify("Please wait until operation finishes");}
}
var seq = ""; 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; font-size : small;
} }
td.headlineToolbar {
padding-top : 10px;
}
table.feeds { table.feeds {
font-size : small; font-size : small;
} }
@ -67,7 +63,17 @@ table.headlinesList td.search {
padding-bottom : 3px; */ 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-weight : bold;
font-size : large; font-size : large;
border-width : 0px 0px 1px 0px; border-width : 0px 0px 1px 0px;
@ -135,13 +141,18 @@ table.main td.feeds {
padding : 10px; padding : 10px;
} }
table.main td.headlines { div.headlineToolbar {
height : 10%; border-width : 1px 0px 0px 0px;
padding : 10px; border-color : #c0c0c0;
border-style : solid;
padding : 10px;
}
table.main td.headlines {
height : 25%;
border-width : 1px 0px 0px 0px; border-width : 1px 0px 0px 0px;
border-color : #c0c0c0; border-color : #c0c0c0;
border-style : solid; border-style : solid;
overflow : scroll;
} }
table.main td.prefContent { 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 { table.main td.content {
padding : 0px; padding : 0px;
border-width : 1px 0px 0px 0px; border-width : 1px 0px 0px 0px;
@ -375,10 +394,11 @@ div.expPane {
margin : 15px; margin : 15px;
} }
iframe.contentFrame { iframe.contentFrame, iframe.headlinesFrame {
width : 100%; width : 100%;
border-width : 0px; border-width : 0px;
padding : 0px; padding : 0px;
margin : 0px; margin : 0px;
height : 100%; height : 100%;
} }

214
tt-rss.js
View File

@ -16,12 +16,6 @@ var active_offset = false;
var total_feed_entries = 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 = ""; var search_query = "";
/*@cc_on @*/ /*@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() { function viewfeed_callback() {
var container = document.getElementById('headlines'); var container = document.getElementById('headlines');
if (xmlhttp.readyState == 4) { if (xmlhttp.readyState == 4) {
@ -121,15 +108,7 @@ function viewfeed_callback() {
notify(""); 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() { 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) { function scheduleFeedUpdate(force) {
notify("Updating feeds in background..."); notify("Updating feeds in background...");
@ -207,6 +176,7 @@ function updateFeedList(silent, fetch) {
} }
} }
/*
function catchupPage(feed) { function catchupPage(feed) {
if (!xmlhttp_ready(xmlhttp)) { if (!xmlhttp_ready(xmlhttp)) {
@ -266,7 +236,7 @@ function catchupPage(feed) {
notify("No unread items on this page."); notify("No unread items on this page.");
} }
} } */
function catchupAllFeeds() { 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) { function viewfeed(feed, skip, subop) {
enableHotkeys(); enableHotkeys();
@ -306,11 +282,6 @@ function viewfeed(feed, skip, subop) {
view_mode = "All Posts"; 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) { if (skip < 0 || skip > total_feed_entries) {
return; return;
} }
@ -327,6 +298,19 @@ function viewfeed(feed, skip, subop) {
active_feed_id = feed; active_feed_id = feed;
active_offset = skip; 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) + var query = "backend.php?op=viewfeed&feed=" + param_escape(feed) +
"&skip=" + param_escape(skip) + "&subop=" + param_escape(subop) + "&skip=" + param_escape(skip) + "&subop=" + param_escape(subop) +
"&view=" + param_escape(view_mode); "&view=" + param_escape(view_mode);
@ -335,47 +319,25 @@ function viewfeed(feed, skip, subop) {
query = query + "&search=" + param_escape(search_query); query = query + "&search=" + param_escape(search_query);
} }
xmlhttp.open("GET", query, true); var headlines_frame = document.getElementById("headlines-frame");
xmlhttp.onreadystatechange=viewfeed_callback;
xmlhttp.send(null);
notify("Loading headlines..."); headlines_frame.src = query + "&addheader=true";
} var feedr = document.getElementById("FEEDR-" + feed);
function markHeadline(id) { cleanSelected("feedsList");
var row = document.getElementById("RROW-" + id); feedr.className = feedr.className + "Selected";
if (row) {
row.className = row.className + "Selected"; var ftitle_d = document.getElementById("headlinesTitle");
} var ftitle_s = document.getElementById("FEEDN-" + feed);
}
ftitle_d.innerHTML = ftitle_s.innerHTML;
function getFeedIds() {
var content = document.getElementById("feedsList"); notify("");
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", "");
}
} }
/*
function view(id,feed_id) { function view(id,feed_id) {
enableHotkeys(); enableHotkeys();
@ -425,15 +387,11 @@ function view(id,feed_id) {
var content = document.getElementById("content-frame"); var content = document.getElementById("content-frame");
if (content) {
content.src = "backend.php?op=view&addheader=true&id=" + param_escape(id); content.src = "backend.php?op=view&addheader=true&id=" + param_escape(id);
markHeadline(active_post_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);
}
} }
*/
function timeout() { function timeout() {
scheduleFeedUpdate(true); scheduleFeedUpdate(true);
@ -445,8 +403,12 @@ function resetSearch() {
viewfeed(active_feed_id, 0, ""); viewfeed(active_feed_id, 0, "");
} }
function search(feed) { function search() {
viewfeed(feed, 0, ""); if (active_feed_id) {
viewfeed(active_feed_id, 0, "");
} else {
notify("Please select some feed first.");
}
} }
function localPiggieFunction(enable) { 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) { function moveToPost(mode) {
var rows = getVisibleHeadlineIds(); var rows = getVisibleHeadlineIds();
@ -547,16 +463,17 @@ function moveToPost(mode) {
} }
} }
*/
function localHotkeyHandler(keycode) { function localHotkeyHandler(keycode) {
if (keycode == 78) { /* if (keycode == 78) {
return moveToPost('next'); return moveToPost('next');
} }
if (keycode == 80) { if (keycode == 80) {
return moveToPost('prev'); return moveToPost('prev');
} } */
if (keycode == 82) { if (keycode == 82) {
return scheduleFeedUpdate(true); 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() { function init() {
// IE kludge // IE kludge

View File

@ -28,7 +28,7 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td valign="top" rowspan="2" class="feeds"> <td valign="top" rowspan="3" class="feeds">
<div id="feeds">&nbsp;</div> <div id="feeds">&nbsp;</div>
@ -41,14 +41,41 @@
href="javascript:catchupAllFeeds()">Mark as read</a></p> href="javascript:catchupAllFeeds()">Mark as read</a></p>
</td> </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"> <td id="headlines" class="headlines" valign="top">
Please select the feed. <iframe name="headlines-frame"
id="headlines-frame" class="headlinesFrame"> </iframe>
</td> </td>
</tr> </tr>
<td class="content" id="content" valign="top"> <td class="content" id="content" valign="top">
<? if (ENABLE_CONTENT_IFRAME) { ?> <iframe name="content-frame" id="content-frame" class="contentFrame"> </iframe>
<iframe id="content-frame" class="contentFrame"> </iframe>
<? } ?>
</td> </td>
</tr> </tr>
<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);
}