diff --git a/js/linkit.dashboard.js b/js/linkit.dashboard.js index e27cf3354dad7a44111f45ac16a9e659eb789ec1..10265762ff3e8336a9c33b37fe7b0cf0f79e96d8 100644 --- a/js/linkit.dashboard.js +++ b/js/linkit.dashboard.js @@ -9,13 +9,13 @@ Drupal.behaviors.linkitDashboard = { attach: function (context, settings) { // Bind the insert link button. $('.linkit-insert', context).once('linkit-insert', function() { - $('.linkit-insert', context).click(function() { + $('.linkit-insert', context).click(function(event) { + event.preventDefault(); // Call the insertLink() function. Drupal.linkit.getDialogHelper(Drupal.settings.linkit.currentInstance.helper).insertLink(Drupal.linkit.getLink()); // Close the dialog. Drupal.linkit.modalClose(); - return false; }); }); @@ -238,5 +238,5 @@ Drupal.behaviors.linkitSearch = { }); } }; - + })(jQuery); diff --git a/js/linkit.field.js b/js/linkit.field.js index 27ca6ba4962eb7d03dcefb4fe487c6a3f0c4848f..08b8e485adb387aa6c11668b8b624d7d5d4b0400 100644 --- a/js/linkit.field.js +++ b/js/linkit.field.js @@ -2,134 +2,149 @@ * @file * Linkit field ui functions */ - -(function ($) { - -Drupal.behaviors.linkit_field = { - attach : function(context, settings) { - // If there is no fields, just stop here. - - if (settings.linkit == undefined || settings.linkit.fields == null) { - return false; - } - - $.each(settings.linkit.fields, function(field_name, field) { - $('#' + field_name, context).once('linkit_field', function() { - $('.linkit-field-' + field_name).click(function() { - // Set profile. - Drupal.settings.linkit.currentInstance.profile = Drupal.settings.linkit.fields[field_name].profile; - - // Set the name of the source field.. - Drupal.settings.linkit.currentInstance.source = field_name; - - // Set the source type. - Drupal.settings.linkit.currentInstance.helper = 'field'; - - // Only care about selection if the element is a textarea. - if ($('textarea#' + field_name).length) { - var selection = Drupal.linkit.getDialogHelper('field').getSelection($('#' + field_name).get(0)); - // Save the selection. - Drupal.settings.linkit.currentInstance.selection = selection; - } - - // Suppress profile changer. - Drupal.settings.linkit.currentInstance.suppressProfileChanger = true; - - // Create the modal. - Drupal.linkit.createModal(); - - return false; +(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', { - init : function() {}, - afterInit : function () {}, - - /** - * Insert the link into the field. - * - * @param {Object} link - * The link object. - */ - insertLink : function(data) { - var source = $('#' + Drupal.settings.linkit.currentInstance.source), - field_settings = Drupal.settings.linkit.fields[Drupal.settings.linkit.currentInstance.source], - - // Call the insert plugin. - link = Drupal.linkit.getInsertPlugin(field_settings.insert_plugin).insert(data, field_settings); - - if (typeof Drupal.settings.linkit.currentInstance.selection != 'undefined') { - // Replace the selection and insert the link there. - this.replaceSelection(source.get(0), Drupal.settings.linkit.currentInstance.selection, link); } - else { - // Replace the field value. - this.replaceFieldValue(source.get(0), link); - } - - // Link field can have a title field. If they have, we populate the title - // field with the search result title if any. - if (typeof field_settings.title_field != 'undefined' && typeof Drupal.settings.linkit.currentInstance.linkContent != 'undefined') { - this.replaceFieldValue($('#' + field_settings.title_field).get(0), Drupal.settings.linkit.currentInstance.linkContent); - } - }, + }; /** - * Get field selection. + * Linkit field dialog helper. */ - getSelection : function(e) { - // Mozilla and DOM 3.0. - if ('selectionStart' in e) { - var l = e.selectionEnd - e.selectionStart; - return { start: e.selectionStart, end: e.selectionEnd, length: l, text: e.value.substr(e.selectionStart, l) }; - } - // IE. - else if(document.selection) { - e.focus(); - var r = document.selection.createRange(), - tr = e.createTextRange(), - tr2 = tr.duplicate(); - tr2.moveToBookmark(r.getBookmark()); - tr.setEndPoint('EndToStart',tr2); - - if (r == null || tr == null) { - return { start: e.value.length, end: e.value.length, length: 0, text: '' }; + 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 = r.text.replace(/[\r\n]/g,'.'), - text_whole = e.value.replace(/[\r\n]/g,'.'), - the_start = text_whole.indexOf(text_part, tr.text.length); - return { start: the_start, end: the_start + text_part.length, length: text_part.length, text: r.text }; + 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); } - // Browser not supported. - else { - return { start: e.value.length, end: e.value.length, length: 0, text: '' }; - } - }, - - /** - * Replace the field selection. - */ - replaceSelection : function (e, selection, text) { - var start_pos = selection.start; - var end_pos = start_pos + text.length; - e.value = e.value.substr(0, start_pos) + text + e.value.substr(selection.end, e.value.length); - }, - - /** - * Replace the field value. - */ - replaceFieldValue : function (e, text) { - e.value = text; - } -}); - -})(jQuery); \ No newline at end of file + }); +})(jQuery, 'linkitField'); diff --git a/js/linkit.js b/js/linkit.js index 50e02cac3ef461a3992c2cd65a40939956708d97..7e9664e3531e5cf8eea70c7bb55fe2984532791e 100644 --- a/js/linkit.js +++ b/js/linkit.js @@ -144,6 +144,12 @@ Drupal.linkit.registerDialogHelper = function(name, helper) { /** * Get a dialog helper. + * + * @param {String} name + * The name of helper. + * + * @return {Object} + * Dialog helper object. */ Drupal.linkit.getDialogHelper = function(name) { return Drupal.linkit.dialogHelper[name]; diff --git a/linkit.field.inc b/linkit.field.inc index 910d9d7d12db7fa1037ae16883a27cc1af142839..1f46d6c118ae50829ebfa9a2a33c4a07d2cc6e06 100644 --- a/linkit.field.inc +++ b/linkit.field.inc @@ -170,72 +170,80 @@ function linkit_field_profile_validate($element, &$form_state, $form) { } /** - * Process callback. + * After build callback. + * + * @param array $element + * Form API element. + * @param array $form_state + * State of form the element belongs to. + * + * @return array + * Form API element with attached Linkit functionality. */ -function linkit_process_field_element($element, &$form_state, &$complete_form) { +function linkit_field_element_after_build(array $element, array &$form_state) { // Only proceed if the field is attached to an entity. if (!isset($element['#entity_type'])) { return $element; } - $field = field_info_field($element['#field_name']); $instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']); - if (isset($instance['settings']['linkit']['enable']) && $instance['settings']['linkit']['enable']) { - - // Load the profile. - $profile = linkit_profile_load($instance['settings']['linkit']['profile']); - if (!$profile) { - return $element; - } - // Load the insert plugin for the profile. - $insert_plugin = isset($profile->data['insert_plugin']['plugin']) ? linkit_insert_plugin_load($profile->data['insert_plugin']['plugin']) : NULL; - if ($insert_plugin === NULL) { - return $element; - } - - // Set the field ID. - $field_id = $element['#id']; + if (empty($instance['settings']['linkit']['enable'])) { + return $element; + } - // Special treatment for link fields. - if ($element['#type'] == 'link_field') { - $field_id = $element['#id'] . '-url'; - } + // Load the profile. + /* @var \LinkitProfile $profile */ + $profile = linkit_profile_load($instance['settings']['linkit']['profile']); - $field_js = array( - 'data' => array( - 'linkit' => array( - 'fields' => array( - $field_id => array( - 'profile' => $instance['settings']['linkit']['profile'], - 'insert_plugin' => $profile->data['insert_plugin']['plugin'], - 'url_method' => $profile->data['insert_plugin']['url_method'], - // @TODO: Add autocomplete settings. - ), - ), - ), - ), - 'type' => 'setting', - ); + if (!$profile || !isset($profile->data['insert_plugin']['plugin'])) { + return $element; + } + // Load the insert plugin for the profile. + $insert_plugin = linkit_insert_plugin_load($profile->data['insert_plugin']['plugin']); + $js_settings = array( + 'helper' => 'field', + 'source' => $element['#id'], + 'profile' => $instance['settings']['linkit']['profile'], + 'insertPlugin' => $profile->data['insert_plugin']['plugin'], + ); - // Link fields can have a title field. - if ($element['#type'] == 'link_field') { - if (isset($instance['settings']['title']) && in_array($instance['settings']['title'], array('optional', 'required'))) { - $field_js['data']['linkit']['fields'][$field_id]['title_field'] = $element['#id'] . '-title'; - } + // Special treatment for link fields. + if ('link_field' == $element['#type']) { + $js_settings['source'] = $element['url']['#id']; + + // @see link_field_info() + // @see link_field_instance_settings_form() + // + // Link fields have a title field, but value could + // be changed only for those options. + if (in_array($instance['settings']['title'], array('optional', 'required'))) { + $js_settings['titleField'] = $element['title']['#id']; } - - // Attach js files and settings Linkit needs. - $element['#attached']['library'][] = array('linkit', 'base'); - $element['#attached']['library'][] = array('linkit', 'field'); - $element['#attached']['js'][] = $insert_plugin['javascript']; - $element['#attached']['js'][] = $field_js; - - $button_text = !empty($instance['settings']['linkit']['button_text']) ? $instance['settings']['linkit']['button_text'] : t('Search'); - // Add Linkit dialog button to the element suffix. - $element['#field_suffix'] = '' . $button_text . ''; } + // Add Linkit dialog button to the element suffix. + $element['#field_suffix'] = l(empty($instance['settings']['linkit']['button_text']) ? t('Search') : $instance['settings']['linkit']['button_text'], '', array( + 'attributes' => array( + 'class' => array( + "button", + "linkit-field-button", + "linkit-field-{$js_settings['source']}", + ), + ), + )); + + // Attach js files and settings Linkit needs. + $element['#attached']['library'][] = array('linkit', 'base'); + $element['#attached']['library'][] = array('linkit', 'field'); + $element['#attached']['js'][] = $insert_plugin['javascript']; + $element['#attached']['js'][] = array( + 'type' => 'setting', + 'data' => array( + 'linkit' => array('fields' => array($js_settings)), + ), + ); + return $element; -} \ No newline at end of file +} diff --git a/linkit.module b/linkit.module index 0184f761e086584350cbfe54dd6ccb72a4fe1b95..78f770438698f12b05bfe113ef065eb3bce0f65e 100644 --- a/linkit.module +++ b/linkit.module @@ -326,10 +326,10 @@ function linkit_module_implements_alter(&$implementations, $hook) { * Implements hook_element_info_alter(). */ function linkit_element_info_alter(&$types) { - // Append a process function for the field integration. + // Append a after_build function for the field integration. foreach (linkit_get_allowed_field_elements() as $element) { if (isset($types[$element])) { - $types[$element]['#process'][] = 'linkit_process_field_element'; + $types[$element]['#after_build'][] = 'linkit_field_element_after_build'; } } diff --git a/plugins/linkit_insert/html_link/html_link.js b/plugins/linkit_insert/html_link/html_link.js index 5edc181b00035e3db16e7752496162dba10549cf..fcc4c29dcb34521a619b94f01581bb45e53bbcd2 100644 --- a/plugins/linkit_insert/html_link/html_link.js +++ b/plugins/linkit_insert/html_link/html_link.js @@ -2,34 +2,32 @@ * @file * HTML Link insert plugin for Linkit. */ -(function ($) { +(function($) { + Drupal.linkit.registerInsertPlugin('html_link', { + insert: function(data) { + var linkitInstance = Drupal.settings.linkit.currentInstance, + selection = linkitInstance.selection, + text = linkitInstance.linkContent || data.path; -Drupal.linkit.registerInsertPlugin('html_link', { - insert : function(data) { - var text, - selection = Drupal.settings.linkit.currentInstance.selection; + // Delete all attributes that are empty. + for (var attr in data.attributes) { + if (data.attributes.hasOwnProperty(attr)) { + delete data.attributes[attr]; + } + } - // Delete all attributes that are empty. - for (name in data.attributes) { - (data.attributes[name]) ? null : delete data.attributes[name]; - } + if (selection && selection.text.length >= 1) { + text = selection.text; + } - if (typeof selection != 'undefined' && - selection.text.length >= 1) { - text = selection.text; - } - else { - text = Drupal.settings.linkit.currentInstance.linkContent; + // Use document.createElement as it is mush fasten then $('). + return $(document.createElement('a')) + .attr(data.attributes) + .attr('href', data.path) + .html(text) + // Convert the element to a string. + .get(0) + .outerHTML; } - - // Use document.createElement as it is mush fasten then $('). - return $(document.createElement('a')) - .attr(data.attributes) - .attr('href', data.path) - .html(text) - // Convert the element to a string. - .get(0).outerHTML; - } -}); - -})(jQuery); \ No newline at end of file + }); +})(jQuery);