smartxml: fix - getIndex returns undefined for a node not attached to a document...
[fnpeditor.git] / src / editor / plugins / core / links / linkElement.js
1 define(function(require) {
2     
3 'use strict';
4 /* globals gettext */
5
6
7 var $ = require('libs/jquery'),
8     _ = require('libs/underscore'),
9     genericElement = require('modules/documentCanvas/canvas/genericElement'),
10     Dialog = require('views/dialog/dialog'),
11     boxTemplate = require('libs/text!./box.html'),
12     linkElement = Object.create(genericElement);
13
14
15 _.extend(linkElement, {
16     init: function() {
17         genericElement.init.call(this);
18         _.bindAll(this, 'changeLink', 'deleteLink');
19
20         var linkText = this.wlxmlNode.getAttr('href') || '',
21             linkUrl = this.getUrl(linkText);
22
23         this.box = $(_.template(boxTemplate)({text: linkText, url: linkUrl}));
24         this.box.find('.change').on('click', this.changeLink);
25         this.box.find('.delete').on('click', this.deleteLink);
26         this.box.hide();
27         this.addWidget(this.box);
28     },
29     onStateChange: function(changes) {
30         genericElement.onStateChange.call(this, changes);
31         if(_.isBoolean(changes.active)) {
32             this.box.toggle(changes.active);
33         }
34     },
35     onNodeAttrChange: function(event) {
36         if(event.meta.attr === 'href') {
37             var link = this.box.find('[link]');
38             link.text(event.meta.newVal);
39             link.attr('href', this.getUrl(event.meta.newVal));
40         }
41     },
42
43     changeLink: function(e) {
44         var el = this,
45             doc = this.wlxmlNode.document,
46             offset = el.canvas.getSelection().toDocumentFragment().offset,
47             dialog = Dialog.create({
48             title: gettext('Edit link'),
49             executeButtonText: gettext('Apply'),
50             cancelButtonText: gettext('Cancel'),
51             fields: [
52                 {label: gettext('Link'), name: 'href', type: 'input', initialValue: el.wlxmlNode.getAttr('href'),
53                 prePasteHandler: function(text) {
54                                     return this.wlxmlNode.document.getLinkForUrl(text);
55                                 }.bind(this)
56             }
57             ]
58         });
59         e.preventDefault();
60         e.stopPropagation();
61
62         dialog.on('execute', function(event) {
63             el.wlxmlNode.document.transaction(function() {
64                 el.wlxmlNode.setAttr('href', event.formData.href);
65                 event.success();
66             }, {
67                 metadata: {
68                     description: gettext('Edit link'),
69                     fragment: doc.createFragment(doc.CaretFragment, {node: el.wlxmlNode.contents()[0], offset:offset})
70                 },
71                 success: function() {
72                     el.canvas.select(doc.createFragment(doc.CaretFragment, {node: el.wlxmlNode.contents()[0], offset:offset}));
73                 }
74             });
75         });
76         dialog.show();
77     },
78
79     deleteLink: function() {
80         var el = this,
81             doc = this.wlxmlNode.document;
82
83         el.wlxmlNode.document.transaction(function() {
84             var f = el.canvas.getSelection().toDocumentFragment(),
85                 prefLen = 0,
86                 ret;
87
88             if(el.wlxmlNode.isPrecededByTextNode()) {
89                 prefLen = el.wlxmlNode.prev().getText().length;
90             }
91
92             ret = el.wlxmlNode.unwrapContent();
93             return doc.createFragment(doc.CaretFragment, {node: ret.element1, offset: prefLen + f.offset});
94         }, {
95             metadata: {
96                 description: gettext('Remove link'),
97                 fragment: doc.createFragment(doc.CaretFragment, {node: el.wlxmlNode.contents()[0], offset:0})
98             },
99             success: function(ret) {
100                 el.canvas.select(ret);
101             }
102         });
103     },
104
105     getUrl: function(link) {
106         var pattern = /^[a-z]*:\/\//g;
107         if(!pattern.test(link)) {
108             link = 'http://' + link;
109         }
110         return this.wlxmlNode.document.getUrlForLink(link);
111     }
112 });
113
114 return linkElement;
115
116 });