web: intial commit of taylored image_annotate module for flukso
This commit is contained in:
parent
8b7a1ee2ea
commit
ab82a944fe
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
contributions/modules/image_annotate
|
|
@ -0,0 +1 @@
|
|||
:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib
|
|
@ -0,0 +1 @@
|
|||
NDRUPAL-6--2-0
|
|
@ -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
|
|
@ -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
|
|
@ -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} ?
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
? menu.allow.display.of.single.tabs.patch
|
||||
Index: menu.inc
|
||||
===================================================================
|
||||
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue