Commit cec41677 authored by BR0kEN's avatar BR0kEN Committed by anon

Issue #1858050 by BR0kEN, l0ke, anon, MiroslavBanov, IRuslan, Peter...

Issue #1858050 by BR0kEN, l0ke, anon, MiroslavBanov, IRuslan, Peter Törnstrand, bibishani, gillesv, zuuperman: Search button breaks when used on a multiple link or text field
parent 297183bf
......@@ -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);
......@@ -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');
......@@ -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];
......
......@@ -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'] = '<a class="button linkit-field-button linkit-field-' . $field_id . '" href="#">' . $button_text . '</a>';
}
// 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
}
......@@ -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';
}
}
......
......@@ -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 $('<a/>).
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 $('<a/>).
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);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment