Commit 00e6642e authored by TwoD's avatar TwoD

Added support for JavaScript Function references and Regular Expressions in settings.

parent 4e43dbe1
......@@ -62,6 +62,12 @@ function hook_wysiwyg_plugin($editor, $version) {
'options' => array(
'file_browser_callback' => 'imceImageBrowser',
'inline_styles' => TRUE,
// Function references (callbacks) need special care.
// @see wysiwyg_wrap_js_callback()
'file_browser_callback' => wysiwyg_wrap_js_callback('myFileBrowserCallback'),
// Regular Expressions need special care.
// @see wysiwyg_wrap_js_regexp()
'stylesheetParser_skipSelectors' => wysiwyg_wrap_js_regexp('(^body\.|^caption\.|\.high|^\.)', 'i'),
),
// Boolean whether the editor needs to load this plugin. When TRUE,
// the editor will automatically load the plugin based on the 'path'
......@@ -156,6 +162,12 @@ function hook_INCLUDE_plugin() {
'css file' => 'awesome.css',
// An array of settings for this button. Required, but API is still in flux.
'settings' => array(
// Function references (callbacks) need special care.
// @see wysiwyg_wrap_js_callback()
'file_browser_callback' => wysiwyg_wrap_js_callback('myFileBrowserCallback'),
// Regular Expressions need special care.
// @see wysiwyg_wrap_js_regexp()
'stylesheetParser_skipSelectors' => wysiwyg_wrap_js_regexp('(^body\.|^caption\.|\.high|^\.)', 'i'),
),
// TinyMCE-specific: Additional HTML elements to allow in the markup.
'extended_valid_elements' => array(
......
......@@ -223,6 +223,105 @@ Drupal.wysiwyg.getParams = function(element, params) {
return params;
};
/**
* Convert JSON type placeholders into the actual types.
*
* Recognizes function references (callbacks) and Regular Expressions.
*
* To create a callback, pass in an object with the following properties:
* - 'drupalWysiwygType': Must be set to 'callback'.
* - 'name': A string with the name of the callback, use
* 'object.subobject.method' syntax for methods in nested objects.
* - 'context': An optional string with the name of an object for overriding
* 'this' inside the function. Use 'object.subobject' syntax for nested
* objects. Defaults to the window object.
*
* To create a RegExp, pass in an object with the following properties:
* - 'drupalWysiwygType: Must be set to 'regexp'.
* - 'regexp': The Regular Expression as a string, without / wrappers.
* - 'modifiers': An optional string with modifiers to set on the RegExp object.
*
* @param json
* The json argument with all recognized type placeholders replaced by the real
* types.
*
* @return The JSON object with placeholder types replaced.
*/
function processObjectTypes(json) {
var out = null;
if (typeof json != 'object') {
return json;
}
out = new json.constructor();
if (json.drupalWysiwygType) {
switch (json.drupalWysiwygType) {
case 'callback':
out = callbackWrapper(json.name, json.context);
break;
case 'regexp':
out = new RegExp(json.regexp, json.modifiers ? json.modifiers : undefined);
break;
default:
out.drupalWysiwygType = json.drupalWysiwygType;
}
}
else {
for (var i in json) {
if (json.hasOwnProperty(i) && json[i] && typeof json[i] == 'object') {
out[i] = processObjectTypes(json[i]);
}
else {
out[i] = json[i];
}
}
}
return out;
}
/**
* Convert function names into function references.
*
* @param name
* The name of a function to use as callback. Use the 'object.subobject.method'
* syntax for methods in nested objects.
* @param context
* An optional string with the name of an object for overriding 'this' inside
* the function. Use 'object.subobject' syntax for nested objects. Defaults to
* the window object.
*
* @return
* A function which will call the named function or method in the proper
* context, passing through arguments and return values.
*/
function callbackWrapper(name, context) {
var namespaces = name.split('.'), func = namespaces.pop(), obj = window;
for (var i = 0; obj && i < namespaces.length; i++) {
obj = obj[namespaces[i]];
}
if (!obj) {
throw "Wysiwyg: Unable to locate callback " + namespaces.join('.') + "." + func + "()";
}
if (!context) {
context = obj;
}
else if (typeof context == 'string'){
namespaces = context.split('.');
context = window;
for (i = 0; context && i < namespaces.length; i++) {
context = context[namespaces[i]];
}
if (!context) {
throw "Wysiwyg: Unable to locate context object " + namespaces.join('.');
}
}
if (typeof obj[func] != 'function') {
throw "Wysiwyg: " + func + " is not a callback function";
}
return function () {
return obj[func].apply(context, arguments);
}
}
/**
* D5 only: Queue our attach behavior.
*/
......
......@@ -926,6 +926,55 @@ function wysiwyg_get_directories($plugintype) {
return $directories;
}
/**
* Create a placeholder structure for JavaScript callbacks.
*
* @param $name
* A string with the name of the callback, use 'object.subobject.method'
* syntax for methods in nested objects.
* @param $context
* An optional string with the name of an object for overriding 'this' inside
* the function. Use 'object.subobject' syntax for nested objects. Defaults to
* the window object.
*
* @return
* An array with placeholder information for creating a JavaScript function
* reference on the client.
*/
function wysiwyg_wrap_js_callback($name, $context = null) {
$obj = array(
'drupalWysiwygType' => 'callback',
'name' => $name,
);
if ($context) {
$obj['context'] = $context;
}
return $obj;
}
/**
* Create a placeholder structure for JavaScript RegExp objects.
*
* @param $regexp
* A JavaScript Regular Expression as a string, without / wrappers.
* @param $modifiers
* An optional string with modifiers for the RegExp object.
*
* @return
* An array with placeholder information for creating a JavaScript RegExp
* object on the client.
*/
function wysiwyg_wrap_js_regexp($regexp, $modifiers = null) {
$obj = array(
'drupalWysiwygType' => 'regexp',
'regexp' => $regexp,
);
if ($modifiers) {
$obj['modifiers'] = $modifiers;
}
return $obj;
}
/**
* Process a single hook implementation of a wysiwyg editor.
*
......
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