diff --git a/drupal_annotation/annotation.module b/drupal_annotation/annotation.module
index bab491f..7674f5b 100644
--- a/drupal_annotation/annotation.module
+++ b/drupal_annotation/annotation.module
@@ -281,6 +281,21 @@ function annotation_menu() {
'file' => 'annotation.store.inc',
);
+ $items['annotation/api/tags'] = array(
+ 'page callback' => 'annotation_api_tags',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_CALLBACK,
+ 'file' => 'annotation.store.inc',
+ );
+
+ $items['annotation/api/quotation_list'] = array(
+ 'page callback' => 'annotation_api_quotation_list',
+ 'access arguments' => array('access content'),
+ 'type' => MENU_CALLBACK,
+ 'file' => 'annotation.store.inc',
+ );
+
+
return $items;
}
@@ -1026,7 +1041,6 @@ function annotation_export_rqda($uid, $filename) {
* @return String containing HTML that renders the annotated text in its context.
*/
function annotation_extract($annotation, $len_before, $len_after){
-
// Get the HTML source text of the annotated field.
$entity = entity_load_single($annotation->entity_type, $annotation->entity_id);
$field_items = field_get_items($annotation->entity_type, $entity, $annotation->field_name, $annotation->field_language);
diff --git a/drupal_annotation/annotation.store.inc b/drupal_annotation/annotation.store.inc
index e533c68..25fd822 100644
--- a/drupal_annotation/annotation.store.inc
+++ b/drupal_annotation/annotation.store.inc
@@ -37,16 +37,43 @@ function annotation_api_endpoint($id = NULL) {
}
/**
- * Annotation API root
+ * API for tags, to populate the sidebar
*/
-function annotation_api() {
- drupal_json_output(
- array(
- 'name' => 'Annotator Store API',
- 'version' => ANNOTATOR_VERSION,
- )
- );
+function visible_tags($nid){
+ $vocabulary = taxonomy_vocabulary_machine_name_load('openethnographer');
+ $tree = taxonomy_get_tree($vocabulary->vid);
+ // XXX this needs to handle public/private tags
+ if(!user_access('view any annotations') ) {
+ $tree = array_filter($tree, function($k){
+ return $k->uid != $USER->uid;});
+ }
+ //$parents = array_filter($tree, function($k){
+ return $tree;
+}
+
+
+function annotation_api_quotation_list(){
+ $tid = $_GET['tid'];
+ $term = taxonomy_term_load($tid);
+ print("
Content tagged $term->name
");# " + $term->name + "");
+ print(annotation_quotation_list($term));
+}
+
+
+
+function annotation_api_tags(){
+ //XXX filter tags to those present on a page
+ // -- complication is that we also need all their ancestors
+ if(!empty($_GET['nid'])){
+ $nid = $_GET['nid'];
+ }
+
+ $vocabulary = taxonomy_vocabulary_machine_name_load('openethnographer');
+ $tree = taxonomy_get_tree($vocabulary->vid);
+ watchdog('oeth', 'I am a teapot');
+ return drupal_json_output(visible_tags());
}
+
/**
* Annotation API index
diff --git a/drupal_annotator/annotator.module b/drupal_annotator/annotator.module
index ca8798b..f543793 100644
--- a/drupal_annotator/annotator.module
+++ b/drupal_annotator/annotator.module
@@ -243,15 +243,20 @@ class OpenethnographerTaxonomy extends TaxonomyDisplayTermDisplayHandler {
public function displayTerm($term, $options = NULL) {
$build = array();
$build['term'] = array(
- '#markup' => $this->quotation_list($term),
+ '#markup' => annotation_quotation_list($term),
'#weight' => 0,
);
return $build;
}
- function annotations_by_node($nid, $termdivs, $term){
+
+ public function formFieldset(&$form, &$values, $options = NULL) {}
+ public function formSubmit($form, &$values) {}
+}
+
+
+function annotation_annotations_by_node($nid, $termdivs, $term){
$nd = node_load($nid);
- $short_title = 'fubar';
$divs = implode('', $termdivs);
$header = '';
$inner = '';
@@ -259,22 +264,18 @@ class OpenethnographerTaxonomy extends TaxonomyDisplayTermDisplayHandler {
return $wrapped;
}
- function quotation_list($term){
+function annotation_quotation_list($term){
$annots_by_nid = array();
$ans = db_query("SELECT * from {annotation} where tid = :tid", array(':tid' => $term->tid));
if($ans){
while($row = $ans->fetchAssoc()){
- $ent = current(entity_load('annotation', array($row['id'])));
- $annots_by_nid[$ent->nid][] = annotation_extract($ent, 35, 25);
+ $annot = current(entity_load('annotation', array($row['id'])));
+ $annots_by_nid[$annot->entity_id][] = annotation_extract($annot, 35, 25);
}
}
$nodedivs = array();
foreach($annots_by_nid as $k=>$v){
- $nodedivs[] = $this->annotations_by_node($k, $v, $term);
+ $nodedivs[] = annotation_annotations_by_node($k, $v, $term);
}
return implode(", ", $nodedivs);
}
-
- public function formFieldset(&$form, &$values, $options = NULL) {}
- public function formSubmit($form, &$values) {}
-}
diff --git a/drupal_annotator/annotator_view/view_annotator.js b/drupal_annotator/annotator_view/view_annotator.js
index a4d7cae..e4f9644 100644
--- a/drupal_annotator/annotator_view/view_annotator.js
+++ b/drupal_annotator/annotator_view/view_annotator.js
@@ -36,18 +36,6 @@ $ = jQuery;
Annotator.Plugin.AnnotatorViewer = (function(_super) {
__extends(AnnotatorViewer, _super);
- AnnotatorViewer.prototype.events = {
- 'annotationsLoaded': 'onAnnotationsLoaded',
- 'annotationCreated': 'onAnnotationCreated',
- 'annotationDeleted': 'onAnnotationDeleted',
- 'annotationUpdated': 'onAnnotationUpdated',
- ".annotator-viewer-delete click": "onDeleteClick",
- ".annotator-viewer-edit click": "onEditClick",
- ".annotator-viewer-delete mouseover": "onDeleteMouseover",
- ".annotator-viewer-delete mouseout": "onDeleteMouseout",
- };
-
-
AnnotatorViewer.prototype.field = null;
AnnotatorViewer.prototype.input = null;
@@ -60,13 +48,35 @@ $ = jQuery;
function AnnotatorViewer(element, options) {
if($('.annotations-list-uoc').length == 0){
$( "body" ).append( this.createAnnotationPanel() );
+ $('#annotator-tabs').tabs();
+
$(".container-anotacions").toggle();
$("#annotations-panel").click(function(event) {
$(".container-anotacions").toggle("slide");
});
- }
+ // set selected nodes according to the radio buttons
+ $('input[type=radio][name=showtags]').on('change', function(){
+ selectors = {
+ 'mine': '.annotator-taglist-mytag',
+ 'all': '.annotator-taglist-mytag,.annotator-taglist-notmytag'}
+ cls = selectors[$(this).val()];
+ $tree = jQuery('.annotator-taglist');
+ state = $tree.tree('getState');
+ state['selected_node'] = jQuery(cls).map(
+ function(){
+ return jQuery(this).data('id')
+ });
+ // deselect all nodes
+ while($tree.tree('getSelectedNode')){
+ $tree.tree('selectNode', null);
+ }
+ $tree.tree('setState', state);
+
+ // change which tags are highlighted
+ AnnotatorViewer.prototype.showSelectedTags();
+ });
};
AnnotatorViewer.prototype.pluginInit = function() {
@@ -76,94 +86,148 @@ $ = jQuery;
$('#type_share').click(this.onFilter);
$('#type_own').click(this.onFilter);
-
- };
-
- /*
- Check the checkboxes filter to search the annotations to show.
- Shared annotations have the class shared
- My annotations have the me class
- */
- AnnotatorViewer.prototype.onFilter = function(event) {
- };
-
- AnnotatorViewer.prototype.onDeleteClick = function(event) {
- };
-
- AnnotatorViewer.prototype.onEditClick = function(event) {
- };
-
- AnnotatorViewer.prototype.onButtonClick = function(event, type) {
- };
-
- //Textarea editor controller
- AnnotatorViewer.prototype.textareaEditor = function(annotator_textArea,item) {
- };
-
- AnnotatorViewer.prototype.tinymceActivation = function(selector) {
- }
-
- //Event triggered when save the content of the annotation
- AnnotatorViewer.prototype.onSavePanel = function(event) {
- var current_annotation = event.data.annotation;
- var textarea = $('li#annotation-'+current_annotation.id).find('textarea.panelTextArea');
- current_annotation.text = textarea.val();
- this.annotator.updateAnnotation(current_annotation);
- this.normalEditor(current_annotation,textarea);
+ this.annotator.subscribe(
+ 'annotationViewerShown',
+ this.onAnnotationViewerShown);
};
- //Event triggered when save the content of the annotation
- AnnotatorViewer.prototype.onCancelPanel = function(event) {
- var current_annotation = event.data.annotation;
- var textarea = $('li#annotation-'+current_annotation.id).find('textarea.panelTextArea');
- this.normalEditor(current_annotation,textarea);
-
- };
-
- //Annotator in a non editable state
- AnnotatorViewer.prototype.normalEditor = function(annotation,editableTextArea) {
- };
-
- AnnotatorViewer.prototype.onDeleteMouseover = function(event) {
- };
-
- AnnotatorViewer.prototype.onDeleteMouseout = function(event) {
- };
-
- AnnotatorViewer.prototype.onAnnotationCreated = function(annotation) {
- };
+ AnnotatorViewer.prototype.onAnnotationViewerShown = function(event){
+ $('.annotator-tag a').click(function(){
+ tid = jQuery(this).attr('href').split('/').pop();
+ AnnotatorViewer.prototype.displayTag(tid);
+ return false;
+ });
+ }
+ }
- AnnotatorViewer.prototype.onAnnotationUpdated = function(annotation) {
- };
- AnnotatorViewer.prototype.onAnnotationsLoaded = function(annotations) {
- };
-
- AnnotatorViewer.prototype.onAnnotationDeleted = function(annotation) {
- };
-
- AnnotatorViewer.prototype.mascaraAnnotation = function(annotation) {
- return '';
- };
AnnotatorViewer.prototype.createAnnotationPanel = function(annotation) {
- var sidebar_label = 'OPEN SIDEBAR';
- var panel_content = 'YOUR CONTENT HERE';
- var annotation_layer = '';
+ var sidebar_label = 'Open Ethnographer';
+ var radios = 'Show my tags Show all tags'
+ var panel_content = 'Open Ethnographer
Click a tag name to see where it has been used
';
+ var annotation_layer = '';
+ // nodeid is ignored on the backend for now,
+ // but we may want to filter nodes present on the current node
+ nodeid = window.location.pathname.split('/').pop()
+ jQuery.get('/annotation/api/tags?node=' + nodeid, this.onTagJSON);
return annotation_layer;
};
-
- AnnotatorViewer.prototype.createReferenceAnnotation = function(annotation) {
- };
-
- AnnotatorViewer.prototype.uniqId = function() {
- return Math.round(new Date().getTime() + (Math.random() * 100));
- }
+ AnnotatorViewer.prototype.showSelectedTags = function(){
+ tids = $('.annotator-taglist').tree('getState')['selected_node'];
+ //disable all tags
+ jQuery('.annotator-hl').addClass('annotator-hl-disabled').removeClass('annotator-hl');
+
+ //then re-enable tags with the right ids
+ for(i in tids){
+ selector = '[data-tid=' + tids[i] + ']';
+ jQuery(selector).addClass('annotator-hl');
+ }
+ }
+
+ AnnotatorViewer.prototype.displayTag = function(tid){
+ jQuery('.annotator-termdetail').load('/annotation/api/quotation_list?tid=' + tid);
+ jQuery('#annotator-tabs').tabs({active: 1});
+ jQuery(".container-anotacions").slideDown();
+ }
+
+ AnnotatorViewer.prototype.onTagJSON = function(data){
+ var html = '';
+ for(var i in data){
+ var tag = data[i];
+ var classes = ['annotator-tag'];
+ if( tag.uid == Drupal.settings.annotator_permissions.user.uid){
+ classes.push('annotator-tag-mine');
+ }
+ else {
+ classes.push('annotator-tag-others');
+ }
+ }
+ //jQuery('.annotator-taglist').html(html);
+
+ // make some tweaks to the tag data while it's still conveniently flat
+ jQuery(data).each(function(i,v){
+ // tid -> id (for benefit of jqtree)
+ v['id'] = v['tid'];
+ // don't let long tag names mess up the layout
+ v['label'] = v['name'].substr(0,25);
+ // separate tags whether this user created them
+ v['is_mine'] = v['uid'] == Drupal.settings.annotator_permissions.user.uid;
+ });
+
+ // recursively find a term, so we can give it children
+ findNode = function(node, nid){
+ if(node['tid'] == nid)
+ return node;
+ if(!node.hasOwnProperty('children')) return null;
+ for(cid in node['children']){
+ found = findNode(node['children'][cid]);
+ if(found)
+ return found;
+ }
+ return null;
+ }
+
+ // turn the taxonomy into a real tree
+ for(var k = data.length-1; k >= 0; k--){
+ leaf = data[k];
+ parentid = leaf['parents'][0]; // ignore multiple inheritance
+ if(parentid == "0") // skip roots without parents
+ continue;
+ // look for a node with the right id
+ for(var n in data){
+ parent = findNode(data[n], parentid);
+ // add this node as a child
+ if(parent){
+ if(!parent.hasOwnProperty('children')){
+ parent['children'] = [];}
+ parent['children'].push(leaf);
+ data.splice(k, 1);
+ }
+ }
+ }
+ $tree = jQuery('.annotator-taglist')
+ $tree.tree(
+ {data: data,
+ autoOpen: true,
+ keyboardSupport: false,
+ dragAndDrop: false,
+ onCreateLi: function(node, li){
+ li.attr('data-id', node.id);
+ li.addClass('annotator-taglist-tag');
+ if(node['is_mine'])
+ li.addClass('annotator-taglist-mytag');
+ else
+ li.addClass('annotator-taglist-notmytag');
+ }
+ });
+ $tree.bind(
+ 'tree.click',
+ function(e) {
+ // Disable single selection
+ e.preventDefault();
+ AnnotatorViewer.prototype.displayTag(e.node.id);
+ return;
+ var selected_node = e.node;
+ if (selected_node.id == undefined) {
+ console.log('The multiple selection functions require that nodes have an id');
+ }
+ if ($tree.tree('isNodeSelected', selected_node)) {
+ $tree.tree('removeFromSelection', selected_node);
+ }
+ else {
+ $tree.tree('addToSelection', selected_node);
+ }
+ AnnotatorViewer.prototype.showSelectedTags();
+ }
+ );
+ // use the radio button to select all
+ jQuery('input[value=all]').click();
+ }
-
return AnnotatorViewer;
})(Annotator.Plugin);
diff --git a/drupal_annotator/css/openethnographer.css b/drupal_annotator/css/openethnographer.css
index 1989d0c..eae29e5 100644
--- a/drupal_annotator/css/openethnographer.css
+++ b/drupal_annotator/css/openethnographer.css
@@ -79,3 +79,32 @@
}
+.annotator-taglist-tag {}
+
+.annotator-taglist-mytag {}
+
+.annotator-taglist-notmytag {}
+
+/* stop jquery-ui changing our background color */
+
+.ui-widget-content {
+ background: #ddd;
+ border: 0px;
+ }
+
+/* tidy up the sidebar */
+
+#anotacions-uoc-panel {
+ overflow-x: hidden;
+ overflow-y: default;
+ }
+
+.jqtree-element {
+ font-weight: lighter;
+ }
+
+
+ul.jqtree-tree li.jqtree-selected > .jqtree-element,
+ul.jqtree-tree li.jqtree-selected > .jqtree-element:hover {
+ font-weight: bold;
+ }
\ No newline at end of file
diff --git a/drupal_annotator/jqtree/jqtree.css b/drupal_annotator/jqtree/jqtree.css
index aa52c00..24a0410 100644
--- a/drupal_annotator/jqtree/jqtree.css
+++ b/drupal_annotator/jqtree/jqtree.css
@@ -130,14 +130,16 @@ ul.jqtree-tree .jqtree-element {
ul.jqtree-tree li.jqtree-selected > .jqtree-element,
ul.jqtree-tree li.jqtree-selected > .jqtree-element:hover {
+ /*
background-color: #97BDD6;
background: -webkit-gradient(linear, left top, left bottom, from(#BEE0F5), to(#89AFCA));
background: -moz-linear-gradient(top, #BEE0F5, #89AFCA);
background: -ms-linear-gradient(top, #BEE0F5, #89AFCA);
background: -o-linear-gradient(top, #BEE0F5, #89AFCA);
- text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);*/
}
+
ul.jqtree-tree .jqtree-moving > .jqtree-element .jqtree-title {
outline: dashed 1px #0000ff;
}
diff --git a/drupal_annotator/jqtree/tree.jquery.js b/drupal_annotator/jqtree/tree.jquery.js
index 9de0d0c..942fa8c 100644
--- a/drupal_annotator/jqtree/tree.jquery.js
+++ b/drupal_annotator/jqtree/tree.jquery.js
@@ -3385,4 +3385,4 @@ limitations under the License.
}).call(this);
-},{}]},{},[3])
\ No newline at end of file
+},{}]},{},[3])
diff --git a/drupal_annotator/js/annotator_drupalnode.js b/drupal_annotator/js/annotator_drupalnode.js
index 0bcc4c1..7af860b 100644
--- a/drupal_annotator/js/annotator_drupalnode.js
+++ b/drupal_annotator/js/annotator_drupalnode.js
@@ -43,6 +43,9 @@ Annotator.Plugin.DrupalNode = (function(_super) {
'annotationsLoaded',
function(annotations) {
jQuery('.annotator-hl').each(function() {
+ tid = jQuery(this).data('annotation')['tid'];
+ jQuery(this).attr('data-tid', tid);
+
if (jQuery(this).data('annotation').user.uid == Drupal.settings.annotator_permissions.user.uid) {
jQuery(this).addClass('annotator-own-annotation');
}
diff --git a/drupal_annotator/plugins/annotator/SidebarAnnotatorPlugin.class.inc b/drupal_annotator/plugins/annotator/SidebarAnnotatorPlugin.class.inc
index fe113e7..fc137d4 100644
--- a/drupal_annotator/plugins/annotator/SidebarAnnotatorPlugin.class.inc
+++ b/drupal_annotator/plugins/annotator/SidebarAnnotatorPlugin.class.inc
@@ -5,7 +5,7 @@
*/
class SidebarAnnotatorPlugin extends AnnotatorPlugin {
public function setup() {
- watchdog('oeth', 'annotator setup');
+ drupal_add_library('system', 'ui.tabs');
drupal_add_js(drupal_get_path('module', 'annotator') . '/annotator_view/view_annotator.js');
drupal_add_js(drupal_get_path('module', 'annotator') . '/annotator_view/categories.js');
drupal_add_js(drupal_get_path('module', 'annotator') . '/annotator_view/lib/jquery-i18n-master/jquery.i18n.js');
@@ -16,5 +16,9 @@ class SidebarAnnotatorPlugin extends AnnotatorPlugin {
drupal_add_css(
drupal_get_path('module', 'annotator') . '/annotator_view/css/style.css',
array('type' => 'file', 'basename' => 'annotator_view_style.css'));
+
+ //for tree view of tags
+ drupal_add_js(drupal_get_path('module', 'annotator') . '/jqtree/tree.jquery.js');
+ drupal_add_css(drupal_get_path('module', 'annotator') . '/jqtree/jqtree.css');
}
}