package stemmaweb::Controller::Relation;
+use JSON qw/ to_json /;
use Moose;
use Module::Load;
use namespace::autoclean;
my $tradition = delete $c->stash->{'tradition'};
my $collation = $tradition->collation;
+ # Stash the relationship definitions
+ $c->stash->{'relationship_scopes'} = to_json( [ qw/ local global / ] );
+ my @reltypeinfo;
+ foreach my $type ( sort { _typesort( $a, $b ) } $collation->relations->types ) {
+ next if $type->is_weak;
+ my $struct = { name => $type->name, description => $type->description };
+ push( @reltypeinfo, $struct );
+ }
+ $c->stash->{'relationship_types'} = to_json( \@reltypeinfo );
+
# See how big the tradition is. Edges are more important than nodes
# when it comes to rendering difficulty.
my $numnodes = scalar $collation->readings;
$c->stash->{'template'} = 'relate.tt';
}
-=head2 definitions
-
- GET relation/$textid/definitions
-
-Returns a data structure giving the valid types and scopes for a relationship in
-this tradition.
-
-=cut
-
-sub definitions :Chained('text') :PathPart :Args(0) {
- my( $self, $c ) = @_;
- my $tradition = delete $c->stash->{'tradition'};
- my @valid_relationships = map { $_->name } grep { !$_->is_weak }
- $tradition->collation->relations->types;
- my $valid_scopes = [ qw/ local global / ];
- $c->stash->{'result'} = {
- 'types' => \@valid_relationships,
- 'scopes' => $valid_scopes
- };
- $c->forward('View::JSON');
+sub _typesort {
+ my( $a, $b ) = @_;
+ my $blsort = $a->bindlevel <=> $b->bindlevel;
+ return $blsort if $blsort;
+ return $a->name cmp $b->name;
}
=head2 help
if( $c->stash->{'permission'} ne 'full' ) {
$c->response->status( '403' );
$c->stash->{'result'} = {
- 'error' => 'You do not have permission to view this tradition.' };
+ 'error' => 'You do not have permission to modify this tradition.' };
+ $c->detach( 'View::JSON' );
} elsif( $c->request->method eq 'POST' ) {
- unless( $c->stash->{'permission'} eq 'full' ) {
- $c->response->status( '403' );
- $c->stash->{'result'} = {
- 'error' => 'You do not have permission to view this tradition.' };
- $c->detach( 'View::JSON' );
- }
my $node = $c->request->param('source_id');
my $target = $c->request->param('target_id');
my $relation = $c->request->param('rel_type');
}
function add_relations( callback_fn ) {
+ // Add the relationship types to the keymap list
+ // TODO Make the descriptions (in typedef.description) available somewhere
+ $.each( relationship_types, function(index, typedef) {
+ var elid = 'list_rel_' + typedef.name;
+ $('#keymaplist').append( $('<li>').attr( 'id', elid ).css( "border-color", relation_manager.relation_colors[index] ).text(typedef.name) );
+ });
+ // Now fetch the relationships themselves and add them to the graph
+ var rel_types = $.map( relationship_types, function(t) { return t.name });
+ // Save this list of names to the outer element data so that the relationship
+ // factory can access it
+ $('#keymap').data('relations', rel_types);
var textrelpath = getTextURL( 'relationships' );
- var typedefpath = getTextURL( 'definitions' );
- $.getJSON( typedefpath, function(data) {
- var rel_types = data.types.sort();
- // Add the relationship types to our document data so that we don't have
- // to call again
- $('#keymap').data( 'relations', rel_types );
- $.getJSON( textrelpath,
- function(data) {
- $.each(data, function( index, rel_info ) {
- var type_index = $.inArray(rel_info.type, rel_types);
- var source_found = get_ellipse( rel_info.source );
- var target_found = get_ellipse( rel_info.target );
- if( type_index != -1 && source_found.size() && target_found.size() ) {
- var relation = relation_manager.create( rel_info.source, rel_info.target, type_index );
- relation.data( 'type', rel_info.type );
- relation.data( 'scope', rel_info.scope );
- relation.data( 'note', rel_info.note );
- var node_obj = get_node_obj(rel_info.source);
- node_obj.set_draggable( false );
- node_obj.ellipse.data( 'node_obj', null );
- node_obj = get_node_obj(rel_info.target);
- node_obj.set_draggable( false );
- node_obj.ellipse.data( 'node_obj', null );
- }
- });
- callback_fn.call();
- });
- });
+ $.getJSON( textrelpath, function(data) {
+ $.each(data, function( index, rel_info ) {
+ var type_index = $.inArray(rel_info.type, rel_types);
+ var source_found = get_ellipse( rel_info.source );
+ var target_found = get_ellipse( rel_info.target );
+ if( type_index != -1 && source_found.size() && target_found.size() ) {
+ var relation = relation_manager.create( rel_info.source, rel_info.target, type_index );
+ relation.data( 'type', rel_info.type );
+ relation.data( 'scope', rel_info.scope );
+ relation.data( 'note', rel_info.note );
+ var node_obj = get_node_obj(rel_info.source);
+ node_obj.set_draggable( false );
+ node_obj.ellipse.data( 'node_obj', null );
+ node_obj = get_node_obj(rel_info.target);
+ node_obj.set_draggable( false );
+ node_obj.ellipse.data( 'node_obj', null );
+ }
+ });
+ callback_fn.call();
+ });
}
function get_ellipse( node_id ) {
},
create: function(event, ui) {
$(this).data( 'relation_drawn', false );
- //TODO Check whether we have already retrieved the definitions
- var typedefpath = getTextURL( 'definitions' );
- var jqjson = $.getJSON( typedefpath, function(data) {
- var types = data.types.sort();
- $.each( types, function(index, value) {
- $('#rel_type').append( $('<option />').attr( "value", value ).text(value) );
- $('#keymaplist').append( $('<li>').css( "border-color", relation_manager.relation_colors[index] ).text(value) );
- });
- var scopes = data.scopes;
- $.each( scopes, function(index, value) {
- $('#scope').append( $('<option />').attr( "value", value ).text(value) );
- });
+ $.each( relationship_types, function(index, typedef) {
+ $('#rel_type').append( $('<option />').attr( "value", typedef.name ).text(typedef.name) );
+ });
+ $.each( relationship_scopes, function(index, value) {
+ $('#scope').append( $('<option />').attr( "value", value ).text(value) );
});
},
open: function() {
}
function add_relations( callback_fn ) {
+ // Add the relationship types to the keymap list
+ $.each( relationship_types, function(index, typedef) {
+ var elid = 'list_rel_' + typedef.name;
+ $('#keymaplist').append( $('<li>').attr( 'id', elid ).css( "border-color", relation_manager.relation_colors[index] ).text(typedef.name) );
+ });
+ // Now fetch the relationships themselves and add them to the graph
+ var rel_types = $.map( relationship_types, function(t) { return t.name });
var textrelpath = getTextURL( 'relationships' );
- var typedefpath = getTextURL( 'definitions' );
- $.getJSON( typedefpath, function(data) {
- var rel_types = data.types.sort();
- $.each( rel_types, function(index, value) {
- $('#keymaplist').append( $('<li>').css( "border-color", relation_manager.relation_colors[index] ).text(value) );
+ $.getJSON( textrelpath, function(data) {
+ $.each(data, function( index, rel_info ) {
+ var type_index = $.inArray(rel_info.type, rel_types);
+ var source_found = get_ellipse( rel_info.source );
+ var target_found = get_ellipse( rel_info.target );
+ if( type_index != -1 && source_found.size() && target_found.size() ) {
+ var relation = relation_manager.create( rel_info.source, rel_info.target, type_index );
+ relation.data( 'type', rel_info.type );
+ relation.data( 'scope', rel_info.scope );
+ relation.data( 'note', rel_info.note );
+ var node_obj = get_node_obj(rel_info.source);
+ node_obj.set_draggable( false );
+ node_obj.ellipse.data( 'node_obj', null );
+ node_obj = get_node_obj(rel_info.target);
+ node_obj.set_draggable( false );
+ node_obj.ellipse.data( 'node_obj', null );
+ }
});
- $.getJSON( textrelpath, function(data) {
- $.each(data, function( index, rel_info ) {
- var type_index = $.inArray(rel_info.type, rel_types);
- var source_found = get_ellipse( rel_info.source );
- var target_found = get_ellipse( rel_info.target );
- if( type_index != -1 && source_found.size() && target_found.size() ) {
- var relation = relation_manager.create( rel_info.source, rel_info.target, type_index );
- relation.data( 'type', rel_info.type );
- relation.data( 'scope', rel_info.scope );
- relation.data( 'note', rel_info.note );
- var node_obj = get_node_obj(rel_info.source);
- node_obj.ellipse.data( 'node_obj', null );
- node_obj = get_node_obj(rel_info.target);
- node_obj.ellipse.data( 'node_obj', null );
- }
- });
- callback_fn.call();
- });
- });
+ callback_fn.call();
+ });
}
function get_ellipse( node_id ) {
var basepath = "[% c.uri_for( '/relation/' ) %]";
var textid = "[% textid %]";
var can_morphologize = "[% can_morphologize %]";
+[% IF error -%]
+var relationship_types = [];
+var relationship_scopes = [];
+[% ELSE -%]
+var relationship_types = [% relationship_types %];
+var relationship_scopes = [% relationship_scopes %];
+[% END -%]
$(document).ready(function () {
loadSVG('[% svg_string %]');
die "Failed to create test tradition #2" unless $t2;
$t2->public( 1 );
$dir->store( $t2 );
-say "Created test public tradition";
+my $t3 = Text::Tradition->new( input => 'Self', file => 't/data/john.xml' );
+$t3->public( 1 );
+$t3->name( 'John verse' );
+$dir->store( $t3 );
+say "Created test public traditions";