diff --git a/docs/guides/javascript.rst b/docs/guides/javascript.rst
index 0b324e3dc27..57f50002365 100644
--- a/docs/guides/javascript.rst
+++ b/docs/guides/javascript.rst
@@ -542,6 +542,66 @@ Plugins that load a widget layout via Ajax should initialize via this module:
widgets.init();
});
+Module ``elgg/lightbox``
+------------------------
+
+Elgg is distributed with the Colorbox jQuery library. Please go to http://www.jacklmoore.com/colorbox for more information on the options of this lightbox.
+
+Use the following classes to bind your anchor elements to a lightbox:
+
+ * ``elgg-lightbox`` - loads an HTML resource
+ * ``elgg-lightbox-photo`` - loads an image resource (should be used to avoid displaying raw image bytes instead of an ``img`` tag)
+ * ``elgg-lightbox-inline`` - displays an inline HTML element in a lightbox
+ * ``elgg-lightbox-iframe`` - loads a resource in an ``iframe``
+
+You may apply colorbox options to an individual ``elgg-lightbox`` element by setting the attribute ``data-colorbox-opts`` to a JSON settings object.
+
+.. code:: php
+
+ echo elgg_view('output/url', [
+ 'text' => 'Open lightbox',
+ 'href' => 'ajax/view/my_view',
+ 'class' => 'elgg-lightbox',
+ 'data-colorbox-opts' => json_encode([
+ 'width' => '300px',
+ ])
+ ]);
+
+Use ``"getOptions", "ui.lightbox"`` plugin hook to filter options passed to ``$.colorbox()`` whenever a lightbox is opened. Note that the hook handler should depend on ``elgg/init`` AMD module.
+
+``elgg/lightbox`` AMD module should be used to open and close the lightbox programmatically:
+
+.. code:: js
+
+ define(function(require) {
+ var lightbox = require('elgg/lightbox');
+ var spinner = require('elgg/spinner');
+
+ lightbox.open({
+ html: '
Hello world!
',
+ onClosed: function() {
+ lightbox.open({
+ onLoad: spinner.start,
+ onComplete: spinner.stop,
+ photo: true,
+ href: 'https://elgg.org/cache/1457904417/default/community_theme/graphics/logo.png',
+ });
+ }
+ });
+ });
+
+To support gallery sets (via ``rel`` attribute), you need to bind colorbox directly to a specific selector (note that this will ignore ``data-colorbox-opts`` on all elements in a set):
+
+.. code:: js
+
+ require(['elgg/lightbox'], function(lightbox) {
+ var options = {
+ photo: true,
+ width: 500
+ };
+ lightbox.bind('a[rel="my-gallery"]', options, false); // 3rd attribute ensures binding is done without proxies
+ });
+
Traditional scripts
===================
@@ -639,6 +699,9 @@ Available hooks
**getOptions, ui.popup**
This hook is fired for pop up displays (``"rel"="popup"``) and allows for customized placement options.
+**getOptions, ui.lightbox**
+ This hook can be used to filter options passed to ``$.colorbox()``
+
**config, ckeditor**
This filters the CKEditor config object. Register for this hook in a plugin boot module. The defaults can be seen in the module ``elgg/ckeditor/config``.
diff --git a/docs/guides/upgrading.rst b/docs/guides/upgrading.rst
index 754124ea872..e3afd19c558 100644
--- a/docs/guides/upgrading.rst
+++ b/docs/guides/upgrading.rst
@@ -17,17 +17,25 @@ Deprecated APIs
* ``elgg.ui.river`` JavaScript library: Remove calls to ``elgg_load_js('elgg.ui.river')`` from plugin code. Update ``core/river/filter`` and ``forms/comment/save``, if overwritten, to require component AMD modules
* ``elgg.ui.popupOpen()`` and ``elgg.ui.popupClose()`` methods in ``elgg.ui`` JS library: Use ``elgg/popup`` module instead.
+ * ``lightbox.js`` library: Do not use ``elgg_load_js('lightbox.js');`` unless your code references deprecated ``elgg.ui.lightbox`` namespace. Use ``elgg/lightbox`` AMD module instead.
+ * ``lightbox.css`` library: Lightbox CSS now extends ``elgg.css``. Calls to ``elgg_require_css('lightbox.css')`` have no effect.
Deprecated Views
----------------
* ``elgg/ui.river.js`` is deprecated: Do not rely on simplecache URLs to work.
+ * ``lightbox/settings.js`` is deprecated: Use ``getOptions, ui.lightbox`` JS plugin hook or ``data-colorbox-opts`` attribute.
Added ``elgg/popup`` module
-----------------------------
New :doc:`elgg/popup module ` can be used to build out more complex trigger-popup interactions, including binding custom anchor types and opening/closing popups programmatically.
+Added ``elgg/lightbox`` module
+------------------------------
+
+New :doc:`elgg/lightbox module ` can be used to open and close the lightbox programmatically.
+
From 2.0 to 2.1
===============
diff --git a/engine/lib/views.php b/engine/lib/views.php
index 6e9386761cf..8ebd5ce852e 100644
--- a/engine/lib/views.php
+++ b/engine/lib/views.php
@@ -1688,9 +1688,10 @@ function elgg_views_boot() {
elgg_register_simplecache_view('elgg/init.js');
- // optional stuff
+ elgg_extend_view('elgg.css', 'colorbox.css');
+
+ // provide warning to use elgg/lightbox AMD
elgg_register_js('lightbox', elgg_get_simplecache_url('lightbox.js'));
- elgg_register_css('lightbox', elgg_get_simplecache_url('lightbox/elgg-colorbox-theme/colorbox.css'));
// just provides warning to use elgg/autocomplete AMD
elgg_register_js('elgg.autocomplete', elgg_normalize_url('js/lib/ui.autocomplete.js'));
diff --git a/engine/views.php b/engine/views.php
index bebe6873af7..1dbcccc2eff 100644
--- a/engine/views.php
+++ b/engine/views.php
@@ -42,5 +42,8 @@
"jquery.jeditable.js" => dirname(__DIR__) . "/bower_components/jquery-jeditable/jquery.jeditable.js",
"jquery.ui.autocomplete.html.js" => dirname(__DIR__) . "/bower_components/jquery-ui-extensions/src/autocomplete/jquery.ui.autocomplete.html.js",
"sprintf.js" => dirname(__DIR__) . "/bower_components/sprintf/src/sprintf.js",
+
+ 'colorbox.css' => dirname(__DIR__) . "/views/default/lightbox/elgg-colorbox-theme/colorbox.css",
+ 'colorbox-images/' => dirname(__DIR__) . "/views/default/lightbox/elgg-colorbox-theme/colorbox-images/",
],
];
diff --git a/js/lib/elgglib.js b/js/lib/elgglib.js
index 14625eab90b..e90552b88bf 100644
--- a/js/lib/elgglib.js
+++ b/js/lib/elgglib.js
@@ -403,7 +403,7 @@ elgg.register_error = function(errors, delay) {
/**
* Logs a notice about use of a deprecated function or capability
* @param {String} msg The deprecation message to display
- * @param {Number} dep_version The version the function was deprecated for
+ * @param {String} dep_version The version the function was deprecated for
* @since 1.9
*/
elgg.deprecated_notice = function(msg, dep_version) {
diff --git a/mod/developers/start.php b/mod/developers/start.php
index 0a99e838272..c1d3452f109 100644
--- a/mod/developers/start.php
+++ b/mod/developers/start.php
@@ -68,8 +68,6 @@ function developers_process_settings() {
if (!empty($settings['show_gear']) && elgg_is_admin_logged_in() && !elgg_in_context('admin')) {
elgg_require_js('elgg/dev/gear');
- elgg_load_js('lightbox');
- elgg_load_css('lightbox');
elgg_register_ajax_view('developers/gear_popup');
elgg_register_simplecache_view('elgg/dev/gear.html');
diff --git a/mod/developers/views/default/elgg/dev/gear.js b/mod/developers/views/default/elgg/dev/gear.js
index a6d17ebb248..90cc6a5c7bb 100644
--- a/mod/developers/views/default/elgg/dev/gear.js
+++ b/mod/developers/views/default/elgg/dev/gear.js
@@ -6,6 +6,7 @@ define(function (require) {
var elgg = require('elgg');
var spinner = require('elgg/spinner');
var gear_html = require('text!elgg/dev/gear.html');
+ require('elgg/lightbox');
$(gear_html)
.appendTo('body')
diff --git a/mod/developers/views/default/theme_sandbox/javascript/lightbox.js b/mod/developers/views/default/theme_sandbox/javascript/lightbox.js
new file mode 100644
index 00000000000..cb5dbf79bc1
--- /dev/null
+++ b/mod/developers/views/default/theme_sandbox/javascript/lightbox.js
@@ -0,0 +1,8 @@
+define(function(require) {
+ var lightbox = require('elgg/lightbox');
+ var opts = {
+ photo: true,
+ width: 600
+ };
+ lightbox.bind('[rel="lightbox-gallery"]', opts, false);
+});
\ No newline at end of file
diff --git a/mod/developers/views/default/theme_sandbox/javascript/lightbox.php b/mod/developers/views/default/theme_sandbox/javascript/lightbox.php
index 1832e730466..2abbd724ff9 100644
--- a/mod/developers/views/default/theme_sandbox/javascript/lightbox.php
+++ b/mod/developers/views/default/theme_sandbox/javascript/lightbox.php
@@ -1,12 +1,72 @@
'Open lighbox',
'href' => "ajax/view/developers/ajax",
'class' => 'elgg-lightbox'
));
-echo $link;
+echo elgg_view('output/url', array(
+ 'text' => 'Open iframe lightbox',
+ 'href' => 'https://elgg.org',
+ 'class' => 'elgg-lightbox-iframe mll',
+ 'data-colorbox-opts' => json_encode([
+ 'width' => '80%',
+ 'height' => '80%',
+ ]),
+));
+
+echo elgg_view('output/url', array(
+ 'text' => 'Open inline HTML lightbox',
+ 'href' => '#lightbox-inline',
+ 'class' => 'elgg-lightbox-inline mll',
+));
+?>
+
+
+ = elgg_view('developers/ipsum') ?>
+
+
+ 'object',
+ 'subtypes' => 'file',
+ 'metadata_name_value_paris' => [
+ 'name' => 'simpletype',
+ 'value' => 'image',
+ ],
+ ));
+
+if (!$files) {
+ return;
+}
+
+elgg_require_js('theme_sandbox/javascript/lightbox');
+
+echo elgg_view('output/url', array(
+ 'text' => 'Open photo lightbox',
+ 'href' => elgg_get_download_url($files[0]),
+ 'class' => 'elgg-lightbox-photo mll',
+));
+?>
+
+
+ -
+ elgg_view('output/img', array(
+ 'src' => $file->getIconURL('small'),
+ 'alt' => $file->getDisplayName(),
+ )),
+ 'href' => $file->getIconURL('large'),
+ 'rel' => 'lightbox-gallery',
+ ));
+ ?>
+
+
+
+
diff --git a/mod/embed/start.php b/mod/embed/start.php
index 160f8388ce6..67673bc1ee0 100644
--- a/mod/embed/start.php
+++ b/mod/embed/start.php
@@ -49,8 +49,6 @@ function embed_longtext_menu($hook, $type, $items, $vars) {
$url = 'embed?container_guid=' . $page_owner->getGUID();
}
- elgg_load_js('lightbox');
- elgg_load_css('lightbox');
elgg_require_js('jquery.form');
elgg_load_js('elgg.embed');
diff --git a/mod/embed/views/default/embed/embed.js.php b/mod/embed/views/default/embed/embed.js.php
index f6326d9d45e..a3b7b4e8439 100644
--- a/mod/embed/views/default/embed/embed.js.php
+++ b/mod/embed/views/default/embed/embed.js.php
@@ -91,7 +91,9 @@
textArea.val(result);
}
- elgg.ui.lightbox.close();
+ require(['elgg/lightbox'], function(lightbox) {
+ lightbox.close();
+ });
event.preventDefault();
};
diff --git a/mod/file/views/default/file/specialcontent/image/default.php b/mod/file/views/default/file/specialcontent/image/default.php
index 7037d600973..4cc852f6ded 100644
--- a/mod/file/views/default/file/specialcontent/image/default.php
+++ b/mod/file/views/default/file/specialcontent/image/default.php
@@ -12,8 +12,6 @@
$download_url = elgg_get_download_url($file);
if ($vars['full_view']) {
- elgg_load_js('lightbox');
- elgg_load_css('lightbox');
echo <<
diff --git a/mod/likes/views/default/likes/count.php b/mod/likes/views/default/likes/count.php
index 2105b8d44a3..a45f90b8d26 100644
--- a/mod/likes/views/default/likes/count.php
+++ b/mod/likes/views/default/likes/count.php
@@ -8,9 +8,6 @@
$num_of_likes = \Elgg\Likes\DataService::instance()->getNumLikes($vars['entity']);
$guid = $vars['entity']->guid;
-elgg_load_js('lightbox');
-elgg_load_css('lightbox');
-
// display the number of likes
if ($num_of_likes == 1) {
$likes_string = elgg_echo('likes:userlikedthis', array($num_of_likes));
diff --git a/mod/reportedcontent/views/default/elgg/reportedcontent.js b/mod/reportedcontent/views/default/elgg/reportedcontent.js
index e5f6848a542..ceb2e1700d5 100644
--- a/mod/reportedcontent/views/default/elgg/reportedcontent.js
+++ b/mod/reportedcontent/views/default/elgg/reportedcontent.js
@@ -16,7 +16,9 @@ define(function (require) {
data: $form.serialize(),
success: function (data) {
if (data.status == 0) {
- elgg.ui.lightbox.close();
+ require(['elgg/lightbox'], function(lightbox) {
+ lightbox.close();
+ });
}
}
});
@@ -24,7 +26,9 @@ define(function (require) {
$(document).on('click', '.elgg-form-reportedcontent-add .elgg-button-cancel', function (e) {
if ($(this).is('#colorbox *')) {
- elgg.ui.lightbox.close();
+ require(['elgg/lightbox'], function(lightbox) {
+ lightbox.close();
+ });
} else {
if (history.length > 1) {
history.go(-1);
diff --git a/views/default/admin/plugins.php b/views/default/admin/plugins.php
index f18b1601e8b..0cbcb558d82 100644
--- a/views/default/admin/plugins.php
+++ b/views/default/admin/plugins.php
@@ -8,9 +8,6 @@
* @subpackage Admin.Plugins
*/
-elgg_load_js('lightbox');
-elgg_load_css('lightbox');
-
// @todo this should occur in the controller code
_elgg_generate_plugin_entities();
diff --git a/views/default/elgg.js.php b/views/default/elgg.js.php
index 18cff3995e4..84e9bd97b2c 100644
--- a/views/default/elgg.js.php
+++ b/views/default/elgg.js.php
@@ -2,8 +2,6 @@
/**
* Core Elgg JavaScript file
*/
-
-use Elgg\Filesystem\Directory;
global $CONFIG;
@@ -25,9 +23,10 @@
// @todo: remove in 3.x and use async calls
echo elgg_view('elgg/widgets.js');
-// We use a named AMD module and inine it here in order to save HTTP requests,
-// as this module will be required on each page
+// We use named AMD modules and inine them here in order to save HTTP requests,
+// as these modules will be required on each page
echo elgg_view('elgg/popup.js');
+echo elgg_view('elgg/lightbox.js');
$elggDir = \Elgg\Application::elggDir();
$files = array(
@@ -110,4 +109,21 @@
elgg.trigger_hook('boot', 'system');
-require(['elgg/init', 'elgg/ready']);
\ No newline at end of file
+require(['elgg/init', 'elgg/ready']);
+
+
+ require(['elgg'], function(elgg) {
+ elgg.provide('elgg.ui.lightbox');
+ = elgg_view('lightbox/settings.js') ?>
+ });
+
+
+// we inline this in 2.x because both elgg/lightbox and the legacy lightbox.js library use it
+// and legacy code assumes that lightbox.js loads the library synchronously.
+= elgg_view('jquery.colorbox.js'); ?>
diff --git a/views/default/elgg/lightbox.js b/views/default/elgg/lightbox.js
new file mode 100644
index 00000000000..b2a231d970c
--- /dev/null
+++ b/views/default/elgg/lightbox.js
@@ -0,0 +1,126 @@
+/**
+ * Lightbox module
+ * We use a named module and inline it in elgg.js. This allows us to deprecate the old
+ * elgg.ui.lightbox library.
+ *
+ * @module elgg/lightbox
+ */
+define('elgg/lightbox', function (require) {
+
+ var elgg = require('elgg');
+ var $ = require('jquery');
+ require('elgg/init');
+ // TODO in 3.0 depend on "jquery.colorbox"
+
+ var lightbox = {
+
+ /**
+ * Returns lightbox settings
+ *
+ * @param {Object} opts Additional options
+ * @return {Object}
+ */
+ getOptions: function (opts) {
+ if (!$.isPlainObject(opts)) {
+ opts = {};
+ }
+
+ // Note: keep these in sync with /views/default/lightbox.js.php
+ var settings = {
+ current: elgg.echo('js:lightbox:current', ['{current}', '{total}']),
+ previous: elgg.echo('previous'),
+ next: elgg.echo('next'),
+ close: elgg.echo('close'),
+ xhrError: elgg.echo('error:default'),
+ imgError: elgg.echo('error:default'),
+ opacity: 0.5,
+ maxWidth: '100%',
+ // don't move colorbox on small viewports https://github.com/Elgg/Elgg/issues/5312
+ reposition: $(window).height() > 600
+ };
+
+ elgg.provide('elgg.ui.lightbox');
+
+ if ($.isPlainObject(elgg.ui.lightbox.deprecated_settings)) {
+ $.extend(settings, elgg.ui.lightbox.deprecated_settings, opts);
+ } else {
+ $.extend(settings, opts);
+ }
+
+ return elgg.trigger_hook('getOptions', 'ui.lightbox', null, settings);
+ },
+
+ /**
+ * Bind colorbox lightbox click to HTML
+ *
+ * @param {Object} selector CSS selector matching colorbox openers
+ * @param {Object} opts Colorbox options. These are overridden by data-colorbox-opts options
+ * @param {Boolean} use_element_data If set to false, selector will be bound directly as `$(selector).colorbox()`
+ * @return void
+ */
+ bind: function (selector, opts, use_element_data) {
+ if (!$.isPlainObject(opts)) {
+ opts = {};
+ }
+
+ //console.log(use_element_data);
+
+ // Allow direct binding to allow grouping by rel attribute
+ if (use_element_data === false) {
+ $(selector).colorbox(lightbox.getOptions(opts));
+ return;
+ }
+
+ $(document)
+ .off('click.lightbox', selector)
+ .on('click.lightbox', selector, function (e) {
+ e.preventDefault();
+ var $this = $(this),
+ href = $this.prop('href') || $this.prop('src'),
+ // Note: data-colorbox was reserved https://github.com/jackmoore/colorbox/issues/435
+ dataOpts = $this.data('colorboxOpts');
+
+ if (!$.isPlainObject(dataOpts)) {
+ dataOpts = {};
+ }
+
+ if (!dataOpts.href && href) {
+ dataOpts.href = href;
+ }
+
+ // merge data- options into opts
+ $.extend(opts, dataOpts);
+ if (opts.inline && opts.href) {
+ opts.href = elgg.getSelectorFromUrlFragment(opts.href);
+ }
+
+ lightbox.open(opts);
+ });
+ },
+
+ /**
+ * Open the colorbox
+ *
+ * @param {object} opts Colorbox options
+ * @return void
+ */
+ open: function (opts) {
+ $.colorbox(lightbox.getOptions(opts));
+ },
+
+ /**
+ * Close the colorbox
+ * @return void
+ */
+ close: function () {
+ $.colorbox.close();
+ }
+ };
+
+ lightbox.bind(".elgg-lightbox");
+ lightbox.bind(".elgg-lightbox-photo", {photo: true});
+ lightbox.bind(".elgg-lightbox-inline", {inline: true});
+ lightbox.bind(".elgg-lightbox-iframe", {iframe: true});
+
+ return lightbox;
+});
\ No newline at end of file
diff --git a/views/default/lightbox.js.php b/views/default/lightbox.js.php
index fcf9a8dbbe8..b0458259ac0 100644
--- a/views/default/lightbox.js.php
+++ b/views/default/lightbox.js.php
@@ -2,23 +2,16 @@
/**
* Elgg lightbox
*
- * Usage
- * ---------------
- * Call elgg_load_js('lightbox') and elgg_load_css('lightbox').
- * Then apply the class elgg-lightbox to links.
- *
- *
- * Advanced Usage
- * -----------------
* Elgg is distributed with the Colorbox jQuery library. Please go to
* http://www.jacklmoore.com/colorbox for more information on the options of this lightbox.
*
- * You can change global options by overriding the js/lightbox/settings view.
+ * Use .elgg-lightbox or .elgg-lightbox-photo class on your anchor element to
+ * bind it to a lightbox.
*
* You may apply colorbox options to an individual .elgg-lightbox element
- * by setting the attribute data-colorbox-opts to a JSON settings object. You
- * can also set options in the elgg.ui.lightbox.bind() method, but data
- * attributes will take precedence.
+ * by setting the attribute data-colorbox-opts to a JSON settings object.
+ * You can use "getOptions", "ui.lightbox" plugin hook to filter options before
+ * they are passed to $.colorbox().
*
* To support a hidden div as the source, add "inline: true" as a
* data-colorbox-opts option. For example, using the output/url view, add:
@@ -29,30 +22,104 @@
* -------------------------------------
* In a plugin, override this view and override the registration for the
* lightbox JavaScript and CSS (@see elgg_views_boot()).
+ *
+ * @deprecated 2.2
*/
-
?>
//