Revision f533f224 ui/templates/home.html
b/ui/templates/home.html | ||
---|---|---|
1 | 1 |
{% load i18n %} |
2 | 2 |
<!DOCTYPE html> |
3 | 3 |
<head> |
4 |
<title>{{ project }}</title>
|
|
5 |
<!-- include the Tools -->
|
|
4 |
<title>{{ project }}</title>
|
|
5 |
<!-- include the Tools -->
|
|
6 | 6 |
<!-- jquery tools minified for deployment--> |
7 | 7 |
<script src="static/jquery.tools.min.js"></script> |
8 |
|
|
9 |
<!-- jquery tools source for JS debugging --> |
|
8 |
<!-- jquery tools source for JS debugging --> |
|
10 | 9 |
<!-- |
11 |
<script src="http://flowplayer.org/tools/download/1.2.5/jquery-1.4.2.js"></script>
|
|
12 |
<script src="http://flowplayer.org/tools/download/1.2.5/tabs/tabs.js"></script>
|
|
13 |
<script src="http://flowplayer.org/tools/download/1.2.5/scrollable/scrollable.js"></script>
|
|
14 |
<script src="http://flowplayer.org/tools/download/1.2.5/overlay/overlay.js"></script>
|
|
15 |
<script src="http://flowplayer.org/tools/download/1.2.5/rangeinput/rangeinput.js"></script>
|
|
16 |
<script src="http://flowplayer.org/tools/download/1.2.5/toolbox/toolbox.expose.js"></script>
|
|
10 |
<script src="http://flowplayer.org/tools/download/1.2.5/jquery-1.4.2.js"></script> |
|
11 |
<script src="http://flowplayer.org/tools/download/1.2.5/tabs/tabs.js"></script>
|
|
12 |
<script src="http://flowplayer.org/tools/download/1.2.5/scrollable/scrollable.js"></script>
|
|
13 |
<script src="http://flowplayer.org/tools/download/1.2.5/overlay/overlay.js"></script>
|
|
14 |
<script src="http://flowplayer.org/tools/download/1.2.5/rangeinput/rangeinput.js"></script>
|
|
15 |
<script src="http://flowplayer.org/tools/download/1.2.5/toolbox/toolbox.expose.js"></script>
|
|
17 | 16 |
--> |
18 |
|
|
19 | 17 |
<script src="static/jquery.cookie.js"></script> |
20 |
<script src="static/jQueryRotate.js"></script> |
|
21 | 18 |
<script src="static/jquery.dataTables.min.js"></script> |
22 | 19 |
<script src="static/synnefo.js"></script> |
23 |
<link rel="stylesheet" type="text/css" href="static/main.css"/>
|
|
20 |
<link rel="stylesheet" type="text/css" href="static/main.css"/>
|
|
24 | 21 |
<script> |
22 |
//populate available image icons array |
|
23 |
var os_icons = {{image_icons|safe}}; |
|
24 |
|
|
25 | 25 |
// timeout value from settings.py |
26 | 26 |
var TIMEOUT = {{timeout}}; |
27 | 27 |
var UPDATE_INTERVAL = {{5000}}; |
28 |
var STATUS_MESSAGES = { |
|
28 |
var STATUSES = { |
|
29 |
'UNKNOWN' : '{% trans "Unknown" %}', |
|
29 | 30 |
'BUILD' : '{% trans "Building" %}', |
30 |
'REBOOT' : '{% trans "Rebooting" %}',
|
|
31 |
'REBOOT' : '{% trans "Rebooting" %}',
|
|
31 | 32 |
'STOPPED' : '{% trans "Stopped" %}', |
32 |
'ACTIVE' : '{% trans "Running" %}', |
|
33 |
'ERROR' : '{% trans "Error" %}' |
|
33 |
'ACTIVE' : '{% trans "Running" %}', |
|
34 |
'ERROR' : '{% trans "Error" %}' |
|
35 |
}; |
|
36 |
|
|
37 |
var TRANSITIONS = { |
|
38 |
'Shutting down' : '{% trans "Shutting down" %}', |
|
39 |
'Rebooting' : '{% trans "Rebooting" %}', |
|
40 |
'Starting' : '{% trans "Starting" %}', |
|
41 |
'Destroying' : '{% trans "Destroying" %}' |
|
34 | 42 |
}; |
35 |
|
|
43 |
|
|
44 |
// Statuses and transitions that should be displayed as active or inactive |
|
45 |
var ACTIVE_STATES = [ |
|
46 |
'{% trans "Building" %}', |
|
47 |
'{% trans "Rebooting" %}', |
|
48 |
'{% trans "Running" %}', |
|
49 |
'{% trans "Shutting down" %}', |
|
50 |
'{% trans "Rebooting" %}', |
|
51 |
'{% trans "Destroying" %}' |
|
52 |
]; |
|
53 |
|
|
54 |
var INACTIVE_STATES = [ |
|
55 |
'{% trans "Unknown" %}', |
|
56 |
'{% trans "Stopped" %}', |
|
57 |
'{% trans "Error" %}', |
|
58 |
'{% trans "Starting" %}', |
|
59 |
'{% trans "Destroying" %}' |
|
60 |
]; |
|
61 |
|
|
36 | 62 |
var ERRORS = { |
37 | 63 |
// error message header |
38 |
'HEADER' : '{% trans "Error!" %}',
|
|
64 |
'HEADER' : '{% trans "Error" %}', |
|
39 | 65 |
// default |
40 | 66 |
'DEFAULT' : '{% trans "Could not contact the service. Please check your network connectivity and try again." %}', |
41 | 67 |
// bad request |
... | ... | |
47 | 73 |
// service unavailable |
48 | 74 |
'501' : '{% trans "This server has not been implemented yet." %}', |
49 | 75 |
// service unavailable |
76 |
'502' : '{% trans "Bad Gateway error." %}', |
|
77 |
// service unavailable |
|
50 | 78 |
'503' : '{% trans "This service is unavailable right now, please try again later." %}', |
51 | 79 |
// no server handshake |
52 | 80 |
'0' : '{% trans "Could not contact the server." %}', |
53 | 81 |
// no images found |
54 | 82 |
'NO_IMAGES' : '{% trans "Cannot show the Create machine wizard: No images found." %}', |
55 | 83 |
// no flavors found |
56 |
'NO_FLAVORS' : '{% trans "Cannot show the Create machine wizard: No machine configurations found." %}' |
|
84 |
'NO_FLAVORS' : '{% trans "Cannot show the Create machine wizard: No machine configurations found." %}', |
|
85 |
// error box title |
|
86 |
'GENERIC_POPUP_HEADER' : '{% trans "Something seems to have gone wrong :( Here is what happened:" %}', |
|
87 |
// no advanced details |
|
88 |
'NO_DETAILS' : '{% trans "Νο advanced details provided" %}' |
|
57 | 89 |
}; |
58 |
|
|
90 |
|
|
59 | 91 |
var SUCCESS = { |
60 |
'HEADER' : '{% trans "Success!" %}',
|
|
92 |
'HEADER' : '{% trans "Success" %}', |
|
61 | 93 |
'DEFAULT' : '{% trans "Your request has been succefully executed." %}', |
94 |
'PASSWORD' : '{% trans "Password:" %}', |
|
62 | 95 |
'CREATE_VM_SUCCESS' : '{% trans "Success!" %}', |
63 |
'CREATE_VM_SUCCESS_ONE' : '{% trans "Your machine is now being built." %}', |
|
64 |
'CREATE_VM_SUCCESS_TWO' : '{% trans "Please write down the following password:" %}', |
|
65 |
'CREATE_VM_SUCCESS_THREE' : '{% trans "Do not lose this! You will need it to connect to your machine, once it is ready." %}' |
|
96 |
'CREATE_VM_SUCCESS_ONE' : '{% trans "Your new machine is now buidling... (this might take a few minutes)" %}', |
|
97 |
'CREATE_VM_SUCCESS_TWO' : '{% trans "Write down your password now!" %}', |
|
98 |
'CREATE_VM_SUCCESS_THREE' : '{% trans "You will need this later to connect to your machine." %}', |
|
99 |
'CREATE_VM_SUCCESS_FOUR' : '{% trans "After closing this window you will NOT be able to retrieve it again." %}' |
|
66 | 100 |
}; |
67 |
|
|
68 |
// ajax error checking
|
|
101 |
|
|
102 |
// ajax error checking |
|
69 | 103 |
function ajax_error(status, serverID, action, responseText) { |
70 | 104 |
var serverName = ''; |
71 |
|
|
105 |
|
|
72 | 106 |
if (serverID != undefined) { |
73 | 107 |
// standard view |
74 | 108 |
serverName = $("#"+serverID).find("span.name").text(); |
75 | 109 |
if (serverName == "") { // list view |
76 |
serverName = $("#"+serverID).parent().parent().find("span.name").text();
|
|
110 |
serverName = $("#"+serverID).parent().parent().find("span.name").text(); |
|
77 | 111 |
} |
78 | 112 |
} |
79 |
|
|
113 |
|
|
80 | 114 |
// prepare the error message |
81 | 115 |
$("#error-success h3").text(ERRORS['HEADER']); |
82 | 116 |
if (responseText != undefined){ |
83 |
var errors = parse_error(responseText), details = ''; |
|
117 |
var errors = parse_error(responseText, status), details = '';
|
|
84 | 118 |
if (serverName){ |
85 |
serverName="<p><strong>Server:</strong> " + serverName + "</p>";
|
|
119 |
serverName="<p>{% trans "Server" %}: " + serverName + "</p>";
|
|
86 | 120 |
} |
87 |
if (errors[0].details != undefined) { |
|
88 |
details = "<p><strong>Details:</strong> " + errors[0].details +"</p>"; |
|
121 |
if ((errors[0].details == undefined) || (errors[0].details == "")) { |
|
122 |
details = ERRORS["NO_DETAILS"]; |
|
123 |
} else { |
|
124 |
details = errors[0].details; |
|
89 | 125 |
} |
90 |
$("#error-success div").html("<p>"+(errors[0].message || ERRORS[errors[0].code]) +"</p>"+serverName +"<p><strong>Action:</strong> " + action + "</p><p><strong>Code</strong>: " + errors[0].code + "</p>" + details); |
|
126 |
|
|
127 |
//$("#error-success div.popup-body-inner").html("<p>"+(errors[0].message || ERRORS[errors[0].code]) +"</p>"+serverName +"<p><strong>{% trans "Action" %}:</strong> " + action + "</p><p><strong>{% trans "Code" %}:</strong> " + errors[0].code + "</p>" + details); |
|
128 |
$("#error-success .machine-now-building").html(ERRORS["GENERIC_POPUP_HEADER"]); |
|
129 |
$("#error-success .popup-header").addClass("popup-header-error"); |
|
130 |
$("#error-success").addClass("popup-border-error"); |
|
131 |
$("#error-success .password-container").hide(); |
|
132 |
$("#error-success .popup-details").addClass("popup-details-error"); |
|
133 |
$("#error-success .popup-separator").addClass("popup-separator-error"); |
|
134 |
$("#error-success .popup-details").html("<p>"+(errors[0].message || ERRORS[errors[0].code]) +"</p>"+serverName +"<p>{% trans "Action" %}: " + action + "</p><p>{% trans "Code" %}: " + errors[0].code + "<p><a class='expand-details' href='#'>{% trans 'Details' %}</a><div class='more-details'>" + details + "</div></p>"); |
|
91 | 135 |
} else if (ERRORS[status] != undefined) { |
92 | 136 |
if (serverID == undefined){ |
93 | 137 |
$("#error-success p").text(ERRORS[status]); |
... | ... | |
95 | 139 |
$("#error-success p").html("<b>" + serverName + "</b>" + ": " + ERRORS[status]); |
96 | 140 |
} |
97 | 141 |
} else { |
98 |
$("#error-success p").text(ERRORS['DEFAULT']); |
|
142 |
$("#error-success p").text(ERRORS['DEFAULT']); |
|
143 |
} |
|
144 |
$("#error-success p:first").css("padding-bottom","10px"); |
|
145 |
$("#error-success p:first").css("color","#800000"); |
|
146 |
$("#error-success div.more-details").hide(); |
|
147 |
$("#error-success a.expand-details").live('click', function() { |
|
148 |
$(this).parent().parent().find("div.more-details").slideToggle(600); |
|
149 |
return false; |
|
150 |
}); |
|
151 |
//stop the progress icon and hide the wizard |
|
152 |
if (action != undefined) { |
|
153 |
if (action == 'Create VM') { |
|
154 |
$('#wizard #start').text('{% trans "Create VM" %}'); |
|
155 |
$("#wizard").hide(); |
|
156 |
} else if (action == 'Create network') { |
|
157 |
$('#networks-wizard').hide(); |
|
158 |
} else if (action == 'Add server to network') { |
|
159 |
$('#add-machines-wizard').hide(); |
|
160 |
} |
|
99 | 161 |
} |
100 |
|
|
162 |
|
|
101 | 163 |
// bring up error notification |
102 | 164 |
var triggers = $("a#notification").overlay({ |
103 | 165 |
// some mask tweaks suitable for modal dialogs |
... | ... | |
118 | 180 |
$("a#notification").data('overlay').load(); |
119 | 181 |
return false; |
120 | 182 |
} |
121 |
|
|
183 |
|
|
122 | 184 |
// ajax success checking |
123 | 185 |
function ajax_success(status, password) { |
124 | 186 |
// prepare the error message |
125 | 187 |
// bring up success notification |
126 | 188 |
if (status != undefined && SUCCESS[status]) { |
127 | 189 |
if (password != undefined && status == "CREATE_VM_SUCCESS") { |
190 |
|
|
191 |
//stop the progress icon and hide the wizard |
|
192 |
$('#wizard #start').text('{% trans "Create VM" %}'); |
|
193 |
$("#wizard").hide(); |
|
194 |
|
|
128 | 195 |
$("#error-success h3").text(SUCCESS[status]); |
129 |
var CREATE_VM_SUCCESS_MSG = SUCCESS["CREATE_VM_SUCCESS_ONE"] + '<br />' |
|
130 |
+ SUCCESS["CREATE_VM_SUCCESS_TWO"] + '<br /><br />' + '<b>' + password + '</b>' |
|
131 |
+ '<br /><br />' + SUCCESS["CREATE_VM_SUCCESS_THREE"] ; |
|
132 |
$("#error-success div").html("<p>" + CREATE_VM_SUCCESS_MSG + "</p>"); |
|
196 |
var CREATE_VM_SUCCESS_MSG = SUCCESS["CREATE_VM_SUCCESS_THREE"] + '<br / >' |
|
197 |
+ SUCCESS["CREATE_VM_SUCCESS_FOUR"]; |
|
198 |
$("#error-success div.machine-now-building").html(SUCCESS["CREATE_VM_SUCCESS_ONE"]); |
|
199 |
$("#error-success .popup-header").removeClass("popup-header-error"); |
|
200 |
$("#error-success").removeClass("popup-border-error"); |
|
201 |
$("#error-success .popup-details").removeClass("popup-details-error"); |
|
202 |
$("#error-success .popup-separator").removeClass("popup-separator-error"); |
|
203 |
$("#error-success .password-container").show(); |
|
204 |
$("#error-success .popup-details").html("<div class=\"write-password\">"+ SUCCESS["CREATE_VM_SUCCESS_TWO"] + "</div><div class=\"write-password-details\">" + CREATE_VM_SUCCESS_MSG +"</div>"); |
|
205 |
$("#error-success div.password").html(password); |
|
206 |
//$("#error-success div.write-password").html(SUCCESS["CREATE_VM_SUCCESS_TWO"]); |
|
207 |
//$("#error-success div.write-password-details").html(CREATE_VM_SUCCESS_MSG); |
|
133 | 208 |
} else { |
134 | 209 |
$("#error-success h3").text(SUCCESS['HEADER']); |
135 |
$("#error-success div").text("<p>" + SUCCESS[status] + "</p>");
|
|
210 |
$("#error-success div.popup-body-inner").text("<p>" + SUCCESS[status] + "</p>");
|
|
136 | 211 |
} |
137 | 212 |
} else { |
138 | 213 |
$("#error-success h3").text(SUCCESS['HEADER']); |
139 |
$("#error-success div").html("<p>" + SUCCESS['DEFAULT'] + "</p>"); |
|
140 |
|
|
214 |
$("#error-success div.popup-body-inner").html("<p>" + SUCCESS['DEFAULT'] + "</p>"); |
|
141 | 215 |
} |
142 | 216 |
|
143 |
|
|
144 | 217 |
var triggers = $("a#notification").overlay({ |
145 | 218 |
// some mask tweaks suitable for modal dialogs |
146 | 219 |
mask: { |
... | ... | |
163 | 236 |
</script> |
164 | 237 |
</head> |
165 | 238 |
<body> |
166 |
<div id="wrapper"> |
|
167 |
<div id='user'> |
|
168 |
<a href="#">{% trans "username" %}</a> | <a href="#">{% trans "settings" %}</a> |
|
169 |
{% get_available_languages as LANGUAGES %} |
|
170 |
{% for lang in LANGUAGES %} |
|
171 |
| |
|
172 |
<a {% if current_lang == lang.0 %}class="current_lang" {% else %} href="/lang/?l={{lang.0}}" {% endif %}>{{lang.0}}</a> |
|
173 |
{% endfor %} |
|
174 |
</div> |
|
239 |
<div id="container"> |
|
175 | 240 |
<div id='header'> |
176 |
<a href="/" class="logo"> |
|
177 |
<img src="static/nefo.png" alt="+nefo"/> |
|
178 |
</a> |
|
179 |
<div class='fatborder'></div> |
|
241 |
<div id='user'> |
|
242 |
<a href="#">{% trans "username" %}</a> |
|
243 |
{% get_available_languages as LANGUAGES %} |
|
244 |
{% for lang in LANGUAGES %} |
|
245 |
| |
|
246 |
<a {% if current_lang == lang.0 %}class="current_lang" {% else %} href="/lang/?l={{lang.0}}" {% endif %}>{{lang.0}}</a> |
|
247 |
{% endfor %} |
|
248 |
</div> |
|
249 |
<div class="header-logo"> |
|
250 |
<a href="/"> |
|
251 |
<img src="static/okeanos.png" alt="okeanos"/> |
|
252 |
</a> |
|
253 |
</div> |
|
180 | 254 |
</div> |
181 |
<!-- tabs --> |
|
182 |
<ul class="css-tabs"> |
|
183 |
<li><a href="machines" title="{% trans "manage your virtual machines" %}" class="primary" id="machines"> |
|
184 |
{% trans "machines" %}</a></li> |
|
185 |
<li><a href="disks" title="{% trans "manage your storage volumes" %}" class="primary" id="disks"> |
|
186 |
{% trans "disks" %}</a></li> |
|
187 |
<li><a href="images" title="{% trans "manage boot images" %}" class="primary" id="images"> |
|
188 |
{% trans "images" %}</a></li> |
|
189 |
<li><a href="networks" title="{% trans "configure networking" %}" class="primary" id="networks"> |
|
190 |
{% trans "networks" %}</a></li> |
|
191 |
<li><a href="files" title="{% trans "your files" %}" class="secondary" id="files"> |
|
192 |
{% trans "files" %}</a></li> |
|
193 |
<li><a href="desktops" title="{% trans "your desktops" %}" class="secondary" id="desktops"> |
|
194 |
{% trans "desktops" %}</a></li> |
|
195 |
<li><a href="apps" title="{% trans "your apps" %}" class="secondary" id="apps"> |
|
196 |
{% trans "apps" %}</a></li> |
|
197 |
</ul> |
|
198 |
<div class="more-tabs"><img src="static/arrow.png" id="arrow"></img></div> |
|
199 |
<div class="css-panes"> |
|
200 |
<div id="machines-pane" class="pane" style="display:block">{% include "machines.html" %}</div> |
|
201 |
<div id="disks-pane" class="pane"></div> |
|
202 |
<div id="images-pane" class="pane"></div> |
|
203 |
<div id="networks-pane" class="pane"></div> |
|
204 |
<div id="files-pane" class="pane"></div> |
|
205 |
<div id="desktops-pane" class="pane"></div> |
|
206 |
<div id="apps-pane" class="pane"></div> |
|
255 |
<div id="content"> |
|
256 |
<div id="wrapper"> |
|
257 |
<!-- tabs --> |
|
258 |
<div class="tab-name">{% trans "machines" %}</div> |
|
259 |
<div class="tab-separator"></div> |
|
260 |
<ul class="css-tabs"> |
|
261 |
<li><a href="machines" title="{% trans "manage your virtual machines" %}" class="primary" id="machines"> |
|
262 |
<img src="static/machines-icon.png" /></a></li><div class="tab-separator"></div> |
|
263 |
<li><a href="networks" title="{% trans "configure networking" %}" class="primary" id="networks"> |
|
264 |
<img src="static/networks-icon.png" /></a></li><div class="tab-separator"></div> |
|
265 |
<li><a href="disks" title="{% trans "manage your storage volumes" %}" class="primary" id="disks"> |
|
266 |
<img src="static/disks-icon.png" /></a></li> |
|
267 |
</ul> |
|
268 |
<div class="css-panes"> |
|
269 |
<div id="machines-pane" class="pane" style="display:block">{% include "machines.html" %}</div> |
|
270 |
<div id="networks-pane" class="pane"></div> |
|
271 |
<div id="disks-pane" class="pane"></div> |
|
272 |
</div> |
|
273 |
<!-- base notification for error/success reporting --> |
|
274 |
<a id="notification" rel="#error-success" href="#"></a> |
|
207 | 275 |
|
276 |
<div class="modal" id="error-success"> |
|
277 |
<h3 class="popup-header">{% trans "Error!/Success!" %}</h3> |
|
278 |
<div class="popup-body"> |
|
279 |
<div class="popup-body-inner"> |
|
280 |
<div class="machine-now-building"></div> |
|
281 |
<div class="popup-separator"></div> |
|
282 |
<div class="password-container"> |
|
283 |
<div class="password-header">{% trans "Password:" %}</div> |
|
284 |
<div class="password"></div> |
|
285 |
</div> |
|
286 |
<div class="popup-details"> |
|
287 |
<div class="write-password"></div> |
|
288 |
<div class="write-password-details">{% trans "More details about the result"%}</div> |
|
289 |
</div> |
|
290 |
</div> |
|
291 |
</div> |
|
292 |
</div> |
|
293 |
</div> |
|
208 | 294 |
</div> |
295 |
{% include "footer.html" %} |
|
209 | 296 |
</div> |
297 |
|
|
210 | 298 |
<!-- activate tabs with JavaScript --> |
211 | 299 |
<script> |
212 |
$(function() { |
|
213 |
$('ul.css-tabs li').hover(function(){ |
|
214 |
$(this).find('a:not(.current)').animate({top:'0px'},{queue:false,duration:150}); |
|
215 |
}, function(){ |
|
216 |
$('ul.css-tabs li a:not(.current)').animate({top:'9px'},{queue:false,duration:150}); |
|
217 |
}); |
|
218 |
}); |
|
219 |
|
|
300 |
|
|
220 | 301 |
$(function() { |
221 |
$("ul.css-tabs").tabs("div.css-panes div.pane", { |
|
222 |
onBeforeClick: function(event, i) { |
|
223 |
$('ul.css-tabs li a').animate({top:'9px'},{queue:false,duration:150}); |
|
224 |
// get the pane to be opened |
|
225 |
var pane = this.getPanes().eq(i); |
|
302 |
$("ul.css-tabs").tabs("div.css-panes div.pane", { |
|
303 |
onBeforeClick: function(event, i) { |
|
304 |
// get the pane to be opened |
|
305 |
var pane = this.getPanes().eq(i); |
|
226 | 306 |
pane.text(''); |
227 |
// load it with a page specified in the tab's href attribute |
|
228 |
pane.load(this.getTabs().eq(i).attr("href"),function(){if (!i) {choose_view()}}); |
|
229 |
} |
|
230 |
}); |
|
307 |
//change the displaying title |
|
308 |
$(".tab-name").text(this.getTabs().eq(i).attr("href")); |
|
309 |
// load it with a page specified in the tab's href attribute |
|
310 |
pane.load(this.getTabs().eq(i).attr("href"),function(){if (!i) {choose_view()}}); |
|
311 |
} |
|
312 |
}); |
|
231 | 313 |
}); |
232 | 314 |
|
233 |
// toggle main menu |
|
234 |
$("#arrow").click(function(event){ |
|
235 |
toggleMenu(); |
|
236 |
}); |
|
237 |
|
|
315 |
//change menu title on hover |
|
316 |
$("ul.css-tabs li").hover( |
|
317 |
function () { |
|
318 |
if ($(this).find("a.current").length == 0) { |
|
319 |
$(this).parent().parent().find(".tab-name").text($(this).find("a").attr("href")); |
|
320 |
} |
|
321 |
}, |
|
322 |
function () { |
|
323 |
$(this).parent().parent().find(".tab-name").text($(this).parent().find("a.current").attr("href")); |
|
324 |
} |
|
325 |
); |
|
238 | 326 |
</script> |
239 | 327 |
</body> |
240 | 328 |
</html> |
241 |
|
Also available in: Unified diff