web: intial commit of taylored image_annotate module for flukso

This commit is contained in:
Bart Van Der Meerssche 2009-09-16 22:39:58 +00:00
parent 8b7a1ee2ea
commit ab82a944fe
16 changed files with 989 additions and 8 deletions

View File

@ -0,0 +1,8 @@
/README.txt/1.4/Fri Jan 30 06:49:42 2009//TDRUPAL-6--2-0
/image_annotate.info/1.2/Tue Jan 20 17:28:05 2009//TDRUPAL-6--2-0
/image_annotate.install/1.3/Wed Jan 28 19:27:13 2009//TDRUPAL-6--2-0
/image_annotate.module/1.6/Fri Mar 6 16:46:22 2009//TDRUPAL-6--2-0
/tag.css/1.4/Thu Jan 29 06:39:20 2009//TDRUPAL-6--2-0
/tag.js/1.6/Fri Jan 30 06:49:42 2009//TDRUPAL-6--2-0
/tag.packed.js/1.2/Fri Jan 30 06:49:42 2009//TDRUPAL-6--2-0
D

View File

@ -0,0 +1 @@
contributions/modules/image_annotate

View File

@ -0,0 +1 @@
:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib

View File

@ -0,0 +1 @@
NDRUPAL-6--2-0

View File

