!import
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is Mozilla Communicator client code, released
15 * March 31, 1998.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998-1999
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 * Akkana Peck (akkana@netscape.com)
24 * Charles Manxke (cmanske@netscape.com)
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
39
40 // Variables used across all the links being checked:
41 var gNumLinksToCheck = 0; // The number of nsILinkCheckers
42 var gLinksBeingChecked = []; // Array of nsIURICheckers
43 var gURIRefObjects = []; // Array of nsIURIRefObjects
44 var gNumLinksCalledBack = 0;
45 var gStartedAllChecks = false;
46 var gLinkCheckTimerID = 0;
47
48 // Implement nsIRequestObserver:
49 var gRequestObserver =
50 {
51 // urichecker requires that we have an OnStartRequest even tho it's a nop.
onStartRequest
52 onStartRequest: function(request, ctxt) { },
53
54 // onStopRequest is where we really handle the status.
onStopRequest
55 onStopRequest: function(request, ctxt, status)
56 {
57 var linkChecker = request.QueryInterface(Components.interfaces.nsIURIChecker);
58 if (linkChecker)
59 {
60 gNumLinksCalledBack++;
61 linkChecker.status = status;
62 for (var i = 0; i < gNumLinksCalledBack; i++)
63 {
64 if (linkChecker == gLinksBeingChecked[i])
65 gLinksBeingChecked[i].status = status;
66 }
67
68 if (gStartedAllChecks && gNumLinksCalledBack >= gNumLinksToCheck)
69 {
70 clearTimeout(gLinkCheckTimerID);
71 LinkCheckTimeOut();
72 }
73 }
74 }
75 }
76
Startup
77 function Startup()
78 {
79 var editor = GetCurrentEditor();
80 if (!editor)
81 {
82 window.close();
83 return;
84 }
85
86 // Get all objects that refer to other locations
87 var objects;
88 try {
89 objects = editor.getLinkedObjects();
90 } catch (e) {}
91
92 if (!objects || objects.Count() == 0)
93 {
94 AlertWithTitle(GetString("Alert"), GetString("NoLinksToCheck"));
95 window.close();
96 return;
97 }
98
99 gDialog.LinksList = document.getElementById("LinksList");
100
101 // Set window location relative to parent window (based on persisted attributes)
102 SetWindowLocation();
103
104
105 // Loop over the nodes that have links:
106 for (var i = 0; i < objects.Count(); i++)
107 {
108 var refobj = objects.GetElementAt(gNumLinksToCheck).QueryInterface(Components.interfaces.nsIURIRefObject);
109 // Loop over the links in this node:
110 if (refobj)
111 {
112 try {
113 var uri;
114 while ((uri = refobj.GetNextURI()))
115 {
116 // Use the real class in netlib:
117 // Note that there may be more than one link per refobj
118 gURIRefObjects[gNumLinksToCheck] = refobj;
119
120 // Make a new nsIURIChecker
121 gLinksBeingChecked[gNumLinksToCheck]
122 = Components.classes["@mozilla.org/network/urichecker;1"]
123 .createInstance()
124 .QueryInterface(Components.interfaces.nsIURIChecker);
125 // XXX uri creation needs to be localized
126 gLinksBeingChecked[gNumLinksToCheck].init(GetIOService().newURI(uri, null, null));
127 gLinksBeingChecked[gNumLinksToCheck].asyncCheck(gRequestObserver, null);
128
129 // Add item
130 var linkChecker = gLinksBeingChecked[gNumLinksToCheck].QueryInterface(Components.interfaces.nsIURIChecker);
131 SetItemStatus(linkChecker.name, "busy");
132 dump(" *** Linkcount = "+gNumLinksToCheck+"\n");
133 gNumLinksToCheck++;
134
135 };
136 } catch (e) { dump (" *** EXCEPTION\n");}
137 }
138 }
139 // Done with the loop, now we can be prepared for the finish:
140 gStartedAllChecks = true;
141
142 // Start timer to limit how long we wait for link checking
143 gLinkCheckTimerID = setTimeout("LinkCheckTimeOut()", 5000);
144 window.sizeToContent();
145 }
146
LinkCheckTimeOut
147 function LinkCheckTimeOut()
148 {
149 // We might have gotten here via a late timeout
150 if (gNumLinksToCheck <= 0)
151 return;
152 gLinkCheckTimerID = 0;
153
154 gNumLinksToCheck = 0;
155 gStartedAllChecks = false;
156 for (var i=0; i < gLinksBeingChecked.length; i++)
157 {
158 var linkChecker = gLinksBeingChecked[i].QueryInterface(Components.interfaces.nsIURIChecker);
159 // nsIURIChecker status values:
160 // NS_BINDING_SUCCEEDED link is valid
161 // NS_BINDING_FAILED link is invalid (gave an error)
162 // NS_BINDING_ABORTED timed out, or cancelled
163 switch (linkChecker.status)
164 {
165 case 0: // NS_BINDING_SUCCEEDED
166 SetItemStatus(linkChecker.name, "done");
167 break;
168 case 0x804b0001: // NS_BINDING_FAILED
169 dump(">> " + linkChecker.name + " is broken\n");
170 case 0x804b0002: // NS_BINDING_ABORTED
171 // dump(">> " + linkChecker.name + " timed out\n");
172 default:
173 // dump(">> " + linkChecker.name + " not checked\n");
174 SetItemStatus(linkChecker.name, "failed");
175 break;
176 }
177 }
178 }
179
180 // Add url to list of links to check
181 // or set status for file already in the list
182 // Returns true if url was in the list
SetItemStatus
183 function SetItemStatus(url, status)
184 {
185 if (!url)
186 return false;
187
188 if (!status)
189 status = "busy";
190
191 // Just set attribute for status icon
192 // if we already have this url
193 var listitems = document.getElementsByTagName("listitem");
194 if (listitems)
195 {
196 for (var i=0; i < listitems.length; i++)
197 {
198 if (listitems[i].getAttribute("label") == url)
199 {
200 listitems[i].setAttribute("progress", status);
201 return true;
202 }
203 }
204 }
205
206 // We're adding a new item to list
207 var listitem = document.createElementNS(XUL_NS, "listitem");
208 if (listitem)
209 {
210 listitem.setAttribute("class", "listitem-iconic progressitem");
211 // This triggers CSS to show icon for each status state
212 listitem.setAttribute("progress", status);
213 listitem.setAttribute("label", url);
214 gDialog.LinksList.appendChild(listitem);
215 }
216 return false;
217 }
218
onAccept
219 function onAccept()
220 {
221 SaveWindowLocation();
222 return true; // do close the window
223 }
224
onCancelLinkChecker
225 function onCancelLinkChecker()
226 {
227 if (gLinkCheckTimerID)
228 clearTimeout(gLinkCheckTimerID);
229
230 /*
231 LinkCheckTimeOut();
232 */
233 return onCancel();
234 }