Mercurial > snowl
changeset 51:7938fd5e956a
first version of river of news view that works
author | Myk Melez <myk@mozilla.org> |
---|---|
date | Wed, 07 May 2008 13:45:18 -0700 |
parents | f83981ab4c88 |
children | 30739558a3e7 |
files | extension/content/river.js extension/modules/RiverWriter.js extension/modules/datastore.js extension/modules/message.js |
diffstat | 4 files changed, 101 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/extension/content/river.js Sun May 04 19:54:47 2008 -0700 +++ b/extension/content/river.js Wed May 07 13:45:18 2008 -0700 @@ -41,18 +41,20 @@ const Cr = Components.results; const Cu = Components.utils; +Cu.import("resource://snowl/modules/collection.js"); Cu.import("resource://snowl/modules/RiverWriter.js"); var RiverHandler = { - /** - * The SnowlRiverWriter object that produces the UI. - */ - _riverWriter: null, + // The set of messages to display in the view. + _collection: null, + // The object that generates the view. + _riverWriter: null, + init: function SH_init() { + this._collection = new SnowlCollection(); this._riverWriter = new SnowlRiverWriter(); - this._riverWriter.init(window); - this._rebuildModel(); + this._riverWriter.init(window, this._collection); }, writeContent: function SH_writeContent() {
--- a/extension/modules/RiverWriter.js Sun May 04 19:54:47 2008 -0700 +++ b/extension/modules/RiverWriter.js Wed May 07 13:45:18 2008 -0700 @@ -219,7 +219,17 @@ /** * Safely sets the href attribute on an anchor tag, providing the URI - * specified can be loaded according to rules. + * specified can be loaded according to rules. + * + * XXX Renamed from safeSetURIAttribute to unsafeSetURIAttribute to reflect + * that we've commented out the stuff that makes it safe. + * + * FIXME: I don't understand the security implications here, but presumably + * there's a reason this is here, and we should be respecting it, so make this + * work by giving each message in a collection have a reference to its source + * and then use the source's URI to create the principal with which we compare + * the URI. + * * @param element * The element to set a URI attribute on * @param attribute @@ -227,8 +237,9 @@ * @param uri * The URI spec to set as the href */ - _safeSetURIAttribute: - function FW__safeSetURIAttribute(element, attribute, uri) { + _unsafeSetURIAttribute: + function FW__unsafeSetURIAttribute(element, attribute, uri) { +/* var secman = Cc["@mozilla.org/scriptsecuritymanager;1"]. getService(Ci.nsIScriptSecurityManager); const flags = Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL; @@ -242,6 +253,7 @@ // Not allowed to load this link because secman.checkLoadURIStr threw return; } +*/ this._contentSandbox.element = element; this._contentSandbox.uri = uri; @@ -417,7 +429,7 @@ // Set up the title image (supplied by the feed) var feedTitleImage = this._document.getElementById("feedTitleImage"); - this._safeSetURIAttribute(feedTitleImage, "src", + this._unsafeSetURIAttribute(feedTitleImage, "src", parts.getPropertyAsAString("url")); // Set up the title image link @@ -432,7 +444,7 @@ this._contentSandbox.feedTitleLink = null; this._contentSandbox.titleText = null; - this._safeSetURIAttribute(feedTitleLink, "href", + this._unsafeSetURIAttribute(feedTitleLink, "href", parts.getPropertyAsAString("link")); // Fix the margin on the main title, so that the image doesn't run over @@ -451,35 +463,34 @@ * @param container * The container of entries in the feed */ - _writeFeedContent: function FW__writeFeedContent(container) { + _writeFeedContent: function FW__writeFeedContent() { // Build the actual feed content - var feed = container.QueryInterface(Ci.nsIFeed); - if (feed.items.length == 0) - return; + //var feed = container.QueryInterface(Ci.nsIFeed); + //if (feed.items.length == 0) + // return; this._contentSandbox.feedContent = this._document.getElementById("feedContent"); - for (var i = 0; i < feed.items.length; ++i) { - var entry = feed.items.queryElementAt(i, Ci.nsIFeedEntry); - entry.QueryInterface(Ci.nsIFeedContainer); + for (let i = 0; i < this._collection.messages.length; ++i) { + let entry = this._collection.messages[i]; var entryContainer = this._document.createElementNS(HTML_NS, "div"); entryContainer.className = "entry"; // If the entry has a title, make it a link - if (entry.title) { + if (entry.subject) { var a = this._document.createElementNS(HTML_NS, "a"); - a.appendChild(this._document.createTextNode(entry.title.plainText())); + a.appendChild(this._document.createTextNode(entry.subject)); // Entries are not required to have links, so entry.link can be null. if (entry.link) - this._safeSetURIAttribute(a, "href", entry.link.spec); + this._unsafeSetURIAttribute(a, "href", entry.link); var title = this._document.createElementNS(HTML_NS, "h3"); title.appendChild(a); - var lastUpdated = this._parseDate(entry.updated); + var lastUpdated = this._parseDate(entry.timestamp); if (lastUpdated) { var dateDiv = this._document.createElementNS(HTML_NS, "div"); dateDiv.className = "lastUpdated"; @@ -491,7 +502,13 @@ } var body = this._document.createElementNS(HTML_NS, "div"); - var summary = entry.summary || entry.content; + + // The summary is currently not stored and made available, so we can + // only use the content. + // FIXME: use the summary instead once it becomes available. + //var summary = entry.summary || entry.content; + var summary = entry.content; + var docFragment = null; if (summary) { if (summary.base) @@ -504,10 +521,10 @@ // If the entry doesn't have a title, append a # permalink // See http://scripting.com/rss.xml for an example - if (!entry.title && entry.link) { + if (!entry.subject && entry.link) { var a = this._document.createElementNS(HTML_NS, "a"); a.appendChild(this._document.createTextNode("#")); - this._safeSetURIAttribute(a, "href", entry.link.spec); + this._unsafeSetURIAttribute(a, "href", entry.link); body.appendChild(this._document.createTextNode(" ")); body.appendChild(a); } @@ -617,7 +634,7 @@ var enc_href = this._document.createElementNS(HTML_NS, "a"); enc_href.appendChild(this._document.createTextNode(this._getURLDisplayName(enc.get("url")))); - this._safeSetURIAttribute(enc_href, "href", enc.get("url")); + this._unsafeSetURIAttribute(enc_href, "href", enc.get("url")); enclosureDiv.appendChild(enc_href); if (type_text && size_text) @@ -889,8 +906,11 @@ _document: null, _feedURI: null, _feedPrincipal: null, + _collection: null, - init: function FW_init(aWindow) { + init: function FW_init(aWindow, aCollection) { + this._collection = aCollection; + // Explicitly wrap |window| in an XPCNativeWrapper to make sure // it's a real native object! This will throw an exception if we // get a non-native object. @@ -920,13 +940,13 @@ try { // Set up the feed content - var container = this._getContainer(); - if (!container) - return; + //var container = this._getContainer(); + //if (!container) + // return; - this._setTitleText(container); - this._setTitleImage(container); - this._writeFeedContent(container); + //this._setTitleText(container); + //this._setTitleImage(container); + this._writeFeedContent(); } finally { this._removeFeedFromCache();
--- a/extension/modules/datastore.js Sun May 04 19:54:47 2008 -0700 +++ b/extension/modules/datastore.js Wed May 07 13:45:18 2008 -0700 @@ -62,6 +62,7 @@ ] }, +/* parts: { type: TABLE_TYPE_FULLTEXT, columns: [ @@ -70,6 +71,7 @@ "content" ] }, +*/ attributes: { type: TABLE_TYPE_NORMAL, @@ -81,10 +83,11 @@ }, metadata: { - type: TABLE_TYPE_NORMAL, + type: TABLE_TYPE_FULLTEXT, columns: [ - "messageID INTEGER REFERENCES messages(id)", - "attributeID INTEGER REFERENCES attributes(id)", + "messageID INTEGER NOT NULL REFERENCES messages(id)", + "attributeID INTEGER NOT NULL REFERENCES attributes(id)", + "contentType TEXT NOT NULL", "value BLOB" ] }
--- a/extension/modules/message.js Sun May 04 19:54:47 2008 -0700 +++ b/extension/modules/message.js Wed May 07 13:45:18 2008 -0700 @@ -5,6 +5,8 @@ const Cr = Components.results; const Cu = Components.utils; +Cu.import("resource://snowl/modules/datastore.js"); + function SnowlMessage(aID, aSubject, aAuthor, aLink, aTimestamp, aRead) { this.id = aID; this.subject = aSubject; @@ -18,7 +20,44 @@ id: null, subject: null, author: null, + // FIXME: make this an nsIURI. link: null, timestamp: null, - read: null + read: null, + + // FIXME: also store and make available the summary. + + get _contentStatement() { + let statement = SnowlDatastore.createStatement( + "SELECT content, contentType FROM parts WHERE messageID = :messageID" + ); + this.__defineGetter__("_contentStatement", function() { return statement }); + return this._contentStatement; + }, + + get content() { + let content; + + try { + this._contentStatement.params.messageID = this.id; + if (this._contentStatement.step()) { + content = Cc["@mozilla.org/feed-textconstruct;1"]. + createInstance(Ci.nsIFeedTextConstruct); + content.text = this._contentStatement.row.content; + content.type = textConstructTypes[this._contentStatement.row.contentType]; + } + } + finally { + this._contentStatement.reset(); + } + + return content; + } + }; + +let textConstructTypes = { + "text/html": "html", + "application/xhtml+xml": "xhtml", + "text/plain": "text" +};