@ -0,0 +1,43 @@
Image Annotate allows users to attach notes or user references to areas of a picture. This is
what Flickr and Facebook already do.
This module is based on jQuery UI and only work with the Image and ImageField modules: please
feedback, issues and remarks on the project page (http://drupal.org/project/image_annotate).
Install
-------
1. Copy the image_annotate folder into your module folder.
2. Go to the modules page (admin/build/modules) and enable the Image Annotate module
(dependency on jquery_ui and imagefield modules)
3. Go to the permissions page (admin/user/permissions) and activate the appropriate
permissions: users need both permissions for comments AND image annotations.
4. Navigate to the admin page of the content type for which you want to have an
annotative image (admin/content/node-type/YOUR_CONTENT_TYPE):
a. Activate comments for that content type ("Comment settings")
b. Go to the "Display fields" sub section (admin/content/node-type/picture/display) and
select the widget for handling display of the body: select the "Image with annotations" one.
4. Next time you create a node of that type, when viewing the node you will see
an "Add a note" link that lets you add comments on the picture (given that you have
the permission to do so).
Todo:
-----
This module is still being actively develop, here are a few things that are still to be done:
* Clean and optimize jQuery
* Add a hook to enable other types of annotations: user reference, taxonomy...
Author:
-------
Ronan Berder <hunvreus@gmail.com>
http://drupal.org/user/49057
http://teddy.fr

View File

@ -0,0 +1,5 @@
; $Id $
name = Image Annotate
description = Allows users to add notes and references to users on pictures.
dependencies[] = jquery_ui
core = 6.x

View File

@ -0,0 +1,74 @@
<?php
// $Id: image_annotate.install,v 1.3 2009/01/28 19:27:13 hunvreus Exp $
/**
* Implementation of hook_schema().
*/
function image_annotate_schema() {
$schema['image_annotate'] = array(
'fields' => array(
'aid' => array(
'type' => 'serial',
'not null' => TRUE,
),
'cid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'field_name' => array(
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'size_width' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'size_height' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'position_top' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'position_left' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
),
'primary key' => array('aid'),
);
return $schema;
}
/**
* Implementation of hook_install().
*/
function image_annotate_install() {
// Create table
drupal_install_schema('image_annotate');
}
/**
* Implementation of hook_uninstall().
*/
function image_annotate_uninstall() {
// Delete all the pathauto variables and then clear the variable cache
db_query("DELETE FROM {variable} WHERE name LIKE 'image_annotate_%'");
db_query("DROP TABLE {image_annotate}");
cache_clear_all('variables', 'cache');
// TODO : DUMP {place} ?
}

View File

@ -0,0 +1,205 @@
<?php
// $Id: image_annotate.module,v 1.6 2009/03/06 16:46:22 hunvreus Exp $
/**
* Implementation of hook_comment
*/
function image_annotate_comment(&$comment, $op) {
if (user_access('create image annotations') || user_access('administer image annotations')) {
if ($op == 'insert' || $op == 'update') {
if (is_numeric($_POST['image-annotate']) && $_POST['image-annotate']) {
global $user;
$field = preg_replace("/[^a-zA-Z0-9_s]/", "", $_POST['image-annotate-field']);
// TODO: check position.size is inside the picture
$top = (int)$_POST['image-annotate-top'];
$left = (int)$_POST['image-annotate-left'];
$width = (int)$_POST['image-annotate-width'];
$height = (int)$_POST['image-annotate-height'];
if (arg(1) == 'reply') {
db_query('INSERT INTO {image_annotate} (cid, field_name, size_width, size_height, position_top, position_left) VALUES (%d, \'%s\', %d, %d, %d, %d)', $comment['cid'], $field, $width, $height, $top, $left);
}
else if (arg(1) == 'edit' && (user_access('administer image annotations') || (user_access('create image annotations') && $comment['uid'] == $user->uid))) {
db_query('UPDATE {image_annotate} SET size_width = %d, size_height = %d, position_top = %d, position_left = %d WHERE cid = %d', $width, $height, $top, $left, arg(2));
}
}
}
}
}
/**
* Implementation of CCK's hook_field_formatter_info().
*/
function image_annotate_field_formatter_info() {
$formatters = array(
'image_annotate' => array(
'label' => t('Image with annotations'),
'field types' => array('image', 'filefield'),
'suitability callback' => 'image_annotate_handles_file',
'css' => array(drupal_get_path('module','image_annotate') .'/tag.css'),
'description' => t('Display a picture and its annotations.'),
),
);
return $formatters;
}
/**
* Implementation of hook_link().
*/
function image_annotate_link($type, $object, $teaser = FALSE) {
if ($type == 'comment') {
if (user_access('view image annotations') || user_access('create image annotations') || user_access('administer image annotations')) {
$note = db_fetch_object(db_query('SELECT aid, field_name FROM {image_annotate} WHERE cid = %d', $object->cid));
if ($note->aid) {
$links = array(
'image_annotate_link' => array(
'title' => t('View image note'),
'href' => $_GET['q'],
'fragment' => 'image-annotate-add-'. $note->field_name,
'attributes' => array(
'title' => t('go to the picture'),
'class' => 'image-annotate-link',
'rel' => 'image-annotate-'. $note->aid,
),
),
);
return $links;
}
}
}
}
/**
* Implementation of hook_menu()
*/
function image_annotate_menu() {
$items = array();
$items['content/image-annotate/create'] = array(
'title' => 'Save note',
'page callback' => '_image_annotate_note_create',
'access callback' => 'image_annotate_user_access',
'type' => MENU_CALLBACK,
);
$items['content/image-annotate/edit'] = array(
'title' => 'Note edit form',
'page callback' => '_image_annotate_note_edit',
'access callback' => 'image_annotate_user_access',
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implementation of hook_nodeapi().
*/
function image_annotate_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
switch ($op) {
case 'delete':
db_query("DELETE FROM {image_annotate} WHERE nid = %d", $node->nid);
break;
}
}
/**
* Implementation of hook_perm().
*/
function image_annotate_perm() {
return array('administer image annotations', 'create image annotations', 'view image annotations');
}
/**
* Implementation of hook_theme
*/
function image_annotate_theme() {
return array(
'image_annotate_formatter_image_annotate' => array(
'arguments' => array('element' => null),
),
);
}
/**
* Return permissions for editing/creating annotations for the current user.
*/
function image_annotate_user_access() {
return user_access('administer image annotations') || user_access('create image annotations');
}
/**
* Theme function for the image annotate formatter
*/
function theme_image_annotate_formatter_image_annotate($element) {
drupal_add_js('misc/collapse.js');
if (empty($element['#item'])) return '';
$item = $element['#item'];
$field = content_fields($element['#field_name']);
if (empty($item['fid']) && $field['use_default_image']) $item = $field['default_image'];
if (empty($item['filepath'])) $item = array_merge($item, field_file_load($item['fid']));
if (user_access('view image annotations') || user_access('create image annotations') || user_access('administer image annotations')) {
// Retrieve all the annotations for that image field
// We sort by area (height*width) to make sure small annotations are always on the top and avoid having some unhoverable ones
$result = db_query('SELECT i.*, c.uid, c.comment, u.name FROM {image_annotate} i JOIN {comments} c ON i.cid = c.cid JOIN {users} u ON c.uid = u.uid WHERE i.field_name = \'%s\' AND c.nid = %d ORDER BY (i.size_height*i.size_width) ASC', $field['field_name'], $element['#node']->vid);
// Build the array of notes settings
global $user;
$notes = array();
while ($note = db_fetch_object($result)) {
$editable = user_access('administer image annotations') || (user_access('create image annotations') && $note->uid && $note->uid == $user->uid);
$author = theme('username', $note);
$text = '"'. check_plain($note->comment) . '"<span class="author"> '. t('by') .' '. $author . '</span>';
if (user_access('access comments')) $text .= '<span class="actions">» '. l(t('View comment'), $_GET['q'], array('fragment'=>'comment-'. $note->cid)) .'</span>';
$notes[] = array(
'aid' => $note->aid,
'cid' => $note->cid,
'uid' => $note->uid,
'height' => $note->size_height,
'width' => $note->size_width,
'top' => $note->position_top,
'left' => $note->position_left,
'text' => $text,
'editable' => $editable,
);
}
// Build the field settings
$settings = array(array(
'nid' => $element['#node']->nid,
'field' => $field['field_name'],
'notes' => $notes,
'editable' => user_access('administer image annotations') || user_access('create image annotations'),
));
// Load all the JS and CSS magic
drupal_add_js(array('imageAnnotate' => $settings), 'setting');
jquery_ui_add(array('ui.resizable', 'ui.draggable'));
drupal_add_js(drupal_get_path('module', 'image_annotate') .'/tag.js');
drupal_add_css(drupal_get_path('module', 'image_annotate') .'/tag.css');
$class = 'imagefield imagefield-'. $field['field_name'] .' image-annotate-'. $field['field_name'];
return theme('imagefield_image', $item, $item['alt'], $item['title'], array('class' => $class));
}
else {
return theme('imagefield_image', $item, $item['alt'], $item['title']);
}
}
/**
* Display the create form of a comment/note
*/
function _image_annotate_note_create($nid) {
if (user_access('post comments') && user_access('access comments')) {
print drupal_get_form('comment_form', array('nid' => $nid));
}
}
/**
* Display the edit form of a comment/note
*/
function _image_annotate_note_edit($aid) {
$cid = db_result(db_query('SELECT cid FROM {image_annotate} WHERE aid = %d', $aid));
include_once(drupal_get_path('module','comment') .'/comment.pages.inc');
print comment_edit($cid);
}

View File

@ -0,0 +1,115 @@
.image-annotate-canvas {
background-position: left top;
background-repeat: no-repeat;
display: block;
position: relative;
}
.image-annotate-view {
display: none;
position: relative;
}
.image-annotate-area {
border: 1px solid #000000;
position: absolute;
}
.image-annotate-area div {
border: 1px solid #FFFFFF;
display: block;
}
.image-annotate-area-hover div {
border-color: yellow !important;
}
.image-annotate-area-editable {
cursor: pointer;
}
.image-annotate-note {
background: #ffb;
color: #333;
display: none;
max-width: 200px;
padding: 3px 7px;
margin: 5px 0;
position: absolute;
text-align: left;
}
.image-annotate-note .author {
font-style: italic;
font-size: 80%;
}
.image-annotate-note .actions {
display: block;
font-size: 80%;
}
.image-annotate-edit {
display: none;
}
#image-annotate-edit-form {
background: #fff;
border: 1px solid #000000;
padding: 7px;
position: absolute;
width: 200px;
}
#image-annotate-edit-form form {
clear: right;
margin: 0 !important;
padding: 0;
z-index: 999;
}
#image-annotate-edit-form .box {
margin: 0;
}
#image-annotate-edit-form input.form-text,
#image-annotate-edit-form #edit-comment-wrapper textarea {
width: 90%;
}
#image-annotate-edit-form textarea {
height: 50px;
}
#image-annotate-edit-form fieldset {
background: transparent;
}
#image-annotate-edit-form .form-item {
margin: 0 0 5px 0;
}
#image-annotate-edit-form .form-button,
#image-annotate-edit-form .form-submit {
margin: 0;
}
.image-annotate-edit-area {
border: 1px solid black;
display: block;
position: absolute;
margin: 0;
padding: 0;
top: 10px;
left: 10px;
cursor: move;
width: 60px;
height: 60px;
}
.image-annotate-edit-area .ui-resizable-handle {
opacity: 0.8;
}
.image-annotate-edit-close {
float: right;
}

