View | Details | Raw Unified | Return to bug 11559
Collapse All | Expand All

(-)a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/marc-mode.js (-1 / +1 lines)
Lines 137-143 CodeMirror.defineMode( 'marc', function( config, modeConfig ) { Link Here
137
137
138
                if ( stream.eat( /[$|ǂ‡]/ ) ) {
138
                if ( stream.eat( /[$|ǂ‡]/ ) ) {
139
                    var subfieldCode;
139
                    var subfieldCode;
140
                    if ( ( subfieldCode = stream.eat( /[a-z0-9%]/ ) ) && stream.eat( ' ' ) ) {
140
                    if ( ( subfieldCode = stream.eat( /[a-zA-Z0-9%]/ ) ) && stream.eat( ' ' ) ) {
141
                        state.subfieldCode = subfieldCode;
141
                        state.subfieldCode = subfieldCode;
142
                        if ( state.seenSubfields[state.subfieldCode] && ( modeConfig.nonRepeatableSubfields[state.tagNumber] || {} )[state.subfieldCode] ) {
142
                        if ( state.seenSubfields[state.subfieldCode] && ( modeConfig.nonRepeatableSubfields[state.tagNumber] || {} )[state.subfieldCode] ) {
143
                            return 'bad-subfieldcode';
143
                            return 'bad-subfieldcode';
(-)a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/marc-record.js (-4 / +17 lines)
Lines 23-28 Link Here
23
 *
23
 *
24
 * ISO2709 import/export is cribbed from marcjs, which is under the MIT license.
24
 * ISO2709 import/export is cribbed from marcjs, which is under the MIT license.
25
 * Source: https://github.com/fredericd/marcjs/blob/master/lib/marcjs.js
25
 * Source: https://github.com/fredericd/marcjs/blob/master/lib/marcjs.js
26
 *
27
 * UTF8 encode/decode cribbed from: http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html
26
 */
28
 */
27
29
28
define( function() {
30
define( function() {
Lines 46-51 define( function() { Link Here
46
        return i;
48
        return i;
47
    }
49
    }
48
50
51
    function _encode_utf8(s) {
52
        return unescape(encodeURIComponent(s));
53
    }
54
55
    function _decode_utf8(s) {
56
        return decodeURIComponent(escape(s));
57
    }
58
49
    MARC.Record = function (fieldlist) {
59
    MARC.Record = function (fieldlist) {
50
        this._fieldlist = fieldlist || [];
60
        this._fieldlist = fieldlist || [];
51
    }
61
    }
Lines 200-206 define( function() { Link Here
200
                } else {
210
                } else {
201
                    chunk = element.indicators().join('');
211
                    chunk = element.indicators().join('');
202
                    $.each( element.subfields(), function( undef, subfield ) {
212
                    $.each( element.subfields(), function( undef, subfield ) {
203
                        chunk += DE + subfield[0] + subfield[1];
213
                        chunk += DE + subfield[0] + _encode_utf8(subfield[1]);
204
                    } );
214
                    } );
205
                }
215
                }
206
                chunk += FT;
216
                chunk += FT;
Lines 218-227 define( function() { Link Here
218
                leader.substr(17);
228
                leader.substr(17);
219
            chunks[0] = leader;
229
            chunks[0] = leader;
220
            chunks[1] = directory;
230
            chunks[1] = directory;
221
            return chunks.join('');
231
            return _decode_utf8( chunks.join('') );
222
        },
232
        },
223
233
224
        loadISO2709: function(data) {
234
        loadISO2709: function(data) {
235
            // The underlying offsets work on bytes, not characters
236
            data = _encode_utf8(data);
237
225
            this._fieldlist.length = 0;
238
            this._fieldlist.length = 0;
226
            this.leader(data.substr(0, 24));
239
            this.leader(data.substr(0, 24));
227
            var directory_len = parseInt(data.substring(12, 17), 0) - 25,
240
            var directory_len = parseInt(data.substring(12, 17), 0) - 25,
Lines 235-247 define( function() { Link Here
235
                if ( parseInt(tag) < 10 ) {
248
                if ( parseInt(tag) < 10 ) {
236
                    this.addField( new MARC.Field( tag, '', '', [ [ '@', value ] ] ) );
249
                    this.addField( new MARC.Field( tag, '', '', [ [ '@', value ] ] ) );
237
                } else {
250
                } else {
238
                    if ( value.indexOf('\x1F') ) { // There are some letters
251
                    if ( value.indexOf('\x1F') ) { // There are some subfields
239
                        var ind1 = value.substr(0, 1), ind2 = value.substr(1, 1);
252
                        var ind1 = value.substr(0, 1), ind2 = value.substr(1, 1);
240
                        var subfields = [];
253
                        var subfields = [];
241
254
242
                        $.each( value.substr(3).split('\x1f'), function( undef, v ) {
255
                        $.each( value.substr(3).split('\x1f'), function( undef, v ) {
243
                            if (v.length < 2) return;
256
                            if (v.length < 2) return;
244
                            subfields.push([v.substr(0, 1), v.substr(1)]);
257
                            subfields.push([v.substr(0, 1), _decode_utf8( v.substr(1) )]);
245
                        } );
258
                        } );
246
259
247
                        this.addField( new MARC.Field( tag, ind1, ind2, subfields ) );
260
                        this.addField( new MARC.Field( tag, ind1, ind2, subfields ) );
(-)a/koha-tmpl/intranet-tmpl/lib/koha/cateditor/text-marc.js (-1 / +6 lines)
Lines 80-86 define( [ 'marc-record' ], function( MARC ) { Link Here
80
80
81
                    var field = new MARC.Field( tagNumber, ( indicators[1] == '_' ? ' ' : indicators[1] ), ( indicators[2] == '_' ? ' ' : indicators[2] ), [] );
81
                    var field = new MARC.Field( tagNumber, ( indicators[1] == '_' ? ' ' : indicators[1] ), ( indicators[2] == '_' ? ' ' : indicators[2] ), [] );
82
82
83
                    var matcher = /[$|ǂ‡]([a-z0-9%]) /g;
83
                    var matcher = /[$|ǂ‡]([a-zA-Z0-9%]) /g;
84
                    var match;
84
                    var match;
85
85
86
                    var subfields = [];
86
                    var subfields = [];
Lines 89-94 define( [ 'marc-record' ], function( MARC ) { Link Here
89
                        subfields.push( { code: match[1], ch: match.index } );
89
                        subfields.push( { code: match[1], ch: match.index } );
90
                    }
90
                    }
91
91
92
                    if ( !subfields.length ) {
93
                        errors.push( { type: 'noSubfields', line: i } );
94
                        return;
95
                    }
96
92
                    $.each( subfields, function( i, subfield ) {
97
                    $.each( subfields, function( i, subfield ) {
93
                        var next = subfields[ i + 1 ];
98
                        var next = subfields[ i + 1 ];
94
99
(-)a/koha-tmpl/intranet-tmpl/prog/en/css/cateditor.css (-6 / +13 lines)
Lines 355-365 body { Link Here
355
}
355
}
356
356
357
/*> Macros */
357
/*> Macros */
358
359
#macro-ui .CodeMirror {
360
    width: 100%;
361
}
362
363
#macro-save-message {
358
#macro-save-message {
364
    color: #666;
359
    color: #666;
365
    font-size: 13px;
360
    font-size: 13px;
Lines 429-434 body { Link Here
429
    padding: 2px;
424
    padding: 2px;
430
}
425
}
431
426
432
#macro-editor .CodeMirror {
427
#macro-editor {
428
    display: flex;
429
    flex-direction: column;
433
    height: 100%;
430
    height: 100%;
434
}
431
}
432
433
#macro-editor .CodeMirror {
434
    flex: 1;
435
    font-size: 13px;
436
}
437
438
/* Hotpatch from latest CodeMirror: Fix gutter positioning */
439
.CodeMirror-gutter-wrapper {
440
    position: absolute;
441
}
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-ui.inc (-24 / +32 lines)
Lines 569-575 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
569
                editor.refresh();
569
                editor.refresh();
570
                break;
570
                break;
571
            case 'macros':
571
            case 'macros':
572
                showSavedMacros();
572
                // Macros loaded on first show of modal
573
                break;
573
                break;
574
            case 'selected_search_targets':
574
            case 'selected_search_targets':
575
                $.each( z3950Servers, function( server_id, server ) {
575
                $.each( z3950Servers, function( server_id, server ) {
Lines 735-748 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
735
            position: function (elt) { $(elt).insertAfter('#toolbar') },
735
            position: function (elt) { $(elt).insertAfter('#toolbar') },
736
        } );
736
        } );
737
737
738
        macroEditor = CodeMirror(
739
            $('#macro-editor')[0],
740
            {
741
                mode: 'null',
742
                lineNumbers: true,
743
            }
744
        );
745
746
        // Automatically detect resizes and change the height of the editor and position of modals.
738
        // Automatically detect resizes and change the height of the editor and position of modals.
747
        var resizeTimer = null;
739
        var resizeTimer = null;
748
        $( window ).resize( function() {
740
        $( window ).resize( function() {
Lines 765-770 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
765
757
766
        } ).resize();
758
        } ).resize();
767
759
760
        $( '#macro-ui' ).on( 'shown', function() {
761
            if ( macroEditor ) return;
762
763
            macroEditor = CodeMirror(
764
                $('#macro-editor')[0],
765
                {
766
                    mode: 'null',
767
                    lineNumbers: true,
768
                }
769
            );
770
            var saveTimeout;
771
            macroEditor.on( 'change', function( cm, change ) {
772
                $('#macro-save-message').empty();
773
                if ( change.origin == 'setValue' ) return;
774
775
                if ( saveTimeout ) clearTimeout( saveTimeout );
776
                saveTimeout = setTimeout( function() {
777
                    saveMacro();
778
779
                    saveTimeout = null;
780
                }, 500 );
781
            } );
782
783
            showSavedMacros();
784
        } );
785
768
        var saveableBackends = [];
786
        var saveableBackends = [];
769
        $.each( backends, function( id, backend ) {
787
        $.each( backends, function( id, backend ) {
770
            if ( backend.save ) saveableBackends.push( [ backend.saveLabel, id ] );
788
            if ( backend.save ) saveableBackends.push( [ backend.saveLabel, id ] );
Lines 805-810 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
805
                        case 'noIndicators':
823
                        case 'noIndicators':
806
                            editor.addError( error.line, _("Invalid indicators") );
824
                            editor.addError( error.line, _("Invalid indicators") );
807
                            break;
825
                            break;
826
                        case 'noSubfields':
827
                            editor.addError( error.line, _("Tag has no subfields") );
828
                            break;
808
                        case 'missingTag':
829
                        case 'missingTag':
809
                            editor.addError( null, _("Missing mandatory tag: ") + error.tag );
830
                            editor.addError( null, _("Missing mandatory tag: ") + error.tag );
810
                            break;
831
                            break;
Lines 854-862 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
854
                    reader.onload = function() {
875
                    reader.onload = function() {
855
                        var record = new MARC.Record();
876
                        var record = new MARC.Record();
856
877
857
                        if ( /\.mrc$/.test( file.name ) ) {
878
                        if ( /\.(mrc|marc|iso|iso2709|marcstd)$/.test( file.name ) ) {
858
                            record.loadISO2709( reader.result );
879
                            record.loadISO2709( reader.result );
859
                        } else if ( /\.xml$/.test( file.name ) ) {
880
                        } else if ( /\.(xml|marcxml)$/.test( file.name ) ) {
860
                            record.loadMARCXML( reader.result );
881
                            record.loadMARCXML( reader.result );
861
                        } else {
882
                        } else {
862
                            humanMsg.displayAlert( _("Unknown record type, cannot import"), { className: 'humanError' } );
883
                            humanMsg.displayAlert( _("Unknown record type, cannot import"), { className: 'humanError' } );
Lines 914-932 require( [ 'koha-backend', 'search', 'macros', 'marc-editor', 'marc-record', 'pr Link Here
914
            return false;
935
            return false;
915
        } );
936
        } );
916
937
917
        var saveTimeout;
918
        macroEditor.on( 'change', function( cm, change ) {
919
            $('#macro-save-message').empty();
920
            if ( change.origin == 'setValue' ) return;
921
922
            if ( saveTimeout ) clearTimeout( saveTimeout );
923
            saveTimeout = setTimeout( function() {
924
                saveMacro();
925
926
                saveTimeout = null;
927
            }, 500 );
928
        } );
929
930
        $( '#switch-editor' ).click( function() {
938
        $( '#switch-editor' ).click( function() {
931
            if ( !confirm( _("Any changes will not be saved. Continue?") ) ) return;
939
            if ( !confirm( _("Any changes will not be saved. Continue?") ) ) return;
932
940
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/cateditor-widgets-marc21.inc (-4 / +3 lines)
Lines 114-120 require( [ 'widget' ], function( Widget ) { Link Here
114
114
115
    Widget.Register( '005@', {
115
    Widget.Register( '005@', {
116
        init: function() {
116
        init: function() {
117
            var $result = $( '<span class="subfield-widget fixed-widget">Updated: </span>' );
117
            var $result = $( '<span class="subfield-widget fixed-widget">' + _("Updated: ") + '</span>' );
118
118
119
            return $result[0];
119
            return $result[0];
120
        },
120
        },
Lines 134-140 require( [ 'widget' ], function( Widget ) { Link Here
134
134
135
                $( this.node ).append( dateVal.toLocaleString() );
135
                $( this.node ).append( dateVal.toLocaleString() );
136
            } else {
136
            } else {
137
                $( this.node ).append( '<span class="hint">unset</span>' );
137
                $( this.node ).append( '<span class="hint">' + _("unset") + '</span>' );
138
            }
138
            }
139
        }
139
        }
140
    } );
140
    } );
Lines 145-151 require( [ 'widget' ], function( Widget ) { Link Here
145
            return Widget.PadNum( now.getYear() % 100, 2 ) + Widget.PadNum( now.getMonth() + 1, 2 ) + Widget.PadNum( now.getDate(), 2 ) + "b        xxu||||| |||| 00| 0 [% DefaultLanguageField008 %] d";
145
            return Widget.PadNum( now.getYear() % 100, 2 ) + Widget.PadNum( now.getMonth() + 1, 2 ) + Widget.PadNum( now.getDate(), 2 ) + "b        xxu||||| |||| 00| 0 [% DefaultLanguageField008 %] d";
146
        },
146
        },
147
        init: function() {
147
        init: function() {
148
            var $result = $( '<span class="subfield-widget fixed-widget">Fixed data:<span class="hint widget-loading">Loading...</span></span>' );
148
            var $result = $( '<span class="subfield-widget fixed-widget">' + _("Fixed data:") + '<span class="hint widget-loading">' + _("Loading...") + '</span></span>' );
149
149
150
            return $result[0];
150
            return $result[0];
151
        },
151
        },
152
- 

Return to bug 11559