1 <%include include/head.html>
3 <div class="page-id hidden">image-browser</div>
5 <script language="javascript">
7 /* hide all those forms. */
8 function hideAndShowBlock(blockElement, clickToShowElement, clickToHideElement) {
9 $(blockElement).hide();
10 $(clickToShowElement).removeClass("hidden");
11 $(clickToShowElement).click(function() {
12 $(blockElement).slideDown();
13 $(clickToShowElement).addClass("hidden");
14 $(clickToHideElement).removeClass("hidden");
16 $(clickToHideElement).click(function() {
17 $(blockElement).slideUp();
18 $(clickToHideElement).addClass("hidden");
19 $(clickToShowElement).removeClass("hidden");
23 /* ID of the image currently being edited. */
24 var editingImageId = null;
27 * Shows the form for editing an image.
29 * @param imageId The ID of the image to edit.
31 function editImage(imageId) {
32 if (editingImageId != imageId) {
37 editingImageId = imageId;
38 $(".show-data", getImage(imageId)).hide();
39 $(".edit-data", getImage(imageId)).show();
40 $(document).bind("click.sone", function(event) {
41 if ($(event.target).closest("#image-" + imageId).size() == 0) {
48 * Cancels all image editing.
50 function cancelImageEditing() {
51 $(".image .show-data").show();
52 $(".image .edit-data").hide();
53 $("form.edit-image").each(function() {
56 $(document).unbind("click.sone");
57 editingImageId = null;
61 * Returns the image element with the given ID.
63 * @param imageId The ID of the image
64 * @return The image element
66 function getImage(imageId) {
67 return $("#sone .image .image-id:contains('" + imageId + "')").closest(".image");
73 * @param sourceId The ID of the source image
74 * @param destinationId The ID of the destionation image
76 function swapImage(sourceId, destinationId) {
77 sourceElement = getImage(sourceId);
78 destinationElement = getImage(destinationId);
79 sourceParent = sourceElement.closest(".image-row");
80 sourcePrevSibling = sourceElement.prev();
81 sourceElement.detach();
82 destinationElement.before(sourceElement);
83 if (sourcePrevSibling.get(0) != destinationElement.get(0)) {
84 destinationElement.detach();
85 (sourcePrevSibling.size() > 0) ? sourcePrevSibling.after(destinationElement) : sourceParent.prepend(destinationElement);
87 if ($("button[name='moveLeft']", sourceElement).hasClass("hidden") != $("button[name='moveLeft']", destinationElement).hasClass("hidden")) {
88 $("button[name='moveLeft']", sourceElement).toggleClass("hidden");
89 $("button[name='moveLeft']", destinationElement).toggleClass("hidden");
91 if ($("button[name='moveRight']", sourceElement).hasClass("hidden") != $("button[name='moveRight']", destinationElement).hasClass("hidden")) {
92 $("button[name='moveRight']", sourceElement).toggleClass("hidden");
93 $("button[name='moveRight']", destinationElement).toggleClass("hidden");
98 * Prepare all images for inline editing.
100 function prepareImages() {
101 $(".image").each(function() {
102 imageId = $(this).closest(".image").find(".image-id").text();
103 (function(element, imageId) {
104 $(".show-data", element).click(function() {
107 $("button[name='moveLeft'], button[name='moveRight']", element).click(function() {
108 ajaxGet("editImage.ajax", { "formPassword": getFormPassword(), "image": imageId, "moveLeft": this.name == "moveLeft", "moveRight": this.name == "moveRight" }, function(data) {
109 if (data && data.success) {
110 swapImage(data.sourceImageId, data.destinationImageId);
115 $("button[name='submit']", element).click(function() {
116 title = $(":input[name='title']:enabled", this.form).val();
117 description = $(":input[name='description']:enabled", this.form).val();
118 ajaxGet("editImage.ajax", { "formPassword": getFormPassword(), "image": imageId, "title": title, "description": description }, function(data) {
119 if (data && data.success) {
120 getImage(data.imageId).find(".image-title").text(data.title);
121 getImage(data.imageId).find(".image-description").html(data.parsedDescription);
122 getImage(data.imageId).find(":input[name='title']").attr("defaultValue", title);
123 getImage(data.imageId).find(":input[name='description']").attr("defaultValue", data.description);
124 cancelImageEditing();
133 /* ID of the album currently being edited. */
134 var editingAlbumId = null;
137 * Shows the form for editing an album.
139 * @param albumId The ID of the album to edit.
141 function editAlbum(albumId) {
142 if (editingAlbumId != albumId) {
143 if (editingAlbumId != null) {
144 cancelAlbumEditing();
147 console.log("already editing " + albumId);
150 editingAlbumId = albumId;
151 $(".show-data", getAlbum(albumId)).hide();
152 $(".edit-data", getAlbum(albumId)).show();
153 console.log(getAlbum(albumId));
154 $(document).bind("click.sone", function(event) {
155 if ($(event.target).closest("#album-" + albumId).size() == 0) {
156 cancelAlbumEditing();
162 * Cancels all album editing.
164 function cancelAlbumEditing() {
165 console.log("cancel-album-edit");
166 $(".album .show-data").show();
167 $(".album .edit-data").hide();
168 $("form.edit-album").each(function() {
171 $(document).unbind("click.sone");
172 editingAlbumId = null;
176 * Returns the album element with the given ID.
178 * @param albumId The ID of the album
179 * @return The album element
181 function getAlbum(albumId) {
182 return $("#sone .album .album-id:contains('" + albumId + "')").closest(".album");
188 * @param sourceId The ID of the source album
189 * @param destinationId The ID of the destionation album
191 function swapAlbum(sourceId, destinationId) {
192 sourceElement = getAlbum(sourceId);
193 destinationElement = getAlbum(destinationId);
194 sourceParent = sourceElement.closest(".album-row");
195 sourcePrevSibling = sourceElement.prev();
196 sourceElement.detach();
197 destinationElement.before(sourceElement);
198 if (sourcePrevSibling.get(0) != destinationElement.get(0)) {
199 destinationElement.detach();
200 (sourcePrevSibling.size() > 0) ? sourcePrevSibling.after(destinationElement) : sourceParent.prepend(destinationElement);
202 if ($("button[name='moveLeft']", sourceElement).hasClass("hidden") != $("button[name='moveLeft']", destinationElement).hasClass("hidden")) {
203 $("button[name='moveLeft']", sourceElement).toggleClass("hidden");
204 $("button[name='moveLeft']", destinationElement).toggleClass("hidden");
206 if ($("button[name='moveRight']", sourceElement).hasClass("hidden") != $("button[name='moveRight']", destinationElement).hasClass("hidden")) {
207 $("button[name='moveRight']", sourceElement).toggleClass("hidden");
208 $("button[name='moveRight']", destinationElement).toggleClass("hidden");
213 * Prepare all albums for inline editing.
215 function prepareAlbums() {
216 $(".album").each(function() {
217 albumId = $(this).closest(".album").find(".album-id").text();
218 (function(element, albumId) {
219 $(".show-data", element).click(function() {
220 console.log("show-data");
223 $("button[name='moveLeft'], button[name='moveRight']", element).click(function() {
224 ajaxGet("editAlbum.ajax", { "formPassword": getFormPassword(), "album": albumId, "moveLeft": this.name == "moveLeft", "moveRight": this.name == "moveRight" }, function(data) {
225 if (data && data.success) {
226 swapAlbum(data.sourceAlbumId, data.destinationAlbumId);
231 $("button[name='submit']", element).click(function() {
232 title = $(":input[name='title']:enabled", this.form).val();
233 description = $(":input[name='description']:enabled", this.form).val();
234 ajaxGet("editAlbum.ajax", { "formPassword": getFormPassword(), "album": albumId, "title": title, "description": description }, function(data) {
235 if (data && data.success) {
236 getAlbum(data.albumId).find(".album-title").text(data.title);
237 getAlbum(data.albumId).find(".album-description").text(data.description);
238 getAlbum(data.albumId).find(":input[name='title']").attr("defaultValue", title);
239 getAlbum(data.albumId).find(":input[name='description']").attr("defaultValue", description);
240 cancelAlbumEditing();
255 <p><%= Page.ImageBrowser.Album.Error.NotFound.Text|l10n|html></p>
257 <%elseifnull album.title>
259 <p><%= Page.ImageBrowser.Album.Error.NotFound.Text|l10n|html></p>
263 <%if album.sone.local>
264 <script language="javascript">
267 getTranslation("WebInterface.DefaultText.UploadImage.Title", function(text) {
268 $("#upload-image :input[name='title']").each(function() {
269 registerInputTextareaSwap(this, text, "title", false, true);
272 getTranslation("WebInterface.DefaultText.UploadImage.Description", function(text) {
273 $("#upload-image :input[name='description']").each(function() {
274 registerInputTextareaSwap(this, text, "description", true, false);
277 $("#upload-image label").hide();
278 getTranslation("WebInterface.DefaultText.CreateAlbum.Name", function(text) {
279 $("#create-album input[name='name']").each(function() {
280 registerInputTextareaSwap(this, text, "name", false, true);
283 getTranslation("WebInterface.DefaultText.CreateAlbum.Description", function(text) {
284 $("#create-album input[name='description']").each(function() {
285 registerInputTextareaSwap(this, text, "description", true, true);
288 $("#create-album label").hide();
289 getTranslation("WebInterface.DefaultText.EditAlbum.Title", function(text) {
290 $("#edit-album input[name='title']").each(function() {
291 registerInputTextareaSwap(this, text, "title", false, true);
294 getTranslation("WebInterface.DefaultText.EditAlbum.Description", function(text) {
295 $("#edit-album :input[name='description']").each(function() {
296 registerInputTextareaSwap(this, text, "description", true, false);
299 $("#edit-album label").hide();
301 hideAndShowBlock("div.edit-album", ".show-edit-album", ".hide-edit-album");
302 hideAndShowBlock("div.create-album", ".show-create-album", ".hide-create-album");
303 hideAndShowBlock("div.upload-image", ".show-upload-image", ".hide-upload-image");
304 hideAndShowBlock("div.delete-album", ".show-delete-album", ".hide-delete-album");
312 <h1 class="backlink"><%= Page.ImageBrowser.Album.Title|l10n|replace needle='{album}' replacementKey=album.title|html></h1>
314 <div class="backlinks">
315 <%foreach album.backlinks backlink backlinks>
316 <div class="backlink">
317 <a href="<% backlink.target|html>"><% backlink.name|html></a>
319 <%if ! backlinks.last>
320 <div class="separator">></div>
325 <p id="description"><% album.description|parse sone=album.sone></p>
327 <%if album.sone.local>
328 <div class="show-edit-album hidden toggle-link"><a class="small-link">» <%= Page.ImageBrowser.Album.Edit.Title|l10n|html></a></div>
329 <div class="hide-edit-album hidden toggle-link"><a class="small-link">« <%= Page.ImageBrowser.Album.Edit.Title|l10n|html></a></div>
330 <div class="edit-album">
331 <h2><%= Page.ImageBrowser.Album.Edit.Title|l10n|html></h2>
333 <form id="edit-album" action="editAlbum.html" method="post">
334 <input type="hidden" name="formPassword" value="<%formPassword|html>" />
335 <input type="hidden" name="album" value="<%album.id|html>" />
337 <%if ! album.images.empty>
339 <label for="album-image"><%= Page.ImageBrowser.Album.Label.AlbumImage|l10n|html></label>
340 <select name="album-image">
341 <option disabled="disabled"><%= Page.ImageBrowser.Album.AlbumImage.Choose|l10n|html></option>
342 <%foreach album.images image>
343 <option value="<% image.id|html>"<%if album.albumImage.id|match key=image.id> selected="selected"<%/if>><% image.title|html></option>
349 <label for="title"><%= Page.ImageBrowser.Album.Label.Title|l10n|html></label>
350 <input type="text" name="title" value="<%album.title|html>" />
353 <label for="description"><%= Page.ImageBrowser.Album.Label.Description|l10n|html></label>
354 <textarea name="description"><%album.description|html></textarea>
356 <button type="submit"><%= Page.ImageBrowser.Album.Button.Save|l10n|html></button>
361 <%include include/browseAlbums.html albums=album.albums>
363 <%if album.sone.local>
364 <div class="show-create-album hidden toggle-link"><a class="small-link">» <%= View.CreateAlbum.Title|l10n|html></a></div>
365 <div class="hide-create-album hidden toggle-link"><a class="small-link">« <%= View.CreateAlbum.Title|l10n|html></a></div>
366 <div class="create-album">
367 <%include include/createAlbum.html>
371 <%foreach album.images image>
372 <%first><h2><%= Page.ImageBrowser.Header.Images|l10n|html></h2><%/first>
373 <%if loop.count|mod divisor=3><div class="image-row"><%/if>
374 <div id="image-<% image.id|html>" class="image">
375 <div class="image-id hidden"><% image.id|html></div>
376 <div class="image-container">
377 <a href="imageBrowser.html?image=<%image.id|html>"><% image|image-link max-width=250 max-height=250 mode=enlarge title==image.title></a>
379 <div class="show-data">
380 <div class="image-title"><% image.title|html></div>
381 <div class="image-description"><% image.description|parse sone=image.sone></div>
383 <%if album.sone.local>
384 <form class="edit-image" action="editImage.html" method="post">
385 <input type="hidden" name="formPassword" value="<%formPassword|html>" />
386 <input type="hidden" name="returnPage" value="<%request.uri|html>" />
387 <input type="hidden" name="image" value="<%image.id|html>" />
389 <div class="edit-data hidden">
391 <input type="text" name="title" value="<%image.title|html>" />
394 <textarea name="description"><%image.description|html></textarea>
397 <button <%first>class="hidden" <%/first>type="submit" name="moveLeft" value="true"><%= Page.ImageBrowser.Image.Button.MoveLeft|l10n|html></button>
398 <button type="submit" name="submit"><%= Page.ImageBrowser.Image.Button.Save|l10n|html></button>
399 <button <%last>class="hidden" <%/last>type="submit" name="moveRight" value="true"><%= Page.ImageBrowser.Image.Button.MoveRight|l10n|html></button>
405 <%= false|store key=endRow>
406 <%if loop.count|mod divisor=3 offset=1><%= true|store key=endRow><%/if>
407 <%last><%= true|store key=endRow><%/last>
408 <%if endRow></div><%/if>
411 <%if album.sone.local>
412 <div class="show-upload-image hidden toggle-link"><a class="small-link">» <%= View.UploadImage.Title|l10n|html></a></div>
413 <div class="hide-upload-image hidden toggle-link"><a class="small-link">« <%= View.UploadImage.Title|l10n|html></a></div>
414 <div class="upload-image">
415 <%include include/uploadImage.html>
419 <div class="show-delete-album hidden toggle-link"><a class="small-link">» <%= Page.ImageBrowser.Album.Delete.Title|l10n|html></a></div>
420 <div class="hide-delete-album hidden toggle-link"><a class="small-link">« <%= Page.ImageBrowser.Album.Delete.Title|l10n|html></a></div>
421 <div class="delete-album">
422 <form id="delete-album" action="deleteAlbum.html" method="get">
423 <input type="hidden" name="album" value="<%album.id|html>" />
424 <button type="submit"><%= Page.ImageBrowser.Album.Button.Delete|l10n|html></button>
433 <%elseif imageRequested>
435 <h1 class="backlink"><%image.title|html></h1>
437 <div class="backlinks">
438 <%foreach image.album.backlinks backlink backlinks>
439 <div class="backlink">
440 <a href="<% backlink.target|html>"><% backlink.name|html></a>
442 <%if ! backlinks.last>
443 <div class="separator">></div>
452 <%if image.sone.local>
453 <script language="javascript">
455 getTranslation("WebInterface.DefaultText.EditImage.Title", function(text) {
456 $("#edit-image input[name='title']").each(function() {
457 registerInputTextareaSwap(this, text, "title", false, true);
460 getTranslation("WebInterface.DefaultText.EditImage.Description", function(text) {
461 $("#edit-image :input[name='description']").each(function() {
462 registerInputTextareaSwap(this, text, "description", true, false);
465 $("#edit-image label").hide();
467 hideAndShowBlock(".edit-image", ".show-edit-image", ".hide-edit-image");
468 hideAndShowBlock(".delete-image", ".show-delete-image", ".hide-delete-image");
473 <div class="single-image">
475 <a href="/<%image.key|html>"><% image|image-link max-width=640 max-height=480></a>
477 <a href="imageBrowser.html?image=<%image.id|html>"><% image|image-link max-width=640 max-height=480></a>
481 <p class="parsed"><%image.description|parse sone=image.sone></p>
483 <%if image.sone.local>
485 <div class="show-edit-image hidden toggle-link"><a class="small-link">» <%= Page.ImageBrowser.Image.Edit.Title|l10n|html></a></div>
486 <div class="hide-edit-image hidden toggle-link"><a class="small-link">« <%= Page.ImageBrowser.Image.Edit.Title|l10n|html></a></div>
487 <div class="edit-image">
488 <h2><%= Page.ImageBrowser.Image.Edit.Title|l10n|html></h2>
490 <form id="edit-image" action="editImage.html" method="post">
491 <input type="hidden" name="formPassword" value="<%formPassword|html>" />
492 <input type="hidden" name="returnPage" value="<%request.uri|html>" />
493 <input type="hidden" name="image" value="<%image.id|html>" />
496 <label for="title"><%= Page.ImageBrowser.Image.Title.Label|l10n|html></label>
497 <input type="text" name="title" value="<%image.title|html>" />
500 <label for="description"><%= Page.ImageBrowser.Image.Description.Label|l10n|html></label>
501 <textarea name="description"><%image.description|html></textarea>
504 <button type="submit"><%= Page.ImageBrowser.Image.Button.Save|l10n|html></button>
509 <div class="show-delete-image hidden toggle-link"><a class="small-link">» <%= Page.ImageBrowser.Image.Delete.Title|l10n|html></a></div>
510 <div class="hide-delete-image hidden toggle-link"><a class="small-link">« <%= Page.ImageBrowser.Image.Delete.Title|l10n|html></a></div>
511 <div class="delete-image">
512 <h2><%= Page.ImageBrowser.Image.Delete.Title|l10n|html></h2>
514 <form id="delete-image" action="deleteImage.html" method="get">
515 <input type="hidden" name="image" value="<%image.id|html>" />
516 <button type="submit"><%= Page.ImageBrowser.Image.Button.Delete|l10n|html></button>
524 <%elseif soneRequested>
527 <script language="javascript">
529 getTranslation("WebInterface.DefaultText.CreateAlbum.Name", function(text) {
530 $("#create-album input[name='name']").each(function() {
531 registerInputTextareaSwap(this, text, "name", false, true);
534 getTranslation("WebInterface.DefaultText.CreateAlbum.Description", function(text) {
535 $("#create-album input[name='description']").each(function() {
536 registerInputTextareaSwap(this, text, "description", true, true);
539 $("#create-album label").hide();
541 hideAndShowBlock(".create-album", ".show-create-album", ".hide-create-album");
550 <p><%= Page.ImageBrowser.Sone.Error.NotFound.Text|l10n|html></p>
554 <h1><%= Page.ImageBrowser.Sone.Title|l10n|replace needle='{sone}' replacementKey=sone.niceName|html></h1>
556 <%include include/browseAlbums.html albums=sone.albums>
559 <div class="show-create-album hidden toggle-link"><a class="small-link">» <%= View.CreateAlbum.Title|l10n|html></a></div>
560 <div class="hide-create-album hidden toggle-link"><a class="small-link">« <%= View.CreateAlbum.Title|l10n|html></a></div>
561 <div class="create-album">
562 <%include include/createAlbum.html>
570 <%include include/tail.html>