updated etxlink, ctools, colorbox, computed_field

This commit is contained in:
2019-05-13 17:51:14 +02:00
parent 33210e10f2
commit 2ffad14939
309 changed files with 4930 additions and 2655 deletions

View File

@@ -145,6 +145,12 @@ function colorbox_admin_settings() {
'#default_value' => variable_get('colorbox_overlayclose', 1),
'#description' => t('Enable closing Colorbox by clicking on the background overlay.'),
);
$form['colorbox_custom_settings']['colorbox_returnfocus'] = array(
'#type' => 'checkbox',
'#title' => t('Return focus'),
'#default_value' => variable_get('colorbox_returnfocus', 1),
'#description' => t('Return focus when Colorbox exits to the element it was launched from.'),
);
$form['colorbox_custom_settings']['colorbox_maxwidth'] = array(
'#type' => 'textfield',
'#title' => t('Max width'),
@@ -266,10 +272,10 @@ function colorbox_admin_settings() {
);
$form['colorbox_advanced_settings']['colorbox_mobile_device_width'] = array(
'#type' => 'textfield',
'#title' => t('Device with'),
'#title' => t('Device width'),
'#default_value' => variable_get('colorbox_mobile_device_width', '480px'),
'#size' => 30,
'#description' => t('Set the mobile device max with. Default: 480px.'),
'#description' => t('Set the mobile device max width. Default: 480px.'),
'#states' => array(
'visible' => array(
':input[name="colorbox_mobile_detect"]' => array('value' => '1'),

View File

@@ -6,9 +6,9 @@ configure = admin/config/media/colorbox
files[] = views/colorbox_handler_field_colorbox.inc
; Information added by Drupal.org packaging script on 2016-06-06
version = "7.x-2.12"
; Information added by Drupal.org packaging script on 2017-04-04
version = "7.x-2.13"
core = "7.x"
project = "colorbox"
datestamp = "1465255741"
datestamp = "1491291489"

View File

@@ -44,7 +44,7 @@ function colorbox_theme() {
'node' => NULL, // Left for legacy support.
'field' => array(),
'display_settings' => array(),
'delta' => null,
'delta' => NULL,
),
'file' => 'colorbox.theme.inc',
),
@@ -167,7 +167,7 @@ function _colorbox_doheader() {
return; // Don't add the JavaScript and CSS multiple times.
}
// Insert options and translated strings as javascript settings.
// Insert options and translated strings as JavaScript settings.
if (variable_get('colorbox_custom_settings_activate', 0)) {
$js_settings = array(
'transition' => variable_get('colorbox_transition_type', 'elastic'),
@@ -183,6 +183,7 @@ function _colorbox_doheader() {
'next' => strip_tags(variable_get('colorbox_text_next', 'Next »')),
'close' => strip_tags(variable_get('colorbox_text_close', 'Close')),
'overlayClose' => variable_get('colorbox_overlayclose', 1) ? TRUE : FALSE,
'returnFocus' => variable_get('colorbox_returnfocus', 1) ? TRUE : FALSE,
'maxWidth' => variable_get('colorbox_maxwidth', '98%'),
'maxHeight' => variable_get('colorbox_maxheight', '98%'),
'initialWidth' => variable_get('colorbox_initialwidth', '300'),
@@ -364,11 +365,18 @@ function colorbox_field_formatter_settings_form($field, $instance, $view_mode, $
// Allow users to hide or set a custom recursion limit.
// The module token_tweaks sets a global recursion limit that can not be bypassed.
if (module_exists('token') && $recursion_limit = min(variable_get('token_tree_recursion_limit', 3), variable_get('colorbox_token_recursion_limit', 3))) {
// File entities do not have $field, only $instance.
if (!empty($field)) {
$token_types = array_merge(array_keys($field['bundles']), array('file'));
}
else {
$token_types = array($instance['entity_type'], 'file');
}
$element['colorbox_token'] = array(
'#type' => 'fieldset',
'#title' => t('Replacement patterns'),
'#theme' => 'token_tree',
'#token_types' => array_merge(array_keys($field['bundles']),array('file')),
'#token_types' => $token_types,
'#recursion_limit' => $recursion_limit,
'#dialog' => TRUE,
'#states' => array(

View File

@@ -66,7 +66,7 @@ function theme_colorbox_image_formatter($variables) {
$entity_title = entity_label($entity_type, $entity);
switch ($settings['colorbox_caption']) {
case 'auto':
case 'auto':
// If the title is empty use alt or the entity title in that order.
if (!empty($image['title'])) {
$caption = $image['title'];
@@ -81,18 +81,23 @@ function theme_colorbox_image_formatter($variables) {
$caption = '';
}
break;
case 'title':
$caption = $image['title'];
break;
case 'alt':
$caption = $image['alt'];
break;
case 'node_title':
$caption = $entity_title;
break;
case 'custom':
$caption = token_replace($settings['colorbox_caption_custom'], array($entity_type => $entity, 'file' => (object) $item), array('clear' => TRUE));
break;
default:
$caption = '';
}
@@ -111,18 +116,23 @@ function theme_colorbox_image_formatter($variables) {
case 'post':
$gallery_id = 'gallery-' . $entity_id;
break;
case 'page':
$gallery_id = 'gallery-all';
break;
case 'field_post':
$gallery_id = 'gallery-' . $entity_id . '-' . $field['field_name'];
break;
case 'field_page':
$gallery_id = 'gallery-' . $field['field_name'];
break;
case 'custom':
$gallery_id = $settings['colorbox_gallery_custom'];
break;
default:
$gallery_id = '';
}
@@ -183,6 +193,7 @@ function theme_colorbox_imagefield($variables) {
'title' => $variables['title'],
'class' => $class,
'data-colorbox-gallery' => $variables['gid'],
'data-cbox-img-attrs' => '{"title": "' . $variables['image']['title'] . '", "alt": "' . $variables['image']['alt'] . '"}',
),
);
@@ -240,6 +251,7 @@ function template_preprocess_colorbox_insert_image(&$variables) {
case 2:
$variables['gallery_id'] = 'gallery-all';
break;
case 3:
$variables['gallery_id'] = '';
break;

View File

@@ -90,39 +90,45 @@ function drush_colorbox_plugin() {
drush_log(dt('Directory @path was created', array('@path' => $path)), 'notice');
}
// Set the directory to the download location.
$olddir = getcwd();
chdir($path);
// Download colorbox plugin only if path is writable.
if (is_writable($path)) {
// Set the directory to the download location.
$olddir = getcwd();
chdir($path);
// Download the zip archive
if ($filepath = drush_download_file(COLORBOX_DOWNLOAD_URI)) {
$filename = basename($filepath);
$dirname = COLORBOX_DOWNLOAD_PREFIX . basename($filepath, '.zip');
// Download the zip archive
if ($filepath = drush_download_file(COLORBOX_DOWNLOAD_URI)) {
$filename = basename($filepath);
$dirname = COLORBOX_DOWNLOAD_PREFIX . basename($filepath, '.zip');
// Remove any existing Colorbox plugin directory
if (is_dir($dirname) || is_dir('colorbox')) {
drush_delete_dir($dirname, TRUE);
drush_delete_dir('colorbox', TRUE);
drush_log(dt('A existing Colorbox plugin was deleted from @path', array('@path' => $path)), 'notice');
// Remove any existing Colorbox plugin directory.
if (is_dir($dirname) || is_dir('colorbox')) {
drush_delete_dir($dirname, TRUE);
drush_delete_dir('colorbox', TRUE);
drush_log(dt('A existing Colorbox plugin was deleted from @path', array('@path' => $path)), 'notice');
}
// Decompress the zip archive
drush_tarball_extract($filename);
// Change the directory name to "colorbox" if needed.
if ($dirname != 'colorbox') {
drush_move_dir($dirname, 'colorbox', TRUE);
$dirname = 'colorbox';
}
}
// Decompress the zip archive
drush_tarball_extract($filename);
// Change the directory name to "colorbox" if needed.
if ($dirname != 'colorbox') {
drush_move_dir($dirname, 'colorbox', TRUE);
$dirname = 'colorbox';
if (is_dir($dirname)) {
drush_log(dt('Colorbox plugin has been installed in @path', array('@path' => $path)), 'success');
}
else {
drush_log(dt('Drush was unable to install the Colorbox plugin to @path', array('@path' => $path)), 'error');
}
}
if (is_dir($dirname)) {
drush_log(dt('Colorbox plugin has been installed in @path', array('@path' => $path)), 'success');
// Set working directory back to the previous working directory.
chdir($olddir);
}
else {
drush_log(dt('Drush was unable to install the Colorbox plugin to @path', array('@path' => $path)), 'error');
drush_log(dt('Drush was unable to install the Colorbox plugin because @path is not writable. If you enable the colorbox module before you install the plugin library, you may find that colorbox does not work until you reinstall the colorbox module.', array('@path' => $path)), 'warning');
}
// Set working directory back to the previous working directory.
chdir($olddir);
}

View File

@@ -1,3 +1,8 @@
/**
* @file
* Colorbox module init js.
*/
(function ($) {
Drupal.behaviors.initColorbox = {

View File

@@ -1,3 +1,8 @@
/**
* @file
* Colorbox module admin settings js.
*/
(function ($) {
Drupal.behaviors.initColorboxAdminSettings = {

View File

@@ -1,3 +1,8 @@
/**
* @file
* Colorbox module inline js.
*/
(function ($) {
Drupal.behaviors.initColorboxInline = {

View File

@@ -1,3 +1,7 @@
/**
* @file
* Colorbox module load js.
*/
(function ($) {
Drupal.behaviors.initColorboxLoad = {
@@ -17,7 +21,7 @@ Drupal.behaviors.initColorboxLoad = {
$.urlParams = function (url) {
var p = {},
e,
a = /\+/g, // Regex for replacing addition symbol with a space
a = /\+/g, // Regex for replacing addition symbol with a space.
r = /([^&=]+)=?([^&]*)/g,
d = function (s) { return decodeURIComponent(s.replace(a, ' ')); },
q = url.split('?');

View File

@@ -1,3 +1,8 @@
/**
* @file
* Colorbox module style js.
*/
(function ($) {
Drupal.behaviors.initColorboxDefaultStyle = {

View File

@@ -1,3 +1,8 @@
/**
* @file
* Colorbox module style js.
*/
(function ($) {
Drupal.behaviors.initColorboxPlainStyle = {

View File

@@ -1,3 +1,8 @@
/**
* @file
* Colorbox module style js.
*/
(function ($) {
Drupal.behaviors.initColorboxStockholmsyndromeStyle = {

View File

@@ -6,7 +6,7 @@
*/
/**
* Implementation of hook_views_data()
* Implements hook_views_data()
*/
function colorbox_views_data() {

View File

@@ -67,7 +67,7 @@ If you would like to have the characters %5B and %5D please use the html entity
$patterns .= theme('item_list',
array(
'items' => $items,
'type' => $type
'type' => $type,
));
}
}
@@ -183,11 +183,11 @@ If you would like to have the characters %5B and %5D please use the html entity
'width' => $width,
'height' => $height,
'title' => $caption,
'inline' => 'true'
'inline' => 'true',
),
'attributes' => array(
'class' => array('colorbox-inline'),
'rel' => $gallery_id
'rel' => $gallery_id,
)
);
// Remove any parameters that aren't set.

View File

@@ -1,4 +1,5 @@
INTRODUCTION
------------
The External Links module is a very simple approach to adding icons to links
to external websites or e-mail addresses. It is a purely JavaScript
implementation, so the icons are only shown to users that have JavaScript
@@ -7,8 +8,12 @@ enabled.
External Links was written by Nathan Haug.
Built by Robots: http://www.lullabot.com
Install
-------
REQUIREMENTS
------------
No special requirements.
INSTALLATION
------------
Simply install External Links like you would any other module.
1) Copy the extlink folder to the modules folder in your installation.
@@ -18,7 +23,13 @@ Simply install External Links like you would any other module.
3) No additional configuration is necessary though you may fine-tune settings at
Administer -> Site configuration -> External Links (/admin/settings/extlink).
A note about the CSS
CONFIGURATION
-------------
No additional configuration is necessary though you may fine-tune settings at
Manage -> Configuration -> External Links
(/admin/config/user-interface/extlink).
A NOTE ABOUT THE CSS
--------------------
This module adds a CSS file that is only a few lines in length. You may choose
to move this CSS to your theme to prevent the file from needing to be loaded
@@ -33,3 +44,10 @@ separately. To do this:
Note that you DO NOT need to make a extlink.css file. Specifying the file in the
info file is enough to tell Drupal not to load the original file.
MAINTAINERS
-----------
Current maintainers:
- Lachlan Ennis (elachlan) - https://www.drupal.org/u/elachlan
- Nate Haug (quicksketch) - https://www.drupal.org/u/quicksketch

View File

@@ -15,7 +15,8 @@ span.mailto {
/* Hide the extra spans when printing. */
@media print {
span.ext, span.mailto {
span.ext,
span.mailto {
display: none;
padding: 0;
}

View File

@@ -6,9 +6,8 @@ configure = admin/config/user-interface/extlink
stylesheets[all][] = extlink.css
files[] = extlink.test
; Information added by Drupal.org packaging script on 2014-07-25
version = "7.x-1.18"
; Information added by Drupal.org packaging script on 2018-04-20
version = "7.x-1.20"
core = "7.x"
project = "extlink"
datestamp = "1406278728"
datestamp = "1524215285"

View File

@@ -1,18 +1,40 @@
<?php
/**
* @file
* Install file for External Links module.
*/
/**
* Implements hook_install().
*/
function extlink_install() {
// Weight needs to be 1 for compatibility with SpamSpan.
db_query("UPDATE {system} SET weight = 1 WHERE name = 'extlink'");
db_update('system')
->fields(array('weight' => 1))
->condition('name', 'extlink', '=')
->execute();
}
/**
* Implements hook_uninstall().
*/
function extlink_uninstall() {
db_query("DELETE FROM {variable} WHERE name LIKE 'extlink_%'");
variable_del('extlink_alert');
variable_del('extlink_alert_text');
variable_del('extlink_class');
variable_del('extlink_css_exclude');
variable_del('extlink_css_explicit');
variable_del('extlink_exclude');
variable_del('extlink_icon_placement');
variable_del('extlink_img_class');
variable_del('extlink_include');
variable_del('extlink_label');
variable_del('extlink_mailto_class');
variable_del('extlink_mailto_label');
variable_del('extlink_subdomains');
variable_del('extlink_target');
cache_clear_all('variables', 'cache');
}

View File

@@ -1,161 +1,204 @@
/**
* @file
*/
(function ($) {
Drupal.extlink = Drupal.extlink || {};
Drupal.extlink.attach = function (context, settings) {
if (!settings.hasOwnProperty('extlink')) {
return;
}
// Strip the host name down, removing ports, subdomains, or www.
var pattern = /^(([^\/:]+?\.)*)([^\.:]{4,})((\.[a-z]{1,4})*)(:[0-9]{1,5})?$/;
var host = window.location.host.replace(pattern, '$3$4');
var subdomain = window.location.host.replace(pattern, '$1');
// Determine what subdomains are considered internal.
var subdomains;
if (settings.extlink.extSubdomains) {
subdomains = "([^/]*\\.)?";
}
else if (subdomain == 'www.' || subdomain == '') {
subdomains = "(www\\.)?";
}
else {
subdomains = subdomain.replace(".", "\\.");
}
// Build regular expressions that define an internal link.
var internal_link = new RegExp("^https?://" + subdomains + host, "i");
// Extra internal link matching.
var extInclude = false;
if (settings.extlink.extInclude) {
extInclude = new RegExp(settings.extlink.extInclude.replace(/\\/, '\\'), "i");
}
// Extra external link matching.
var extExclude = false;
if (settings.extlink.extExclude) {
extExclude = new RegExp(settings.extlink.extExclude.replace(/\\/, '\\'), "i");
}
// Extra external link CSS selector exclusion.
var extCssExclude = false;
if (settings.extlink.extCssExclude) {
extCssExclude = settings.extlink.extCssExclude;
}
// Extra external link CSS selector explicit.
var extCssExplicit = false;
if (settings.extlink.extCssExplicit) {
extCssExplicit = settings.extlink.extCssExplicit;
}
// Find all links which are NOT internal and begin with http as opposed
// to ftp://, javascript:, etc. other kinds of links.
// When operating on the 'this' variable, the host has been appended to
// all links by the browser, even local ones.
// In jQuery 1.1 and higher, we'd use a filter method here, but it is not
// available in jQuery 1.0 (Drupal 5 default).
var external_links = new Array();
var mailto_links = new Array();
$("a:not(." + settings.extlink.extClass + ", ." + settings.extlink.mailtoClass + "), area:not(." + settings.extlink.extClass + ", ." + settings.extlink.mailtoClass + ")", context).each(function(el) {
try {
var url = this.href.toLowerCase();
if (url.indexOf('http') == 0
&& ((!url.match(internal_link) && !(extExclude && url.match(extExclude))) || (extInclude && url.match(extInclude)))
&& !(extCssExclude && $(this).parents(extCssExclude).length > 0)
&& !(extCssExplicit && $(this).parents(extCssExplicit).length < 1)) {
external_links.push(this);
}
// Do not include area tags with begin with mailto: (this prohibits
// icons from being added to image-maps).
else if (this.tagName != 'AREA'
&& url.indexOf('mailto:') == 0
&& !(extCssExclude && $(this).parents(extCssExclude).length > 0)
&& !(extCssExplicit && $(this).parents(extCssExplicit).length < 1)) {
mailto_links.push(this);
}
}
// IE7 throws errors often when dealing with irregular links, such as:
// <a href="node/10"></a> Empty tags.
// <a href="http://user:pass@example.com">example</a> User:pass syntax.
catch (error) {
return false;
}
});
if (settings.extlink.extClass) {
Drupal.extlink.applyClassAndSpan(external_links, settings.extlink.extClass);
}
if (settings.extlink.mailtoClass) {
Drupal.extlink.applyClassAndSpan(mailto_links, settings.extlink.mailtoClass);
}
if (settings.extlink.extTarget) {
// Apply the target attribute to all links.
$(external_links).attr('target', settings.extlink.extTarget);
}
'use strict';
Drupal.extlink = Drupal.extlink || {};
// Set up default click function for the external links popup. This should be
// overridden by modules wanting to alter the popup.
Drupal.extlink.popupClickHandler = Drupal.extlink.popupClickHandler || function() {
if (settings.extlink.extAlert) {
return confirm(settings.extlink.extAlertText);
Drupal.extlink.attach = function (context, settings) {
if (!settings.hasOwnProperty('extlink')) {
return;
}
}
$(external_links).click(function(e) {
return Drupal.extlink.popupClickHandler(e);
});
};
// Strip the host name down, removing ports, subdomains, or www.
var pattern = /^(([^\/:]+?\.)*)([^\.:]{1,})((\.[a-z0-9]{1,253})*)(:[0-9]{1,5})?$/;
var host = window.location.host.replace(pattern, '$2$3');
var subdomain = window.location.host.replace(host, '');
/**
* Apply a class and a trailing <span> to all links not containing images.
*
* @param links
* An array of DOM elements representing the links.
* @param class_name
* The class to apply to the links.
*/
Drupal.extlink.applyClassAndSpan = function (links, class_name) {
var $links_to_process;
if (Drupal.settings.extlink.extImgClass){
$links_to_process = $(links);
}
else {
var links_with_images = $(links).find('img').parents('a');
$links_to_process = $(links).not(links_with_images);
}
$links_to_process.addClass(class_name);
var i;
var length = $links_to_process.length;
for (i = 0; i < length; i++) {
var $link = $($links_to_process[i]);
if ($link.css('display') == 'inline' || $link.css('display') == 'inline-block') {
if (class_name == Drupal.settings.extlink.mailtoClass) {
$link.append('<span class="' + class_name + '"><span class="element-invisible"> ' + Drupal.settings.extlink.mailtoLabel + '</span></span>');
// Determine what subdomains are considered internal.
var subdomains;
if (settings.extlink.extSubdomains) {
subdomains = '([^/]*\\.)?';
}
else if (subdomain === 'www.' || subdomain === '') {
subdomains = '(www\\.)?';
}
else {
subdomains = subdomain.replace('.', '\\.');
}
// Build regular expressions that define an internal link.
var internal_link = new RegExp('^https?://([^@]*@)?' + subdomains + host, 'i');
// Extra internal link matching.
var extInclude = false;
if (settings.extlink.extInclude) {
extInclude = new RegExp(settings.extlink.extInclude.replace(/\\/, '\\'), 'i');
}
// Extra external link matching.
var extExclude = false;
if (settings.extlink.extExclude) {
extExclude = new RegExp(settings.extlink.extExclude.replace(/\\/, '\\'), 'i');
}
// Extra external link CSS selector exclusion.
var extCssExclude = false;
if (settings.extlink.extCssExclude) {
extCssExclude = settings.extlink.extCssExclude;
}
// Extra external link CSS selector explicit.
var extCssExplicit = false;
if (settings.extlink.extCssExplicit) {
extCssExplicit = settings.extlink.extCssExplicit;
}
// Define the jQuery method (either 'append' or 'prepend') of placing the icon, defaults to 'append'.
var extIconPlacement = settings.extlink.extIconPlacement || 'append';
// Find all links which are NOT internal and begin with http as opposed
// to ftp://, javascript:, etc. other kinds of links.
// When operating on the 'this' variable, the host has been appended to
// all links by the browser, even local ones.
// In jQuery 1.1 and higher, we'd use a filter method here, but it is not
// available in jQuery 1.0 (Drupal 5 default).
var external_links = [];
var mailto_links = [];
$('a:not(.' + settings.extlink.extClass + ', .' + settings.extlink.mailtoClass + '), area:not(.' + settings.extlink.extClass + ', .' + settings.extlink.mailtoClass + ')', context).each(function (el) {
try {
var url = '';
if (typeof this.href == 'string') {
url = this.href.toLowerCase();
}
// Handle SVG links (xlink:href).
else if (typeof this.href == 'object') {
url = this.href.baseVal;
}
if (url.indexOf('http') === 0
&& ((!url.match(internal_link) && !(extExclude && url.match(extExclude))) || (extInclude && url.match(extInclude)))
&& !(extCssExclude && $(this).is(extCssExclude))
&& !(extCssExclude && $(this).parents(extCssExclude).length > 0)
&& !(extCssExplicit && $(this).parents(extCssExplicit).length < 1)) {
external_links.push(this);
}
// Do not include area tags with begin with mailto: (this prohibits
// icons from being added to image-maps).
else if (this.tagName !== 'AREA'
&& url.indexOf('mailto:') === 0
&& !(extCssExclude && $(this).parents(extCssExclude).length > 0)
&& !(extCssExplicit && $(this).parents(extCssExplicit).length < 1)) {
mailto_links.push(this);
}
}
else {
$link.append('<span class="' + class_name + '"><span class="element-invisible"> ' + Drupal.settings.extlink.extLabel + '</span></span>');
// IE7 throws errors often when dealing with irregular links, such as:
// <a href="node/10"></a> Empty tags.
// <a href="http://user:pass@example.com">example</a> User:pass syntax.
catch (error) {
return false;
}
});
if (settings.extlink.extClass) {
Drupal.extlink.applyClassAndSpan(external_links, settings.extlink.extClass, extIconPlacement);
}
if (settings.extlink.mailtoClass) {
Drupal.extlink.applyClassAndSpan(mailto_links, settings.extlink.mailtoClass, extIconPlacement);
}
if (settings.extlink.extTarget) {
// Apply the target attribute to all links.
$(external_links).attr('target', settings.extlink.extTarget);
// Add rel attributes noopener and noreferrer.
$(external_links).attr('rel', function (i, val) {
// If no rel attribute is present, create one with the values noopener and noreferrer.
if (val == null) {
return 'noopener noreferrer';
}
// Check to see if rel contains noopener or noreferrer. Add what doesn't exist.
if (val.indexOf('noopener') > -1 || val.indexOf('noreferrer') > -1) {
if (val.indexOf('noopener') === -1) {
return val + ' noopener';
}
if (val.indexOf('noreferrer') === -1) {
return val + ' noreferrer';
}
// Both noopener and noreferrer exist. Nothing needs to be added.
else {
return val;
}
}
// Else, append noopener and noreferrer to val.
else {
return val + ' noopener noreferrer';
}
});
}
Drupal.extlink = Drupal.extlink || {};
// Set up default click function for the external links popup. This should be
// overridden by modules wanting to alter the popup.
Drupal.extlink.popupClickHandler = Drupal.extlink.popupClickHandler || function () {
if (settings.extlink.extAlert) {
return confirm(settings.extlink.extAlertText);
}
};
$(external_links).click(function (e) {
return Drupal.extlink.popupClickHandler(e, this);
});
};
/**
* Apply a class and a trailing <span> to all links not containing images.
*
* @param {object[]} links
* An array of DOM elements representing the links.
* @param {string} class_name
* The class to apply to the links.
* @param {string} icon_placement
* 'append' or 'prepend' the icon to the link.
*/
Drupal.extlink.applyClassAndSpan = function (links, class_name, icon_placement) {
var $links_to_process;
if (Drupal.settings.extlink.extImgClass) {
$links_to_process = $(links);
}
else {
var links_with_images = $(links).find('img').parents('a');
$links_to_process = $(links).not(links_with_images);
}
$links_to_process.addClass(class_name);
var i;
var length = $links_to_process.length;
for (i = 0; i < length; i++) {
var $link = $($links_to_process[i]);
if ($link.css('display') === 'inline' || $link.css('display') === 'inline-block') {
if (class_name === Drupal.settings.extlink.mailtoClass) {
$link[icon_placement]('<span class="' + class_name + '" aria-label="' + Drupal.settings.extlink.mailtoLabel + '"></span>');
}
else {
$link[icon_placement]('<span class="' + class_name + '" aria-label="' + Drupal.settings.extlink.extLabel + '"></span>');
}
}
}
}
};
};
Drupal.behaviors.extlink = Drupal.behaviors.extlink || {};
Drupal.behaviors.extlink.attach = function (context, settings) {
// Backwards compatibility, for the benefit of modules overriding extlink
// functionality by defining an "extlinkAttach" global function.
if (typeof extlinkAttach === 'function') {
extlinkAttach(context);
}
else {
Drupal.extlink.attach(context, settings);
}
};
Drupal.behaviors.extlink = Drupal.behaviors.extlink || {};
Drupal.behaviors.extlink.attach = function (context, settings) {
// Backwards compatibility, for the benefit of modules overriding extlink
// functionality by defining an "extlinkAttach" global function.
if (typeof extlinkAttach === 'function') {
extlinkAttach(context);
}
else {
Drupal.extlink.attach(context, settings);
}
};
})(jQuery);

View File

@@ -1,4 +1,22 @@
<?php
/**
* @file
* External Link module.
*/
/**
* Implements hook_help().
*/
function extlink_help($path, $arg) {
switch ($path) {
case 'admin/help#extlink':
$output = '';
$output .= '<p>' . t('External Links is used to differentiate between internal and external links. Using jQuery, it will find all external links on a page and add an external icon indicating it will take you offsite or a mail icon for mailto links.') . '</p>';
return $output;
}
}
/**
* Implements hook_menu().
*/
@@ -20,24 +38,30 @@ function extlink_menu() {
*/
function extlink_page_build() {
$path = drupal_get_path('module', 'extlink');
drupal_add_js($path .'/extlink.js', array('every_page' => TRUE));
drupal_add_js(array('extlink' => array(
'extTarget' => variable_get('extlink_target', 0),
'extClass' => variable_get('extlink_class', 'ext'),
'extLabel' => check_plain(variable_get('extlink_label', t('(link is external)'))),
'extImgClass' => variable_get('extlink_img_class', 0),
'extSubdomains' => variable_get('extlink_subdomains', 1),
'extExclude' => variable_get('extlink_exclude', ''),
'extInclude' => variable_get('extlink_include', ''),
'extCssExclude' => variable_get('extlink_css_exclude', ''),
'extCssExplicit' => variable_get('extlink_css_explicit', ''),
'extAlert' => variable_get('extlink_alert', 0),
'extAlertText' => variable_get('extlink_alert_text', 'This link will take you to an external web site. We are not responsible for their content.'),
'mailtoClass' => variable_get('extlink_mailto_class', 'mailto'),
'mailtoLabel' => check_plain(variable_get('extlink_mailto_label', t('(link sends e-mail)'))),
)), 'setting');
drupal_add_js($path . '/extlink.js', array('every_page' => TRUE));
drupal_add_js(array(
'extlink' => array(
'extTarget' => variable_get('extlink_target', 0),
'extClass' => variable_get('extlink_class', 'ext'),
'extLabel' => check_plain(variable_get('extlink_label', t('(link is external)'))),
'extImgClass' => variable_get('extlink_img_class', 0),
'extIconPlacement' => variable_get('extlink_icon_placement', 'append'),
'extSubdomains' => variable_get('extlink_subdomains', 1),
'extExclude' => variable_get('extlink_exclude', ''),
'extInclude' => variable_get('extlink_include', ''),
'extCssExclude' => variable_get('extlink_css_exclude', ''),
'extCssExplicit' => variable_get('extlink_css_explicit', ''),
'extAlert' => variable_get('extlink_alert', 0),
'extAlertText' => variable_get('extlink_alert_text', 'This link will take you to an external web site. We are not responsible for their content.'),
'mailtoClass' => variable_get('extlink_mailto_class', 'mailto'),
'mailtoLabel' => check_plain(variable_get('extlink_mailto_label', t('(link sends e-mail)'))),
),
), 'setting');
}
/**
* Administrative settings.
*/
function extlink_admin_settings() {
$form = array();
@@ -46,7 +70,15 @@ function extlink_admin_settings() {
'#title' => t('Place an icon next to external links.'),
'#return_value' => 'ext',
'#default_value' => variable_get('extlink_class', 'ext'),
'#description' => t('Places an !icon icon next to external links.', array('!icon' => theme('image', array('path' => drupal_get_path('module', 'extlink') . '/extlink.png', 'alt' => t('External Links icon'))))),
'#description' => t('Places an !icon icon next to external links.',
array(
'!icon' => theme('image',
array(
'path' => drupal_get_path('module', 'extlink') . '/extlink.png',
'alt' => t('External Links icon'),
)
),
)),
);
$form['extlink_mailto_class'] = array(
@@ -54,7 +86,15 @@ function extlink_admin_settings() {
'#title' => t('Place an icon next to mailto links.'),
'#return_value' => 'mailto',
'#default_value' => variable_get('extlink_mailto_class', 'mailto'),
'#description' => t('Places an !icon icon next to mailto links.', array('!icon' => theme('image',array('path' => drupal_get_path('module', 'extlink') . '/mailto.png', 'alt' => t('Email links icon'))))),
'#description' => t('Places an !icon icon next to mailto links.',
array(
'!icon' => theme('image',
array(
'path' => drupal_get_path('module', 'extlink') . '/mailto.png',
'alt' => t('Email links icon'),
)
),
)),
);
$form['extlink_img_class'] = array(
@@ -65,6 +105,14 @@ function extlink_admin_settings() {
'#description' => t('If checked, images wrapped in an anchor tag will be treated as external links.'),
);
$form['extlink_icon_placement'] = array(
'#type' => 'checkbox',
'#title' => t('Add icon in front of any processed link'),
'#return_value' => 'prepend',
'#default_value' => variable_get('extlink_icon_placement', 'append'),
'#description' => t('If checked, the icon will be placed in front of any external link, otherwise it will be placed behind it.'),
);
$form['extlink_subdomains'] = array(
'#type' => 'checkbox',
'#title' => t('Exclude links with the same primary domain.'),
@@ -120,12 +168,9 @@ function extlink_admin_settings() {
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' =>
'<p>' . t('External links uses patterns (regular expressions) to match the "href" property of links.') . '</p>' .
t('Here are some common patterns.') .
theme('item_list', array('items' => $patterns)) .
t('Common special characters:') .
theme('item_list', array('items' => $wildcards)) .
'<p>' . t('All special characters (!characters) must also be escaped with backslashes. Patterns are not case-sensitive. Any <a href="http://www.javascriptkit.com/javatutors/redev2.shtml">pattern supported by JavaScript</a> may be used.', array('!characters' => '<code>^ $ . ? ( ) | * +</code>')) . '</p>',
'<p>' . t('External links uses patterns (regular expressions) to match the "href" property of links.') . '</p>' . t('Here are some common patterns.') .
theme('item_list', array('items' => $patterns)) . t('Common special characters:') .
theme('item_list', array('items' => $wildcards)) . '<p>' . t('All special characters (!characters) must also be escaped with backslashes. Patterns are not case-sensitive. Any <a href="http://www.javascriptkit.com/javatutors/redev2.shtml">pattern supported by JavaScript</a> may be used.', array('!characters' => '<code>^ $ . ? ( ) | * +</code>')) . '</p>',
);
$form['patterns']['extlink_exclude'] = array(
@@ -151,7 +196,7 @@ function extlink_admin_settings() {
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' =>
'<p>' . t('Use CSS selectors to exclude entirely or only look inside explicitly specified classes and IDs for external links. These will be passed straight to jQuery for matching.') . '</p>',
'<p>' . t('Use CSS selectors to exclude entirely or only look inside explicitly specified classes and IDs for external links. These will be passed straight to jQuery for matching.') . '</p>',
);
$form['css_matching']['extlink_css_exclude'] = array(
@@ -173,22 +218,25 @@ function extlink_admin_settings() {
return system_settings_form($form);
}
/**
* Validation handler for admin settings form.
*/
function extlink_admin_settings_validate($form, &$form_state) {
// Check if the exclude pattern is a valid regular expression
// Check if the exclude pattern is a valid regular expression.
if ($exclude = $form_state['values']['extlink_exclude']) {
// Testing the regex via replace
// Testing the regex via replace.
$regexeval = @preg_replace('/' . $exclude . '/', '', 'Lorem ipsum');
// If the regex returns NULL, then throw an error and reset the variable
// If the regex returns NULL, then throw an error and reset the variable.
if ($regexeval === NULL) {
form_set_error('extlink_exclude', t('Invalid regular expression.'));
variable_set('extlink_exclude', '');
}
}
// Check if the include pattern is a valid regular expression
// Check if the include pattern is a valid regular expression.
if ($include = $form_state['values']['extlink_include']) {
// Testing the regex via replace
$regexeval = @preg_replace('/' . $include . '/', '', 'Lorem ipsum');
// If the regex returns NULL, then throw an error and reset the variable
// Testing the regex via replace.
$regexeval = @preg_replace('/' . $include . '/', '', 'Lorem ipsum');
// If the regex returns NULL, then throw an error and reset the variable.
if ($regexeval === NULL) {
form_set_error('extlink_include', t('Invalid regular expression.'));
variable_set('extlink_include', '');

View File

@@ -1,28 +1,39 @@
<?php
/**
* @file
* External Link tests.
*/
/**
* Base class for External Link tests.
*
* Provides common setup stuff and various helper functions
* Provides common setup stuff and various helper functions.
*/
class ExtlinkBaseWebTestCase extends DrupalWebTestCase {
/**
* User with various administrative permissions.
* @var Drupal user
*
* @var Drupaluser
*/
protected $admin_user;
protected $adminUser;
/**
* Normal visitor with limited permissions
* @var Drupal user;
* Normal visitor with limited permissions.
*
* @var Drupaluser
*/
protected $normal_user;
/**
* Drupal path of the (general) External Links admin page
protected $normalUser;
/**
* Drupal path of the (general) External Links admin page.
*/
const EXTLINK_ADMIN_PATH = 'admin/config/user-interface/extlink';
function setUp() {
/**
* Set up tests.
*/
public function setUp() {
// Enable any module that you will need in your tests.
parent::setUp('extlink');
@@ -31,46 +42,25 @@ class ExtlinkBaseWebTestCase extends DrupalWebTestCase {
'access comments', 'post comments', 'skip comment approval',
'access content', 'create page content', 'edit own page content',
);
$this->normal_user = $this->drupalCreateUser($permissions);
$this->normalUser = $this->drupalCreateUser($permissions);
// Create an admin user.
$permissions[] = 'administer site configuration';
$permissions[] = 'administer permissions';
$permissions[] = 'administer content types';
$this->admin_user = $this->drupalCreateUser($permissions);
}
protected function getNodeFormValues() {
$edit = array(
'title' => 'node_title ' . $this->randomName(32),
'body[' . LANGUAGE_NONE . '][0][value]' => 'node_body ' . $this->randomName(256) . ' <a href="http://google.com">Google!</a>',
);
return $edit;
}
/**
* Test if External Link is present
*/
protected function assertExternalLinkPresence() {
$elements = $this->xpath('//span[@class="ext"]');
if (count($elements) > 0)
$this->pass('There should be an External Link on the form.', 'External Links');
else
$this->fail('There should be an External Link on the form.', 'External Links');
}
}
class ExtlinkTestCase extends ExtlinkBaseWebTestCase {
public static function getInfo() {
return array(
'name' => t('General External Links functionality'),
'description' => t('Testing the basic functionality of External Links'),
'group' => t('External Links'),
);
$this->adminUser = $this->drupalCreateUser($permissions);
}
}
/**
* Test Case for External Links administration functionality.
*/
class ExtlinkAdminTestCase extends ExtlinkBaseWebTestCase {
/**
* Get test info.
*/
public static function getInfo() {
return array(
'name' => t('External Links administration functionality'),
@@ -82,16 +72,14 @@ class ExtlinkAdminTestCase extends ExtlinkBaseWebTestCase {
/**
* Test access to the admin pages.
*/
function testAdminAccess() {
$this->drupalLogin($this->normal_user);
public function testAdminAccess() {
$this->drupalLogin($this->normalUser);
$this->drupalGet(self::EXTLINK_ADMIN_PATH);
file_put_contents('tmp.simpletest.html', $this->drupalGetContent());
$this->assertText(t('Access denied'), 'Normal users should not be able to access the External Links admin pages', 'External Links');
$this->drupalLogin($this->admin_user);
$this->drupalLogin($this->adminUser);
$this->drupalGet(self::EXTLINK_ADMIN_PATH);
file_put_contents('tmp.simpletest.html', $this->drupalGetContent());
$this->assertNoText(t('Access denied'), 'Admin users should be able to access the External Links admin pages', 'External Links');
}
}
?>