View File

@ -0,0 +1,330 @@
Drupal.behaviors.imageAnnotate = function (context) {
var annotativeImage = new Array();
for (var i=0; i<Drupal.settings.imageAnnotate.length; i++) {
annotativeImage[i] = new Drupal.annotativeImage(Drupal.settings.imageAnnotate[i]);
}
// If the URL contains a fragment starting with image-annotate we define the aid of the note to highlight/show
var url = document.location.toString();
var highlight = 0;
if (url.match('#image-annotate-')) {
highlight = url.split('#image-annotate-')[1];
for (var i=0; i<annotativeImage.length; i++) {
annotativeImage[i].showNote(highlight);
}
}
// We replace the target of the comment links
$('a.image-annotate-link').click(function() {
for (var i=0; i<annotativeImage.length; i++) {
annotativeImage[i].showNote($(this).attr('rel').split('image-annotate-')[1]);
}
return false;
});
};
/**
* An annotative image object
*/
Drupal.annotativeImage = function (image) {
//BVDM 13/09/09: substitute image.field for image.nid
this.image = $('img.image-annotate-nid-' + image.nid);
this.nid = image.nid;
this.field = image.field;
this.mode = 'view';
// Add the canvas (which has the image as a background) and the containers for the notes
this.canvas = $('<div class="image-annotate-canvas"><div class="image-annotate-view"></div><div class="image-annotate-edit"><div class="image-annotate-edit-area"></div></div></div>');
this.canvas.children('.image-annotate-edit').hide();
this.canvas.children('.image-annotate-view').hide();
this.image.after(this.canvas);
// Give the canvas and the container their size and background
this.canvas.height(this.image.height());
this.canvas.width(this.image.width());
this.canvas.css('background-image', 'url("'+ this.image.attr('src') +'")');
this.canvas.children('.image-annotate-view, .image-annotate-edit').height(this.image.height());
this.canvas.children('.image-annotate-view, .image-annotate-edit').width(this.image.width());
// Add the behavior: hide/show the notes when hovering the picture
this.canvas.hover(
function() {
if ($(this).children('.image-annotate-edit').css('display') == 'none') {
$(this).children('.image-annotate-view').show();
}
},
function() {
$(this).children('.image-annotate-view').hide();
}
);
this.canvas.children('.image-annotate-view').hover(
function() {
$(this).show();
},
function() {
$(this).hide();
}
);
// Create the notes
this.notes = new Array();
for (var i=0; i<image.notes.length; i++) {
this.notes[image.notes[i].aid] = new Drupal.imageAnnotation(this, image.notes[i]);
}
// Add the "Add a note" button
if (image.editable) {
this.button = $('<a class="image-annotate-add" id="image-annotate-add-'+ image.field +'">' + Drupal.t('Add a note') + '</a>');
var image = this;
this.button.click(function(){
image.addNote();
});
this.image.before(this.button);
}
else {
this.image.before($('<a class="image-annotate-add" id="image-annotate-add-'+ image.field +'"></a>'));
}
// Hide the original
this.image.hide();
};
/**
* Highlight and show one of the notes
*/
Drupal.annotativeImage.prototype.showNote = function(aid) {
for (key in this.notes) {
if (key == aid) {
var highlight = this.notes[key];
}
this.notes[key].hide();
}
if (highlight) {
this.canvas.children('.image-annotate-view').show();
highlight.show();
$('html, body').animate({scrollTop: highlight.area.offset().top}, 'slow'); // Hack with html & body scrolling so that it works in Safari
}
};
/**
* Add a note
*/
Drupal.annotativeImage.prototype.addNote = function () {
if (this.mode == 'view') {
this.mode = 'edit';
var image = this;
// Create/prepare the editable note elements
var editable = new Drupal.imageAnnotationEditable(this);
// Load the form and set the draggable/resizable area
editable.note.load(Drupal.settings.basePath + 'content/image-annotate/create/' + this.nid, {}, function() {
Drupal.behaviors.collapse(editable.note);
var form = $('#image-annotate-edit-form form');
// TODO: remove these *EVIL* fixes
form.attr('action', Drupal.settings.basePath + 'comment/reply/' + image.nid); /* Evil! */
$('#image-annotate-edit-form input').attr('for', ''); /* Kicking babies evil! */
// Add the image note information to the form action on submission
form.submit(function() {
var areaFields = $('<input type="hidden" value="1" name="image-annotate"/>'+
'<input type="hidden" value="'+ editable.area.height() +'" name="image-annotate-height"/>'+
'<input type="hidden" value="'+ editable.area.width() +'" name="image-annotate-width"/>'+
'<input type="hidden" value="'+ editable.area.position().top +'" name="image-annotate-top"/>'+
'<input type="hidden" value="'+ editable.area.position().left +'" name="image-annotate-left"/>'+
'<input type="hidden" value="'+ editable.image.field +'" name="image-annotate-field"/>');
form.append(areaFields);
});
// We add the cancel/close button
var cancel = $('<a class="image-annotate-edit-close">'+ Drupal.t('Cancel') +'</a>');
cancel.click(function() {
editable.destroy();
image.mode = 'view';
});
editable.note.prepend(cancel);
});
}
};
/**
* An image annotation
*/
Drupal.imageAnnotation = function (image, note) {
this.image = image;
this.aid = note.aid;
this.cid = note.cid;
this.height = note.height;
this.width = note.width;
this.left = note.left;
this.top = note.top;
this.editable = note.editable;
// Add the area
this.area = $('<div class="image-annotate-area'+ (this.editable ? ' image-annotate-area-editable' : '') +'"><div></div></div>');
this.image.canvas.children('.image-annotate-view').prepend(this.area);
// Add the note
this.note = $('<div class="image-annotate-note">'+ note.text +'</div>');
this.note.hide();
this.image.canvas.children('.image-annotate-view').append(this.note);
this.note.children('span.actions').hide();
// Set the position and size of the note
this.set();
// Add the behavior: hide/display the note when hovering the area
var annotation = this;
this.area.hover(
function() {
annotation.show();
},
function() {
annotation.hide();
}
);
this.note.hover(
function(){
annotation.show();
annotation.note.children('span.actions').show('slow');
},
function(){
annotation.hide();
annotation.note.children('span.actions').hide();
}
);
// Edit a note feature
if (this.editable) {
var note = this;
this.area.click(function () {
note.edit();
});
}
};
/**
* Set the position and size of the note
*/
Drupal.imageAnnotation.prototype.set = function() {
this.area.children('div').height((this.height - 2) +'px');
this.area.children('div').width((this.width - 2) +'px');
this.area.css('left', (this.left) +'px');
this.area.css('top', (this.top) +'px');
this.note.css('left', (this.left) +'px');
this.note.css('top', (parseInt(this.top) + parseInt(this.height) + 2) +'px');
};
/**
* Highlight/show the note
*/
Drupal.imageAnnotation.prototype.show = function() {
this.note.show();
this.area.addClass('image-annotate-area-hover');
};
/**
* Hide the note
*/
Drupal.imageAnnotation.prototype.hide = function() {
this.note.hide();
this.area.removeClass('image-annotate-area-hover');
};
/**
* Show the note edit form
*/
Drupal.imageAnnotation.prototype.edit = function() {
if (this.image.mode == 'view') {
this.image.mode = 'edit';
var note = this;
// Create/prepare the editable note elements
var editable = new Drupal.imageAnnotationEditable(this.image, this);
// Load the form and set the draggable/resizable area
editable.note.load(Drupal.settings.basePath + 'content/image-annotate/edit/' + this.aid, {}, function() {
Drupal.behaviors.collapse(editable.note);
var form = $('#image-annotate-edit-form form');
// TODO: remove these *EVIL* fixes
form.attr('action', Drupal.settings.basePath + 'comment/edit/'+ note.cid); /* Evil! */
$('#image-annotate-edit-form input').attr('for', ''); /* Kicking babies evil! */
// Add the image note information to the form action on submission
form.submit(function() {
var areaFields = $('<input type="hidden" value="1" name="image-annotate"/>'+
'<input type="hidden" value="'+ editable.area.height() +'" name="image-annotate-height"/>'+
'<input type="hidden" value="'+ editable.area.width() +'" name="image-annotate-width"/>'+
'<input type="hidden" value="'+ editable.area.position().top +'" name="image-annotate-top"/>'+
'<input type="hidden" value="'+ editable.area.position().left +'" name="image-annotate-left"/>'+
'<input type="hidden" value="'+ editable.image.field +'" name="image-annotate-field"/>');
form.append(areaFields);
// var areaInfo = editable.area.position().top +'/'+ editable.area.position().left +'/'+ editable.area.height() +'/'+ editable.area.width();
// form.attr('action', form.attr('action') +'/image-annotate/'+ areaInfo);
});
// We add the cancel/close button
var cancel = $('<a class="image-annotate-edit-close">'+ Drupal.t('Cancel') +'</a>');
cancel.click(function() {
editable.destroy();
note.image.mode = 'view';
});
editable.note.prepend(cancel);
});
}
};
/**
* The annotation form
*/
Drupal.imageAnnotationEditable = function (image, note) {
this.image = image;
// Set up the area
this.area = this.image.canvas.children('.image-annotate-edit').children('.image-annotate-edit-area');
if (note) {
this.area.css('height', note.height +'px');
this.area.css('width', note.width +'px');
this.area.css('left', note.left +'px');
this.area.css('top', note.top +'px');
}
// Show the edition canvas and hide the view canvas
this.image.canvas.children('.image-annotate-view').hide();
this.image.canvas.children('.image-annotate-edit').show();
// Add the note (which we'll load with the form afterwards)
this.note = $('<div id="image-annotate-edit-form"></div>');
$('body').append(this.note);
this.note.css('left', this.area.offset().left +'px');
this.note.css('top', (parseInt(this.area.offset().top) + parseInt(this.area.height()) + 2) +'px');
// Set the area as a draggable/resizable element contained in the image canvas.
// Would be better to use the containment option for resizable but buggy
var editable = this;
var area = this.area;
var note = this.note;
this.area.resizable({
handles: 'all',
resize: function(e, ui) {
if (parseInt(area.position().top) + parseInt(area.height()) + 2 > parseInt(editable.image.canvas.height())) {
area.height(parseInt(editable.image.canvas.height()) - parseInt(area.position().top) - 2);
}
if (parseInt(area.position().left) + parseInt(area.width()) + 2 > parseInt(editable.image.canvas.width())) {
area.width(parseInt(editable.image.canvas.width()) - parseInt(area.position().left) - 2);
}
if (parseInt(area.position().top) < 0) {
area.height(parseInt(editable.image.canvas.height())).css('top', 0);
}
if (parseInt(area.position().left) < 0) {
area.width(parseInt(editable.image.canvas.width())).css('left', 0);
}
note.css('left', area.offset().left +'px');
note.css('top', (parseInt(area.offset().top) + parseInt(area.height()) + 2) +'px');
},
stop: function(e, ui) {
note.css('left', area.offset().left +'px');
note.css('top', (parseInt(area.offset().top) + parseInt(area.height()) + 2) +'px');
}
})
.draggable({
containment: editable.image.canvas,
drag: function(e, ui) {
note.css('left', area.offset().left +'px');
note.css('top', (parseInt(area.offset().top) + parseInt(area.height()) + 2) +'px');
},
stop: function(e, ui) {
note.css('left', area.offset().left +'px');
note.css('top', (parseInt(area.offset().top) + parseInt(area.height()) + 2) +'px');
}
});
};
/**
* Destroy the annotation form
*/
Drupal.imageAnnotationEditable.prototype.destroy = function () {
this.image.canvas.children('.image-annotate-edit').hide();
this.area.resizable('destroy');
this.area.draggable('destroy');
this.area.css('height', '');
this.area.css('width', '');
this.area.css('left', '');
this.area.css('top', '');
this.note.remove();
};

