smartxml: Allow Fragments to refresh their node references using their initial paths
[fnpeditor.git] / src / editor / modules / documentCanvas / documentCanvas.js
1 // Module that implements main WYSIWIG edit area
2
3 define([
4 'libs/jquery',
5 'libs/underscore',
6 'fnpjs/logging/logging',
7 './canvas/canvas',
8 'libs/text!./template.html'], function($, _, logging, canvas3, template) {
9
10 'use strict';
11
12
13 var logger = logging.getLogger('documentCanvas');
14
15 return function(sandbox) {
16
17     var canvasElements = [];
18
19     sandbox.getPlugins().forEach(function(plugin) {
20         canvasElements = canvasElements.concat(plugin.canvasElements || []);
21     });
22
23     var canvas = canvas3.fromXMLDocument(null, canvasElements);
24     var canvasWrapper = $(template);
25     var shownAlready = false;
26     var scrollbarPosition = 0,
27         actionHandlers = {},
28         cursorPosition;
29         
30     
31     canvas.on('selectionChanged', function(selection) {
32         sandbox.publish('selectionChanged', selection);
33     });
34
35     canvasWrapper.onShow = function() {
36         if(!shownAlready) {
37             shownAlready = true;
38             canvas.setCurrentElement(canvas.doc().getVerticallyFirstTextElement());
39         } else {
40             canvas.setCursorPosition(cursorPosition);
41             this.find('#rng-module-documentCanvas-contentWrapper').scrollTop(scrollbarPosition);
42         }
43     };
44     
45     canvasWrapper.onHide = function() {
46        scrollbarPosition = this.find('#rng-module-documentCanvas-contentWrapper').scrollTop();
47        cursorPosition = canvas.getCursor().getPosition();
48     };
49
50     /* public api */
51     return {
52         start: function() {
53             sandbox.getPlugins().forEach(function(plugin) {
54                 var handlers;
55                 if(plugin.canvas) {
56                     handlers = plugin.canvas.actionHandlers;
57                     if(handlers && !_.isArray(handlers)) {
58                         handlers = [handlers];
59                     }
60                     actionHandlers[plugin.name] = handlers;
61                 }
62             });
63             sandbox.publish('ready');
64         },
65         getView: function() {
66             return canvasWrapper;
67         },
68         getCanvas: function() {
69             return canvas;
70         },
71         setDocument: function(wlxmlDocument) {
72             canvas.loadWlxmlDocument(wlxmlDocument);
73             canvasWrapper.find('#rng-module-documentCanvas-content').empty().append(canvas.view());
74         },
75         highlightElement: function(node) {
76             canvas.toggleElementHighlight(node, true);
77         },
78         dimElement: function(node) {
79             canvas.toggleElementHighlight(node, false);
80         },
81         jumpToElement: function(node) {
82             canvas.setCurrentElement(node);
83         },
84         onAfterActionExecuted: function(action, ret) {
85             if(ret && ret.isValid() && ret instanceof canvas.wlxmlDocument.NodeFragment) {
86                 logger.debug('The action returned a valid fragment');
87                 var params = {
88                     caretTo: ret instanceof canvas.wlxmlDocument.CaretFragment ? ret.offset : 'start'
89                 };
90                 canvas.setCurrentElement(ret.node, params);
91                 return;
92             }
93             logger.debug('No valid fragment returned from the action');
94
95             (actionHandlers[action.getPluginName()] || []).forEach(function(handler) {
96                 handler(canvas, action, ret);
97             });
98         }
99     };
100     
101 };
102
103 });