790f56dfdcbea02febac76e04903f207c46f068a
[fnpeditor.git] / src / editor / modules / documentCanvas / canvas / selection.js
1 define(function(require) {
2     
3 'use strict';
4
5 var $ = require('libs/jquery');
6
7 var Selection = function(canvas, params) {
8     this.canvas = canvas;
9     $.extend(this, params);
10 };
11
12 var CaretSelection = function(canvas, params) {
13     Selection.call(this, canvas, params);
14 };
15 CaretSelection.prototype = Object.create(Selection.prototype);
16 $.extend(CaretSelection.prototype, {
17     toDocumentFragment: function() {
18         var doc = this.canvas.wlxmlDocument;
19         return doc.createFragment(doc.CaretFragment, {node: this.element.wlxmlNode, offset: this.offset});
20     }
21 });
22
23 var TextSelection = function(canvas, params) {
24     Selection.call(this, canvas, params);
25 };
26 TextSelection.prototype = Object.create(Selection.prototype);
27 $.extend(TextSelection.prototype, {
28     toDocumentFragment: function() {
29         var doc = this.canvas.wlxmlDocument,
30             anchorNode = this.anchorElement ? this.anchorElement.wlxmlNode : null,
31             focusNode = this.focusElement ? this.focusElement.wlxmlNode : null;
32         
33         if(!anchorNode || !focusNode) {
34             return;
35         }
36
37         if(anchorNode.isSiblingOf(focusNode)) {
38             return doc.createFragment(doc.TextRangeFragment, {
39                 node1: anchorNode,
40                 offset1: this.anchorOffset,
41                 node2: focusNode,
42                 offset2: this.focusOffset,
43             });
44         }
45         else {
46             var siblingParents = doc.getSiblingParents({node1: anchorNode, node2: focusNode});
47             return doc.createFragment(doc.RangeFragment, {
48                 node1: siblingParents.node1,
49                 node2: siblingParents.node2
50             });
51         }
52     }
53 });
54
55 var NodeSelection = function(canvas, params) {
56     Selection.call(this, canvas, params);
57 };
58 NodeSelection.prototype = Object.create(Selection.prototype);
59 $.extend(NodeSelection.prototype, {
60     toDocumentFragment: function() {
61         var doc = this.canvas.wlxmlDocument;
62         doc.createFragment(doc.NodeFragment, {node: this.element.wlxmlNode});
63     }
64 });
65
66
67 var isText = function(node) {
68     /* globals Node */
69     return node && node.nodeType === Node.TEXT_NODE && $(node.parentNode).is('[document-text-element]');
70 };
71
72 var types = {
73     caret: CaretSelection,
74     textSelection: TextSelection,
75     nodeSelection: NodeSelection
76 };
77
78 return {
79     fromParams: function(canvas, params) {
80         return new types[params.type](canvas, params);
81     },
82     fromNativeSelection: function(canvas) {
83         /* globals window */
84         var nativeSelection =  window.getSelection(),
85             params = {},
86             element;
87         if(nativeSelection.focusNode) {
88             if(nativeSelection.isCollapsed && isText(nativeSelection.focusNode)) {
89                 params = {
90                     type: 'caret',
91                     element: canvas.getDocumentElement(nativeSelection.focusNode),
92                     offset: nativeSelection.focusOffset
93                 };
94             } else if(isText(nativeSelection.focusNode) && isText(nativeSelection.anchorNode)) {
95                 params = {
96                     type: 'textSelection',
97                     anchorElement: canvas.getDocumentElement(nativeSelection.anchorNode),
98                     anchorOffset: nativeSelection.anchorOffset,
99                     focusElement: canvas.getDocumentElement(nativeSelection.focusNode),
100                     focusOffset: nativeSelection.focusOffset
101                 };
102             }
103         } else if((element = canvas.getCurrentNodeElement())) {
104             params = {
105                 type: 'nodeSelection',
106                 element: element
107             };
108         }
109         if(params.type) {
110             return this.fromParams(canvas, params);
111         }
112     }
113 };
114
115 });