/* -*- Mode: Java; tab-width: 4; insert-tabs-mode: nil; c-basic-offset: 2 -*- * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-1999 Netscape Communications Corporation. All * Rights Reserved. * */ // the rdf service var RDF = 'component://netscape/rdf/rdf-service' RDF = Components.classes[RDF].getService(); RDF = RDF.QueryInterface(Components.interfaces.nsIRDFService); var NC = "http://home.netscape.com/NC-rdf#"; var sidebarObj = new Object; var original_panels = new Array(); function debug(msg) { //dump(msg+"\n"); } function Init() { var all_panels_datasources = window.arguments[0]; var all_panels_resource = window.arguments[1]; sidebarObj.datasource_uri = window.arguments[2]; sidebarObj.resource = window.arguments[3]; debug("Init: all panels datasources = " + all_panels_datasources); debug("Init: all panels resource = " + all_panels_resource); debug("Init: sidebarObj.datasource_uri = " + sidebarObj.datasource_uri); debug("Init: sidebarObj.resource = " + sidebarObj.resource); var all_panels = document.getElementById('other-panels'); var current_panels = document.getElementById('current-panels'); all_panels_datasources = all_panels_datasources.replace(/^\s+/,''); all_panels_datasources = all_panels_datasources.replace(/\s+$/,''); all_panels_datasources = all_panels_datasources.split(/\s+/); for (var ii = 0; ii < all_panels_datasources.length; ii++) { debug("Init: Adding "+all_panels_datasources[ii]); // This will load the datasource, if it isn't already. var datasource = RDF.GetDataSource(all_panels_datasources[ii]); all_panels.database.AddDataSource(datasource); current_panels.database.AddDataSource(datasource); } // Add the datasource for current list of panels. It selects panels out // of the other datasources. debug("Init: Adding current panels, "+sidebarObj.datasource_uri); sidebarObj.datasource = RDF.GetDataSource(sidebarObj.datasource_uri); current_panels.database.AddDataSource(sidebarObj.datasource); // Root the customize dialog at the correct place. debug("Init: reset all panels ref, "+all_panels_resource); all_panels.setAttribute('ref', all_panels_resource); debug("Init: reset current panels ref, "+sidebarObj.resource); current_panels.setAttribute('ref', sidebarObj.resource); save_initial_panels(); enable_buttons_for_current_panels(); } // Remember the original list of panels so that // the save button can be enabled when something changes. function save_initial_panels() { var root = document.getElementById('current-panels-root'); for (var node = root.firstChild; node != null; node = node.nextSibling) { original_panels[original_panels.length] = node.getAttribute('id'); } } function get_attr(registry,service,attr_name) { var attr = registry.GetTarget(service, RDF.GetResource(NC + attr_name), true); if (attr) attr = attr.QueryInterface(Components.interfaces.nsIRDFLiteral); if (attr) attr = attr.Value; return attr; } function SelectChangeForOtherPanels(event, target) { // Remove the selection in the "current" panels list var current_panels = document.getElementById('current-panels'); current_panels.clearItemSelection(); enable_buttons_for_current_panels(); if (target.getAttribute('container') == 'true') { if (target.getAttribute('open') == 'true') { target.removeAttribute('open'); } else { target.setAttribute('open','true'); } } else { link = target.getAttribute('link'); if (link && link != '') { debug("Has remote datasource: "+link); add_datasource_to_other_panels(link); target.setAttribute('container', 'true'); target.setAttribute('open', 'true'); } } enable_buttons_for_other_panels(); } function add_datasource_to_other_panels(link) { // Convert the |link| attribute into a URL var url = document.location; debug("Current URL: " +url); debug("Current link: " +link); uri = Components.classes['component://netscape/network/standard-url'].createInstance(); uri = uri.QueryInterface(Components.interfaces.nsIURI); uri.spec = url; uri = uri.resolve(link); debug("New URL: " +uri); // Add the datasource to the tree var all_panels = document.getElementById('other-panels'); all_panels.database.AddDataSource(RDF.GetDataSource(uri)); // XXX This is a hack to force re-display all_panels.setAttribute('ref', 'urn:blah:main-root'); } // Handle a selection change in the current panels. function SelectChangeForCurrentPanels() { // Remove the selection in the available panels list var all_panels = document.getElementById('other-panels'); all_panels.clearItemSelection(); enable_buttons_for_current_panels(); enable_buttons_for_other_panels(); } // Move the selected item up the the current panels list. function MoveUp() { var tree = document.getElementById('current-panels'); if (tree.selectedItems.length == 1) { var selected = tree.selectedItems[0]; var before = selected.previousSibling if (before) { before.parentNode.insertBefore(selected, before); tree.selectItem(selected); tree.ensureElementIsVisible(selected); } } enable_buttons_for_current_panels(); enable_save(); } // Move the selected item down the the current panels list. function MoveDown() { var tree = document.getElementById('current-panels'); if (tree.selectedItems.length == 1) { var selected = tree.selectedItems[0]; if (selected.nextSibling) { if (selected.nextSibling.nextSibling) { selected.parentNode.insertBefore(selected, selected.nextSibling.nextSibling); } else { selected.parentNode.appendChild(selected); } tree.selectItem(selected); } } enable_buttons_for_current_panels(); enable_save(); } function PreviewPanel() { var tree = document.getElementById('other-panels'); var database = tree.database; var select_list = tree.selectedItems for (var nodeIndex=0; nodeIndex 0) { var selectedNode = tree.selectedItems[0] nextNode = selectedNode.nextSibling; if (!nextNode) { nextNode = selectedNode.previousSibling; } selectedNode.parentNode.removeChild(selectedNode) } if (nextNode) { tree.selectItem(nextNode) } enable_buttons_for_current_panels(); enable_save(); } // Bring up a new window with the customize url // for an individual panel. function CustomizePanel() { var tree = document.getElementById('current-panels'); var numSelected = tree.selectedItems.length; if (numSelected == 1) { var selectedNode = tree.selectedItems[0]; var customize_url = selectedNode.getAttribute('customize'); debug("url = " + customize_url); if (!customize_url) return; window.open(customize_url, "_blank", "resizable,width=690,height=600"); } enable_save(); } // Serialize the new list of panels. function Save() { var all_panels = document.getElementById('other-panels'); var current_panels = document.getElementById('current-panels'); // Iterate through the 'current-panels' tree to collect the panels // that the user has chosen. We need to do this _before_ we remove // the panels from the datasource, because the act of removing them // from the datasource will change the tree! var panels = new Array(); var root = document.getElementById('current-panels-root'); for (var node = root.firstChild; node != null; node = node.nextSibling) { panels[panels.length] = node.getAttribute('id'); } // Cut off the connection between the dialog and the datasource. // The dialog is closed at the end of this function. // Without this, the dialog tries to update as it is being destroyed. current_panels.setAttribute('ref', 'rdf:null'); start_batch(sidebarObj.datasource, sidebarObj.resource); // Create a "container" wrapper around the current panels to // manipulate the RDF:Seq more easily. var container = Components.classes["component://netscape/rdf/container"].createInstance(); container = container.QueryInterface(Components.interfaces.nsIRDFContainer); container.Init(sidebarObj.datasource, RDF.GetResource(sidebarObj.resource)); // Remove all the current panels from the datasource. var current_panels = container.GetElements(); while (current_panels.HasMoreElements()) { panel = current_panels.GetNext(); id = panel.QueryInterface(Components.interfaces.nsIRDFResource).Value; // If this panel is not in the new list, // or, if description of this panel is in the all panels list, // then, remove all assertions for the panel to avoid leaving // unneeded assertions behind and to avoid multiply asserted // attributes, respectively. if (!has_element(panels, id) || has_targets(all_panels.database, panel)) { delete_resource_deeply(container, panel); } else { container.RemoveElement(panel, false); } } // Add the new list of panels for (var ii = 0; ii < panels.length; ++ii) { copy_resource_deeply(all_panels.database, RDF.GetResource(panels[ii]), container); } end_batch(sidebarObj.datasource, sidebarObj.resource); // Write the modified panels out. sidebarObj.datasource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush(); window.close(); } // Search for an element in an array function has_element(array, element) { for (var ii=0; ii < array.length; ii++) { if (array[ii] == element) { return true; } } return false; } // Search for targets from resource in datasource function has_targets(datasource, resource) { var arcs = datasource.ArcLabelsOut(resource); return arcs.HasMoreElements(); } // Mark the beginning of a batch by asserting inbatch="true" // into the datasource. The observer in sidebarOverlay.js uses // this to remember the panel selection. function start_batch(datasource, resource) { datasource.Assert(RDF.GetResource(resource), RDF.GetResource(NC + "inbatch"), RDF.GetLiteral("true"), true); } // Mark the end of a batch by unasserting 'inbatch' on the datasource. function end_batch(datasource, resource) { datasource.Unassert(RDF.GetResource(resource), RDF.GetResource(NC + "inbatch"), RDF.GetLiteral("true")); } // Remove a resource and all the arcs out from it. function delete_resource_deeply(container, resource) { var arcs = container.DataSource.ArcLabelsOut(resource); while (arcs.HasMoreElements()) { var arc = arcs.GetNext(); var targets = container.DataSource.GetTargets(resource, arc, true); while (targets.HasMoreElements()) { var target = targets.GetNext(); container.DataSource.Unassert(resource, arc, target, true); } } container.RemoveElement(panel, false); } // Copy a resource and all its arcs out to a new container. function copy_resource_deeply(source_datasource, resource, dest_container) { var arcs = source_datasource.ArcLabelsOut(resource); while (arcs.HasMoreElements()) { var arc = arcs.GetNext(); var targets = source_datasource.GetTargets(resource, arc, true); while (targets.HasMoreElements()) { var target = targets.GetNext(); dest_container.DataSource.Assert(resource, arc, target, true); } } dest_container.AppendElement(resource); } function enable_buttons_for_other_panels() { var add_button = document.getElementById('add_button'); var preview_button = document.getElementById('preview_button'); var all_panels = document.getElementById('other-panels'); var num_selected = 0; // Only count non-folders as selected for button enabling for (var ii=0; ii 0) { add_button.removeAttribute('disabled'); preview_button.removeAttribute('disabled'); } else { add_button.setAttribute('disabled','true'); preview_button.setAttribute('disabled','true'); } } function enable_buttons_for_current_panels() { var up = document.getElementById('up'); var down = document.getElementById('down'); var tree = document.getElementById('current-panels'); var customize = document.getElementById('customize-button'); var remove = document.getElementById('remove-button'); var numSelected = tree.selectedItems.length; var noneSelected, isFirst, isLast, selectedNode if (numSelected > 0) { selectedNode = tree.selectedItems[0] isFirst = selectedNode == selectedNode.parentNode.firstChild isLast = selectedNode == selectedNode.parentNode.lastChild } // up /\ button if (numSelected != 1 || isFirst) { up.setAttribute('disabled', 'true'); } else { up.removeAttribute('disabled'); } // down \/ button if (numSelected != 1 || isLast) { down.setAttribute('disabled', 'true'); } else { down.removeAttribute('disabled'); } // "Customize..." button var customizeURL = null; if (numSelected == 1) { customizeURL = selectedNode.getAttribute('customize'); } if (customizeURL == null || customizeURL == '') { customize.setAttribute('disabled','true'); } else { customize.removeAttribute('disabled'); } // "Remove" button if (numSelected == 0) { remove.setAttribute('disabled','true'); } else { remove.removeAttribute('disabled'); } } // Check to see if the "current" panel list has changed. // If so, enable the save button. function enable_save() { var root = document.getElementById('current-panels-root'); var panels = root.childNodes; var list_unchanged = (panels.length == original_panels.length); for (var ii = 0; ii < panels.length && list_unchanged; ii++) { if (original_panels[ii] != panels.item(ii).getAttribute('id')) { list_unchanged = false; } } var save_button = document.getElementById('save_button'); if (list_unchanged) { save_button.setAttribute('disabled','true'); } else { save_button.removeAttribute('disabled'); } } function dump_attributes(node) { var attributes = node.attributes if (!attributes || attributes.length == 0) { debug("no attributes\n") } for (var ii=0; ii < attributes.length; ii++) { var attr = attributes.item(ii) debug("attr "+ii+": "+ attr.name +"="+attr.value) } }