From 6a64cd597b36411fa01d681c693786750b68c92c Mon Sep 17 00:00:00 2001
From: "myk%mozilla.org" <>
Date: Tue, 5 Nov 2002 09:53:59 +0000
Subject: Fix for bug 156548: XUL implementation of duplicates report.
---
CGI.pl | 2 +-
checksetup.pl | 6 +-
collectstats.pl | 17 +++
css/duplicates.css | 27 +++++
duplicates.cgi | 12 ++
duplicates.xul | 133 ++++++++++++++++++++
js/duplicates.js | 153 ++++++++++++++++++++++++
skins/standard/duplicates.css | 27 +++++
template/en/default/reports/duplicates.rdf.tmpl | 51 ++++++++
9 files changed, 426 insertions(+), 2 deletions(-)
create mode 100644 css/duplicates.css
create mode 100644 duplicates.xul
create mode 100644 js/duplicates.js
create mode 100644 skins/standard/duplicates.css
create mode 100644 template/en/default/reports/duplicates.rdf.tmpl
diff --git a/CGI.pl b/CGI.pl
index d6dca3a39..2069d9235 100644
--- a/CGI.pl
+++ b/CGI.pl
@@ -206,7 +206,7 @@ sub get_netaddr {
my ($ipaddr) = @_;
# Check for a valid IPv4 addr which we know how to parse
- if ($ipaddr !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
+ if (!$ipaddr || $ipaddr !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
return undef;
}
diff --git a/checksetup.pl b/checksetup.pl
index 3a60a3937..aa91c3a34 100755
--- a/checksetup.pl
+++ b/checksetup.pl
@@ -837,8 +837,12 @@ END
open HTACCESS, ">data/.htaccess";
print HTACCESS <<'END';
# nothing in this directory is retrievable unless overriden by an .htaccess
-# in a subdirectory
+# in a subdirectory; the only exception is duplicates.rdf, which is used by
+# duplicates.xul and must be loadable over the web
deny from all
+
+ allow from all
+
END
close HTACCESS;
chmod $fileperm, "data/.htaccess";
diff --git a/collectstats.pl b/collectstats.pl
index 8caf92d77..61e7cf204 100755
--- a/collectstats.pl
+++ b/collectstats.pl
@@ -53,6 +53,23 @@ foreach (@myproducts) {
&calculate_dupes();
+# Generate a static RDF file containing the default view of the duplicates data.
+open(CGI, "REQUEST_METHOD=GET QUERY_STRING=ctype=rdf ./duplicates.cgi |")
+ || die "can't fork duplicates.cgi: $!";
+open(RDF, ">data/duplicates.tmp")
+ || die "can't write to data/duplicates.tmp: $!";
+my $headers_done = 0;
+while () {
+ print RDF if $headers_done;
+ $headers_done = 1 if $_ eq "\n";
+}
+close CGI;
+close RDF;
+if (-s "data/duplicates.tmp") {
+ rename("data/duplicates.rdf", "data/duplicates-old.rdf");
+ rename("data/duplicates.tmp", "data/duplicates.rdf");
+}
+
sub check_data_dir {
my $dir = shift;
diff --git a/css/duplicates.css b/css/duplicates.css
new file mode 100644
index 000000000..aab36fb2a
--- /dev/null
+++ b/css/duplicates.css
@@ -0,0 +1,27 @@
+/* The contents of this file are subject to the Mozilla 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/MPL/
+ *
+ * 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 the Bugzilla Bug Tracking System.
+ *
+ * The Initial Developer of the Original Code is Netscape Communications
+ * Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s): Myk Melez
+ */
+
+treechildren:-moz-tree-cell-text(resolution-FIXED) {
+ text-decoration: line-through;
+}
+
+treecol#id_column { width: 6em; }
+treecol#duplicate_count_column { width: 5em; }
+treecol#duplicate_delta_column { width: 5em; }
diff --git a/duplicates.cgi b/duplicates.cgi
index 643a54423..e95d4b02c 100755
--- a/duplicates.cgi
+++ b/duplicates.cgi
@@ -32,6 +32,18 @@ use lib qw(.);
require "globals.pl";
require "CGI.pl";
+use vars qw($buffer);
+
+# Go directly to the XUL version of the duplicates report (duplicates.xul)
+# if the user specified ctype=xul. Adds params if they exist, and directs
+# the user to a signed copy of the script in duplicates.jar if it exists.
+if ($::FORM{'ctype'} eq "xul") {
+ my $params = CanonicaliseParams($::buffer, ["format", "ctype"]);
+ print "Location: " . (-e "duplicates.jar" ? "duplicates.jar!/" : "") .
+ "duplicates.xul" . ($params ? "?$params" : "") . "\n\n";
+ exit;
+}
+
# Use global templatisation variables.
use vars qw($template $vars);
diff --git a/duplicates.xul b/duplicates.xul
new file mode 100644
index 000000000..be647c188
--- /dev/null
+++ b/duplicates.xul
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+]>
+
+
+
+
+
+
+ // Code for populating the tree from the RDF data source
+ // and loading bug reports when the user selects rows in the tree.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/js/duplicates.js b/js/duplicates.js
new file mode 100644
index 000000000..b1e94a8a6
--- /dev/null
+++ b/js/duplicates.js
@@ -0,0 +1,153 @@
+/* The contents of this file are subject to the Mozilla 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/MPL/
+ *
+ * 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 the Bugzilla Bug Tracking System.
+ *
+ * The Initial Developer of the Original Code is Netscape Communications
+ * Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s): Myk Melez
+ */
+
+// When the XUL window finishes loading, load the RDF data into it.
+window.addEventListener('load', loadData, false);
+
+// The base URL of this Bugzilla installation; derived from the page's URL.
+var gBaseURL = window.location.href.replace(/duplicates\.(jar!|xul).*/, "");
+
+function loadData()
+{
+ // Loads the duplicates data as an RDF data source, attaches it to the tree,
+ // and rebuilds the tree to display the data.
+
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+
+ // Get the RDF service so we can use it to load the data source.
+ var rdfService =
+ Components
+ .classes["@mozilla.org/rdf/rdf-service;1"]
+ .getService(Components.interfaces.nsIRDFService);
+
+ // When a bug report loads in the content iframe, a 'load' event bubbles up
+ // to the browser window, which calls this load handler again, which reloads
+ // the RDF data, which causes the tree to lose the selection. To prevent
+ // this, we have to remove this handler.
+ window.removeEventListener('load', loadData, false);
+
+ // The URL of the RDF file; by default for performance a static file
+ // generated by collectstats.pl, but a call to duplicates.cgi if the page's
+ // URL contains parameters (so we can dynamically generate the RDF data
+ // based on those parameters).
+ var dataURL = gBaseURL + "data/duplicates.rdf";
+ if (window.location.href.search(/duplicates\.xul\?.+/) != -1)
+ dataURL = window.location.href.replace(/(duplicates\.jar!\/)?duplicates\.xul\?/, "duplicates.cgi?ctype=rdf&");
+
+ // Get the data source and add it to the XUL tree's database to populate
+ // the tree with the data.
+ var dataSource = rdfService.GetDataSource(dataURL);
+
+ // If we're using the static file, add an observer that detects failed loads
+ // (in case this installation isn't generating the file nightly) and redirects
+ // to the CGI version when loading of the static version fails.
+ if (window.location.href.search(/duplicates\.xul\?.+/) == -1)
+ {
+ var sink = dataSource.QueryInterface(Components.interfaces.nsIRDFXMLSink);
+ sink.addXMLSinkObserver(StaticDataSourceObserver);
+ }
+
+ // Add the data source to the tree, set the tree's "ref" attribute
+ // to the base URL of the data source, and rebuild the tree.
+ var resultsTree = document.getElementById('results-tree');
+ resultsTree.database.AddDataSource(dataSource);
+ resultsTree.setAttribute('ref', gBaseURL + "data/duplicates.rdf");
+ resultsTree.builder.rebuild();
+}
+
+function getBugURI()
+{
+ var tree = document.getElementById('results-tree');
+ var index = tree.currentIndex;
+
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+ var builder = tree.builder.QueryInterface(Components.interfaces.nsIXULTreeBuilder);
+ var resource = builder.getResourceAtIndex(index);
+
+ return resource.Value;
+}
+
+function loadBugInWindow()
+{
+ // Loads the selected bug in the browser window, replacing the duplicates report
+ // with the bug report.
+
+ var bugURI = getBugURI();
+ window.location = bugURI;
+}
+
+function loadBugInPane()
+{
+ // Loads the selected bug in the iframe-based content pane that is part of
+ // this XUL document.
+
+ var splitter = document.getElementById('report-content-splitter');
+ var state = splitter.getAttribute('state');
+ if (state != "collapsed")
+ {
+ var bugURI = getBugURI();
+ var browser = document.getElementById('content-browser');
+ browser.setAttribute('src', bugURI);
+ }
+}
+
+var StaticDataSourceObserver = {
+ onBeginLoad: function(aSink) { } ,
+ onInterrupt: function(aSink) { } ,
+ onResume: function(aSink) { } ,
+ onEndLoad: function(aSink)
+ {
+ // Removes the observer from the data source so it doesn't stay around
+ // when duplicates.xul is reloaded from scratch.
+
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+
+ aSink.removeXMLSinkObserver(StaticDataSourceObserver);
+ } ,
+ onError: function(aSink, aStatus, aErrorMsg)
+ {
+ // Tries the dynamic data source since the static one failed to load.
+
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+
+ // Get the RDF service so we can use it to load the data source.
+ var rdfService =
+ Components
+ .classes["@mozilla.org/rdf/rdf-service;1"]
+ .getService(Components.interfaces.nsIRDFService);
+
+ // Remove the observer from the data source so it doesn't stay around
+ // when duplicates.xul is reloaded from scratch.
+ aSink.removeXMLSinkObserver(StaticDataSourceObserver);
+
+ // Remove the static data source from the tree.
+ var oldDataSource = aSink.QueryInterface(Components.interfaces.nsIRDFDataSource);
+ var resultsTree = document.getElementById('results-tree');
+ resultsTree.database.RemoveDataSource(oldDataSource);
+
+ // Munge the URL to point to the CGI and load the data source.
+ var dataURL = gBaseURL + "duplicates.cgi?ctype=rdf";
+ newDataSource = rdfService.GetDataSource(dataURL);
+
+ // Add the data source to the tree and rebuild the tree with the new data.
+ resultsTree.database.AddDataSource(newDataSource);
+ resultsTree.builder.rebuild();
+ }
+};
diff --git a/skins/standard/duplicates.css b/skins/standard/duplicates.css
new file mode 100644
index 000000000..aab36fb2a
--- /dev/null
+++ b/skins/standard/duplicates.css
@@ -0,0 +1,27 @@
+/* The contents of this file are subject to the Mozilla 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/MPL/
+ *
+ * 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 the Bugzilla Bug Tracking System.
+ *
+ * The Initial Developer of the Original Code is Netscape Communications
+ * Corporation. Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation. All
+ * Rights Reserved.
+ *
+ * Contributor(s): Myk Melez
+ */
+
+treechildren:-moz-tree-cell-text(resolution-FIXED) {
+ text-decoration: line-through;
+}
+
+treecol#id_column { width: 6em; }
+treecol#duplicate_count_column { width: 5em; }
+treecol#duplicate_delta_column { width: 5em; }
diff --git a/template/en/default/reports/duplicates.rdf.tmpl b/template/en/default/reports/duplicates.rdf.tmpl
new file mode 100644
index 000000000..941f9f70f
--- /dev/null
+++ b/template/en/default/reports/duplicates.rdf.tmpl
@@ -0,0 +1,51 @@
+[% template_version = "1.0@bugzilla.org" %]
+[%# The contents of this file are subject to the Mozilla 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/MPL/
+ #
+ # 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 the Bugzilla Bug Tracking System.
+ #
+ # The Initial Developer of the Original Code is Netscape Communications
+ # Corporation. Portions created by Netscape are
+ # Copyright (C) 1998 Netscape Communications Corporation. All
+ # Rights Reserved.
+ #
+ # Contributor(s): Myk Melez
+ #%]
+
+
+
+
+
+
+
+
+ [% FOREACH bug = bugs %]
+
+
+ [% bug.id %]
+ [% bug.resolution FILTER html %]
+ [% bug.count %]
+ [% bug.delta %]
+ [% bug.component FILTER html %]
+ [% bug.bug_severity FILTER html %]
+ [% bug.op_sys FILTER html %]
+ [% bug.target_milestone FILTER html %]
+ [% bug.short_desc FILTER html %]
+
+
+ [% END %]
+
+
+
+
+
--
cgit v1.2.3-24-g4f1b