From 135cb3bf3d8b6b4c0f31fdb736df80c14cc647a7 Mon Sep 17 00:00:00 2001
From: Jesse Weaver <pianohacker@gmail.com>
Date: Mon, 15 Jun 2015 16:57:46 -0400
Subject: [PATCH] Bug 11559 - Supporting changes for Rancor

  * Extends login screen to pass along #hash
  * Adds JSONP support to C4::Service
  * Extends humanmsg to allow per-message classes
  * Adds proper charset to results of svc/bib

Test plan:

  1. C4/Auth.pm and .../intranet/.../auth.tt: verify that login/usage
     works as expected, despite the change to pass on the fragment (...#blah)
     from the URL.
  2. C4/Service.pm and humanmsg.js: verify that editing system
     preferences (the main user of these modules) works correctly despite
     updates.
  3. svc/bib: verify that records can be correctly downloaded with the
     change of character set. This can be done in a Firebug/Chrome Devtools
     console by running `$.get('/cgi-bin/koha/svc/bib/1')` and inspecting the
     results (possibly replacing 1 with a different valid biblionumber).
---
 C4/Auth.pm                                         |  2 +
 C4/Service.pm                                      | 17 ++++++--
 .../intranet-tmpl/lib/jquery/plugins/humanmsg.js   | 51 ++++++++++++----------
 koha-tmpl/intranet-tmpl/prog/en/css/humanmsg.css   | 15 ++++---
 koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt    |  8 ++++
 svc/bib                                            |  2 +-
 6 files changed, 61 insertions(+), 34 deletions(-)

diff --git a/C4/Auth.pm b/C4/Auth.pm
index 0d21575..d9b61c6 100644
--- a/C4/Auth.pm
+++ b/C4/Auth.pm
@@ -359,6 +359,8 @@ sub get_template_and_user {
         $template->param( dateformat => C4::Context->preference('dateformat') );
     }
 
+    $template->param(auth_forwarded_hash => $in->{'query'}->param('auth_forwarded_hash'));
+
     # these template parameters are set the same regardless of $in->{'type'}
 
     # Set the using_https variable for templates
diff --git a/C4/Service.pm b/C4/Service.pm
index 14d0ddd..da1d1ee 100644
--- a/C4/Service.pm
+++ b/C4/Service.pm
@@ -55,6 +55,17 @@ BEGIN {
 
 our ( $query, $cookie );
 
+sub _output {
+    my ( $response, $status ) = @_;
+    binmode STDOUT, ':encoding(UTF-8)';
+
+    if ( $query->param( 'callback' ) ) {
+        output_with_http_headers $query, $cookie, $query->param( 'callback' ) . '(' . $response->output . ');', 'js';
+    } else {
+        output_with_http_headers $query, $cookie, $response->output, 'json', $status;
+    }
+}
+
 =head1 METHODS
 
 =head2 init
@@ -113,7 +124,7 @@ sub return_error {
     $response->param( message => $error ) if ( $error );
     $response->param( type => $type, %flags );
 
-    output_with_http_headers $query, $cookie, $response->output, 'json', '400 Bad Request';
+    _output( $response, '400 Bad Request' );
     exit;
 }
 
@@ -159,7 +170,7 @@ sub return_multi {
         }
 
         $response->param( 'multi' => JSON::true, responses => \@responses_formatted, @flags );
-        output_with_http_headers $query, $cookie, $response->output, 'json', '207 Multi-Status';
+        _output( $response, '207 Multi-Status' );
     }
 
     exit;
@@ -177,7 +188,7 @@ exit with HTTP status 200.
 sub return_success {
     my ( $class, $response ) = @_;
 
-    output_with_http_headers $query, $cookie, $response->output, 'json';
+    _output( $response );
 }
 
 =head2 require_params
diff --git a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/humanmsg.js b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/humanmsg.js
index 4a2d62c..347d345 100644
--- a/koha-tmpl/intranet-tmpl/lib/jquery/plugins/humanmsg.js
+++ b/koha-tmpl/intranet-tmpl/lib/jquery/plugins/humanmsg.js
@@ -21,7 +21,7 @@ var humanMsg = {
 		if (msgOpacity != undefined) humanMsg.msgOpacity = parseFloat(msgOpacity);
 
 		// Inject the message structure
-		jQuery(appendTo).append('<div id="'+humanMsg.msgID+'" class="humanMsg"><div class="round"></div><div id="'+humanMsg.msgID+'-contents"></div><div class="round"></div></div> <div id="'+humanMsg.logID+'"><p class="launcher">'+logName+'</p><ul></ul></div>')
+		jQuery(appendTo).append('<div id="'+humanMsg.msgID+'" class="humanMsg"><div id="'+humanMsg.msgID+'-contents"></div></div> <div id="'+humanMsg.logID+'"><p class="launcher">'+logName+'</p><ul></ul></div>');
 
 		jQuery('#'+humanMsg.logID+' p').click(
 			function() { jQuery(this).siblings('ul').slideToggle() }
@@ -29,44 +29,47 @@ var humanMsg = {
 	},
 
 	displayAlert: function(msg, options) {
-		humanMsg.displayMsg(msg, options, true);
+		humanMsg.displayMsg('<p>' + msg + '</p>', options);
 	},
 
-	displayMsg: function(msg, options, is_alert) {
+    logMsg: function(msg) {
+        jQuery('#'+humanMsg.logID)
+            .show().children('ul').prepend('<li>'+msg+'</li>')	// Prepend message to log
+            .children('li:first').slideDown(200)				// Slide it down
+
+        if ( jQuery('#'+humanMsg.logID+' ul').css('display') == 'none') {
+            jQuery('#'+humanMsg.logID+' p').animate({ bottom: 40 }, 200, 'linear', function() {
+                jQuery(this).animate({ bottom: 0 }, 300, 'swing', function() { jQuery(this).css({ bottom: 0 }) })
+            })
+        }
+    },
+
+	displayMsg: function(msg, options) {
 		if (msg == '')
 			return;
 
-		if (options != undefined) {
-			delay = 'delay' in options ? parseInt(options.delay) * 1000 : 1000
-			life = 'life' in options ? parseInt(options.life) * 1000 : Infinity
-		} else {
-			delay = 1000
-			life = Infinity
-		}
+        options = $.extend({
+            delay: 1000,
+            life: Infinity,
+            log: true,
+            className: '',
+        }, options);
 
+		clearTimeout(humanMsg.t1);
 		clearTimeout(humanMsg.t2);
 
 		// Inject message
-		jQuery('#'+humanMsg.msgID+'-contents').html(is_alert ? ('<p>' + msg + '</p>') : msg)
+		jQuery('#'+humanMsg.msgID+'-contents').html(msg);
 
 		// Show message
-		jQuery('#'+humanMsg.msgID).show().animate({ opacity: humanMsg.msgOpacity}, 200, function() {
-			jQuery('#'+humanMsg.logID)
-				.show().children('ul').prepend('<li>'+msg+'</li>')	// Prepend message to log
-				.children('li:first').slideDown(200)				// Slide it down
-
-			if ( jQuery('#'+humanMsg.logID+' ul').css('display') == 'none') {
-				jQuery('#'+humanMsg.logID+' p').animate({ bottom: 40 }, 200, 'linear', function() {
-					jQuery(this).animate({ bottom: 0 }, 300, 'swing', function() { jQuery(this).css({ bottom: 0 }) })
-				})
-			}
-
+		jQuery('#'+humanMsg.msgID).attr('class', 'humanMsg ' + options.className).show().animate({ opacity: humanMsg.msgOpacity}, 200, function() {
+            humanMsg.logMsg(msg, options);
 		})
 
 		// Watch for mouse & keyboard in `delay`
-		humanMsg.t1 = setTimeout("humanMsg.bindEvents()", delay)
+		humanMsg.t1 = setTimeout("humanMsg.bindEvents()", options.delay)
 		// Remove message after `life`
-		humanMsg.t2 = setTimeout("humanMsg.removeMsg()", life)
+		humanMsg.t2 = setTimeout("humanMsg.removeMsg()", options.life)
 	},
 
 	bindEvents: function() {
diff --git a/koha-tmpl/intranet-tmpl/prog/en/css/humanmsg.css b/koha-tmpl/intranet-tmpl/prog/en/css/humanmsg.css
index 47eb2e6..f9b0071 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/css/humanmsg.css
+++ b/koha-tmpl/intranet-tmpl/prog/en/css/humanmsg.css
@@ -9,6 +9,7 @@ html, body {
 }
 
 .humanMsg {
+    border-radius: 5px;
 	font: normal 20px/50px Helvetica, Arial, Sans-Serif;
 	letter-spacing: -1px;
 	position: fixed;
@@ -23,6 +24,14 @@ html, body {
 	z-index: 100000;
 }
 
+.humanError {
+	background-color: #400;
+}
+
+.humanSuccess {
+	background-color: #040;
+}
+
 .humanMsg h3 {
 	margin: 0.3em;
 	margin-top: 0;
@@ -30,12 +39,6 @@ html, body {
 	font-weight: bold;
 }
 
-.humanMsg .round {
-    border-left: solid 2px white;
-	border-right: solid 2px white;
-    font-size: 1px; height: 2px;
-	}
-
 .humanMsg p {
 	margin: 0.3em;
 	}
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt
index 9ae147e..d6379fe 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt
@@ -103,4 +103,12 @@ please choose against which one you would like to authenticate: </p>
 </div>
 </div>
 
+<script>
+$(document).ready( function() {
+    if ( document.location.hash ) {
+        $( '#loginform' ).append( '<input name="auth_forwarded_hash" type="hidden" value="' + document.location.hash + '"/>' );
+    }
+} );
+</script>
+
 [% INCLUDE 'intranet-bottom.inc' %]
diff --git a/svc/bib b/svc/bib
index 231734e..789951b 100755
--- a/svc/bib
+++ b/svc/bib
@@ -86,7 +86,7 @@ sub update_bib {
 
     my $result = {};
     my $inxml = $query->param('POSTDATA');
-    print $query->header(-type => 'text/xml');
+    print $query->header(-type => 'text/xml', -charset => 'utf-8');
 
     my $record = eval {MARC::Record::new_from_xml( $inxml, "utf8", C4::Context->preference('marcflavour'))};
     my $do_not_escape = 0;
-- 
2.1.4