From a7038f425219f9c095a2ce415b5a0f5be3d5bc0b Mon Sep 17 00:00:00 2001 From: Manuel Reimer Date: Wed, 10 Nov 2010 08:42:00 +0100 Subject: [PATCH] Bug 399310 - Add Firefox Sidebar API to SeaMonkey Sidebar. r+moa=Mnyromyr --- suite/common/jar.mn | 1 - suite/common/sidebar/customize.js | 11 +- suite/common/sidebar/local-panels.rdf | 70 --------- suite/common/sidebar/sidebarOverlay.js | 133 ++++++++++++++++-- suite/common/sidebar/sidebarOverlay.xul | 32 +++++ .../chrome/common/sidebar/local-panels.dtd | 43 ------ .../chrome/common/sidebar/sidebarOverlay.dtd | 4 + suite/locales/jar.mn | 1 - 8 files changed, 170 insertions(+), 125 deletions(-) delete mode 100644 suite/common/sidebar/local-panels.rdf delete mode 100644 suite/locales/en-US/chrome/common/sidebar/local-panels.dtd diff --git a/suite/common/jar.mn b/suite/common/jar.mn index e21183db34..49af35d5e5 100644 --- a/suite/common/jar.mn +++ b/suite/common/jar.mn @@ -238,7 +238,6 @@ comm.jar: content/communicator/sidebar/customize-panel.xul (sidebar/customize-panel.xul) content/communicator/sidebar/customize.js (sidebar/customize.js) content/communicator/sidebar/customize.xul (sidebar/customize.xul) - content/communicator/sidebar/local-panels.rdf (sidebar/local-panels.rdf) content/communicator/sidebar/PageNotFound.xul (sidebar/PageNotFound.xul) content/communicator/sidebar/preview.js (sidebar/preview.js) content/communicator/sidebar/preview.xul (sidebar/preview.xul) diff --git a/suite/common/sidebar/customize.js b/suite/common/sidebar/customize.js index 4d6721af64..1c128ed455 100644 --- a/suite/common/sidebar/customize.js +++ b/suite/common/sidebar/customize.js @@ -502,7 +502,16 @@ function Save() current_panels = sidebarObj.container.GetElements(); while (current_panels.hasMoreElements()) { panel = current_panels.getNext().QueryInterface(Components.interfaces.nsIRDFResource); - if (panel.Value in panels) { + + // "Check if the item is one of the broadcaster panels imported to RDF from + // mainBroadcasterSet. If so, then don't remove it from datasource. + var master_list = sidebarObj.datasource.GetTarget(RDF.GetResource(allPanelsObj.resource), RDF.GetResource(NC + "panel-list"), true); + var masterSeq = Components.classes["@mozilla.org/rdf/container;1"] + .createInstance(Components.interfaces.nsIRDFContainer); + masterSeq.Init(sidebarObj.datasource, master_list); + var inmaster = (masterSeq.IndexOf(panel) != -1); + + if (panel.Value in panels || inmaster) { // This panel will remain in the sidebar. // Remove the resource, but keep all the other attributes. // Removing it will allow it to be added in the correct order. diff --git a/suite/common/sidebar/local-panels.rdf b/suite/common/sidebar/local-panels.rdf deleted file mode 100644 index b069acc274..0000000000 --- a/suite/common/sidebar/local-panels.rdf +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - &sidebar.search.label; - chrome://communicator/content/search/search-panel.xul - - - &sidebar.client-bookmarks.label; - chrome://communicator/content/bookmarks/bm-panel.xul - - - &sidebar.client-history.label; - chrome://communicator/content/history/history-panel.xul - - - &sidebar.client-addressbook.label; - chrome://messenger/content/addressbook/addressbook-panel.xul - - diff --git a/suite/common/sidebar/sidebarOverlay.js b/suite/common/sidebar/sidebarOverlay.js index aa83b7fc5a..1956fa5656 100644 --- a/suite/common/sidebar/sidebarOverlay.js +++ b/suite/common/sidebar/sidebarOverlay.js @@ -1,4 +1,4 @@ -/* -*- Mode: Java; tab-width: 4; insert-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 @@ -583,7 +583,7 @@ sbPanel.prototype.is_persistent = function () { var rv = false; - var datasource = RDF.GetDataSource(sidebarObj.datasource_uri); + var datasource = sidebarObj.datasource; var persistNode = datasource.GetTarget(RDF.GetResource(this.id), RDF.GetResource(NC + "persist"), true); @@ -739,15 +739,19 @@ function sidebar_overlay_init() { gMustInit = false; sidebarObj.panels = new sbPanelList('sidebar-panels'); sidebarObj.datasource_uri = get_sidebar_datasource_uri(); + sidebarObj.datasource = RDF.GetDataSourceBlocking(sidebarObj.datasource_uri); sidebarObj.resource = 'urn:sidebar:current-panel-list'; sidebarObj.master_datasources = ""; sidebarObj.master_datasources = get_remote_datasource_url(); - sidebarObj.master_datasources += " chrome://communicator/content/sidebar/local-panels.rdf"; + sidebarObj.master_datasources += " " + sidebarObj.datasource_uri; sidebarObj.master_resource = 'urn:sidebar:master-panel-list'; sidebarObj.component = document.documentElement.getAttribute('windowtype'); debug("sidebarObj.component is " + sidebarObj.component); + // Sync RDF with broadcasters. + SidebarBroadcastersToRDF(); + // Initialize the display var sidebar_element = document.getElementById('sidebar-box'); var sidebar_menuitem = document.getElementById('sidebar-menu'); @@ -814,7 +818,7 @@ function sidebar_open_default_panel(wait, tries) { return; gBusyOpeningDefault = true; - var ds = RDF.GetDataSource(sidebarObj.datasource_uri); + var ds = sidebarObj.datasource; var currentListRes = RDF.GetResource("urn:sidebar:current-panel-list"); var panelListRes = RDF.GetResource("http://home.netscape.com/NC-rdf#panel-list"); var container = ds.GetTarget(currentListRes, panelListRes, true); @@ -874,7 +878,6 @@ function check_for_missing_panels() { channel.open(); } catch(ex if (ex.result == NS_ERROR_FILE_NOT_FOUND)) { - sidebarObj.datasource = RDF.GetDataSource(sidebarObj.datasource_uri); sidebarObj.datasource.Assert(RDF.GetResource(currHeader.getAttribute("id")), RDF.GetResource(NC + "exclude"), RDF.GetLiteral(sidebarObj.component), @@ -928,7 +931,7 @@ function sidebar_revert_to_default_panels() { sidebar_file = sidebar_get_panels_file(); debug("sidebar defaults reloaded"); - var datasource = RDF.GetDataSource(sidebarObj.datasource_uri); + var datasource = sidebarObj.datasource; datasource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Refresh(true); } catch (ex) { debug("Error: Unable to reload panel defaults file.\n"); @@ -977,7 +980,7 @@ function get_remote_datasource_url() { } function sidebar_fixup_datasource() { - var datasource = RDF.GetDataSource(sidebarObj.datasource_uri); + var datasource = sidebarObj.datasource; var resource = RDF.GetResource(sidebarObj.resource); var panel_list = datasource.GetTarget(resource, @@ -1243,7 +1246,7 @@ function SidebarShowHide() { function SidebarBuildPickerPopup() { var menu = document.getElementById('sidebar-panel-picker-popup'); - menu.database.AddDataSource(RDF.GetDataSource(sidebarObj.datasource_uri)); + menu.database.AddDataSource(sidebarObj.datasource); menu.builder.rebuild(); for (var ii=3; ii < menu.childNodes.length; ii++) { @@ -1261,7 +1264,6 @@ function SidebarBuildPickerPopup() { function SidebarTogglePanel(panel_menuitem) { // Create a "container" wrapper around the current panels to // manipulate the RDF:Seq more easily. - sidebarObj.datasource = RDF.GetDataSource(sidebarObj.datasource_uri); var did_exclude = false; var panel_id = panel_menuitem.getAttribute('id'); @@ -1625,6 +1627,119 @@ if (!SB_DEBUG) { } } +function SidebarBroadcastersToRDF() +{ + // Translation rules to translate between new broadcaster id and old RDF id. + const TRANSLATE = {viewBookmarksSidebar: "bookmarks", + viewHistorySidebar: "history", + viewSearchSidebar: "search", + viewAddressbookSidebar: "addressbook"}; + const URN_PREFIX = "urn:sidebar:panel:"; + + const RDFCU = Components.classes['@mozilla.org/rdf/container-utils;1'] + .getService(Components.interfaces.nsIRDFContainerUtils); + + /* + * Initialize RDF stuff. + */ + let ds = sidebarObj.datasource; + let panelListRes = RDF.GetResource(NC + "panel-list"); + + let currentListRes = RDF.GetResource(sidebarObj.resource); + let masterListRes = RDF.GetResource(sidebarObj.master_resource); + let currentTarget = ds.GetTarget(currentListRes, panelListRes, true); + let masterTarget = ds.GetTarget(masterListRes, panelListRes, true); + if (!masterTarget) { + // No "master-panel-list" found, so create it. + masterTarget = RDF.GetAnonymousResource(); + ds.Assert(masterListRes, panelListRes, masterTarget, true); + } + let currentSeq = RDFCU.MakeSeq(ds, currentTarget); + let masterSeq = RDFCU.MakeSeq(ds, masterTarget); + + /* + * Run over broadcasters in browser window and add/update RDF entries + * based on them. + */ + let titleRes = RDF.GetResource(NC + "title"); + let urlRes = RDF.GetResource(NC + "content"); + + let bset = document.getElementById("mainBroadcasterSet"); + let broadcasters = bset.getElementsByTagName("broadcaster"); + let bclist = {}; + for (let bId = 0; bId < broadcasters.length; bId++) { + let curBC = broadcasters[bId]; + let title = curBC.getAttribute("sidebartitle") || curBC.getAttribute("label"); + let url = curBC.getAttribute("sidebarurl"); + let bcid = (curBC.id in TRANSLATE) ? TRANSLATE[curBC.id] : curBC.id; + + if (!url || !title || !bcid) + continue; + + // This one is needed later to check for obsolete sidebars. + bclist[bcid] = 1; + + let panelRes = RDF.GetResource(URN_PREFIX + bcid); + + // Literals of values that should be in RDF. + let titleLit = RDF.GetLiteral(title); + let urlLit = RDF.GetLiteral(url); + // Literals of values that are in RDF. + let curtitleLit = ds.GetTarget(panelRes, titleRes, true); + let cururlLit = ds.GetTarget(panelRes, urlRes, true); + + // If the item doesn't already exist, create it. + if (!curtitleLit && !cururlLit) { + ds.Assert(panelRes, titleRes, titleLit, true); + ds.Assert(panelRes, urlRes, titleLit, true); + masterSeq.AppendElement(panelRes); + if (currentSeq.IndexOf(panelRes) == -1) + currentSeq.AppendElement(panelRes); + } + // Item already exists, but perhaps we need to update... + else { + let curtitle = curtitleLit.QueryInterface(Components.interfaces.nsIRDFLiteral).Value; + let cururl = cururlLit.QueryInterface(Components.interfaces.nsIRDFLiteral).Value; + + if (curtitle != title) + ds.Change(panelRes, titleRes, curtitleLit, titleLit); + + if (cururl != url) + ds.Change(panelRes, urlRes, cururlLit, urlLit); + } + } + + /* + * Do the same the other way around to delete obsolete sidebars. + */ + + let masterElements = masterSeq.GetElements(); + while (masterElements.hasMoreElements()) { + let curElementRes = masterElements.getNext(); + let curId = curElementRes.QueryInterface(Components.interfaces.nsIRDFResource).Value; + + if (curId.substr(0, URN_PREFIX.length) != URN_PREFIX) + continue; + + curId = curId.substr(URN_PREFIX.length); + if (!(curId in bclist)) { + let properties = ds.ArcLabelsOut(curElementRes); + while(properties.hasMoreElements()) { + let propertyRes = properties.getNext(); + let valueLit = ds.GetTarget(curElementRes, propertyRes, true); + ds.Unassert(curElementRes, propertyRes, valueLit); + } + masterSeq.RemoveElement(curElementRes, true); + if (currentSeq.IndexOf(curElementRes) != -1) + currentSeq.RemoveElement(curElementRes, true); + } + } + + // Write modified data. + sidebarObj.datasource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush(); +} + + ////////////////////////////////////////////////////////////// // Install the load/unload handlers ////////////////////////////////////////////////////////////// diff --git a/suite/common/sidebar/sidebarOverlay.xul b/suite/common/sidebar/sidebarOverlay.xul index c990dc6ec4..c6fe0f08e8 100644 --- a/suite/common/sidebar/sidebarOverlay.xul +++ b/suite/common/sidebar/sidebarOverlay.xul @@ -49,6 +49,38 @@ + + + + + + + + - - - - Alternatively, the contents of this file may be used under the terms of - - either of the GNU General Public License Version 2 or later (the "GPL"), - - or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - - in which case the provisions of the GPL or the LGPL are applicable instead - - of those above. If you wish to allow use of your version of this file only - - under the terms of either the GPL or the LGPL, and not to allow others to - - use your version of this file under the terms of the MPL, indicate your - - decision by deleting the provisions above and replace them with the notice - - and other provisions required by the GPL or the LGPL. If you do not delete - - the provisions above, a recipient may use your version of this file under - - the terms of any one of the MPL, the GPL or the LGPL. - - - - ***** END LICENSE BLOCK ***** --> - - - - - - - diff --git a/suite/locales/en-US/chrome/common/sidebar/sidebarOverlay.dtd b/suite/locales/en-US/chrome/common/sidebar/sidebarOverlay.dtd index e23c2ef85d..b63787dceb 100644 --- a/suite/locales/en-US/chrome/common/sidebar/sidebarOverlay.dtd +++ b/suite/locales/en-US/chrome/common/sidebar/sidebarOverlay.dtd @@ -63,3 +63,7 @@ + + + + diff --git a/suite/locales/jar.mn b/suite/locales/jar.mn index d854229f12..04565db86a 100644 --- a/suite/locales/jar.mn +++ b/suite/locales/jar.mn @@ -185,7 +185,6 @@ locale/@AB_CD@/communicator/profile/profileSelection.properties (%chrome/common/profile/profileSelection.properties) locale/@AB_CD@/communicator/search/search-panel.dtd (%chrome/common/search/search-panel.dtd) locale/@AB_CD@/communicator/sidebar/customize.dtd (%chrome/common/sidebar/customize.dtd) - locale/@AB_CD@/communicator/sidebar/local-panels.dtd (%chrome/common/sidebar/local-panels.dtd) locale/@AB_CD@/communicator/sidebar/preview.dtd (%chrome/common/sidebar/preview.dtd) locale/@AB_CD@/communicator/sidebar/sidebar.properties (%chrome/common/sidebar/sidebar.properties) locale/@AB_CD@/communicator/sidebar/sidebarOverlay.dtd (%chrome/common/sidebar/sidebarOverlay.dtd)