Permalink
Browse files

feature(embed): adds elgg/embed AMD module

Adds elgg/embed module that is defined as dependency of a menu item.
Deprecates elgg.embed JS library
  • Loading branch information...
hypeJunction committed Apr 13, 2016
1 parent fce63d3 commit 1f1dad12c0ce30ef426893802f46dd1c5f5114e1
@@ -726,6 +726,9 @@ Available hooks
**ajax_response_data, \***
This filters the response data returned to users of the ``elgg/Ajax`` module. See :doc:`ajax` for details.
+**insert, editor**
+ This hook is triggered by the embed plugin and can be used to filter content before it is inserted into the textarea. This hook can also be used by WYSIWYG editors to insert content using their own API (in this case the handler should return ``false``). See ckeditor plugin for an example.
+
Third-party assets
==================
@@ -18,6 +18,7 @@ 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.
+ * ``elgg.embed`` library and ``elgg.embed`` object: Do not use ``elgg_load_js('elgg.embed')``. Use ``elgg/embed`` AMD module instead
* Accessing ``icons_sizes`` config value directly: Use ``elgg_get_icon_sizes()``
* ``can_write_to_container()``: Use ``ElggEntity::canWriteToContainer()``
@@ -28,6 +29,7 @@ Deprecated Views
* ``groups/js`` is deprecated: Use ``groups/navigation`` AMD module as a menu item dependency for "feature" and "unfeature" menu items instead.
* ``lightbox/settings.js`` is deprecated: Use ``getOptions, ui.lightbox`` JS plugin hook or ``data-colorbox-opts`` attribute.
* ``elgg/ckeditor/insert.js`` is deprecated: You no longer need to include it, hook registration takes place in ``elgg/ckeditor`` module
+ * ``embed/embed.js`` is deprecated: Use ``elgg/embed`` AMD module.
Added ``elgg/popup`` module
---------------------------
@@ -39,6 +41,11 @@ Added ``elgg/lightbox`` module
New :doc:`elgg/lightbox module <javascript>` can be used to open and close the lightbox programmatically.
+Added ``elgg/embed`` module
+------------------------------
+
+Even though rarely necessary, ``elgg/embed`` AMD module can be used to access the embed methods programmatically. The module bootstraps itself when necessary and is unlikely to require further decoration.
+
New API for handling entity icons
---------------------------------
View
@@ -22,10 +22,16 @@ function embed_init() {
// Page handler for the modal media embed
elgg_register_page_handler('embed', 'embed_page_handler');
-
+
+ // @deprecated 2.2
$embed_js = elgg_get_simplecache_url('embed/embed.js');
elgg_register_js('elgg.embed', $embed_js, 'footer');
+ if (elgg_view_exists('embed/custom_insert_js')) {
+ elgg_deprecated_notice("The view embed/custom_insert_js has been replaced by the 'embed, editor' JS hook.", '1.9');
+ elgg_extend_view('elgg.js', 'embed/embed_custom_insert.js.php');
+ }
+
elgg_register_plugin_hook_handler('entity:icon:url', 'object', 'embed_set_thumbnail_url', 1000);
}
@@ -49,52 +55,30 @@ function embed_longtext_menu($hook, $type, $items, $vars) {
return;
}
+ $id = elgg_extract('id', $vars);
+ if ($id === null) {
+ return;
+ }
+
$url = 'embed';
$page_owner = elgg_get_page_owner_entity();
if (elgg_instanceof($page_owner, 'group') && $page_owner->isMember()) {
- $url = 'embed?container_guid=' . $page_owner->getGUID();
- }
-
- elgg_require_js('jquery.form');
- elgg_load_js('elgg.embed');
-
- $text = elgg_echo('embed:media');
-
- // if loaded through ajax (like on /activity), pull in JS libs manually
- // hack for #6422 because we haven't converted everything to amd yet
- if (elgg_in_context('ajax')) {
- $externals = $GLOBALS['_ELGG']->externals_map;
- $embed = elgg_extract('elgg.embed', $externals['js']);
- $lightbox_js = elgg_extract('lightbox', $externals['js']);
- $lightbox_css = elgg_extract('lightbox', $externals['css']);
-
- $text .= <<<___JS
-<script>
- require(['jquery.form']);
- if (typeof $.fancybox === 'undefined') {
- $.getScript('$lightbox_js->url');
- $('head').append('<link rel="stylesheet" href="$lightbox_css->url"></link>');
- }
- if (typeof elgg.embed === 'undefined') {
- $.getScript('$embed->url');
- }
-</script>
-___JS;
+ $url = elgg_http_add_url_query_elements($url, [
+ 'container_guid' => $page_owner->guid,
+ ]);
}
$items[] = ElggMenuItem::factory(array(
'name' => 'embed',
- 'href' => 'javascript:void()',
- 'data-colorbox-opts' => json_encode([
- 'href' => elgg_normalize_url($url),
- ]),
- 'text' => $text,
+ 'href' => elgg_normalize_url($url),
+ 'text' => elgg_echo('embed:media'),
'rel' => "embed-lightbox-{$id}",
- 'link_class' => "elgg-longtext-control elgg-lightbox embed-control embed-control-{$id}",
+ 'link_class' => "elgg-longtext-control elgg-lightbox embed-control embed-control-{$id} elgg-lightbox",
+ 'deps' => ['elgg/embed'],
'priority' => 10,
));
-
+
return $items;
}
@@ -131,6 +115,8 @@ function embed_select_tab($hook, $type, $items, $vars) {
*/
function embed_page_handler($page) {
+ elgg_ajax_gatekeeper();
+
$container_guid = (int)get_input('container_guid');
if ($container_guid) {
$container = get_entity($container_guid);
@@ -144,9 +130,7 @@ function embed_page_handler($page) {
set_input('page', $page[1]);
echo elgg_view('embed/layout');
-
- // exit because this is in a modal display.
- exit;
+ return true;
}
/**
@@ -222,4 +206,4 @@ function embed_set_thumbnail_url($hook, $type, $return, $params) {
}
return elgg_get_embed_url($entity, $size);
-}
+}
@@ -0,0 +1,185 @@
+/**
+ * Embed module bootstraps the embed funtionality
+ * Note that this module will initialize itself once elgg/ready module is loaded,
+ * hence you do not need to call elgg/embed#init after requiring elgg/embed module.
+ *
+ * @module elgg/embed
+ */
+define(function (require) {
+
+ var elgg = require('elgg');
+ var $ = require('jquery');
+ var lightbox = require('elgg/lightbox');
+ require('jquery.form');
+
+ elgg.provide('elgg.embed');
+
+ var embed = {
+ /**
+ * Initializes the module
+ * @return void
+ */
+ init: function () {
+
+ // we only need to bind these events once
+ embed.init = elgg.nullFunction;
+
+ // inserts the embed content into the textarea
+ $(document).on('click', ".embed-item", embed.insert);
+ if (typeof elgg.embed._deprecated_custom_insert_js === 'function') {
+ elgg.register_hook_handler('embed', 'editor', elgg.embed._deprecated_custom_insert_js);
+ }
+ // caches the current textarea id
+ $(document).on('click', ".embed-control", function () {
+ var textAreaId = /embed-control-(\S)+/.exec($(this).attr('class'))[0];
+ embed.textAreaId = textAreaId.substr("embed-control-".length);
+ });
+ // special pagination helper for lightbox
+ $(document).on('click', '.embed-wrapper .elgg-pagination a', embed.forward);
+ $(document).on('click', '.embed-section', embed.forward);
+ $(document).on('submit', '.elgg-form-embed', embed.submit);
+ },
+ /**
+ * Inserts data attached to an embed list item in textarea
+ *
+ * @param {Object} event
+ * @return void
+ */
+ insert: function (event) {
+ var textAreaId = embed.textAreaId;
+ var textArea = $('#' + textAreaId);
+ // generalize this based on a css class attached to what should be inserted
+ var content = ' ' + $(this).find(".embed-insert").parent().html() + ' ';
+ var value = textArea.val();
+ var result = textArea.val();
+ // this is a temporary work-around for #3971
+ if (content.indexOf('thumbnail.php') != -1) {
+ content = content.replace('size=small', 'size=medium');
+ }
+
+ textArea.focus();
+ if (!elgg.isNullOrUndefined(textArea.prop('selectionStart'))) {
+ var cursorPos = textArea.prop('selectionStart');
+ var textBefore = value.substring(0, cursorPos);
+ var textAfter = value.substring(cursorPos, value.length);
+ result = textBefore + content + textAfter;
+ } else if (document.selection) {
+ // IE compatibility
+ var sel = document.selection.createRange();
+ sel.text = content;
+ result = textArea.val();
+ }
+
+ // See the ckeditor plugin for an example of this hook
+ result = elgg.trigger_hook('embed', 'editor', {
+ textAreaId: textAreaId,
+ content: content,
+ value: value,
+ event: event
+ }, result);
+ if (result || result === '') {
+ textArea.val(result);
+ }
+
+ lightbox.close();
+ event.preventDefault();
+ },
+ /**
+ * Submit an upload form through Ajax
+ *
+ * Requires the jQuery Form Plugin. Because files cannot be uploaded with
+ * XMLHttpRequest, the plugin uses an invisible iframe. This results in the
+ * the X-Requested-With header not being set. To work around this, we are
+ * sending the header as a POST variable and Elgg's code checks for it in
+ * elgg_is_xhr().
+ *
+ * @param {Object} event
+ * @return bool
+ */
+ submit: function (event) {
+ $('.embed-wrapper .elgg-form-file-upload').hide();
+ $('.embed-throbber').show();
+ $(this).ajaxSubmit({
+ dataType: 'json',
+ data: {'X-Requested-With': 'XMLHttpRequest'},
+ success: function (response, status, xhr) {
+ if (response) {
+ if (response.system_messages) {
+ elgg.register_error(response.system_messages.error);
+ elgg.system_message(response.system_messages.success);
+ }
+ if (response.status >= 0) {
+ var forward = $('input[name=embed_forward]').val();
+ var url = elgg.normalize_url('embed/tab/' + forward);
+ url = embed.addContainerGUID(url);
+ $('.embed-wrapper').parent().load(url);
+ } else {
+ // incorrect response, presumably an error has been displayed
+ $('.embed-throbber').hide();
+ $('.embed-wrapper .elgg-form-file-upload').show();
+ }
+ }
+
+ // ie 7 and 8 have a null response because of the use of an iFrame
+ // so just show the list after upload.
+ // http://jquery.malsup.com/form/#file-upload claims you can wrap JSON
+ // in a textarea, but a quick test didn't work, and that is fairly
+ // intrusive to the rest of the ajax system.
+ else if (response === undefined && $.browser.msie) {
+ var forward = $('input[name=embed_forward]').val();
+ var url = elgg.normalize_url('embed/tab/' + forward);
+ url = embed.addContainerGUID(url);
+ $('.embed-wrapper').parent().load(url);
+ }
+ },
+ error: function (xhr, status) {
+ elgg.register_error(elgg.echo('actiongatekeeper:uploadexceeded'));
+ $('.embed-throbber').hide();
+ $('.embed-wrapper .elgg-form-file-upload').show();
+ }
+ });
+ // this was bubbling up the DOM causing a submission
+ event.preventDefault();
+ event.stopPropagation();
+ },
+ /**
+ * Loads content within the lightbox
+ *
+ * @param {Object} event
+ * @return void
+ */
+ forward: function (event) {
+ // make sure container guid is passed
+ var url = $(this).attr('href');
+ url = embed.addContainerGUID(url);
+ $('.embed-wrapper').parent().load(url);
+ event.preventDefault();
+ },
+ /**
+ * Adds the container guid to a URL
+ *
+ * @param {string} url
+ * @return string
+ */
+ addContainerGUID: function (url) {
+ if (url.indexOf('container_guid=') == -1) {
+ var guid = $('input[name=embed_container_guid]').val();
+ return url + '?container_guid=' + guid;
+ } else {
+ return url;
+ }
+ }
+ };
+
+ /**
+ * elgg.embed object is deprecated. Do not call it directly.
+ * @deprecaated 2.2
+ */
+ elgg.embed = embed;
+
+ require(['elgg/init'], function () {
+ embed.init();
+ });
+
+ return embed;
+});
Oops, something went wrong.

0 comments on commit 1f1dad1

Please sign in to comment.