Fix in RAL.
[redakcja.git] / project / static / js / views / xml.js
1 /*global View CodeMirror ButtonToolbarView render_template panels */
2 var XMLView = View.extend({
3     _className: 'XMLView',
4     element: null,
5     model: null,
6     template: 'xml-view-template',
7     editor: null,
8     buttonToolbar: null,
9   
10     init: function(element, model, parent, template) {
11         this._super(element, model, template);
12         this.parent = parent;
13         this.buttonToolbar = new ButtonToolbarView(
14             $('.xmlview-toolbar', this.element),
15             this.model.toolbarButtonsModel, parent);
16
17         this.hotkeys = [];
18         var self = this;
19
20         $('.xmlview-toolbar', this.element).bind('resize.xmlview', this.resized.bind(this));
21    
22     
23         this.parent.freeze('Ładowanie edytora...');
24         this.editor = new CodeMirror($('.xmlview', this.element).get(0), {
25             parserfile: 'parsexml.js',
26             path: "/static/js/lib/codemirror/",
27             stylesheet: "/static/css/xmlcolors.css",
28             parserConfig: {
29                 useHTMLKludges: false
30             },
31             textWrapping: false,
32             tabMode: 'spaces',
33             indentUnit: 0,
34             onChange: this.editorDataChanged.bind(this),
35             initCallback: this.editorDidLoad.bind(this)
36         });
37     },
38   
39     resized: function(event) {
40         var height = this.element.height() - $('.xmlview-toolbar', this.element).outerHeight();
41         $('.xmlview', this.element).height(height);
42     },
43   
44     reload: function() {
45         this.model.load(true);
46     },
47   
48     editorDidLoad: function(editor) {
49         $(editor.frame).css({
50             width: '100%',
51             height: '100%'
52         });
53         this.model
54         .addObserver(this, 'data', this.modelDataChanged.bind(this))
55         .addObserver(this, 'state', this.modelStateChanged.bind(this))
56         .load();
57     
58         this.parent.unfreeze();
59       
60         this.editor.setCode(this.model.get('data'));
61         this.modelStateChanged('state', this.model.get('state'));
62         
63         editor.grabKeys(
64             this.hotkeyPressed.bind(this),
65             this.isHotkey.bind(this)
66             );
67     },
68   
69     editorDataChanged: function() {
70         this.model.set('data', this.editor.getCode());
71     },
72   
73     modelDataChanged: function(property, value) {
74         if (this.editor.getCode() != value) {
75             this.editor.setCode(value);
76         }
77     },
78   
79     modelStateChanged: function(property, value) {
80         if (value == 'synced' || value == 'dirty') {
81             this.unfreeze();
82         } else if (value == 'unsynced') {
83             this.freeze('Niezsynchronizowany...');
84         } else if (value == 'loading') {
85             this.freeze('Ładowanie...');
86         } else if (value == 'saving') {
87             this.freeze('Zapisywanie...');
88         } else if (value == 'error') {
89             this.freeze(this.model.get('error'));
90         }
91     },
92     
93     dispose: function() {
94         this.model.removeObserver(this);
95         $(this.editor.frame).remove();
96         this._super();
97     },    
98
99     getHotkey: function(event) {
100         var code = event.keyCode;
101         if(!((code >= 97 && code <= 122)
102            || (code >= 65 && code <= 90)) ) return null;
103
104         var ch = String.fromCharCode(code & 0xff).toLowerCase();
105         /* # console.log(ch.charCodeAt(0), '#', buttons); */
106
107         var buttons = $('.buttontoolbarview-button[title='+ch+']', this.element);
108         var mod = 0;
109             
110         if(event.altKey) mod |= 0x01;
111         if(event.ctrlKey) mod |= 0x02;
112         if(event.shiftKey) mod |= 0x04;
113
114         if(buttons.length) {
115             var match = null;
116
117             buttons.each(function() {
118                 if( parseInt($(this).attr('ui:hotkey_mod')) == mod ) {
119                     match = this;
120                     return;
121                 }
122             })
123
124             return match;
125         }
126         else {
127             return null;
128         }
129     },
130
131     isHotkey: function() {
132         /* console.log(arguments); */
133         if(this.getHotkey.apply(this, arguments))
134             return true;
135         else
136             return false;
137     },
138
139     hotkeyPressed: function() {
140         var button = this.getHotkey.apply(this, arguments);
141         this.buttonToolbar.buttonPressed({
142             target: button
143         });
144     }
145
146 });
147
148 function Hotkey(code) {
149     this.code = code;
150     this.has_alt = ((code & 0x01 << 8) !== 0);
151     this.has_ctrl = ((code & 0x01 << 9) !== 0);
152     this.has_shift = ((code & 0x01 << 10) !== 0);
153     this.character = String.fromCharCode(code & 0xff);
154 }
155
156 Hotkey.prototype.toString = function() {
157     var mods = [];
158     if(this.has_alt) mods.push('Alt');
159     if(this.has_ctrl) mods.push('Ctrl');
160     if(this.has_shift) mods.push('Shift');
161     mods.push('"'+this.character+'"');
162     return mods.join('+');
163 };
164
165 // Register view
166 panels['xml'] = XMLView;