View File

@ -0,0 +1,25 @@
Index: img_assist.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/img_assist/img_assist.module,v
retrieving revision 1.75.2.31
diff -u -p -r1.75.2.31 img_assist.module
--- img_assist.module 15 Jul 2009 22:58:07 -0000 1.75.2.31
+++ img_assist.module 16 Sep 2009 21:32:43 -0000
@@ -512,7 +512,7 @@ function img_assist_filter($op, $delta =
* Implementation of hook_filter_tips().
*/
function img_assist_filter_tips($delta, $format, $long = FALSE) {
- return t('Images can be added to this post.');
+// return t('Images can be added to this post.');
}
/**
@@ -1304,7 +1304,7 @@ function img_assist_display(&$node, $siz
_img_assist_build_derivatives($node, $size);
}
- return image_display($node, $label);
+ return image_display($node, $label, $attributes);
}
/**

View File

@ -1,7 +1,3 @@
? .svn
? 330233.patch
? 480646.patch
? translations/.svn
Index: invite.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/invite/invite.module,v

View File

@ -1,4 +1,3 @@
? menu.allow.display.of.single.tabs.patch
Index: menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v

View File

@ -1,4 +1,3 @@
? reciprocal-one-way-relationships-not-allowed.patch
Index: user_relationships_api.api.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/user_relationships/user_relationships_api/Attic/user_relationships_api.api.inc,v

View File

@ -26,7 +26,7 @@ a:hover {
body {
background: #fff;
color: #222;
font: 100%/1.4 "Helvetica Neue", Arial, Helvetica, sans-serif;
font: 100%/1.5 Tahoma, Arial, Helvetica, sans-serif;
}
p {
@ -114,6 +114,7 @@ table {
background: #f3f3f3;
border: 1px solid #ddd;
font-size: 0.8em;
line-height: 1.4;
margin: 0% 0 6% 0;
}
@ -126,7 +127,7 @@ table {
width: 660px;
margin: 0;
padding: 12px;
text-align: justify;
text-align: left;
}
/* :BVDM: center charts in text body */
@ -267,6 +268,7 @@ h3.searchresult a:hover {
.node .content p {
margin: 2em 0;
letter-spacing: 1px;
}
.meta {

View File

@ -101,3 +101,180 @@ function flukso_preprocess_page(&$vars) {
// -- tab text sould always be Flukso
$vars['head_title'] = 'Flukso';
}
/**
* Support for image_annotate on image nodes
*
*/
function phptemplate_image_body($node, $size) {
if (user_access('view image annotations') || user_access('create image annotations') || user_access('administer image annotations')) {
// Retrieve all the annotations for that image field
// We sort by area (height*width) to make sure small annotations are always on the top and avoid having some unhoverable ones
$result = db_query('SELECT i.*, c.uid, c.comment, u.name FROM {image_annotate} i INNER JOIN {comments} c ON i.cid = c.cid JOIN {users} u ON c.uid = u.uid WHERE c.nid = %d ORDER BY (i.size_height*i.size_width) ASC', $node->nid);
// Build the array of notes settings
global $user;
$notes = array();
while ($note = db_fetch_object($result)) {
$editable = user_access('administer image annotations') || (user_access('create image annotations') && $note->uid && $note->uid == $user->uid);
$author = theme('username', $note);
$text = check_plain($note->comment); // . '"<span class="author"> '. t('by') .' '. $author . '</span>';
// if (user_access('access comments')) {
// $text .= '<span class="actions"> » '. l(t('View comment'), $_GET['q'], array('fragment'=>'comment-'. $note->cid)) .'</span>';
// }
$notes[] = array(
'aid' => $note->aid,
'cid' => $note->cid,
'uid' => $note->uid,
'height' => $note->size_height,
'width' => $note->size_width,
'top' => $note->position_top,
'left' => $note->position_left,
'text' => $text,
'editable' => $editable,
);
}
// Build the field settings
$settings = array(array(
'nid' => $node->nid,
'field' => 'image',
'notes' => $notes,
'editable' => user_access('administer image annotations') || user_access('create image annotations'),
));
// Load all the JS and CSS magic
drupal_add_js(array('imageAnnotate' => $settings), 'setting');
jquery_ui_add(array('ui.resizable', 'ui.draggable'));
drupal_add_js('misc/collapse.js');
drupal_add_js(drupal_get_path('module', 'image_annotate') .'/tag.js');
drupal_add_css(drupal_get_path('module', 'image_annotate') .'/tag.css');
//BVDM 13/09/09: substitute image-annotate-image for image-annotate-nid-$node->nid to create a unique class per inserted image
$class = 'imagefield imagefield-image image-annotate-nid-' . $node->nid;
return image_display($node, $size, array('class' => $class));
}
}
/**
* Support for image_annotate on img_assist inserted images
*
*/
function phptemplate_img_assist_inline($node, $size, $attributes) {
$caption = '';
if ($attributes['title'] && $attributes['desc']) {
$caption = '<strong>'. $attributes['title'] .': </strong>'. $attributes['desc'];
}
elseif ($attributes['title']) {
$caption = '<strong>'. $attributes['title'] .'</strong>';
}
elseif ($attributes['desc']) {
$caption = $attributes['desc'];
}
// Change the node title because img_assist_display() uses the node title for
// alt and title.
$node->title = strip_tags($caption);
// --------------------------
if (user_access('view image annotations') || user_access('create image annotations') || user_access('administer image annotations')) {
// Retrieve all the annotations for that image field
// We sort by area (height*width) to make sure small annotations are always on the top and avoid having some unhoverable ones
$result = db_query('SELECT i.*, c.uid, c.comment, u.name FROM {image_annotate} i INNER JOIN {comments} c ON i.cid = c.cid JOIN {users} u ON c.uid = u.uid WHERE c.nid = %d ORDER BY (i.size_height*i.size_width) ASC', $node->nid);
// Build the array of notes settings
global $user;
$notes = array();
while ($note = db_fetch_object($result)) {
$editable = user_access('administer image annotations') || (user_access('create image annotations') && $note->uid && $note->uid == $user->uid);
$author = theme('username', $note);
$text = check_plain($note->comment); // . '"<span class="author"> '. t('by') .' '. $author . '</span>';
// if (user_access('access comments')) {
// $text .= '<span class="actions"> » '. l(t('View comment'), $_GET['q'], array('fragment'=>'comment-'. $note->cid)) .'</span>';
// }
$notes[] = array(
'aid' => $note->aid,
'cid' => $note->cid,
'uid' => $note->uid,
'height' => $note->size_height,
'width' => $note->size_width,
'top' => $note->position_top,
'left' => $note->position_left,
'text' => $text,
'editable' => $editable,
);
}
// Build the field settings
$settings = array(array(
'nid' => $node->nid,
'field' => 'image',
'notes' => $notes,
'editable' => user_access('administer image annotations') || user_access('create image annotations'),
));
// Load all the JS and CSS magic
drupal_add_js(array('imageAnnotate' => $settings), 'setting');
jquery_ui_add(array('ui.resizable', 'ui.draggable'));
drupal_add_js('misc/collapse.js');
drupal_add_js(drupal_get_path('module', 'image_annotate') .'/tag.js');
drupal_add_css(drupal_get_path('module', 'image_annotate') .'/tag.css');
//BVDM 13/09/09: substitute image-annotate-image for image-annotate-nid-$node->nid to create a unique class per inserted image
$class = 'imagefield imagefield-image image-annotate-nid-' . $node->nid;
$img_tag = img_assist_display($node, $size, array('class' => $class));
}
else {
$img_tag = img_assist_display($node, $size);
}
// -----------------------
// Always define an alignment class, even if it is 'none'.
$output = '<span class="inline inline-'. $attributes['align'] .'">';
$link = $attributes['link'];
$url = '';
// Backwards compatibility: Also parse link/url in the format link=url,foo.
if (strpos($link, ',') !== FALSE) {
list($link, $url) = explode(',', $link, 2);
}
elseif (isset($attributes['url'])) {
$url = $attributes['url'];
}
if ($link == 'node') {
$output .= l($img_tag, 'node/'. $node->nid, array('html' => TRUE));
}
elseif ($link == 'popup') {
$popup_size = variable_get('img_assist_popup_label', IMAGE_PREVIEW);
$info = image_get_info(file_create_path($node->images[$popup_size]));
$width = $info['width'];
$height = $info['height'];
$popup_url = file_create_url($node->images[variable_get('img_assist_popup_label', IMAGE_PREVIEW)]);
$output .= l($img_tag, $popup_url, array('attributes' => array('onclick' => "launch_popup({$node->nid}, {$width}, {$height}); return false;", 'target' => '_blank'), 'html' =>TRUE));
}
elseif ($link == 'url') {
$output .= l($img_tag, $url, array('html' => TRUE));
}
else {
$output .= $img_tag;
}
if ($caption) {
if ($attributes['align'] != 'center') {
$info = image_get_info(file_create_path($node->images[$size['key']]));
// Reduce the caption width slightly so the variable width of the text
// doesn't ever exceed image width.
$width = $info['width'] - 2;
$output .= '<span class="caption" style="width: '. $width .'px;">'. $caption .'</span>';
}
else {
$output .= '<span class="caption">'. $caption .'</span>';
}
}
$output .= '</span>';
return $output;
}