Index: inline.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/inline/inline.module,v retrieving revision 1.35 diff -u -p -r1.35 inline.module --- inline.module 28 Jan 2009 21:43:05 -0000 1.35 +++ inline.module 1 Feb 2009 10:35:10 -0000 @@ -14,6 +14,31 @@ function inline_perm() { } /** + * Implementation of hook_inline_info(). + * + * @return + * An associative array of inline tags provided by this module, keyed by tag + * name with the following properties: + * - callback: (optional) The inline callback function name. Defaults to + * MODULENAME_TAGNAME_inline(). + * - file: (optional) The include file where callback function resides. + * - path: (optional) The path of the include file. Defaults to the module's + * directory. + */ +function inline_inline_info() { + $info = array(); + $info['node'] = array( + 'file' => 'inline.node.inc', + ); + if (module_exists('upload')) { + $info['upload'] = array( + 'file' => 'inline.upload.inc', + ); + } + return $info; +} + +/** * @defgroup inline_macro Inline input filter/macro parsing * @{ */ @@ -53,16 +78,48 @@ function inline_filter($op, $delta = 0, } /** + * Invoke a hook_inline() implementation. + */ +function inline_invoke($params, $op) { + if (!function_exists($params['callback'])) { + if (isset($params['file'])) { + if (!isset($params['path'])) { + $params['path'] = drupal_get_path('module', $params['module']); + } + require_once $params['path'] . '/' . $params['file']; + } + } + if (function_exists($params['callback'])) { + $args = func_get_args(); + array_shift($args); + return call_user_func_array($params['callback'], $args); + } +} + +/** * Return all inline macros as an array. */ function inline_get_macros($text) { $macros = array(); // Collect possible inline tag names. - // @todo Use module_invoke_all() to allow more than one Inline implementation - // per module, and allow to configure which Inline implementations should - // be enabled per filter format. - $tagnames = '('. implode('|', module_implements('inline')) .')'; + $implementations = array(); + foreach (module_implements('inline_info') as $module) { + $module_tags = module_invoke($module, 'inline_info'); + if (!is_array($module_tags)) { + continue; + } + foreach ($module_tags as $tag => $info) { + $module_tags[$tag]['module'] = $module; + $module_tags[$tag]['tag'] = $tag; + if (!isset($info['callback'])) { + $module_tags[$tag]['callback'] = $module . '_' . $tag . '_inline'; + } + } + $implementations = array_merge($implementations, $module_tags); + } + + $tagnames = '('. implode('|', array_keys($implementations)) .')'; // @todo Add support for escaped [, ] chars preg_match_all('@\['. $tagnames .'\s*\|([^\[\]]+)\]@', $text, $matches); // Don't process duplicates. @@ -71,11 +128,10 @@ function inline_get_macros($text) { foreach ($tags as $n => $macro) { // @todo Add support for escaped | char $macro_params = array_map('trim', explode('|', $macro)); - $params = array(); - $params['module'] = $matches[1][$n]; + $params = $implementations[$matches[1][$n]]; // @todo Add a macro counter for each found tag *per module* to allow stuff // like odd/even classes (f.e. $params['#count']). - $args = module_invoke($params['module'], 'inline', 'args'); + $args = inline_invoke($params, 'args'); foreach ($macro_params as $param) { list($key, $value) = explode('=', $param, 2); $key = trim($key); @@ -95,14 +151,14 @@ function inline_get_macros($text) { $value = (bool)$value; } // Stack multiple occurences. - if (isset($params[$key]) && isset($args[$key]['#multiple']) && $args[$key]['#multiple']) { - if (!is_array($params[$key])) { - $params[$key] = array($params[$key]); + if (isset($params['params'][$key]) && isset($args[$key]['#multiple']) && $args[$key]['#multiple']) { + if (!is_array($params['params'][$key])) { + $params['params'][$key] = array($params['params'][$key]); } - $params[$key][] = $value; + $params['params'][$key][] = $value; } else { - $params[$key] = $value; + $params['params'][$key] = $value; } } // The full unaltered tag is the key for the filter attributes array. @@ -122,28 +178,22 @@ function inline_get_macros($text) { * Whether the supplied input is valid (TRUE) or not (FALSE). */ function inline_validate_params($params) { - // Return if no module has been supplied or module does not implement - // hook_inline(). - if (!isset($params['module']) || !module_hook($params['module'], 'inline')) { - return FALSE; - } - // Perform basic validation of tag arguments. - $args = module_invoke($params['module'], 'inline', 'args'); + $args = inline_invoke($params, 'args'); foreach ($args as $arg => $info) { // Check if required arguments are set. - if (isset($info['#required']) && $info['#required'] && !isset($info['#default_value']) && (!isset($params[$arg]) || $params[$arg] === '')) { + if (isset($info['#required']) && $info['#required'] && !isset($info['#default_value']) && (!isset($params['params'][$arg]) || $params['params'][$arg] === '')) { return t('Missing argument %arg.', array('%arg' => $arg)); } - if (isset($params[$arg])) { + if (isset($params['params'][$arg])) { // Keep only the first value if multiple flag is not set. - if ((!isset($info['#multiple']) || !$info['#multiple']) && is_array($params[$arg])) { - $params[$arg] = $params[$arg][0]; + if ((!isset($info['#multiple']) || !$info['#multiple']) && is_array($params['params'][$arg])) { + $params['params'][$arg] = $params['params'][$arg][0]; } // Check if supplied arguments are of an expected type. if (isset($info['#type'])) { $typecheck = 'is_'. $info['#type']; - if (!function_exists($typecheck) || !$typecheck($params[$arg])) { + if (!function_exists($typecheck) || !$typecheck($params['params'][$arg])) { return t('Wrong value type supplied for argument %arg.', array('%arg' => $arg)); } } @@ -151,7 +201,7 @@ function inline_validate_params($params) } // Extended validation check by given module. - $module_validation = module_invoke($params['module'], 'inline', 'validate', $params); + $module_validation = inline_invoke($params, 'validate', $params['params']); if (isset($module_validation) && !$module_validation) { return FALSE; } @@ -170,22 +220,22 @@ function inline_validate_params($params) */ function inline_render($params) { // Merge in default values. - $args = module_invoke($params['module'], 'inline', 'args'); + $args = inline_invoke($params, 'args'); foreach ($args as $arg => $info) { - if (empty($params[$arg])) { + if (empty($params['params'][$arg])) { // @todo Allow special defaults like 'current user' or 'current node'. - $params[$arg] = $info['#default_value']; + $params['params'][$arg] = $info['#default_value']; } } // Allow module to prepare tag parameters. - $params = module_invoke($params['module'], 'inline', 'prepare', $params); + $params['params'] = inline_invoke($params, 'prepare', $params['params']); // @todo Prepare operation may not be successful; final validation before // rendering required. // Generate a rendered representation for tag replacement. - $output = module_invoke($params['module'], 'inline', 'render', $params); + $output = inline_invoke($params, 'render', $params['params']); // If an error occured during rendering, we expect the result to be FALSE. if (!is_bool($output)) { @@ -266,8 +316,8 @@ function _inline_alter_macros(&$node, $f // @todo Assign the currently processed field name to $params['#field'] to // allow certain hook_inline implementations to add/ensure this // information in their macros. - if (isset($params['nid']) && $params['nid'] == 0) { - $params['nid'] = $node->nid; + if (isset($params['params']['nid']) && $params['params']['nid'] == 0) { + $params['params']['nid'] = $node->nid; $content = str_replace($macro, inline_build_macro($params), $content); // @todo Update of reference table perhaps needed. } @@ -286,13 +336,10 @@ function _inline_alter_macros(&$node, $f function inline_build_macro($params) { $macro_params = array(); - if (isset($params['module'])) { - $macro_params[] = $params['module']; - unset($params['module']); - } + $macro_params[] = $params['tag']; // @todo Support for #multiple values. // @todo Escape |, [, ] chars in values. - foreach ($params as $key => $value) { + foreach ($params['params'] as $key => $value) { $macro_params[] = $key .'='. $value; } return '['. implode('|', $macro_params) .']'; @@ -437,3 +484,13 @@ function inline_filter_tips($delta, $for * @} End of "defgroup inline_help". */ +/** + * Implementation of hook_wysiwyg_include_directory(). + */ +function inline_wysiwyg_include_directory($type) { + switch ($type) { + case 'plugins': + return $type; + } +} + Index: inline.node.inc =================================================================== RCS file: inline.node.inc diff -N inline.node.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ inline.node.inc 27 Jan 2009 00:56:51 -0000 @@ -0,0 +1,55 @@ + array( + '#title' => t('Node id'), + '#description' => t('A node id to embed.'), + '#type' => 'int', + '#default_value' => 0, + ), + ); + return $args; + + case 'validate': + // Custom validation of user supplied values. + return TRUE; + + case 'prepare': + // Load a node object if valid nid is given. + if ($params['nid'] > 0) { + $node = node_load($params['nid']); + if (node_access('view', $node)) { + $params['#node'] = $node; + } + } + return $params; + + case 'render': + // Return a rendered representation to replace a tag. + if (!isset($params['#node'])) { + return; + } + $node = node_build_content($params['#node'], FALSE, TRUE); + $output = drupal_render($node->content); + return $output; + } +} + Index: plugins/dialog.js =================================================================== RCS file: plugins/dialog.js diff -N plugins/dialog.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ plugins/dialog.js 27 Jan 2009 00:19:15 -0000 @@ -0,0 +1,19 @@ +// $Id$ + +Drupal.behaviors.inlineNodeDialog = function (context) { + var target = window.opener || window.parent; + $('form input[type=submit]', context).click(function () { + var settings = {}; + settings.nid = this.form.nid.value; + // Insert into currently attached editor. + target.Drupal.wysiwyg.instances[Drupal.settings.instance].insert(target.Drupal.wysiwyg.plugins.inline_node.insert(settings)); + // Close this dialog. + target.Drupal.wysiwyg.instances[Drupal.settings.instance].closeDialog(window); + return false; + }); + $('a.form-cancel', context).click(function () { + // Close this dialog. + target.Drupal.wysiwyg.instances[Drupal.settings.instance].closeDialog(window); + return false; + }); +} Index: plugins/node.inc =================================================================== RCS file: plugins/node.inc diff -N plugins/node.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ plugins/node.inc 27 Jan 2009 00:20:08 -0000 @@ -0,0 +1,58 @@ + t('Inline node'), + 'vendor url' => 'http://drupal.org/project/inline', + 'icon file' => 'inline_node.gif', + 'icon title' => t('Insert or update an embedded content'), + 'settings' => array( + 'dialog' => array( + 'url' => base_path() . 'index.php?q=wysiwyg/inline_node', + 'width' => 700, + 'height' => 500, + ), + ), + // @todo Use a more granular way to validate contents for input formats. + #'extended_valid_elements' => array('img[class|src|border=0|alt|title|width|height|align|name|style]'), + ); + return $plugins; +} + +function inline_node_wysiwyg_dialog($instance) { + drupal_set_title(t('Add or edit external content')); + + // Add dialog JavaScript. + drupal_add_js(drupal_get_path('module', 'inline') . '/plugins/dialog.js'); + + $output = drupal_get_form('inline_node_wysiwyg_dialog_form', $instance); + return $output; +} + +function inline_node_wysiwyg_dialog_form(&$form_state, $instance) { + $form['nid'] = array( + '#type' => 'select', + '#title' => t('Content to embed'), + '#options' => array( + 1 => 'foo bar', + ), + '#description' => t('The selected content will be inserted and embedded into your content.'), + ); + $form['submit'] = array( + '#prefix' => '