623 lines
17 KiB
JavaScript
623 lines
17 KiB
JavaScript
/************************************************/
|
|
/* IPB3 Javascript */
|
|
/* -------------------------------------------- */
|
|
/* ips.slideshow.js - Gallery image notes code */
|
|
/* (c) IPS, Inc 2009 */
|
|
/* -------------------------------------------- */
|
|
/* Author: Rikki Tissier */
|
|
/************************************************/
|
|
|
|
var _notes = window.IPBoard;
|
|
|
|
_notes.prototype.imagenotes = Class.create({
|
|
|
|
/* Image ID */
|
|
id: 0,
|
|
/* Notes already made */
|
|
notes: null,
|
|
/* Wrapper */
|
|
imageWrap: null,
|
|
/* Mouseover handlers */
|
|
mouseOvers: {},
|
|
/* Mouseover for image */
|
|
mainMouseover: null,
|
|
/* Are we dragging */
|
|
dragging: false,
|
|
/* Default sizing */
|
|
defaultSize: { 'width': 50, 'height': 50 },
|
|
/* Incrementor */
|
|
i: 0,
|
|
/* Resizer objects */
|
|
resizers: {},
|
|
/* Currently editing...*/
|
|
currentEdit: null,
|
|
|
|
/*------------------------------*/
|
|
/* Constructor */
|
|
initialize: function( image, notes, options )
|
|
{
|
|
Debug.write("Initializing ips.imagenotes.js");
|
|
if( !$( image ) ){ return; }
|
|
|
|
this.id = $( image ).identify();
|
|
this.notes = notes;
|
|
this.options = Object.extend({
|
|
editable: false,
|
|
add_note: null
|
|
}, options || {} );
|
|
|
|
this.initImage();
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* Initialize image */
|
|
initImage: function()
|
|
{
|
|
if( !$( this.id ).complete )
|
|
{
|
|
this.initImage.bind( this ).delay( .2 );
|
|
return;
|
|
}
|
|
|
|
var imageDims = $( this.id ).getDimensions();
|
|
|
|
// Wrap the image
|
|
this.imageWrap = new Element( 'div', { id: this.id + '_wrap' } );
|
|
$( this.id ).wrap( this.imageWrap );
|
|
this.imageWrap.setStyle( { width: imageDims['width'] + 'px', height: imageDims['height'] + 'px' } ).addClassName('image_view_wrap');
|
|
|
|
// Build current notes
|
|
this.buildNotes();
|
|
|
|
// Set events on image
|
|
$( this.imageWrap ).observe( 'mouseover', this.imageHover.bindAsEventListener( this ) );
|
|
$( this.imageWrap ).observe( 'mouseout', this.imageHoverOff.bindAsEventListener( this ) );
|
|
|
|
// Add droppables if we can edit
|
|
if( this.options.editable ){
|
|
Droppables.add( this.id + '_wrap', { accept: 'note_wrap', containment: $( this.imageWrap ), onDrop: function(){ return false; }.bind(this) } );
|
|
}
|
|
|
|
// Add note button
|
|
if( this.options.add_note ){
|
|
$( this.options.add_note ).observe('click', this.addNote.bindAsEventListener( this ));
|
|
}
|
|
|
|
// Set up body events
|
|
Event.observe( document.body, 'click', this.bodyClick.bindAsEventListener( this ) );
|
|
},
|
|
|
|
/*------------------------------*/
|
|
addNote: function( e )
|
|
{
|
|
Event.stop(e);
|
|
|
|
if( this.currentEdit ){
|
|
return;
|
|
}
|
|
|
|
this.i++;
|
|
|
|
var wrapDims = $( this.imageWrap ).getDimensions();
|
|
|
|
this.buildNote( this.id + '_new_' + this.i, { content: '',
|
|
width: this.defaultSize['width'], height: this.defaultSize['height'],
|
|
top: Math.ceil( wrapDims['height'] / 2 ), left: Math.ceil( wrapDims['width'] / 2 )
|
|
});
|
|
|
|
// Show notes even if not mousing over
|
|
this.imageHover( e, function(){
|
|
this.noteSelect( null, this.id + '_new_' + this.i );
|
|
/*new Effect.Pulsate( $( 'note_' + this.id + '_new_' + this.i ), { pulses: 2, duration: 0.5, afterFinish: function(){
|
|
this.noteSelect( null, this.id + '_new_' + this.i );
|
|
}.bind(this) } )*/
|
|
}.bind(this) );
|
|
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* image mouseover */
|
|
imageHover: function( e, afterFinish )
|
|
{
|
|
clearTimeout( this.mainMouseover );
|
|
|
|
this.mainMouseover = setTimeout( function(){
|
|
$( this.imageWrap ).select('.note_wrap').each( function(item){
|
|
new Effect.Appear( $( item ), { duration: 0.2, afterFinish: afterFinish || null } );
|
|
});
|
|
}.bind(this), 300 );
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* image mouseoff */
|
|
imageHoverOff: function( e )
|
|
{
|
|
clearTimeout( this.mainMouseover );
|
|
|
|
this.mainMouseover = setTimeout( function(){
|
|
$( this.imageWrap ).select('.note_wrap').each( function(item){
|
|
if( $( item ).readAttribute('editing') != 'yes' ){
|
|
new Effect.Fade( $( item ), { duration: 0.2 } );
|
|
}
|
|
});
|
|
}.bind( this ), 1000 );
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* Build existing notes */
|
|
buildNotes: function()
|
|
{
|
|
|
|
this.notes.each( function( item ){
|
|
this.buildNote( this.id + '_' + item.key, item.value );
|
|
}.bind(this) );
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* Builds a note */
|
|
buildNote: function( id, info )
|
|
{
|
|
/* Info should contain:
|
|
* { content, left, top, width, height }
|
|
*/
|
|
|
|
var note = noteTemplate.evaluate( { id: id, text: info['content'] } );
|
|
$( this.id + '_wrap' ).insert( note );
|
|
|
|
/* IE won't recognize mouseover unless there's some kind of fill inside,
|
|
* so we'll set a very transparent background on it */
|
|
if( Prototype.Browser.IE ){
|
|
$( 'note_fill_' + id ).setStyle('background: #fff; opacity: 0.01');
|
|
}
|
|
|
|
// Set the size
|
|
$('note_' + id ).setStyle( { left: info['left'] + 'px', top: info['top'] + 'px' } ).hide();
|
|
$('note_box_' + id ).setStyle( { width: info['width'] + 'px', height: info['height'] + 'px' } );
|
|
|
|
// Set event
|
|
$( 'note_box_' + id ).observe('mouseover', this.noteHover.bindAsEventListener( this, id ));
|
|
$( 'note_box_' + id ).observe('mouseout', this.noteHoverOff.bindAsEventListener( this, id ));
|
|
|
|
if( this.options.editable ){
|
|
$( 'note_' + id ).addClassName('editable');
|
|
$( 'note_box_' + id ).observe('click', this.noteSelect.bindAsEventListener( this, id ) );
|
|
|
|
// Add draggable
|
|
new Draggable( $('note_' + id), {
|
|
revert: 'failure',
|
|
onDrag: function(){
|
|
$('note_' + id ).addClassName('selected');
|
|
$('note_text_' + id ).hide();
|
|
this.dragging = true;
|
|
}.bind(this),
|
|
onEnd: function(){
|
|
this.updateCoords( id );
|
|
}.bind(this)
|
|
});
|
|
|
|
this.resizers[ id ] = new ipb.resizer(
|
|
$('note_box_' + id ),
|
|
$('note_handle_' + id ),
|
|
{
|
|
onStart: function(drag){
|
|
$('note_' + id ).addClassName('selected');
|
|
$('note_text_' + id ).hide();
|
|
this.dragging = true;
|
|
}.bind(this),
|
|
onFinish: function(drag){
|
|
this.updateCoords( id );
|
|
}.bind(this)
|
|
}
|
|
);
|
|
}
|
|
|
|
Debug.write( id );
|
|
},
|
|
|
|
updateCoords: function( id )
|
|
{
|
|
var realID = id.replace( this.id + '_', '');
|
|
|
|
if( !this.notes.get( realID ) ){ return; } // This is a new, unsaved note
|
|
|
|
var containerPos = $('note_' + id).positionedOffset();
|
|
var boxSize = $('note_box_' + id).getDimensions();
|
|
var noteId = this.notes.get( realID )['noteId'];
|
|
var content = this.notes.get( realID )['content'];
|
|
|
|
new Ajax.Request( ipb.vars['base_url'] + "app=gallery&module=ajax§ion=image&do=edit-note&secure_key="+ipb.vars['secure_hash']+'&img='+ipb.gallery.imageID,
|
|
{
|
|
method: 'post',
|
|
parameters: {
|
|
'top': containerPos['top'],
|
|
'left': containerPos['left'],
|
|
'width': boxSize['width'],
|
|
'height': boxSize['height'],
|
|
'note': content,
|
|
'noteId': noteId
|
|
},
|
|
onSuccess: function(t)
|
|
{
|
|
Debug.write( t.responseText );
|
|
|
|
switch( t.responseText )
|
|
{
|
|
case 'ok':
|
|
this.notes.get( realID )['top'] = containerPos['top'];
|
|
this.notes.get( realID )['left'] = containerPos['left'];
|
|
this.notes.get( realID )['width'] = boxSize['width'];
|
|
this.notes.get( realID )['height'] = boxSize['height'];
|
|
|
|
Debug.write("Width: " + boxSize['width']);
|
|
Debug.write("height: " + boxSize['height']);
|
|
break;
|
|
case 'nopermission':
|
|
alert( ipb.lang['note_no_permission_e'] );
|
|
break;
|
|
case 'missing_data':
|
|
alert( ipb.lang['required_data_missing'] );
|
|
break;
|
|
}
|
|
}.bind( this )
|
|
});
|
|
|
|
setTimeout( function(){
|
|
if( $('note_' + id).readAttribute('editing') != 'yes' ){
|
|
$('note_' + id ).removeClassName('selected');
|
|
}
|
|
this.dragging = false;
|
|
}.bind(this), 200);
|
|
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* Note select */
|
|
noteSelect: function( e, id )
|
|
{
|
|
if( this.dragging ){ return; }
|
|
|
|
$( 'note_' + id ).addClassName('selected');
|
|
|
|
if( !this.currentEdit )
|
|
{
|
|
this.currentEdit = id;
|
|
|
|
$( 'note_' + id ).writeAttribute('editing', 'yes');
|
|
$( 'note_text_' + id).hide();
|
|
|
|
var realID = id.replace( this.id + '_', '');
|
|
|
|
if( realID.startsWith('new_') && Object.isUndefined( this.notes.get( realID ) ) ){
|
|
var content = '';
|
|
} else {
|
|
var content = this.notes.get( realID )['content'];
|
|
}
|
|
|
|
var noteForm = editTemplate.evaluate({ id: id, content: content });
|
|
$( 'note_' + id ).insert( noteForm );
|
|
$('note_content_' + id).activate();
|
|
|
|
if( realID.startsWith('new_') && Object.isUndefined( this.notes.get( realID ) ) ){
|
|
$('note_cancel_' + id).hide();
|
|
} else {
|
|
$('note_cancel_' + id).show();
|
|
}
|
|
|
|
// Events
|
|
$( 'note_save_' + id ).observe( 'click', this.formSave.bindAsEventListener( this, id ) );
|
|
$( 'note_cancel_' + id ).observe( 'click', this.formCancel.bindAsEventListener( this, id ) );
|
|
$( 'note_delete_' + id ).observe( 'click', this.formDelete.bindAsEventListener( this, id ) );
|
|
}
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* Save note */
|
|
formSave: function( e, id )
|
|
{
|
|
if( e ){ Event.stop(e); }
|
|
|
|
if( $F('note_content_' + id).blank() ){
|
|
alert( ipb.lang['note_save_empty'] );
|
|
return;
|
|
}
|
|
|
|
var realID = id.replace( this.id + '_', '');
|
|
var content = $F( 'note_content_' + id );
|
|
var newNote = false;
|
|
var containerPos = {};
|
|
var boxSize = {};
|
|
var type = '';
|
|
var noteId = null;
|
|
var done = false;
|
|
|
|
// Is this a new note?
|
|
if( realID.startsWith('new_') && Object.isUndefined( this.notes.get( realID ) ) ){
|
|
containerPos = $('note_' + id).positionedOffset();
|
|
boxSize = $('note_box_' + id).getDimensions();
|
|
newNote = true;
|
|
type = 'add';
|
|
} else {
|
|
containerPos = { 'left': this.notes.get( realID )['left'], 'top': this.notes.get( realID )['top'] };
|
|
boxSize = { 'width': this.notes.get( realID )['width'], 'height': this.notes.get( realID )['height'] };
|
|
type = 'edit';
|
|
noteId = this.notes.get( realID )['noteId'];
|
|
}
|
|
|
|
new Ajax.Request( ipb.vars['base_url'] + "app=gallery&module=ajax§ion=image&do=" + type + "-note&secure_key="+ipb.vars['secure_hash']+'&img='+ipb.gallery.imageID,
|
|
{
|
|
method: 'post',
|
|
parameters: {
|
|
'top': containerPos['top'],
|
|
'left': containerPos['left'],
|
|
'width': boxSize['width'],
|
|
'height': boxSize['height'],
|
|
'note': content,
|
|
'noteId': noteId
|
|
},
|
|
onSuccess: function(t)
|
|
{
|
|
Debug.write( t.responseText );
|
|
|
|
/*** ADDING A NOTE ***/
|
|
if( type == 'add' )
|
|
{
|
|
if( t.responseText.startsWith('ok') )
|
|
{
|
|
noteId = t.responseText.replace('ok|', '');
|
|
this.notes.set( realID, {
|
|
'width': boxSize['width'],
|
|
'height': boxSize['height'],
|
|
'top': containerPos['top'],
|
|
'left': containerPos['left'],
|
|
'content': content,
|
|
'noteId': noteId
|
|
} );
|
|
done = true;
|
|
}
|
|
else
|
|
{
|
|
switch( t.responseText )
|
|
{
|
|
case 'missing_data':
|
|
alert( ipb.lang['required_data_missing'] );
|
|
break;
|
|
case 'nopermission':
|
|
alert( ipb.lang['notes_no_permission_a'] );
|
|
break;
|
|
case 'max_notes_reached':
|
|
alert( ipb.lang['max_notes_reached'] );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/*** EDITING A NOTE ***/
|
|
else
|
|
{
|
|
switch( t.responseText )
|
|
{
|
|
case 'ok':
|
|
this.notes.get( realID )['content'] = content;
|
|
done = true;
|
|
break;
|
|
case 'missing_data':
|
|
alert( ipb.lang['required_data_missing'] );
|
|
break;
|
|
case 'nopermission':
|
|
alert( ipb.lang['notes_no_permission_e'] );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( done ){
|
|
$('note_text_' + id).update( content );
|
|
|
|
this.finishEditing( id );
|
|
|
|
$('note_text_' + id).show();
|
|
this.noteHoverOff( null, id );
|
|
}
|
|
}.bind(this)
|
|
});
|
|
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* Cancel note */
|
|
formCancel: function( e, id )
|
|
{
|
|
if( e ){ Event.stop(e); }
|
|
this.finishEditing( id );
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* Delete note */
|
|
formDelete: function( e, id )
|
|
{
|
|
if( e ){ Event.stop(e); }
|
|
|
|
if( confirm( ipb.lang['note_confirm_delete'] ) )
|
|
{
|
|
var realID = id.replace( this.id + '_', '');
|
|
|
|
if( this.notes.get( realID ) )
|
|
{
|
|
new Ajax.Request( ipb.vars['base_url'] + "app=gallery&module=ajax§ion=image&do=remove-note&secure_key="+ipb.vars['secure_hash']+'&img='+ipb.gallery.imageID,
|
|
{
|
|
method: 'post',
|
|
parameters: {
|
|
'noteId': this.notes.get( realID )['noteId']
|
|
},
|
|
onSuccess: function(t)
|
|
{
|
|
switch( t.responseText )
|
|
{
|
|
case 'ok':
|
|
new Effect.Fade( $('note_' + id), { duration: 0.2, afterFinish: function(){
|
|
this.finishEditing( id );
|
|
$('note_' + id).remove();
|
|
this.notes.unset( realID );
|
|
}.bind( this )
|
|
});
|
|
break;
|
|
case 'nopermission':
|
|
alert( ipb.lang['note_no_permission_d'] );
|
|
break;
|
|
case 'missing_data':
|
|
alert( ipb.lang['required_data_missing'] );
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
else
|
|
{
|
|
new Effect.Fade( $('note_' + id), { duration: 0.2, afterFinish: function(){
|
|
this.finishEditing( id );
|
|
$('note_' + id).remove();
|
|
}.bind( this )
|
|
});
|
|
}
|
|
}
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* Completed editing */
|
|
finishEditing: function( id )
|
|
{
|
|
// Remove form
|
|
$( 'note_form_' + id ).remove();
|
|
$( 'note_' + id ).writeAttribute('editing', 'no').removeClassName('selected');
|
|
this.currentEdit = null;
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* Note mouseover */
|
|
noteHover: function(e, id)
|
|
{
|
|
if( !this.dragging && $('note_' + id).readAttribute('editing') != 'yes' )
|
|
{
|
|
clearTimeout( this.mouseOvers[ id ] );
|
|
|
|
this.mouseOvers[ id ] = setTimeout( function(){
|
|
new Effect.Appear( $( 'note_text_' + id ), { duration: 0.2 } );
|
|
}.bind( this ), 300 );
|
|
}
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* Note mouseoff */
|
|
noteHoverOff: function(e, id)
|
|
{
|
|
clearTimeout( this.mouseOvers[ id ] );
|
|
|
|
if( $('note_text_' + id ).visible() )
|
|
{
|
|
this.mouseOvers[ id ] = setTimeout( function(){
|
|
new Effect.Fade( $( 'note_text_' + id ), { duration: 0.2 } );
|
|
}.bind( this ), 800 );
|
|
}
|
|
},
|
|
|
|
/*------------------------------*/
|
|
/* Handles document click */
|
|
bodyClick: function( e )
|
|
{
|
|
// Get all notes inside the wrapper
|
|
$( this.imageWrap ).select('.note_wrap').each( function( elem ){
|
|
if( !Event.element(e).descendantOf( elem ) ){
|
|
if( $( elem ).readAttribute('editing') != 'yes' ){
|
|
$( elem ).removeClassName('selected');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
});
|
|
|
|
/************************************************/
|
|
/* Element resizing class */
|
|
/************************************************/
|
|
var _resize = window.IPBoard;
|
|
_resize.prototype.resizer = Class.create({
|
|
|
|
container: null,
|
|
handler: null,
|
|
movePosition: {'x': 0, 'y': 0},
|
|
func: null,
|
|
|
|
/*--------------------------*/
|
|
/* Constructor */
|
|
initialize: function( container, handle, options )
|
|
{
|
|
if( !$( container ) || !$( handle ) ){
|
|
return false;
|
|
}
|
|
|
|
this.container = $( container );
|
|
this.handle = $( handle );
|
|
this.options = Object.extend( {
|
|
onStart: null,
|
|
onFinish: null
|
|
}, options || {});
|
|
|
|
new Draggable( $( this.handle ), {
|
|
onStart: this.setUpResize.bindAsEventListener( this ),
|
|
change: this.mouseMoved.bindAsEventListener( this ),
|
|
onEnd: this.endResize.bindAsEventListener( this )
|
|
});
|
|
|
|
},
|
|
|
|
/*---------------------------*/
|
|
/* onStart event, gets sizes */
|
|
setUpResize: function( draggable, e )
|
|
{
|
|
this.containerPos = $( this.container ).positionedOffset();
|
|
this.handleSize = $( this.handle ).getDimensions();
|
|
|
|
$( this.container ).makePositioned();
|
|
$( this.handle ).makePositioned();
|
|
|
|
// Set cursor
|
|
document.body.addClassName('resizing');
|
|
|
|
if( Object.isFunction( this.options.onStart ) ){
|
|
this.options.onStart( draggable );
|
|
}
|
|
},
|
|
|
|
/*--------------------------*/
|
|
/* Finish resizing */
|
|
endResize: function( draggable, e )
|
|
{
|
|
document.body.removeClassName('resizing');
|
|
|
|
if( Object.isFunction( this.options.onFinish ) ){
|
|
this.options.onFinish( draggable );
|
|
}
|
|
},
|
|
|
|
/*--------------------------*/
|
|
/* 'change' event */
|
|
mouseMoved: function( draggable, e )
|
|
{
|
|
// Get position
|
|
var pos = $( this.handle ).positionedOffset();
|
|
|
|
var newWidth = ( pos['left'] - this.containerPos['left'] ) + this.handleSize['width'];
|
|
var newHeight = ( pos['top'] - this.containerPos['top'] ) + this.handleSize['height'];
|
|
|
|
if( newWidth < 25 ){
|
|
newWidth = 25;
|
|
$( this.handle ).setStyle( { left: ( ( this.containerPos['left'] + 25 ) - this.handleSize['width'] ) + 'px' } );
|
|
}
|
|
|
|
if( newHeight < 25 ){
|
|
newHeight = 25;
|
|
$( this.handle ).setStyle( { top: ( ( this.containerPos['top'] + 25 ) - this.handleSize['height'] ) + 'px' } );
|
|
}
|
|
|
|
$( this.container ).setStyle( { width: newWidth + 'px', height: newHeight + 'px' } );
|
|
}
|
|
|
|
}); |