summaryrefslogtreecommitdiffstats
path: root/js/linkit.field.js
blob: 08b8e485adb387aa6c11668b8b624d7d5d4b0400 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/**
 * @file
 * Linkit field ui functions
 */
(function($, behavior) {
  'use strict';

  Drupal.behaviors[behavior] = {
    attach: function(context, settings) {
      // If there is no fields, just stop here.
      if (undefined === settings.linkit || null === settings.linkit.fields) {
        return false;
      }

      $.each(settings.linkit.fields, function(i, instance) {
        $('#' + instance.source, context).once(behavior, function() {
          var element = this;

          $('.linkit-field-' + instance.source).click(function(event) {
            event.preventDefault();

            // Only care about selection if the element is a textarea.
            if ('textarea' === element.nodeName.toLowerCase()) {
              instance.selection = Drupal.linkit.getDialogHelper('field').getSelection(element);
            }

            Drupal.settings.linkit.currentInstance = instance;
            Drupal.linkit.createModal();
          });
        });
      });
    }
  };

  /**
   * Linkit field dialog helper.
   */
  Drupal.linkit.registerDialogHelper('field', {
    afterInit: function() {},

    /**
     * Insert the link into the field.
     *
     * @param {Object} data
     *   The link object.
     */
    insertLink: function(data) {
      var instance = Drupal.settings.linkit.currentInstance,
          // Call the insert plugin.
          link = Drupal.linkit.getInsertPlugin(instance.insertPlugin).insert(data, instance);

      if (instance.hasOwnProperty('selection')) {
        // Replace the selection and insert the link there.
        this.replaceSelection(instance.source, instance.selection, link);
      }
      else if (instance.hasOwnProperty('titleField')) {
        // The "linkContent" property will always be present when AJAX used.
        // Otherwise, if you use simple insert without autocomplete, then this
        // property will be undefined and title field should not be filled in.
        //
        // @see Drupal.behaviors.linkitSearch.attach
        if (instance.hasOwnProperty('linkContent')) {
          this.replaceFieldValue(instance.titleField, instance.linkContent);
        }

        // The "path" property will always be present after dialog was
        // opened and contain raw URL.
        //
        // @see Drupal.behaviors.linkitDashboard.attach
        this.replaceFieldValue(instance.source, data.path);
      }
      else {
        // Replace the field value.
        this.replaceFieldValue(instance.source, link);
      }
    },

    /**
     * Get field selection.
     */
    getSelection: function(element) {
      var object = {
        start: element.value.length,
        end: element.value.length,
        length: 0,
        text: ''
      };

      // Mozilla and DOM 3.0.
      if ('selectionStart' in element) {
        var length = element.selectionEnd - element.selectionStart;

        object = {
          start: element.selectionStart,
          end: element.selectionEnd,
          length: length,
          text: element.value.substr(element.selectionStart, length)
        };
      }
      // IE.
      else if (document.selection) {
        element.focus();

        var range = document.selection.createRange(),
            textRange = element.createTextRange(),
            textRangeDuplicate = textRange.duplicate();

        textRangeDuplicate.moveToBookmark(range.getBookmark());
        textRange.setEndPoint('EndToStart', textRangeDuplicate);

        if (!(range || textRange)) {
          return object;
        }

        // For some reason IE doesn't always count the \n and \r in the length.
        var text_part = range.text.replace(/[\r\n]/g, '.'),
            text_whole = element.value.replace(/[\r\n]/g, '.'),
            the_start = text_whole.indexOf(text_part, textRange.text.length);

        object = {
          start: the_start,
          end: the_start + text_part.length,
          length: text_part.length,
          text: range.text
        };
      }

      return object;
    },

    /**
     * Replace the field selection.
     */
    replaceSelection: function(id, selection, text) {
      var field = this.getField(id);
      field.value = field.value.substr(0, selection.start) + text + field.value.substr(selection.end, field.value.length);
    },

    /**
     * Replace the field value.
     */
    replaceFieldValue: function(id, text) {
      this.getField(id).value = text;
    },

    getField: function(id) {
      return document.getElementById(id);
    }
  });
})(jQuery, 'linkitField');