save caret position when ending a list
[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     add_attachments = require('views/attachments/add_attachments'),
13     linkElement = Object.create(genericElement);
14
15
16 _.extend(linkElement, {
17     init: function() {
18         genericElement.init.call(this);
19         _.bindAll(this, 'changeLink', 'deleteLink');
20
21         var linkText = this.wlxmlNode.getAttr('href') || '',
22             linkUrl = this.getUrl(linkText),
23             badLink;
24
25         if (linkText.substr(0,7) === 'file://') {
26             var filename = decodeURIComponent(linkText.substr(7));
27             // ugly
28             badLink = (window.materials.indexOf(filename) < 0);
29         }
30
31         this.box = $(_.template(boxTemplate)({text: linkText, url: linkUrl, bad: badLink}));
32         this.box.find('.change').on('click', this.changeLink);
33         this.box.find('.delete').on('click', this.deleteLink);
34         this.box.hide();
35         this.addWidget(this.box);
36     },
37     onStateChange: function(changes) {
38         genericElement.onStateChange.call(this, changes);
39         if(_.isBoolean(changes.active)) {
40             this.box.toggle(changes.active);
41         }
42     },
43     onNodeAttrChange: function(event) {
44         if(event.meta.attr === 'href') {
45             var link = this.box.find('[link]');
46             link.text(event.meta.newVal);
47             link.attr('href', this.getUrl(event.meta.newVal));
48         }
49     },
50
51     changeLink: function(e) {
52         var el = this,
53             doc = this.wlxmlNode.document,
54             offset = el.canvas.getSelection().toDocumentFragment().offset,
55             dialog = Dialog.create({
56             title: gettext('Edit link'),
57             executeButtonText: gettext('Apply'),
58             cancelButtonText: gettext('Cancel'),
59             fields: [
60                 {label: gettext('Link'), name: 'href', type: 'input', initialValue: el.wlxmlNode.getAttr('href'),
61                 prePasteHandler: function(text) {
62                                     return this.wlxmlNode.document.getLinkForUrl(text);
63                                 }.bind(this)
64             }
65             ]
66         });
67         e.preventDefault();
68         e.stopPropagation();
69
70         dialog.on('execute', function(event) {
71             el.wlxmlNode.document.transaction(function() {
72                 el.wlxmlNode.setAttr('href', event.formData.href);
73                 event.success();
74             }, {
75                 metadata: {
76                     description: gettext('Edit link'),
77                     fragment: doc.createFragment(doc.CaretFragment, {node: el.wlxmlNode.contents()[0], offset:offset})
78                 },
79                 success: function() {
80                     el.canvas.select(doc.createFragment(doc.CaretFragment, {node: el.wlxmlNode.contents()[0], offset:offset}));
81                 }
82             });
83         });
84         dialog.show();
85         add_attachments(dialog);
86     },
87
88     deleteLink: function() {
89         var el = this,
90             doc = this.wlxmlNode.document;
91
92         el.wlxmlNode.document.transaction(function() {
93             var f = el.canvas.getSelection().toDocumentFragment(),
94                 prefLen = 0,
95                 ret;
96
97             if(el.wlxmlNode.isPrecededByTextNode()) {
98                 prefLen = el.wlxmlNode.prev().getText().length;
99             }
100
101             ret = el.wlxmlNode.unwrapContent();
102             return doc.createFragment(doc.CaretFragment, {node: ret.element1, offset: prefLen + f.offset});
103         }, {
104             metadata: {
105                 description: gettext('Remove link'),
106                 fragment: doc.createFragment(doc.CaretFragment, {node: el.wlxmlNode.contents()[0], offset:0})
107             },
108             success: function(ret) {
109                 el.canvas.select(ret);
110             }
111         });
112     },
113
114     getUrl: function(link) {
115         var pattern = /^[a-z]*:\/\//g;
116         if(!pattern.test(link)) {
117             link = 'http://' + link;
118         }
119         return this.wlxmlNode.document.getUrlForLink(link);
120     }
121 });
122
123 return linkElement;
124
125 });