Bug 11559: Rancor: advanced cataloging interface
[koha.git] / koha-tmpl / intranet-tmpl / lib / koha / cateditor / macros / its.js
1 /**
2  * Copyright 2015 ByWater Solutions
3  *
4  * This file is part of Koha.
5  *
6  * Koha is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Koha is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Koha; if not, see <http://www.gnu.org/licenses>.
18  */
19
20 define( function() {
21     var NAV_FAILED = new Object();
22     var NAV_SUCCEEDED = new Object();
23
24     var _commandGenerators = [
25         [ /^copy field data$/i, function() {
26             return function( editor, state ) {
27                 if ( state.field == null ) return;
28
29                 return state.field.getText();
30             };
31         } ],
32         [ /^copy subfield data$/i, function() {
33             return function( editor, state ) {
34                 if ( state.field == null ) return;
35
36                 var cur = editor.getCursor();
37                 var subfields = state.field.getSubfields();
38
39                 for (var i = 0; i < subfields.length; i++) {
40                     if ( cur.ch > subfields[i].end ) continue;
41
42                     state.clipboard = subfields[i].text;
43                     return;
44                 }
45
46                 return false;
47             }
48         } ],
49         [ /^del(ete)? field$/i, function() {
50             return function( editor, state ) {
51                 if ( state.field == null ) return;
52
53                 state.field.delete();
54                 return NAV_FAILED;
55             }
56         } ],
57         [ /^goto field end$/i, function() {
58             return function( editor, state ) {
59                 if ( state.field == null ) return NAV_FAILED;
60                 var cur = editor.cm.getCursor();
61
62                 editor.cm.setCursor( { line: cur.line } );
63                 return NAV_SUCCEEDED;
64             }
65         } ],
66         [ /^goto field (\w{3})$/i, function(tag) {
67             return function( editor, state ) {
68                 var field = editor.getFirstField(tag);
69                 if ( field == null ) return NAV_FAILED;
70
71                 field.focus();
72                 return NAV_SUCCEEDED;
73             }
74         } ],
75         [ /^goto subfield end$/i, function() {
76             return function( editor, state ) {
77                 if ( state.field == null ) return NAV_FAILED;
78
79                 var cur = editor.getCursor();
80                 var subfields = state.field.getSubfields();
81
82                 for (var i = 0; i < subfields.length; i++) {
83                     if ( cur.ch > subfields[i].end ) continue;
84
85                     subfield.focusEnd();
86                     return NAV_SUCCEEDED;
87                 }
88
89                 return NAV_FAILED;
90             }
91         } ],
92         [ /^goto subfield (\w)$/i, function( code ) {
93             return function( editor, state ) {
94                 if ( state.field == null ) return NAV_FAILED;
95
96                 var subfield = state.field.getFirstSubfield( code );
97                 if ( subfield == null ) return NAV_FAILED;
98
99                 subfield.focus();
100                 return NAV_SUCCEEDED;
101             }
102         } ],
103         [ /^insert (new )?field (\w{3}) data=(.*)/i, function(undef, tag, text) {
104             text = text.replace(/\\([0-9a-z])/g, '$$$1 ');
105             return function( editor, state ) {
106                 editor.createFieldGrouped(tag).setText(text).focus();
107                 return NAV_SUCCEEDED;
108             }
109         } ],
110         [ /^insert (new )?subfield (\w) data=(.*)/i, function(undef, code, text) {
111             return function( editor, state ) {
112                 if ( state.field == null ) return;
113
114                 state.field.appendSubfield(code).setText(text);
115             }
116         } ],
117         [ /^paste$/i, function() {
118             return function( editor, state ) {
119                 var cur = editor.cm.getCursor();
120
121                 editor.cm.replaceRange( state.clipboard, cur, null, 'marcAware' );
122             }
123         } ],
124         [ /^set indicator([12])=([ _0-9])$/i, function( ind, value ) {
125             return function( editor, state ) {
126                 if ( state.field == null ) return;
127                 if ( state.field.isControlField ) return false;
128
129                 if ( ind == '1' ) {
130                     state.field.setIndicator1(value);
131                     return true;
132                 } else if ( ind == '2' ) {
133                     state.field.setIndicator2(value);
134                     return true;
135                 } else {
136                     return false;
137                 }
138             }
139         } ],
140         [ /^set indicators=([ _0-9])([ _0-9])?$/i, function( ind1, ind2 ) {
141             return function( editor, state ) {
142                 if ( state.field == null ) return;
143                 if ( state.field.isControlField ) return false;
144
145                 state.field.setIndicator1(ind1);
146                 state.field.setIndicator2(ind2 || '_');
147             }
148         } ],
149     ];
150
151     var ITSMacro = {
152         Compile: function( macro ) {
153             var result = { commands: [], errors: [] };
154
155             $.each( macro.split(/\r\n|\n/), function( line, contents ) {
156                 var command;
157
158                 if ( contents.match(/^\s*$/) ) return;
159
160                 $.each( _commandGenerators, function( undef, gen ) {
161                     var match;
162
163                     if ( !( match = gen[0].exec( contents ) ) ) return;
164
165                     command = gen[1].apply(null, match.slice(1));
166                     return false;
167                 } );
168
169                 if ( !command ) {
170                     result.errors.push( { line: line, error: 'unrecognized' } );
171                 }
172
173                 result.commands.push( { func: command, orig: contents, line: line } );
174             } );
175
176             return result;
177         },
178         Run: function( editor, macro ) {
179             var compiled = ITSMacro.Compile(macro);
180             if ( compiled.errors.length ) return { errors: compiled.errors };
181             var state = {
182                 clipboard: '',
183                 field: null,
184             };
185
186             var run_result = { errors: [] };
187
188             editor.cm.operation( function() {
189                 $.each( compiled.commands, function( undef, command ) {
190                     var result = command.func( editor, state );
191
192                     if ( result == NAV_FAILED ) {
193                         state.field = null;
194                     } else if ( result == NAV_SUCCEEDED ) {
195                         state.field = editor.getCurrentField();
196                     } else if ( result === false ) {
197                         run_result.errors.push( { line: command.line, error: 'failed' } );
198                         return false;
199                     }
200                 } );
201             } );
202
203             return run_result;
204         },
205     };
206
207     return ITSMacro;
208 } );