;( function($, _, undefined){ "use strict"; ips.controller.register('gallery.front.global.nsfw', { initialize () { this.on( 'click', '.ipsNsfwOverlay button', this.removeOverlays ); }, removeOverlays( e ) { let expires = new Date(); expires.setDate( expires.getDate() + 365 ); ips.utils.cookie.set( 'nsfwImageOptIn', true, expires.toUTCString() ); $('.ipsNsfwOverlay').fadeOut(500, function() { this.remove() }); }, }); }(jQuery, _)); /** * Invision Community * (c) Invision Power Services, Inc. - https://www.invisioncommunity.com * * ips.settings.settings.js * * Author: Brandon Farber */ ;( function($, _, undefined){ "use strict"; ips.controller.register('gallery.admin.settings.settings', { alertOpen: false, initialize: function () { if( $('input[name=rebuildWatermarkScreenshots]').val() == 0 ) { this.on( 'uploadComplete', '[data-ipsUploader]', this.promptRebuildPreference ); this.on( 'fileDeleted', this.promptRebuildPreference ); this.on( 'change', '#gallery_watermark_images input, #form_gallery_large_dims input, #form_gallery_small_dims input, #form_gallery_use_square_thumbnails input', this.promptRebuildPreference ); } }, promptRebuildPreference: function (e) { if( this.alertOpen ) { return; } this.alertOpen = true; /* Show Rebuild Prompt */ ips.ui.alert.show({ type: 'confirm', message: ips.getString('rebuildGalleryThumbnails'), subText: ips.getString('rebuildGalleryThumbnailsBlurb'), icon: 'question', buttons: { ok: ips.getString('rebuildGalleryThumbnailsYes'), cancel: ips.getString('rebuildGalleryThumbnailsNo') }, callbacks: { ok: function(){ $('input[name=rebuildWatermarkScreenshots]').val( 1 ); this.alertOpen = false; }, cancel: function(){ $('input[name=rebuildWatermarkScreenshots]').val( 0 ); this.alertOpen = false; } } }); } }); }(jQuery, _)); li', this.clickAlbum ); this.clickAlbum(); }, /** * Checks whether any radios are selected, and enables/disables the submit button as needed * * @returns {void} */ clickAlbum: function (e) { if( this.scope.find('[name="existing_album"]:checked').length ){ this.scope.find('[type="submit"]').prop( 'disabled', false ); } else { this.scope.find('[type="submit"]').prop( 'disabled', true ); } } }); }(jQuery, _));]]> 0 ){ this.trigger('gallery.activateSubmitButton'); } if( data.error > 0 ){ this.trigger('gallery.uploadErrors'); } if( !this.sortableInitialized ){ // And allow images to be reordered this.scope.find('[data-role="fileList"] > .cGallerySubmit_fileList').sortable({ forcePlaceholderSize: true }); this.sortableInitialized = true; } }, /** * Track whether we've initialized the sortable */ sortableInitialized: false, /** * Responds to event from the uploader * * @param {event} e Event object * @param {object} data Data object from uploader * @returns {void} */ filesAdded: function (e, data) { this.trigger('gallery.disableSubmitButton'); $('[data-role="addFiles"]').removeClass( 'ipsHide' ); $('[data-role="imageDetails"]').removeClass('ipsHide'); // Only add the uploadStep class if we aren't on mobile if( !ips.utils.responsive.enabled() || !ips.utils.responsive.currentIs('phone') ){ this.scope.closest('.cGalleryDialog').addClass('cGalleryDialog_uploadStep'); } $( window ).trigger('resize'); } }); }(jQuery, _));]]> ' + htmlToInsert.replace( /name="image_tags_DEFAULT"/g, 'name="image_tags_DEFAULT" data-ipsAutocomplete ').replace( /_DEFAULT/g, '_' + imageId ) + ""; // Now insert this form detailsPanel.find('> form').prepend( htmlToInsert ); var imageForm = $('#image_details_' + imageId ); // Set the image caption var filename = $( e.currentTarget ).find('[data-role="title"]').text(); var filenameWithoutExt = filename.replace(/\.[^/.]+$/, ''); $('#elInput_image_title_' + imageId ).val( filenameWithoutExt ); if( !_.isUndefined( imagePreview ) ){ imageForm .find('.cGallerySubmit_preview') .html( $("").attr('src', imagePreview ) ) .show(); } else { imageForm .find('.cGallerySubmit_preview') .html("") .show(); } // If this is a movie, show the thumbnail uploader if( !$( e.currentTarget ).attr('data-thumbnailurl') ){ imageForm.find('.cGalleryThumbField').removeClass('ipsHide'); } else { // Otherwise if it's an image, find out if we have GPS info and need to let them toggle map on/off ips.getAjax()( ips.getSetting('baseURL') + 'index.php?app=gallery&module=gallery&controller=submit&do=checkGps&imageId=' + imageId, { type: 'get', bypassRedirect: true }) .done( function (response, status, jqXHR) { // Just find the internal content if( parseInt( response.hasGeo ) ){ imageForm.find('.cGalleryMapField').removeClass('ipsHide'); } }); } // Show the details panel if we're on mobile if( ips.utils.responsive.currentIs('phone') ){ this._toggleDetailsPanelMobile(true); } // And then emit contentChange event to trigger javascript controllers (e.g. tags) $( document ).trigger( 'contentChange', [ $('[data-role="imageDetails"] > form') ] ); // Check for current errors if( !_.isUndefined( this._currentErrors[ imageId ] ) ){ this._updateDetailsWithErrors( imageId, this._currentErrors[ imageId ] ); } } }, /** * Toggle details panel on mobile * * @returns {void} */ _toggleDetailsPanelMobile: function (show) { var detailsPanel = this.scope.find('[data-role="imageDetails"]'); if( !show ){ detailsPanel .animate({ opacity: "0", top: '400px' }, 400, function () { detailsPanel.hide() }); } else if( !detailsPanel.is(':visible') ) { detailsPanel .show() .css({ opacity: "0", top: '400px' }) .animate({ opacity: "1", top: '0px' }, 400 ); } }, /** * Set up description events * * @returns {void} */ setUpImageDescriptionRich: function(e) { const currentDescription = $(e.currentTarget).closest('[data-role="imageDescriptionTextarea"]') .find('> textarea') .val() .trim(); if( currentDescription.length ){ const editorObj = ips.ui.editorv5.getObj($(e.currentTarget).closest('[data-role="imageDescriptionTextarea"]') .prev('[data-role="imageDescriptionEditor"]') .find('[data-ipseditorv5]')); const editorInstance = editorObj.getInstance(); editorInstance.commands.setContent( currentDescription ); $( e.currentTarget ).closest('[data-role="imageDescriptionTextarea"]') .find( '> textarea' ) .val(''); } $( e.currentTarget ).closest('[data-role="imageDescriptionTextarea"]') .addClass('ipsHide') .prev('[data-role="imageDescriptionEditor"]') .removeClass('ipsHide'); e.preventDefault(); }, /** * Set up description events * * @returns {void} */ setUpImageDescriptionPlain: function (e) { const editorObj = ips.ui.editorv5.getObj($(e.currentTarget).closest('[data-role="imageDescriptionEditor"]') .find('[data-ipseditorv5]')); const currentDescription = $(editorObj.getInstance().getHTML()).text() .trim(); if( currentDescription.length ){ $( e.currentTarget ).closest('[data-role="imageDescriptionEditor"]') .next('[data-role="imageDescriptionTextarea"]') .find( 'textarea' ) .val( currentDescription ); } $( e.currentTarget ).closest('[data-role="imageDescriptionEditor"]') .addClass('ipsHide') .next('[data-role="imageDescriptionTextarea"]') .removeClass('ipsHide'); e.preventDefault(); }, /** * IE11 doesn't support submit buttons outside of a
like HTML5 does. * So, if we click the button, are on IE11, and not inside a form, manually trigger a submit. * * @param {event} e Event object * @returns {void} */ maybeSubmitForm: function (e) { var isIE11 = !(window.ActiveXObject) && "ActiveXObject" in window; if( !$( e.currentTarget ).closest('form').length && $( e.currentTarget ).is('[form]') && isIE11 ){ var form = $('#' + $( e.currentTarget ).attr('form')); if( form.length ){ form.submit(); } } }, /** * Event handler for submitting forms inside the wizard * * @param {event} e Event object * @returns {void} */ submitForm: function (e) { e.preventDefault(); var form = $( e.currentTarget ); var url = form.attr('action'); // If we are submitting images, get the info we need if( form.attr('id') == 'elGallerySubmit' ){ // Sync editor to its textarea this.scope.find('[data-ipseditorv5]').each( function(){ try { var editorObj = ips.ui.editorv5.getObj( $( this ) ); var editorInstance = editorObj.getInstance(); $( this ).find('textarea[data-role="contentEditor"]').val( editorInstance.getHTML() ); } catch (err) { Debug.error("Couldn't update textarea from editor"); } }); // Get credit, copyright and auto-follow fields and add to our form form.find('textarea[name="credit_all"]').val( $('#elTextarea_image_credit_info').val() ); form.find('textarea[name="copyright_all"]').val( $('#elInput_image_copyright').val() ); if( $('#elInput_image_tags_wrapper').length ){ try { var tags = ips.ui.autocomplete.getObj( this.scope.find('#elInput_image_tags') ).getTokens(); form.find('textarea[name="tags_all"]').val( tags.join("\n") ); form.find('textarea[name="prefix_all"]').val( $('[name="image_tags_prefix"]').val() ); } catch (err) { Debug.error("Couldn't update tags"); } } if( ips.getSetting('memberID') ) { form.find('input[name="images_autofollow_all"]').val( $('#check_image_auto_follow_wrapper').hasClass('ipsToggle_on') ? 1 : 0 ); } if( $('#check_image_nsfw_wrapper').length ) { form.find('input[name="nsfw_all"]').val($('#check_image_nsfw_wrapper').hasClass('ipsToggle_on') ? 1 : 0); } // Get the order of the images and store this in the submission var imageOrder = []; form.find('[data-role="file"]').each( function(){ if( $(this).attr('data-fileid').indexOf('o_') != -1 ) { imageOrder.push( $('input[name="images_existing\\[' + $(this).attr('data-fileid') + '\\]"').val() ); } else { imageOrder.push( $(this).attr('data-fileid') ); } }); form.find('textarea[name="images_order"]').val( JSON.stringify( imageOrder ) ); // And get the individual image details and store in the submission form.find('textarea[name="images_info"]').val( JSON.stringify( $('#form_imageDetails').serializeArray() ) ); // Hide/disable some stuff this.scope.find('[data-role="imageDetails"]').addClass('ipsHide'); this.scope.find('#elGallerySubmit_toolBar').hide(); this.scope.find('[data-role="submitForm"]').prop('disabled', true); this.scope.find('.cGalleryDialog').removeClass('cGalleryDialog_uploadStep'); } // And don't bubble up e.stopPropagation(); this._changeContents( url, form.serialize() ); }, /** * Updates the wizard contents from a URL response * * @param {string} url URL to call * @param {object} data Data to pass to ajax handler * @returns {void} */ _changeContents: function (url, data) { if( _.isUndefined( data ) ){ data = {}; } var self = this; var loadingElement = this.scope.closest('.ipsDialog_content'); this.scope.find('.cGalleryDialog_container, .cGalleryDialog_imageForm').hide(); this.cleanContents(); loadingElement.addClass('ipsLoading'); ips.getAjax()( url + '&noWrapper=1', { data: data, type: 'post', bypassRedirect: true }) .done( function (response, status, jqXHR) { // Just find the internal content self._updateContents( response ); }) .always( function() { loadingElement.removeClass('ipsLoading'); }); }, /** * Event listener for passing through AJAX responses * * @param {object} response AJAX response object * @returns {void} */ _updateWrapper: function( e, data ) { this._updateContents( data.response ); }, /** * Updates the wizard contents * * @param {object} response Response object * @returns {void} */ _updateContents: function ( response ) { var wrapper = $('[data-role="submitWrapper"]'); var container = wrapper.find('[data-role="container"]'); if( response.container ) { container.html( response.container ); container.show(); } else { container.hide(); } if( response.containerInfo ) { wrapper.find('[data-role="containerInfo"]').html( response.containerInfo ); } if( response.images ) { this._updateTitle( ips.getString('addImages') ); // Animate the dialog expanding for the upload step if( this.scope.closest('.cGalleryDialog_outer').length && !this.scope.find('[data-role="imagesForm"]').is(':visible') && !this._expanded ){ this._enlargeUploadStep( function () { wrapper.find('[data-role="imageForm"]').html( response.images ); }); } else { wrapper.find('[data-role="images"]').show(); wrapper.find('[data-role="imageForm"]').html( response.images ); } } if( response.imageTags && wrapper.find('.cGalleryTagsField').hasClass('ipsHide') ){ wrapper.find('.cGalleryTagsField').removeClass('ipsHide'); wrapper.find('.cGalleryTagsField .ipsFieldRow__content').append( response.imageTags ); } if( response.tagsField && wrapper.find('.cGalleryTagsButton').hasClass('ipsHide') ) { wrapper.find('.cGalleryTagsButton').removeClass('ipsHide'); wrapper.find('[data-role="globalTagsField"]').append( response.tagsField ); } $( document ).trigger( 'contentChange', [ wrapper ] ); if( !_.isUndefined( response.imageErrors ) && _.size( response.imageErrors ) > 0 ){ this._handleUploaderErrors( response.imageErrors ); } }, /** * Handles a submission error * * @param {object} errors Object containing errors * @returns {void} */ _handleUploaderErrors: function (errors) { var self = this; this.scope.find('[data-role="imageDetails"]').removeClass('ipsHide'); this.scope.find('#elGallerySubmit_toolBar').show(); this.scope.find('[data-role="submitForm"]').prop('disabled', false); this.scope.find('.cGalleryDialog').addClass('cGalleryDialog_uploadStep'); this._currentErrors = errors; var errorCount = _.size( errors ); var errorIDs = _.keys( errors ); var errorFileIDs = _.map( errorIDs, function (id) { if( self.scope.find('input[type="hidden"][value="' + id + '"]').attr('name') ) { return '#' + self.scope.find('input[type="hidden"][value="' + id + '"]').attr('name').replace(/images_existing\[/g, '').replace(/\]/g, ''); } }); var errorFileThumbs = this.scope.find( errorFileIDs.join(',') ); // Mark all thumbs as 'done' this.scope.find('.cGallerySubmit_fileList [data-role="file"]').addClass('cGallerySubmit_imageSaved'); // Add error class to all the errored ones errorFileThumbs.addClass('cGallerySubmit_imageError').removeClass('cGallerySubmit_imageSaved'); _.each( errorIDs, function (id) { if( self.scope.find('#image_details_' + id).length ){ self._updateDetailsWithErrors( id, errors[ id ] ); } }); // Show an error if( !_.isUndefined( errors[0] ) && !_.isUndefined( errors[0]['images'] ) ) { ips.ui.alert.show( { type: 'alert', icon: 'warn', message: errors[0]['images'], }); } else { ips.ui.alert.show( { type: 'alert', icon: 'warn', message: ips.pluralize( ips.getString('imageUploadErrors'), errorCount ), subText: ips.pluralize( ips.getString('imageUploadErrorsDesc'), errorCount ) }); } }, /** * Updates the details panel for a file with the provided errors * * @param {object} errors Object containing errors * @returns {void} */ _updateDetailsWithErrors: function (fileID, errors) { var panel = this.scope.find('#image_details_' + fileID); _.each( errors, function (error, field) { panel.find('[data-errorField="' + field + '"]').text( error ).show(); if( field == 'image_tags' || field == 'image_credit' || field == 'image_copyright' ){ panel.find('[data-errorField="' + field + '"]').closest('.ipsFieldRow').find('[data-role="addCopyrightCredit"]').click(); } }); }, /** * Expands the dialog for the upload step * * @param {object} response Response object * @returns {void} */ _enlargeUploadStep: function (callback) { var wrapper = $('[data-role="submitWrapper"]'); var dialogElem = this.scope.closest('.cGalleryDialog_outer > div'); if( dialogElem.length ) { var dialogElemPos = ips.utils.position.getElemPosition( dialogElem ); var viewportSize = { width: $( window ).width(), height: $( window ).height() }; var left = ( viewportSize.width - dialogElem.width() ) / 2; // Set the size of the dialog div, and then animate expanding to fullscreen size this.scope.closest('.cGalleryDialog_outer > div').css({ width: 'auto', maxWidth: '100%', position: 'fixed', margin: 0, top: dialogElemPos.absPos.top + 'px', left: left + 'px', right: viewportSize.width - ( left + dialogElem.width() ) + 'px' }).animate({ left: '10px', right: '10px', bottom: '10px', top: '10px', }, function () { // Now fade in the wrapper wrapper.find('[data-role="images"]').css({ opacity: "0.0001", }).show(); if( callback ){ callback(); } wrapper.find('[data-role="images"]').animate({ opacity: "1" }); dialogElem.find('.ipsDialog_close').hide(); $( document ).trigger( 'contentChange', [ wrapper ] ); }); } else { if( callback ){ callback(); } $( document ).trigger( 'contentChange', [ wrapper ] ); } // Positioning needed for upload step this.scope.find('.cGalleryDialog').css({ minHeight: "0", position: 'absolute', top: "0", left: "0", right: "0", bottom: "0" }); this.scope.closest('.ipsDialog_content').css({ position: 'absolute', top: "0", left: "0", right: "0", bottom: "0" }); if( !wrapper.find('.cGallerySubmit_bottomBar').hasClass('ipsHide') ){ wrapper.find('.cGallerySubmit_bottomBar').removeClass('ipsHide').fadeIn(); } this._expanded = true; } }); }(jQuery, _));]]> /** * Invision Community * (c) Invision Power Services, Inc. - https://www.invisioncommunity.com * * ips.view.image.js - Image controller * * Author: Rikki Tissier */ ;( function($, _, undefined){ "use strict"; ips.controller.register('gallery.front.view.image', { initialize: function () { this.on( 'menuOpened', this.menuOpened ); this.on( 'menuClosed', this.menuClosed ); this.on( document, 'keydown', this.keyDown ); this.on( 'click', '[data-action="setAsCover"]', this.setAsCover ); this.on( 'click', '[data-action="setAsProfile"]', this.setAsProfile ); this.on( 'click', '[data-action="rotateImage"]', this.rotateImage ); }, /** * Adds a classname to wrapper when a menu opens * * @returns {void} */ menuOpened: function () { this.scope.find('.elGalleryImage').addClass('cGalleryImageHover'); }, /** * Removes classname to wrapper when a menu opens * * @returns {void} */ menuClosed: function (e) { this.scope.find('.elGalleryImage').removeClass('cGalleryImageHover'); }, /** * Handles the keyDown event for navigating photos * * @returns {void} */ keyDown: function (e) { // Ignore the keypress if we're in a form element if( $( e.target ).closest('input, textarea, .ipsComposeArea, .ipsComposeArea_editor').length ){ return; } switch( e.keyCode ){ case ips.ui.key.LEFT: this.scope.find('[data-action="prevMedia"]')[0].click(); break; case ips.ui.key.RIGHT: this.scope.find('[data-action="nextMedia"]')[0].click(); break; } }, /** * Sets the current image as the user's profile picture * * @param {event} e Event object * @returns {void} */ setAsProfile: function (e) { e.preventDefault(); var url = $( e.currentTarget ).attr('href'); ips.ui.alert.show( { type: 'confirm', icon: 'question', message: ips.getString('set_as_photo_confirm'), callbacks: { ok: function () { ips.getAjax()( url, { showLoading: true } ) .done( function (response) { ips.ui.flashMsg.show( response.message ); }) .fail( function () { window.location = url; }); } } }); }, /** * Sets the image as a cover photo * * @param {event} e Event object * @returns {void} */ setAsCover: function (e) { e.preventDefault(); var url = $( e.currentTarget ).attr('href'); ips.getAjax()( url, { showLoading: true } ) .done( function (response) { ips.ui.flashMsg.show( response.message ); }) .fail( function () { window.location = url; }); }, /** * Rotates the image * * @param {event} e Event object * @returns {void} */ rotateImage: function (e) { e.preventDefault(); var url = $( e.currentTarget ).attr('href'); var self = this; ips.getAjax()( url, { showLoading: true } ) .done( function (response) { self.scope.find('[data-role="theImage"]')[0].src = response.src; self.scope.find('[data-role="theImage"]').css( { 'width': response.width + 'px', 'height': response.height + 'px' } ); self.scope.find('[data-role="theImage"]').closest('.cGalleryViewImage').css( { 'width': response.width + 'px', 'height': response.height + 'px' } ); ips.ui.flashMsg.show( response.message ); }) .fail( function () { window.location = url; }); } }); }(jQuery, _)); div textarea').focus(); return; } this._editing = true; this.scope .addClass('cGalleryNote_editing') .append( ips.templates.render('gallery.notes.delete') ) .find('.cGalleryNote_note > div') .html( ips.templates.render('gallery.notes.edit', { note: this._note })) .find('textarea') .focus(); }, /** * Deletes the note * * @returns {void} */ _doDeleteNote: function () { var url = this._baseURL; var self = this; if( this.scope.attr('data-noteID') == 'new' ) { ips.utils.anim.go( 'fadeOutDown', self.scope ) .done( function () { self.scope.remove(); }); return; } ips.getAjax()( url + '&delete=1&id=' + this.scope.attr('data-noteID') ) .done( function () { ips.utils.anim.go( 'fadeOutDown', self.scope ) .done( function () { self.scope.remove(); }); }) }, /** * Saves the note * * @param {string} noteContent If provided, the updated note text to be saved * @param {boolean} savePosition If true, will update the position info for the note * @returns {promise} */ _saveNote: function (noteContent, savePosition) { var deferred = $.Deferred(); var self = this; var url = this._baseURL; var position = ''; var note = ''; if( this.scope.attr('data-noteID') == 'new' ){ url += '&add=1'; } else { url += '&edit=1&id=' + this.scope.attr('data-noteID'); } if( savePosition ){ position = this._getPosition(); } if( noteContent ){ note = noteContent; } if( this.scope.find('[data-action="save"]').length && note ){ this.scope.find('[data-action="save"]').prop('disabled', true).text( ips.getString('saving_note') ); } // Send request ips.getAjax()( url, { data: { note: note, position: position } }) .done( function (response) { if( self.scope.find('[data-action="save"]').length && note ){ self.scope.find('[data-action="save"]').prop( 'disabled', false ).text( 'Save' ); } // If this was a new note and the server returned an ID, update our attribute if( _.isObject( response ) && response.id ){ self.scope.attr( 'data-noteID', response.id ); } deferred.resolve(); }) .fail( function () { deferred.reject(); }); return deferred.promise(); }, /** * Gets the position and dims of the note, in percentage values (relative to the image) * * @returns {string} In format ,,, */ _getPosition: function () { var position = []; var parent = this.scope.closest('.cGalleryViewImage'); var notePos = this.scope.position(); // Left position[0] = ( notePos['left'] / parent.width() ) * 100; // Top position[1] = ( notePos['top'] / parent.height() ) * 100; // Width position[2] = ( this.scope.width() / parent.width() ) * 100; // Height position[3] = ( this.scope.height() / parent.height() ) * 100; return position.join(','); }, /** * Takes note out of editing state * * @returns {void} */ _stopEditing: function () { this._editing = false; this._draggingNotEditing = false; this.scope .removeClass('cGalleryNote_editing') .find('.cGalleryNote_note > div') .text( this._note ) .end() .find('.cGalleryNote_delete') .remove(); }, /** * Adds the note text to the note * * @returns {void} */ _buildNote: function () { this.scope.find('.cGalleryNote_note > div').text( this._note ); }, /** * When the note is editable, loads jQuery UI and sets up resizable/draggable * * @returns {void} */ _setUpEditable: function () { if( !this._editable ){ return; } var self = this; ips.loader.get( ['core/interface/jquery/jquery-ui.js'] ).then( function () { self.scope.resizable({ containment: self.scope.closest('.cGalleryViewImage'), handles: 'se', stop: self._updatePosition.bind( self ) }); self.scope.draggable({ containment: self.scope.closest('.cGalleryViewImage'), start: self._startDragging.bind( self ), stop: self._updatePosition.bind( self ) }); }); }, /** * Event handler for start event on Draggable. If we aren't already editing, set a flag so that * when we stop dragging, the click doens't incorrectly put note into editing mode * * @returns {void} */ _startDragging: function () { if( !this._editing ){ this._draggingNotEditing = true; } }, /** * Saves the current position of the note. Called when resizable or draggable stop * * @returns {void} */ _updatePosition: function () { var self = this; // If the note block is now out of view, flip it to the other side /* var parent = this.scope.closest('.cGalleryViewImage'); var notePos = this.scope.position(); var posLeft = this.scope.find('.cGalleryNote_note').css('left'); var posRight = this.scope.find('.cGalleryNote_note').css('right'); // If the text box is on the right side, and is now past the boundary of the image, flip it to the left side if( parseInt( posLeft ) > 0 ) { if( notePos['left'] + parseInt( this.scope.width() ) + parseInt( this.scope.find('.cGalleryNote_note').width() ) > parent.width() ) { // But don't bother doing it if it will just be off the other side now if( notePos['left'] - parseInt( this.scope.find('.cGalleryNote_note').width() ) > 0 ) { this.scope.find('.cGalleryNote_note').css( 'left', posRight ); this.scope.find('.cGalleryNote_note').css( 'right', posLeft ); } } } else { if( notePos['left'] - parseInt( this.scope.find('.cGalleryNote_note').width() ) < 0 ) { // Don't flip if it will be off the other side now if( notePos['left'] + parseInt( this.scope.width() ) + parseInt( this.scope.find('.cGalleryNote_note').width() ) < parent.width() ) { this.scope.find('.cGalleryNote_note').css( 'left', posRight ); this.scope.find('.cGalleryNote_note').css( 'right', posLeft ); } } } */ // If this is a new note, we don't want to update the position remotely yet. // We'll only do that once the note text is saved for the first time. if( this.scope.attr('data-noteID') == 'new' ){ return; } this._saveNote( false, true ) .done( function () { // If we were editing before updating pos/dims, we don't want to run the stop method // otherwise changes to the note text will be lost. if( !self._editing ){ self._stopEditing(); } }); }, /** * Positions the note based on the attributes on the scope element * * @returns {void} */ _initialPosition: function () { var left = this.scope.attr('data-posLeft'); var top = this.scope.attr('data-posTop'); var width = this.scope.attr('data-dimWidth'); var height = this.scope.attr('data-dimHeight'); // Position the note this.scope.css({ left: left + '%', top: top + '%', width: width + '%', height: height + '%' }); } }); }(jQuery, _));]]> // Empty \
    \
  • \ \
  • \ \ \
  • \
\
\ {{#status}}\ {{{status}}}\ \ {{/status}}\ {{#thumb}}\ {{{thumb}}}\ {{/thumb}}\
\

{{title}}

\

{{size}} {{#statusText}}· {{statusText}}{{/statusText}}

\ \ "); ips.templates.set('gallery.submit.imageItemWrapper', " \
{{{content}}}
\ ");]]>
\
\ \ \ "); ips.templates.set('gallery.notes.delete', " \ ×\ "); ips.templates.set('gallery.notes.edit', " \ \ \ ");]]>
templates common/ips.loader.js common/ui common/utils common controllers underscore jquery mustache Debug.js app.js jquery.js jquery-migrate.js jquery.transform.js linkify.min.js linkify-jquery.min.js