home *** CD-ROM | disk | FTP | other *** search
- /* -*- 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.
- *
- */
-
- //////////////////////////////////////////////////////////////
- // Global variables
- //////////////////////////////////////////////////////////////
-
- // Set to true for noise
- const CUST_DEBUG = true;
-
- // the rdf service
- var RDF = '@mozilla.org/rdf/rdf-service;1'
- RDF = Components.classes[RDF].getService();
- RDF = RDF.QueryInterface(Components.interfaces.nsIRDFService);
-
- var NC = "http://home.netscape.com/NC-rdf#";
-
- var sidebarObj = new Object;
- var allPanelsObj = new Object;
- var original_panels = new Array();
-
- //////////////////////////////////////////////////////////////
- // Sidebar Init/Destroy
- //////////////////////////////////////////////////////////////
-
- function sidebar_customize_init()
- {
- allPanelsObj.datasources = window.arguments[0];
- allPanelsObj.resource = window.arguments[1];
- sidebarObj.datasource_uri = window.arguments[2];
- sidebarObj.resource = window.arguments[3];
-
- debug("Init: all panels datasources = " + allPanelsObj.datasources);
- debug("Init: all panels resource = " + allPanelsObj.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');
-
- debug("Adding observer to all panels database.");
- all_panels.database.AddObserver(panels_observer);
-
- allPanelsObj.datasources = allPanelsObj.datasources.replace(/^\s+/,'');
- allPanelsObj.datasources = allPanelsObj.datasources.replace(/\s+$/,'');
- allPanelsObj.datasources = allPanelsObj.datasources.split(/\s+/);
- for (var ii = 0; ii < allPanelsObj.datasources.length; ii++) {
- debug("Init: Adding "+allPanelsObj.datasources[ii]);
-
- // This will load the datasource, if it isn't already.
- var datasource = RDF.GetDataSource(allPanelsObj.datasources[ii]);
- all_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);
-
- // Root the customize dialog at the correct place.
- debug("Init: reset all panels ref, "+allPanelsObj.resource);
- all_panels.setAttribute('ref', allPanelsObj.resource);
-
- // Create a "container" wrapper around the current panels to
- // manipulate the RDF:Seq more easily.
- var panel_list = sidebarObj.datasource.GetTarget(RDF.GetResource(sidebarObj.resource), RDF.GetResource(NC + "panel-list"), true);
- sidebarObj.container = Components.classes["@mozilla.org/rdf/container;1"].createInstance(Components.interfaces.nsIRDFContainer);
- sidebarObj.container.Init(sidebarObj.datasource, panel_list);
-
- // Add all the current panels to the tree
- current_panels = sidebarObj.container.GetElements();
- while (current_panels.hasMoreElements()) {
- var panel = current_panels.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
- if (add_node_to_current_list(sidebarObj.datasource, panel) >= 0) {
- original_panels.push(panel.Value);
- original_panels[panel.Value] = true;
- }
- }
-
- var links =
- all_panels.database.GetSources(RDF.GetResource(NC + "haslink"),
- RDF.GetLiteral("true"), true);
-
- while (links.hasMoreElements()) {
- var folder =
- links.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
- var folder_name = folder.Value;
- debug("+++ fixing up remote container " + folder_name + "\n");
- fixup_remote_container(folder_name);
- }
-
- sizeToContent();
- }
-
- function sidebar_customize_destruct()
- {
- var all_panels = document.getElementById('other-panels');
- debug("Removing observer from all_panels database.");
- all_panels.database.RemoveObserver(panels_observer);
- }
-
-
- //////////////////////////////////////////////////////////////////
- // Panels' RDF Datasource Observer
- //////////////////////////////////////////////////////////////////
- var panels_observer = {
- onAssert : function(ds,src,prop,target) {
- //debug ("observer: assert");
- // "refresh" is asserted by select menu and by customize.js.
- if (prop == RDF.GetResource(NC + "link")) {
- setTimeout("fixup_remote_container('"+src.Value+"')",100);
- //fixup_remote_container(src.Value);
- }
- },
- onUnassert : function(ds,src,prop,target) {
- //debug ("observer: unassert");
- },
- onChange : function(ds,src,prop,old_target,new_target) {
- //debug ("observer: change");
- },
- onMove : function(ds,old_src,new_src,prop,target) {
- //debug ("observer: move");
- },
- onBeginUpdateBatch : function(ds) {
- //debug ("observer: onBeginUpdateBatch");
- },
- onEndUpdateBatch : function(ds) {
- //debug ("observer: onEndUpdateBatch");
- }
- };
-
- function fixup_remote_container(id)
- {
- debug('fixup_remote_container('+id+')');
-
- var container = document.getElementById(id);
- if (container) {
- container.setAttribute('container', 'true');
- container.removeAttribute('open');
- }
- }
-
- function fixup_children(id) {
- // Add container="true" on nodes with "link" attribute
- var treeitem = document.getElementById(id);
-
- var children = treeitem.childNodes.item(1).childNodes;
- for (var ii=0; ii < children.length; ii++) {
- var child = children.item(ii);
- if (child.getAttribute('link') != '' &&
- child.getAttribute('container') != 'true') {
- child.setAttribute('container', 'true');
- child.removeAttribute('open');
- }
- }
- }
-
- 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)
- {
- enable_buttons_for_other_panels();
- }
-
- function ClickOnOtherPanels(event)
- {
- var tree = document.getElementById("other-panels");
-
- var rowIndex = -1;
- if (event.type == "click" && event.button == 0) {
- var row = {}, col = {}, obj = {};
- var b = tree.treeBoxObject;
- b.getCellAt(event.clientX, event.clientY, row, col, obj);
-
- if (obj.value == "twisty" || event.detail == 2) {
- rowIndex = row.value;
- }
- }
-
- if (rowIndex < 0) return;
-
- var treeitem = tree.contentView.getItemAtIndex(rowIndex);
- var res = RDF.GetResource(treeitem.id);
-
- if (treeitem.getAttribute('container') == 'true') {
- if (treeitem.getAttribute('open') == 'true') {
- var link = treeitem.getAttribute('link');
- var loaded_link = treeitem.getAttribute('loaded_link');
- if (link != '' && !loaded_link) {
- debug("Has remote datasource: "+link);
- add_datasource_to_other_panels(link);
- treeitem.setAttribute('loaded_link', 'true');
- } else {
- setTimeout('fixup_children("'+ treeitem.getAttribute('id') +'")', 100);
- }
- }
- }
-
- // Remove the selection in the "current" panels list
- var current_panels = document.getElementById('current-panels');
- current_panels.view.selection.clearSelection();
- enable_buttons_for_current_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);
-
- var uri = Components.classes['@mozilla.org/network/standard-url;1'].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', allPanelsObj.resource);
- }
-
- // 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.view.selection.clearSelection();
-
- enable_buttons_for_current_panels();
- }
-
- // Move the selected item up the the current panels list.
- function MoveUp() {
- var tree = document.getElementById('current-panels');
- if (tree.view.selection.count == 1) {
- var index = tree.currentIndex;
- var selected = tree.contentView.getItemAtIndex(index);
- var before = selected.previousSibling;
- if (before) {
- before.parentNode.removeChild(selected);
- before.parentNode.insertBefore(selected, before);
- tree.view.selection.select(index-1);
- tree.treeBoxObject.ensureRowIsVisible(index-1);
- }
- }
- }
-
- // Move the selected item down the the current panels list.
- function MoveDown() {
- var tree = document.getElementById('current-panels');
- if (tree.view.selection.count == 1) {
- var index = tree.currentIndex;
- var selected = tree.contentView.getItemAtIndex(index);
- if (selected.nextSibling) {
- if (selected.nextSibling.nextSibling)
- selected.parentNode.insertBefore(selected, selected.nextSibling.nextSibling);
- else
- selected.parentNode.appendChild(selected);
- tree.view.selection.select(index+1);
- tree.treeBoxObject.ensureRowIsVisible(index+1);
- }
- }
- }
-
- function PreviewPanel()
- {
- var tree = document.getElementById('other-panels');
- var database = tree.database;
- var sel = tree.view.selection;
- var rangeCount = sel.getRangeCount();
- for (var range = 0; range < rangeCount; ++range) {
- var min = {}, max = {};
- sel.getRangeAt(range, min, max);
- for (var index = min.value; index <= max.value; ++index) {
- var item = tree.contentView.getItemAtIndex(index);
- var res = RDF.GetResource(item.id);
-
- var preview_name = get_attr(database, res, 'title');
- var preview_URL = get_attr(database, res, 'content');
- if (!preview_URL || !preview_name) continue;
-
- window.openDialog("chrome://communicator/content/sidebar/preview.xul",
- "_blank", "chrome,resizable,close,dialog=no",
- preview_name, preview_URL);
- }
- }
- }
-
- // Add the selected panel(s).
- function AddPanel()
- {
- var added = -1;
-
- var tree = document.getElementById('other-panels');
- var database = tree.database;
- var sel = tree.view.selection;
- var ranges = sel.getRangeCount();
- for (var range = 0; range < ranges; ++range) {
- var min = {}, max = {};
- sel.getRangeAt(range, min, max);
- for (var index = min.value; index <= max.value; ++index) {
- var item = tree.contentView.getItemAtIndex(index);
- if (item.getAttribute("container") != "true") {
- var res = RDF.GetResource(item.id);
- // Add the panel to the current list.
- added = add_node_to_current_list(database, res);
- }
- }
- }
-
- if (added >= 0) {
- // Remove the selection in the other list.
- // Selection will move to "current" list.
- tree.view.selection.clearSelection();
-
- var current_panels = document.getElementById('current-panels');
- current_panels.view.selection.select(added);
- current_panels.treeBoxObject.ensureRowIsVisible(added);
- }
- }
-
- // Copy a panel node into a database such as the current panel list.
- function add_node_to_current_list(registry, service)
- {
- debug("Adding "+service.Value);
-
- // Copy out the attributes we want
- var option_title = get_attr(registry, service, 'title');
- var option_customize = get_attr(registry, service, 'customize');
- var option_content = get_attr(registry, service, 'content');
- if (!option_title || !option_content)
- return -1;
-
- var tree = document.getElementById('current-panels');
- var tree_root = tree.lastChild;
-
- // Check to see if the panel already exists...
- var i = 0;
- for (var treeitem = tree_root.firstChild; treeitem; treeitem = treeitem.nextSibling) {
- if (treeitem.id == service.Value)
- // The panel is already in the current panel list.
- // Avoid adding it twice.
- return i;
- ++i;
- }
-
- // Create a treerow for the new panel
- var item = document.createElement('treeitem');
- var row = document.createElement('treerow');
- var cell = document.createElement('treecell');
-
- // Copy over the attributes
- item.setAttribute('id', service.Value);
- cell.setAttribute('label', option_title);
-
- // Add it to the current panels tree
- item.appendChild(row);
- row.appendChild(cell);
- tree_root.appendChild(item);
- return i;
- }
-
- // Remove the selected panel(s) from the current list tree.
- function RemovePanel()
- {
- var tree = document.getElementById('current-panels');
- var sel = tree.view.selection;
-
- var nextNode = -1;
- var rangeCount = sel.getRangeCount();
- for (var range = rangeCount-1; range >= 0; --range) {
- var min = {}, max = {};
- sel.getRangeAt(range, min, max);
- for (var index = max.value; index >= min.value; --index) {
- var item = tree.contentView.getItemAtIndex(index);
- nextNode = item.nextSibling ? index : -1;
- item.parentNode.removeChild(item);
- }
- }
-
- if (nextNode >= 0)
- sel.select(nextNode);
- }
-
- // Bring up a new window with the customize url
- // for an individual panel.
- function CustomizePanel()
- {
- var tree = document.getElementById('current-panels');
- var numSelected = tree.view.selection.count;
-
- if (numSelected == 1) {
- var index = tree.currentIndex;
- var selectedNode = tree.contentView.getItemAtIndex(index);
- var panel_id = selectedNode.getAttribute('id');
- var customize_url = selectedNode.getAttribute('customize');
-
- debug("url = " + customize_url);
-
- if (!customize_url) return;
-
- window.openDialog('chrome://communicator/content/sidebar/customize-panel.xul',
- '_blank',
- 'chrome,resizable,width=690,height=600,dialog=no,close',
- panel_id,
- customize_url,
- sidebarObj.datasource_uri,
- sidebarObj.resource);
- }
- }
-
- function BrowseMorePanels()
- {
- var url = '';
- var browser_url = "chrome://navigator/content/navigator.xul";
- var locale;
- try {
- var prefs = Components.classes["@mozilla.org/preferences-service;1"]
- .getService(Components.interfaces.nsIPrefBranch);
- url = prefs.getCharPref("sidebar.customize.more_panels.url");
- var temp = prefs.getCharPref("browser.chromeURL");
- if (temp) browser_url = temp;
- } catch(ex) {
- debug("Unable to get prefs: "+ex);
- }
- window.openDialog(browser_url, "_blank", "chrome,all,dialog=no", url);
- }
-
- function customize_getBrowserURL()
- {
- return url;
- }
-
- // Serialize the new list of panels.
- function Save()
- {
- persist_dialog_dimensions();
-
- var all_panels = document.getElementById('other-panels');
- var current_panels = document.getElementById('current-panels');
-
- // See if list membership has changed
- var panels = [];
- var tree_root = current_panels.lastChild.childNodes;
- var list_unchanged = (tree_root.length == original_panels.length);
- for (var i = 0; i < tree_root.length; i++) {
- var panel = tree_root[i].id;
- panels.push(panel);
- panels[panel] = true;
- if (list_unchanged && original_panels[i] != panel)
- list_unchanged = false;
- }
- if (list_unchanged)
- return;
-
- // Remove all the current panels from the datasource.
- current_panels = sidebarObj.container.GetElements();
- while (current_panels.hasMoreElements()) {
- panel = current_panels.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
- if (panel.Value in panels) {
- // 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.
- // Saving the attributes will preserve things such as the exclude state.
- sidebarObj.container.RemoveElement(panel, false);
- } else {
- // Kiss it goodbye.
- delete_resource_deeply(sidebarObj.container, panel);
- }
- }
-
- // Add the new list of panels
- for (var ii = 0; ii < panels.length; ++ii) {
- var id = panels[ii];
- var resource = RDF.GetResource(id);
- if (id in original_panels) {
- sidebarObj.container.AppendElement(resource);
- } else {
- copy_resource_deeply(all_panels.database, resource, sidebarObj.container);
- }
- }
- refresh_all_sidebars();
-
- // Write the modified panels out.
- sidebarObj.datasource.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource).Flush();
- }
-
- // 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();
- }
-
- // Use an assertion to pass a "refresh" event to all the sidebars.
- // They use observers to watch for this assertion (in sidebarOverlay.js).
- function refresh_all_sidebars() {
- sidebarObj.datasource.Assert(RDF.GetResource(sidebarObj.resource),
- RDF.GetResource(NC + "refresh"),
- RDF.GetLiteral("true"),
- true);
- sidebarObj.datasource.Unassert(RDF.GetResource(sidebarObj.resource),
- RDF.GetResource(NC + "refresh"),
- 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(resource, 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 sel = all_panels.view.selection;
- var num_selected = sel ? sel.count : 0;
- if (sel) {
- var ranges = sel.getRangeCount();
- for (var range = 0; range < ranges; ++range) {
- var min = {}, max = {};
- sel.getRangeAt(range, min, max);
- for (var index = min; index <= max; ++index) {
- var node = all_panels.contentView.getItemAtIndex(index);
- if (node.getAttribute('container') != 'true') {
- ++num_selected;
- }
- }
- }
- }
-
- if (num_selected > 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.view.selection.count;
- var canMoveUp = false, canMoveDown = false, customizeURL = '';
-
- if (numSelected == 1 && tree.view.selection.isSelected(tree.currentIndex)) {
- var selectedNode = tree.view.getItemAtIndex(tree.currentIndex);
- customizeURL = selectedNode.getAttribute('customize');
- canMoveUp = selectedNode != selectedNode.parentNode.firstChild;
- canMoveDown = selectedNode != selectedNode.parentNode.lastChild;
- }
-
- up.disabled = !canMoveUp;
- down.disabled = !canMoveDown;
- customize.disabled = !customizeURL;
- remove.disabled = !numSelected;
- }
-
- function persist_dialog_dimensions() {
- // Stole this code from navigator.js to
- // insure the windows dimensions are saved.
-
- // Get the current window position/size.
- var x = window.screenX;
- var y = window.screenY;
- var h = window.outerHeight;
- var w = window.outerWidth;
-
- // Store these into the window attributes (for persistence).
- var win = document.getElementById( "main-window" );
- win.setAttribute( "x", x );
- win.setAttribute( "y", y );
- win.setAttribute( "height", h );
- win.setAttribute( "width", w );
- }
-
- ///////////////////////////////////////////////////////////////
- // Handy Debug Tools
- //////////////////////////////////////////////////////////////
- var debug = null;
- var dump_attributes = null;
- var dump_tree = null;
- var _dump_tree_recur = null;
-
- if (!CUST_DEBUG) {
- debug = function (s) {};
- dump_attributes = function (node, depth) {};
- dump_tree = function (node) {};
- _dump_tree_recur = function (node, depth, index) {};
- } else {
- debug = function (s) { dump("-*- sb customize: " + s + "\n"); };
-
- dump_attributes = function (node, depth) {
- var attributes = node.attributes;
- var indent = "| | | | | | | | | | | | | | | | | | | | | | | | | | | | . ";
-
- if (!attributes || attributes.length == 0) {
- debug(indent.substr(indent.length - depth*2) + "no attributes");
- }
- for (var ii=0; ii < attributes.length; ii++) {
- var attr = attributes.item(ii);
- debug(indent.substr(indent.length - depth*2) + attr.name +
- "=" + attr.value);
- }
- }
- dump_tree = function (node) {
- _dump_tree_recur(node, 0, 0);
- }
- _dump_tree_recur = function (node, depth, index) {
- if (!node) {
- debug("dump_tree: node is null");
- }
- var indent = "| | | | | | | | | | | | | | | | | | | | | | | | | | | | + ";
- debug(indent.substr(indent.length - depth*2) + index +
- " " + node.nodeName);
- if (node.nodeName != "#text") {
- dump_attributes(node, depth);
- }
- var kids = node.childNodes;
- for (var ii=0; ii < kids.length; ii++) {
- _dump_tree_recur(kids[ii], depth + 1, ii);
- }
- }
- }
-
- //////////////////////////////////////////////////////////////
- // Install the load/unload handlers
- //////////////////////////////////////////////////////////////
- addEventListener("load", sidebar_customize_init, false);
- addEventListener("unload", sidebar_customize_destruct, false);
-