owncloud /
gallery
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | /* global Handlebars, Gallery */ |
||
| 2 | (function ($, _, OC, t, Gallery) { |
||
| 3 | "use strict"; |
||
| 4 | |||
| 5 | var TEMPLATE_ADDBUTTON = '<a href="#" class="button new"><img src="{{iconUrl}}" alt="{{addText}}"></img></a>'; |
||
| 6 | |||
| 7 | /** |
||
| 8 | * Builds and updates the Gallery view |
||
| 9 | * |
||
| 10 | * @constructor |
||
| 11 | */ |
||
| 12 | var View = function () { |
||
| 13 | this.element = $('#gallery'); |
||
| 14 | this.loadVisibleRows.loading = false; |
||
| 15 | this._setupUploader(); |
||
| 16 | this.breadcrumb = new Gallery.Breadcrumb(); |
||
| 17 | this.emptyContentElement = $('#emptycontent'); |
||
| 18 | this.controlsElement = $('#controls'); |
||
| 19 | }; |
||
| 20 | |||
| 21 | View.prototype = { |
||
| 22 | element: null, |
||
| 23 | breadcrumb: null, |
||
| 24 | requestId: -1, |
||
| 25 | emptyContentElement: null, |
||
| 26 | controlsElement: null, |
||
| 27 | |||
| 28 | /** |
||
| 29 | * Removes all thumbnails from the view |
||
| 30 | */ |
||
| 31 | clear: function () { |
||
| 32 | this.loadVisibleRows.processing = false; |
||
| 33 | this.loadVisibleRows.loading = null; |
||
| 34 | // We want to keep all the events |
||
| 35 | this.element.children().detach(); |
||
| 36 | this.showLoading(); |
||
| 37 | }, |
||
| 38 | |||
| 39 | /** |
||
| 40 | * Populates the view if there are images or albums to show |
||
| 41 | * |
||
| 42 | * @param {string} albumPath |
||
| 43 | * @param {string|undefined} errorMessage |
||
| 44 | */ |
||
| 45 | init: function (albumPath, errorMessage) { |
||
| 46 | // Only do it when the app is initialised |
||
| 47 | if (this.requestId === -1) { |
||
| 48 | this._initButtons(); |
||
| 49 | this._blankUrl(); |
||
| 50 | } |
||
| 51 | if ($.isEmptyObject(Gallery.imageMap)) { |
||
| 52 | Gallery.view.showEmptyFolder(albumPath, errorMessage); |
||
| 53 | } else { |
||
| 54 | this.viewAlbum(albumPath); |
||
| 55 | } |
||
| 56 | |||
| 57 | this._setBackgroundColour(); |
||
| 58 | }, |
||
| 59 | |||
| 60 | /** |
||
| 61 | * Starts the slideshow |
||
| 62 | * |
||
| 63 | * @param {string} path |
||
| 64 | * @param {string} albumPath |
||
| 65 | */ |
||
| 66 | startSlideshow: function (path, albumPath) { |
||
| 67 | var album = Gallery.albumMap[albumPath]; |
||
| 68 | var images = album.images; |
||
| 69 | var startImage = Gallery.imageMap[path]; |
||
| 70 | Gallery.slideShow(images, startImage, false); |
||
| 71 | }, |
||
| 72 | |||
| 73 | /** |
||
| 74 | * Sets up the controls and starts loading the gallery rows |
||
| 75 | * |
||
| 76 | * @param {string|null} albumPath |
||
| 77 | */ |
||
| 78 | viewAlbum: function (albumPath) { |
||
| 79 | albumPath = albumPath || ''; |
||
| 80 | if (!Gallery.albumMap[albumPath]) { |
||
| 81 | return; |
||
| 82 | } |
||
| 83 | |||
| 84 | this.clear(); |
||
| 85 | |||
| 86 | if (albumPath !== Gallery.currentAlbum |
||
| 87 | || (albumPath === Gallery.currentAlbum && |
||
| 88 | Gallery.albumMap[albumPath].etag !== Gallery.currentEtag)) { |
||
| 89 | Gallery.currentAlbum = albumPath; |
||
| 90 | Gallery.currentEtag = Gallery.albumMap[albumPath].etag; |
||
| 91 | this._setupButtons(albumPath); |
||
| 92 | } |
||
| 93 | |||
| 94 | Gallery.albumMap[albumPath].viewedItems = 0; |
||
| 95 | Gallery.albumMap[albumPath].preloadOffset = 0; |
||
| 96 | |||
| 97 | // Each request has a unique ID, so that we can track which request a row belongs to |
||
| 98 | this.requestId = Math.random(); |
||
| 99 | Gallery.albumMap[Gallery.currentAlbum].requestId = this.requestId; |
||
| 100 | |||
| 101 | // Loading rows without blocking the execution of the rest of the script |
||
| 102 | setTimeout(function () { |
||
| 103 | this.loadVisibleRows.activeIndex = 0; |
||
| 104 | this.loadVisibleRows(Gallery.albumMap[Gallery.currentAlbum]); |
||
| 105 | }.bind(this), 0); |
||
| 106 | }, |
||
| 107 | |||
| 108 | /** |
||
| 109 | * Manages the sorting interface |
||
| 110 | * |
||
| 111 | * @param {string} sortType name or date |
||
| 112 | * @param {string} sortOrder asc or des |
||
| 113 | */ |
||
| 114 | sortControlsSetup: function (sortType, sortOrder) { |
||
| 115 | var reverseSortType = 'date'; |
||
| 116 | if (sortType === 'date') { |
||
| 117 | reverseSortType = 'name'; |
||
| 118 | } |
||
| 119 | this._setSortButton(sortType, sortOrder, true); |
||
| 120 | this._setSortButton(reverseSortType, 'asc', false); // default icon |
||
| 121 | }, |
||
| 122 | |||
| 123 | /** |
||
| 124 | * Loads and displays gallery rows on screen |
||
| 125 | * |
||
| 126 | * view.loadVisibleRows.loading holds the Promise of a row |
||
| 127 | * |
||
| 128 | * @param {Album} album |
||
| 129 | */ |
||
| 130 | loadVisibleRows: function (album) { |
||
| 131 | var view = this; |
||
| 132 | // Wait for the previous request to be completed |
||
| 133 | if (this.loadVisibleRows.processing) { |
||
| 134 | return; |
||
| 135 | } |
||
| 136 | |||
| 137 | /** |
||
| 138 | * At this stage, there is no loading taking place, so we can look for new rows |
||
| 139 | */ |
||
| 140 | |||
| 141 | var scroll = $('#content-wrapper').scrollTop() + $(window).scrollTop(); |
||
| 142 | // 2 windows worth of rows is the limit from which we need to start loading new rows. |
||
| 143 | // As we scroll down, it grows |
||
| 144 | var targetHeight = ($(window).height() * 2) + scroll; |
||
| 145 | // We throttle rows in order to try and not generate too many CSS resizing events at |
||
| 146 | // the same time |
||
| 147 | var showRows = _.throttle(function (album) { |
||
| 148 | |||
| 149 | // If we've reached the end of the album, we kill the loader |
||
| 150 | if (!(album.viewedItems < album.subAlbums.length + album.images.length)) { |
||
|
0 ignored issues
–
show
|
|||
| 151 | view.loadVisibleRows.processing = false; |
||
| 152 | view.loadVisibleRows.loading = null; |
||
| 153 | return; |
||
| 154 | } |
||
| 155 | |||
| 156 | // Prevents creating rows which are no longer required. I.e when changing album |
||
| 157 | if (view.requestId !== album.requestId) { |
||
| 158 | return; |
||
| 159 | } |
||
| 160 | |||
| 161 | // We can now safely create a new row |
||
| 162 | var row = album.getRow($(window).width()); |
||
| 163 | var rowDom = row.getDom(); |
||
| 164 | view.element.append(rowDom); |
||
| 165 | |||
| 166 | return album.fillNextRow(row).then(function () { |
||
| 167 | if (album.viewedItems < album.subAlbums.length + album.images.length && |
||
| 168 | view.element.height() < targetHeight) { |
||
| 169 | return showRows(album); |
||
| 170 | } |
||
| 171 | // No more rows to load at the moment |
||
| 172 | view.loadVisibleRows.processing = false; |
||
| 173 | view.loadVisibleRows.loading = null; |
||
| 174 | }, function () { |
||
| 175 | // Something went wrong, so kill the loader |
||
| 176 | view.loadVisibleRows.processing = false; |
||
| 177 | view.loadVisibleRows.loading = null; |
||
| 178 | }); |
||
| 179 | }, 100); |
||
| 180 | if (this.element.height() < targetHeight) { |
||
| 181 | this._showNormal(); |
||
| 182 | this.loadVisibleRows.processing = true; |
||
| 183 | album.requestId = view.requestId; |
||
| 184 | this.loadVisibleRows.loading = showRows(album); |
||
| 185 | } |
||
| 186 | }, |
||
| 187 | |||
| 188 | /** |
||
| 189 | * Shows an empty gallery message |
||
| 190 | * |
||
| 191 | * @param {string} albumPath |
||
| 192 | * @param {string|null} errorMessage |
||
| 193 | */ |
||
| 194 | showEmptyFolder: function (albumPath, errorMessage) { |
||
| 195 | var message = '<div class="icon-gallery"></div>'; |
||
| 196 | var uploadAllowed = true; |
||
| 197 | |||
| 198 | this.element.children().detach(); |
||
| 199 | this.removeLoading(); |
||
| 200 | |||
| 201 | if (!_.isUndefined(errorMessage) && errorMessage !== null) { |
||
| 202 | message += '<h2>' + t('gallery', |
||
| 203 | 'Album cannot be shown') + '</h2>'; |
||
| 204 | message += '<p>' + escapeHTML(errorMessage) + '</p>'; |
||
| 205 | uploadAllowed = false; |
||
| 206 | } else { |
||
| 207 | message += '<h2>' + t('gallery', |
||
| 208 | 'No media files found') + '</h2>'; |
||
| 209 | // We can't upload yet on the public side |
||
| 210 | if (Gallery.token) { |
||
| 211 | message += '<p>' + t('gallery', |
||
| 212 | 'Upload pictures in the files app to display them here') + '</p>'; |
||
| 213 | } else { |
||
| 214 | message += '<p>' + t('gallery', |
||
| 215 | 'Upload new files via drag and drop or by using the [+] button above') + |
||
| 216 | '</p>'; |
||
| 217 | } |
||
| 218 | } |
||
| 219 | this.emptyContentElement.html(message); |
||
| 220 | this.emptyContentElement.removeClass('hidden'); |
||
| 221 | |||
| 222 | this._hideButtons(uploadAllowed); |
||
| 223 | Gallery.currentAlbum = albumPath; |
||
| 224 | var availableWidth = $(window).width() - Gallery.buttonsWidth; |
||
| 225 | this.breadcrumb.init(albumPath, availableWidth); |
||
| 226 | Gallery.config.albumDesign = null; |
||
| 227 | }, |
||
| 228 | |||
| 229 | /** |
||
| 230 | * Dims the controls bar when retrieving new content. Matches the effect in Files |
||
| 231 | */ |
||
| 232 | dimControls: function () { |
||
| 233 | // Use the existing mask if its already there |
||
| 234 | var $mask = this.controlsElement.find('.mask'); |
||
| 235 | if ($mask.exists()) { |
||
| 236 | return; |
||
| 237 | } |
||
| 238 | $mask = $('<div class="mask transparent"></div>'); |
||
| 239 | this.controlsElement.append($mask); |
||
| 240 | $mask.removeClass('transparent'); |
||
| 241 | }, |
||
| 242 | |||
| 243 | /** |
||
| 244 | * Shows the infamous loading spinner |
||
| 245 | */ |
||
| 246 | showLoading: function () { |
||
| 247 | this.emptyContentElement.addClass('hidden'); |
||
| 248 | this.controlsElement.removeClass('hidden'); |
||
| 249 | $('#content').addClass('icon-loading'); |
||
| 250 | this.dimControls(); |
||
| 251 | }, |
||
| 252 | |||
| 253 | /** |
||
| 254 | * Removes the spinner in the main area and restore normal visibility of the controls bar |
||
| 255 | */ |
||
| 256 | removeLoading: function () { |
||
| 257 | $('#content').removeClass('icon-loading'); |
||
| 258 | this.controlsElement.find('.mask').remove(); |
||
| 259 | }, |
||
| 260 | |||
| 261 | /** |
||
| 262 | * Shows thumbnails |
||
| 263 | */ |
||
| 264 | _showNormal: function () { |
||
| 265 | this.emptyContentElement.addClass('hidden'); |
||
| 266 | this.controlsElement.removeClass('hidden'); |
||
| 267 | this.removeLoading(); |
||
| 268 | }, |
||
| 269 | |||
| 270 | /** |
||
| 271 | * Sets up our custom handlers for folder uploading operations |
||
| 272 | * |
||
| 273 | * @see OC.Upload.init/file_upload_param.done() |
||
| 274 | * |
||
| 275 | * @private |
||
| 276 | */ |
||
| 277 | _setupUploader: function () { |
||
| 278 | var self = this; |
||
| 279 | var $uploadEl = $('#file_upload_start'); |
||
| 280 | var uploads = []; |
||
| 281 | if (!$uploadEl.exists()) { |
||
| 282 | return; |
||
| 283 | } |
||
| 284 | this._uploader = new OC.Uploader($uploadEl, { |
||
| 285 | fileList: FileList, |
||
| 286 | dropZone: $('#content') |
||
| 287 | }); |
||
| 288 | this._uploader.on('add', function (e, data) { |
||
| 289 | data.targetDir = '/' + Gallery.currentAlbum; |
||
| 290 | }); |
||
| 291 | this._uploader.on('done', function (e, upload) { |
||
| 292 | var data = upload.data; |
||
| 293 | // is that the last upload ? |
||
| 294 | if (data.files[0] === data.originalFiles[data.originalFiles.length - 1]) { |
||
| 295 | var fileList = data.originalFiles; |
||
| 296 | //Ask for a refresh of the photowall |
||
| 297 | Gallery.getFiles(Gallery.currentAlbum).done(function () { |
||
| 298 | var fileId, path; |
||
| 299 | // Removes the cached thumbnails of files which have been re-uploaded |
||
| 300 | _(fileList).each(function (fileName) { |
||
| 301 | path = Gallery.currentAlbum + '/' + fileName; |
||
| 302 | if (Gallery.imageMap[path]) { |
||
| 303 | fileId = Gallery.imageMap[path].fileId; |
||
| 304 | if (Thumbnails.map[fileId]) { |
||
| 305 | delete Thumbnails.map[fileId]; |
||
| 306 | } |
||
| 307 | } |
||
| 308 | }); |
||
| 309 | |||
| 310 | Gallery.view.init(Gallery.currentAlbum); |
||
| 311 | }); |
||
| 312 | } |
||
| 313 | }); |
||
| 314 | |||
| 315 | // Since 9.0 |
||
| 316 | if (OC.Uploader) { |
||
| 317 | OC.Uploader.prototype._isReceivedSharedFile = function (file) { |
||
| 318 | var path = file.name; |
||
| 319 | var sharedWith = false; |
||
| 320 | |||
| 321 | if (Gallery.currentAlbum !== '' && Gallery.currentAlbum !== '/') { |
||
| 322 | path = Gallery.currentAlbum + '/' + path; |
||
| 323 | } |
||
| 324 | if (Gallery.imageMap[path] && Gallery.imageMap[path].sharedWithUser) { |
||
| 325 | sharedWith = true; |
||
| 326 | } |
||
| 327 | |||
| 328 | return sharedWith; |
||
| 329 | }; |
||
| 330 | } |
||
| 331 | }, |
||
| 332 | |||
| 333 | /** |
||
| 334 | * Adds all the click handlers to buttons the first time they appear in the interface |
||
| 335 | * |
||
| 336 | * @private |
||
| 337 | */ |
||
| 338 | _initButtons: function () { |
||
| 339 | this.element.on("contextmenu", function(e) { e.preventDefault(); }); |
||
| 340 | $('#filelist-button').click(Gallery.switchToFilesView); |
||
| 341 | $('#download').click(Gallery.download); |
||
| 342 | $('#share-button').click(Gallery.share); |
||
| 343 | Gallery.infoBox = new Gallery.InfoBox(); |
||
| 344 | $('#album-info-button').click(Gallery.showInfo); |
||
| 345 | $('#sort-name-button').click(Gallery.sorter); |
||
| 346 | $('#sort-date-button').click(Gallery.sorter); |
||
| 347 | $('#save #save-button').click(Gallery.showSaveForm); |
||
| 348 | $('.save-form').submit(Gallery.saveForm); |
||
| 349 | this._renderNewButton(); |
||
| 350 | // Trigger cancelling of file upload |
||
| 351 | $('#uploadprogresswrapper .stop').on('click', function () { |
||
| 352 | OC.Upload.cancelUploads(); |
||
| 353 | }); |
||
| 354 | this.requestId = Math.random(); |
||
| 355 | }, |
||
| 356 | |||
| 357 | /** |
||
| 358 | * Sets up all the buttons of the interface and the breadcrumbs |
||
| 359 | * |
||
| 360 | * @param {string} albumPath |
||
| 361 | * @private |
||
| 362 | */ |
||
| 363 | _setupButtons: function (albumPath) { |
||
| 364 | this._shareButtonSetup(albumPath); |
||
| 365 | this._infoButtonSetup(); |
||
| 366 | |||
| 367 | var availableWidth = $(window).width() - Gallery.buttonsWidth; |
||
| 368 | this.breadcrumb.init(albumPath, availableWidth); |
||
| 369 | var album = Gallery.albumMap[albumPath]; |
||
| 370 | |||
| 371 | var sum = album.images.length + album.subAlbums.length; |
||
| 372 | //If sum of the number of images and subalbums exceeds 1 then show the buttons. |
||
| 373 | if(sum > 1) |
||
| 374 | { |
||
| 375 | $('#sort-name-button').show(); |
||
| 376 | $('#sort-date-button').show(); |
||
| 377 | } |
||
| 378 | else |
||
| 379 | { |
||
| 380 | $('#sort-name-button').hide(); |
||
| 381 | $('#sort-date-button').hide(); |
||
| 382 | } |
||
| 383 | var currentSort = Gallery.config.albumSorting; |
||
| 384 | this.sortControlsSetup(currentSort.type, currentSort.order); |
||
| 385 | Gallery.albumMap[Gallery.currentAlbum].images.sort( |
||
| 386 | Gallery.utility.sortBy(currentSort.type, |
||
| 387 | currentSort.order)); |
||
| 388 | Gallery.albumMap[Gallery.currentAlbum].subAlbums.sort(Gallery.utility.sortBy('name', |
||
| 389 | currentSort.albumOrder)); |
||
| 390 | |||
| 391 | $('#save-button').show(); |
||
| 392 | $('#download').show(); |
||
| 393 | $('a.button.new').show(); |
||
| 394 | }, |
||
| 395 | |||
| 396 | /** |
||
| 397 | * Hide buttons in the controls bar |
||
| 398 | * |
||
| 399 | * @param uploadAllowed |
||
| 400 | */ |
||
| 401 | _hideButtons: function (uploadAllowed) { |
||
| 402 | $('#album-info-button').hide(); |
||
| 403 | $('#share-button').hide(); |
||
| 404 | $('#sort-name-button').hide(); |
||
| 405 | $('#sort-date-button').hide(); |
||
| 406 | $('#save-button').hide(); |
||
| 407 | $('#download').hide(); |
||
| 408 | |||
| 409 | if (!uploadAllowed) { |
||
| 410 | $('a.button.new').hide(); |
||
| 411 | } |
||
| 412 | }, |
||
| 413 | |||
| 414 | /** |
||
| 415 | * Shows or hides the share button depending on if we're in a public gallery or not |
||
| 416 | * |
||
| 417 | * @param {string} albumPath |
||
| 418 | * @private |
||
| 419 | */ |
||
| 420 | _shareButtonSetup: function (albumPath) { |
||
| 421 | var shareButton = $('#share-button'); |
||
| 422 | if (albumPath === '' || Gallery.token) { |
||
| 423 | shareButton.hide(); |
||
| 424 | } else { |
||
| 425 | shareButton.show(); |
||
| 426 | } |
||
| 427 | }, |
||
| 428 | |||
| 429 | /** |
||
| 430 | * Shows or hides the info button based on the information we've received from the server |
||
| 431 | * |
||
| 432 | * @private |
||
| 433 | */ |
||
| 434 | _infoButtonSetup: function () { |
||
| 435 | var infoButton = $('#album-info-button'); |
||
| 436 | infoButton.find('span').hide(); |
||
| 437 | var infoContentContainer = $('.album-info-container'); |
||
| 438 | infoContentContainer.slideUp(); |
||
| 439 | infoContentContainer.css('max-height', |
||
| 440 | $(window).height() - Gallery.browserToolbarHeight); |
||
| 441 | var albumInfo = Gallery.config.albumInfo; |
||
| 442 | if (Gallery.config.albumError) { |
||
| 443 | infoButton.hide(); |
||
| 444 | var text = '<strong>' + t('gallery', 'Configuration error') + '</strong></br>' + |
||
| 445 | Gallery.config.albumError.message + '</br></br>'; |
||
| 446 | Gallery.utility.showHtmlNotification(text, 7); |
||
| 447 | } else if ($.isEmptyObject(albumInfo)) { |
||
| 448 | infoButton.hide(); |
||
| 449 | } else { |
||
| 450 | infoButton.show(); |
||
| 451 | if (albumInfo.inherit !== 'yes' || albumInfo.level === 0) { |
||
| 452 | infoButton.find('span').delay(1000).slideDown(); |
||
| 453 | } |
||
| 454 | } |
||
| 455 | }, |
||
| 456 | |||
| 457 | /** |
||
| 458 | * Sets the background colour of the photowall |
||
| 459 | * |
||
| 460 | * @private |
||
| 461 | */ |
||
| 462 | _setBackgroundColour: function () { |
||
| 463 | var wrapper = $('#content-wrapper'); |
||
| 464 | var albumDesign = Gallery.config.albumDesign; |
||
| 465 | if (!$.isEmptyObject(albumDesign) && albumDesign.background) { |
||
| 466 | wrapper.css('background-color', albumDesign.background); |
||
| 467 | } else { |
||
| 468 | wrapper.css('background-color', '#fff'); |
||
| 469 | } |
||
| 470 | }, |
||
| 471 | |||
| 472 | /** |
||
| 473 | * Picks the image which matches the sort order |
||
| 474 | * |
||
| 475 | * @param {string} sortType name or date |
||
| 476 | * @param {string} sortOrder asc or des |
||
| 477 | * @param {boolean} active determines if we're setting up the active sort button |
||
| 478 | * @private |
||
| 479 | */ |
||
| 480 | _setSortButton: function (sortType, sortOrder, active) { |
||
| 481 | var button = $('#sort-' + sortType + '-button'); |
||
| 482 | // Removing all the classes which control the image in the button |
||
| 483 | button.removeClass('active-button'); |
||
| 484 | button.find('img').removeClass('front'); |
||
| 485 | button.find('img').removeClass('back'); |
||
| 486 | |||
| 487 | // We need to determine the reverse order in order to send that image to the back |
||
| 488 | var reverseSortOrder = 'des'; |
||
| 489 | if (sortOrder === 'des') { |
||
| 490 | reverseSortOrder = 'asc'; |
||
| 491 | } |
||
| 492 | |||
| 493 | // We assign the proper order to the button images |
||
| 494 | button.find('img.' + sortOrder).addClass('front'); |
||
| 495 | button.find('img.' + reverseSortOrder).addClass('back'); |
||
| 496 | |||
| 497 | // The active button needs a hover action for the flip effect |
||
| 498 | if (active) { |
||
| 499 | button.addClass('active-button'); |
||
| 500 | if (button.is(":hover")) { |
||
| 501 | button.removeClass('hover'); |
||
| 502 | } |
||
| 503 | // We can't use a toggle here |
||
| 504 | button.hover(function () { |
||
| 505 | $(this).addClass('hover'); |
||
| 506 | }, |
||
| 507 | function () { |
||
| 508 | $(this).removeClass('hover'); |
||
| 509 | }); |
||
| 510 | } |
||
| 511 | }, |
||
| 512 | |||
| 513 | /** |
||
| 514 | * If no url is entered then do not show the error box. |
||
| 515 | * |
||
| 516 | */ |
||
| 517 | _blankUrl: function() { |
||
| 518 | $('#remote_address').on("change keyup paste", function() { |
||
| 519 | if ($(this).val() === '') { |
||
| 520 | $('#save-button-confirm').prop('disabled', true); |
||
| 521 | } else { |
||
| 522 | $('#save-button-confirm').prop('disabled', false); |
||
| 523 | } |
||
| 524 | }); |
||
| 525 | }, |
||
| 526 | |||
| 527 | /** |
||
| 528 | * Creates the [+] button allowing users who can't drag and drop to upload files |
||
| 529 | * |
||
| 530 | * @see core/apps/files/js/filelist.js |
||
| 531 | * @private |
||
| 532 | */ |
||
| 533 | _renderNewButton: function () { |
||
| 534 | // if no actions container exist, skip |
||
| 535 | var $actionsContainer = $('.actions'); |
||
| 536 | if (!$actionsContainer.length) { |
||
| 537 | return; |
||
| 538 | } |
||
| 539 | if (!this._addButtonTemplate) { |
||
| 540 | this._addButtonTemplate = Handlebars.compile(TEMPLATE_ADDBUTTON); |
||
| 541 | } |
||
| 542 | var $newButton = $(this._addButtonTemplate({ |
||
| 543 | addText: t('gallery', 'New'), |
||
| 544 | iconUrl: OC.imagePath('core', 'actions/add') |
||
| 545 | })); |
||
| 546 | |||
| 547 | $actionsContainer.prepend($newButton); |
||
| 548 | $newButton.tooltip({'placement': 'bottom'}); |
||
| 549 | |||
| 550 | $newButton.click(_.bind(this._onClickNewButton, this)); |
||
| 551 | this._newButton = $newButton; |
||
| 552 | }, |
||
| 553 | |||
| 554 | /** |
||
| 555 | * Creates the click handler for the [+] button |
||
| 556 | * @param event |
||
| 557 | * @returns {boolean} |
||
| 558 | * |
||
| 559 | * @see core/apps/files/js/filelist.js |
||
| 560 | * @private |
||
| 561 | */ |
||
| 562 | _onClickNewButton: function (event) { |
||
| 563 | var $target = $(event.target); |
||
| 564 | if (!$target.hasClass('.button')) { |
||
| 565 | $target = $target.closest('.button'); |
||
| 566 | } |
||
| 567 | this._newButton.tooltip('hide'); |
||
| 568 | event.preventDefault(); |
||
| 569 | if ($target.hasClass('disabled')) { |
||
| 570 | return false; |
||
| 571 | } |
||
| 572 | if (!this._newFileMenu) { |
||
| 573 | this._newFileMenu = new Gallery.NewFileMenu(); |
||
| 574 | $('body').append(this._newFileMenu.$el); |
||
| 575 | } |
||
| 576 | this._newFileMenu.showAt($target); |
||
| 577 | |||
| 578 | if (Gallery.currentAlbum === '') { |
||
| 579 | $('.menuitem[data-action="hideAlbum"]').parent().hide(); |
||
| 580 | } |
||
| 581 | return false; |
||
| 582 | } |
||
| 583 | }; |
||
| 584 | |||
| 585 | Gallery.View = View; |
||
| 586 | })(jQuery, _, OC, t, Gallery); |
||
| 587 |
The following shows a case which JSHint considers confusing and its respective non-confusing counterpart: