uppdated modules
This commit is contained in:
Executable → Regular
+38
-2
@@ -1,19 +1,55 @@
|
||||
Note: This file is no longer updated. See the git history or release notes instead.
|
||||
Project change records will also be published for major changes.
|
||||
|
||||
Wysiwyg 7.x-2.x, xxxx-xx-xx
|
||||
|
||||
Wysiwyg 7.x-2.2, 2012-10-02
|
||||
---------------------------
|
||||
#356480 by TwoD, zhangtaihao, sun: Fixed initialization of editor libraries in
|
||||
Ajax scenarios.
|
||||
Revert "- #841794 by catch, smk-ka: Fixed wysiwyg_load_includes() performance."
|
||||
#771424 by TwoD: Fixed Missing library breaks admin UI.
|
||||
#967400 by skwashd, helmo, rocketeerbkw: Plugin/button label linking to project
|
||||
homepage is poor usability.
|
||||
#835682 by james.elliott, TwoD, Paul Lomax, JacobSingh: Fixed %t
|
||||
(path_to_theme()) returns wrong theme path.
|
||||
#841794 by catch, smk-ka: Fixed wysiwyg_load_includes() performance.
|
||||
#614402 by jide, TwoD: Added Plugin API support for YUI Editor.
|
||||
#947676 by merlinofchaos, zhangtaihao, mradcliffe: Added event for detaching
|
||||
when CTools modal closes.
|
||||
#356480 by Shawn_Smiley, zhangtaihao, idflood, whurleyf1: Added Lazy-load
|
||||
support for editors.
|
||||
#1732880 by loominade, yannickoo, sun: Added EpicEditor support.
|
||||
#1691478 by aaronbauman: Fixed {wysiwyg}.settings column is not marked as
|
||||
serialized.
|
||||
#1679272 by marcusx: Fixed Path/statusbar location setting has no effect in
|
||||
TinyMCE.
|
||||
Fixed bogus variable references.
|
||||
#1679980 by sun: Fixed Wysiwyg Dialog code is not ported to D7.
|
||||
#614146 by jide, fearlsgroove, TwoD, aklump, sun: Added
|
||||
Drupal.wysiwyg.editor.instance content methods.
|
||||
#1650416 by TwoD, sun: Changed settings form callback to leverage $form_state.
|
||||
#1650416 by sun: Changed arguments for settings form callback.
|
||||
#1388224 by ksenzee, sun, TwoD: Fixed editors detaching on form submissions.
|
||||
#746524 by fietserwin, sun, Sborsody, jastraat, kardave, pacproduct, osopolar,
|
||||
amanaplan, joelcollinsdc, roderik, plach, sylus, aaronbauman, g10: Fixed No
|
||||
Font Styles for CKeditor.
|
||||
#1650416 by sun, fietserwin: Added 'settings form callback' to allow editor
|
||||
specific changes to be made to the profile settings form.
|
||||
#682160 by n_vashenko, TwoD: Fixed lists plugin support for TinyMCE.
|
||||
#1414354 by Merco: Fixed none.js breaks if textarea.js is not loaded.
|
||||
#1064600 by TwoD: Fixed maximized editors hidden under Drupal's toolbar.
|
||||
#1405786 by logaritmisk: Fixed CKEditor being wider than parent elements.
|
||||
#1531896 by Chi: Fixed strict warning for WYMeditor.
|
||||
#1048300 by sreynen: Fixed external CSS not properly handled in
|
||||
wysiwyg_get_css().
|
||||
#1442226 by robertom: Fixed inverted list button names for WYMeditor.
|
||||
#1352426 by TwoD, sun: Added install notes (CKEditor edition clarification).
|
||||
#1112212 by timdiacon, TwoD: Added language direction buttons for CKEditor.
|
||||
#1398560 by markwittens: Fixed TinyMCE removing the longdesc attribute.
|
||||
#970452 by smk-ka, sun, TwoD, drzraf: Fixed outdated TinyMCE plugin info.
|
||||
#1155678 by james.elliott, Jody Lynn, sun: Add Drupal.detachBehaviors support.
|
||||
#624018 by smk-ka, quartsize, dagmar, nedjo, rickvug, catch, sun: Added Features support.
|
||||
#624018 by smk-ka, quartsize, dagmar, nedjo, rickvug, catch, sun: Added Features
|
||||
support.
|
||||
#1238766 by Dave Reid: Fixed Missing cells in profile plugins table.
|
||||
#1073106 by scottrouse: Fixed 'Input Format' should be 'Text Format'.
|
||||
#1153458 by TwoD: Fixed TinyMCE 'Verify HTML' setting ignored.
|
||||
|
||||
Executable → Regular
Executable → Regular
+9
-4
@@ -1,8 +1,8 @@
|
||||
|
||||
-- SUMMARY --
|
||||
|
||||
Wysiwyg API allows to users of your site to use WYSIWYG/rich-text, and other
|
||||
client-side editors for editing contents. This module depends on third-party
|
||||
Wysiwyg API allows users of your site to use WYSIWYG/rich-text, and other
|
||||
client-side editors for editing contents. This module depends on third-party
|
||||
editor libraries, most often based on JavaScript.
|
||||
|
||||
For a full description of the module, visit the project page:
|
||||
@@ -31,10 +31,15 @@ To submit bug reports and feature suggestions, or to track changes:
|
||||
* Go to Administration » Configuration » Content authoring » Text formats, and
|
||||
|
||||
- either configure the Full HTML format, assign it to trusted roles, and
|
||||
disable "HTML filter", "Line break converter", and (optionally) "URL filter".
|
||||
disable "Limit allowed HTML tags", "Convert line breaks...", and
|
||||
(optionally) "Convert URLs into links".
|
||||
Note that disabling "Limit allowed HTML tags" will allow users to post
|
||||
anything, including potentially malicious content. For a more configurable
|
||||
alternative to "Limit allowed HTML tags" try
|
||||
http://drupal.org/project/wysiwyg_filter.
|
||||
|
||||
- or add a new text format, assign it to trusted roles, and ensure that above
|
||||
mentioned input filters are disabled.
|
||||
mentioned input filters are configured as detailed.
|
||||
|
||||
* Setup editor profiles in Administration » Configuration » Content authoring
|
||||
» Wysiwyg.
|
||||
|
||||
Executable → Regular
+522
-81
@@ -5,6 +5,10 @@
|
||||
* Editor integration functions for CKEditor.
|
||||
*/
|
||||
|
||||
define('WYSIWYG_CKEDITOR_ACF_DISABLED', 0);
|
||||
define('WYSIWYG_CKEDITOR_ACF_AUTOMATIC', 1);
|
||||
define('WYSIWYG_CKEDITOR_ACF_CUSTOM', 2);
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*/
|
||||
@@ -28,20 +32,22 @@ function wysiwyg_ckeditor_editor() {
|
||||
),
|
||||
),
|
||||
'install note callback' => 'wysiwyg_ckeditor_install_note',
|
||||
'verified version range' => array('3.0', '4.6.1.580bcaf'),
|
||||
'migrate settings callback' => 'wysiwyg_ckeditor_migrate_settings',
|
||||
'version callback' => 'wysiwyg_ckeditor_version',
|
||||
'themes callback' => 'wysiwyg_ckeditor_themes',
|
||||
'settings form callback' => 'wysiwyg_ckeditor_settings_form',
|
||||
'init callback' => 'wysiwyg_ckeditor_init',
|
||||
'settings callback' => 'wysiwyg_ckeditor_settings',
|
||||
'plugin callback' => 'wysiwyg_ckeditor_plugins',
|
||||
'plugin settings callback' => 'wysiwyg_ckeditor_plugin_settings',
|
||||
'plugin callback' => '_wysiwyg_ckeditor_plugins',
|
||||
'plugin meta callback' => '_wysiwyg_ckeditor_plugin_meta',
|
||||
'proxy plugin' => array(
|
||||
'drupal' => array(
|
||||
'load' => TRUE,
|
||||
'proxy' => TRUE,
|
||||
),
|
||||
),
|
||||
'proxy plugin settings callback' => 'wysiwyg_ckeditor_proxy_plugin_settings',
|
||||
'proxy plugin settings callback' => '_wysiwyg_ckeditor_proxy_plugin_settings',
|
||||
'versions' => array(
|
||||
'3.0.0.3665' => array(
|
||||
'js files' => array('ckeditor-3.0.js'),
|
||||
@@ -51,11 +57,97 @@ function wysiwyg_ckeditor_editor() {
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Profile migration callback for CKEditor.
|
||||
*
|
||||
* Applies known changes to the editor settings as needed when the installed
|
||||
* editor version is different from the one used to configure the profile.
|
||||
* This fixes problems caused by settings, plugins or buttons being renamed,
|
||||
* removed, or added between versions.
|
||||
*
|
||||
* Only changes needed up/down to and including the installed version from the
|
||||
* profile version may be applied, in case the user did not install the latest
|
||||
* supported version.
|
||||
*
|
||||
* @param $settings
|
||||
* The editor settings array as it was stored in the database.
|
||||
* @param $editor
|
||||
* The editor definition from wysiwyg_get_editor().
|
||||
* @param $profile_version
|
||||
* The editor version string from when the profile was last saved.
|
||||
* @param $installed_version
|
||||
* The editor version currently installed on the system.
|
||||
*
|
||||
* @return
|
||||
* An editor version string telling Wysiwyg past which version the profile
|
||||
* could be migrated. If no changes were needed return TRUE.
|
||||
* Returning FALSE indicates migration failed and the profile is likely
|
||||
* unusable. Wysiwyg will recommend the user starts over with a new profile.
|
||||
*/
|
||||
function wysiwyg_ckeditor_migrate_settings(&$settings, $editor, $profile_version, $installed_version) {
|
||||
$version_diff = version_compare($installed_version, $profile_version);
|
||||
// Default to no changes needed.
|
||||
$migrated_version = TRUE;
|
||||
if ($version_diff === 1) {
|
||||
// Upgrading, starting at the profile version going up.
|
||||
// 3.x to 4.0.
|
||||
if (version_compare($profile_version, '4.0', '<')
|
||||
&& version_compare($installed_version, '4.0', '>=')) {
|
||||
// The default skin changed from "kama" to "moono".
|
||||
if (isset($settings['skin']) && $settings['skin'] === 'kama') {
|
||||
$settings['skin'] = 'moono';
|
||||
}
|
||||
$migrated_version = '4.0';
|
||||
}
|
||||
// Version 4.6.0.
|
||||
if (version_compare($profile_version, '4.6.0', '<')
|
||||
&& version_compare($installed_version, '4.6.0', '>=')) {
|
||||
// The default skin changed from "moono" to "moono-lisa".
|
||||
if (isset($settings['skin']) && $settings['skin'] === 'moono') {
|
||||
$settings['skin'] = 'moono-lisa';
|
||||
}
|
||||
$migrated_version = '4.6.0';
|
||||
}
|
||||
}
|
||||
elseif ($version_diff === 0) {
|
||||
// Same version. This function would never have been called.
|
||||
}
|
||||
// $version_diff === -1, an older version was installed.
|
||||
else {
|
||||
// Downgrading, starting at the profile version going down.
|
||||
// 4.6.0 down to 4.x.
|
||||
if (version_compare($profile_version, '4.6', '>=')
|
||||
&& version_compare($installed_version, '4.6', '<')) {
|
||||
if (isset($settings['skin']) && $settings['skin'] === 'moono-lisa') {
|
||||
$settings['skin'] = 'moono';
|
||||
}
|
||||
// Going down directly to 4.0 since no changes need to run anyway.
|
||||
$migrated_version = '4.6';
|
||||
}
|
||||
|
||||
// 4.x to 3.x.
|
||||
if (version_compare($profile_version, '4.0', '>=')
|
||||
&& version_compare($installed_version, '4.0', '<')) {
|
||||
// Change the default skin back "moono" to "kama".
|
||||
if (isset($settings['skin']) && $settings['skin'] === 'moono') {
|
||||
$settings['skin'] = 'kama';
|
||||
}
|
||||
$migrated_version = '4.0';
|
||||
}
|
||||
}
|
||||
// Return the version which was possible to migrate to, or FALSE on fail. Must
|
||||
// be within the verified range, but not necessarily match the exact version
|
||||
// which is currently installed.
|
||||
return $migrated_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an install note.
|
||||
*/
|
||||
function wysiwyg_ckeditor_install_note() {
|
||||
return '<p class="warning">' . t('Do NOT download the "CKEditor for Drupal" edition.') . '</p>';
|
||||
$output = '<p class="warning">' . t('Do NOT download the "CKEditor for Drupal" edition.') . '</br>';
|
||||
$output .= t('Make sure you install the full package as not all plugins work with the standard package.') . '</p>';
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,7 +170,8 @@ function wysiwyg_ckeditor_version($editor) {
|
||||
// version:'CKEditor 3.0 SVN',revision:'3665'
|
||||
// version:'3.0 RC',revision:'3753'
|
||||
// version:'3.0.1',revision:'4391'
|
||||
if (preg_match('@version:\'(?:CKEditor )?([\d\.]+)(?:.+revision:\'([\d]+))?@', $line, $version)) {
|
||||
// version:"4.0",revision:"769d96134b"
|
||||
if (preg_match('@version:[\'"](?:CKEditor )?([\d\.]+)(?:.+revision:[\'"]([[:xdigit:]]+))?@', $line, $version)) {
|
||||
fclose($library);
|
||||
// Version numbers need to have three parts since 3.0.1.
|
||||
$version[1] = preg_replace('/^(\d+)\.(\d+)$/', '${1}.${2}.0', $version[1]);
|
||||
@@ -124,32 +217,213 @@ function wysiwyg_ckeditor_themes($editor, $profile) {
|
||||
/**
|
||||
* Enhances the editor profile settings form for CKEditor.
|
||||
*
|
||||
* Adds support for CKEditor's advanced stylesSets, which are a more advanced
|
||||
* implementation and combination of block formats and font styles that allow
|
||||
* to adjust the HTML element, attributes, and CSS styles at once.
|
||||
*
|
||||
* @see http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Styles
|
||||
* @see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#.stylesSet
|
||||
* @see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html
|
||||
*/
|
||||
function wysiwyg_ckeditor_settings_form(&$form, &$form_state) {
|
||||
if (version_compare($form_state['wysiwyg']['editor']['installed version'], '3.2.1', '>=')) {
|
||||
// Replace CSS classes element description to explain the advanced syntax.
|
||||
$form['css']['css_classes']['#description'] = t('Optionally define CSS classes for the "Font style" dropdown list.<br />Enter one class on each line in the format: !format. Example: !example<br />If left blank, CSS classes are automatically imported from loaded stylesheet(s).', array(
|
||||
'!format' => '<code>[label]=[element].[class]</code>',
|
||||
'!example' => '<code>Title=h1.title</code>',
|
||||
));
|
||||
$form['css']['css_classes']['#element_validate'][] = 'wysiwyg_ckeditor_settings_form_validate_css_classes';
|
||||
$profile = $form_state['wysiwyg_profile'];
|
||||
$settings = $profile->settings;
|
||||
$installed_version = $form_state['wysiwyg']['editor']['installed version'];
|
||||
|
||||
$ckeditor_defaults = array(
|
||||
'block_formats' => 'p,address,pre,h2,h3,h4,h5,h6,div',
|
||||
// Custom setting.
|
||||
'default_toolbar_grouping' => FALSE,
|
||||
'forcePasteAsPlainText' => FALSE,
|
||||
'resize_enabled' => TRUE,
|
||||
'simple_source_formatting' => FALSE,
|
||||
'toolbarLocation' => 'top',
|
||||
'allowedContent' => TRUE,
|
||||
);
|
||||
|
||||
if (version_compare($installed_version, '3.1.0', '>=')) {
|
||||
// Enabled by default.
|
||||
$ckeditor_defaults['pasteFromWordRemoveFontStyles'] = TRUE;
|
||||
$ckeditor_defaults['pasteFromWordRemoveStyles'] = TRUE;
|
||||
}
|
||||
else {
|
||||
if (version_compare($installed_version, '4.6.0', '>=')) {
|
||||
// Disabled by default, deprecated.
|
||||
$ckeditor_defaults['pasteFromWordRemoveFontStyles'] = FALSE;
|
||||
// Dropped, no effect.
|
||||
unset($ckeditor_defaults['pasteFromWordNumberedHeadingToList'],
|
||||
$ckeditor_defaults['pasteFromWordRemoveStyles']);
|
||||
}
|
||||
|
||||
if (version_compare($installed_version, '3.2.1', '>=')) {
|
||||
$ckeditor_defaults['stylesSet'] = '';
|
||||
}
|
||||
|
||||
$settings += $ckeditor_defaults;
|
||||
|
||||
$form['appearance']['toolbarLocation'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Toolbar location'),
|
||||
'#default_value' => $settings['toolbarLocation'],
|
||||
'#options' => array('bottom' => t('Bottom'), 'top' => t('Top')),
|
||||
'#description' => t('This option controls whether the editor toolbar is displayed above or below the editing area.') . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'toolbarLocation', '@url' => url('http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-toolbarLocation'))),
|
||||
);
|
||||
|
||||
$form['appearance']['resize_enabled'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Enable resizing button'),
|
||||
'#default_value' => $settings['resize_enabled'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('This option gives you the ability to enable/disable the editor resizing feature.') . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'resize_enabled', '@url' => url('http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-resize_enabled'))),
|
||||
);
|
||||
|
||||
$form['output']['simple_source_formatting'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Apply simple source formatting'),
|
||||
'#default_value' => $settings['simple_source_formatting'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, the editor will re-format the HTML source code using a simple set of predefined rules. Disabling this option could avoid conflicts with other input filters.') . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'dataProcessor.write.setRules()', '@url' => url('http://docs.cksource.com/ckeditor_api/symbols/src/plugins_htmlwriter_plugin.js.html'))),
|
||||
);
|
||||
|
||||
$form['paste'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Paste plugin'),
|
||||
'#description' => t('Settings for the <a href="@url">@plugin</a> plugin.', array('@plugin' => 'paste', '@url' => url('http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-forcePasteAsPlainText'))),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
'#group' => 'advanced',
|
||||
);
|
||||
|
||||
$form['paste']['forcePasteAsPlainText'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Force paste as plain text'),
|
||||
'#default_value' => !empty($settings['forcePasteAsPlainText']),
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, all pasting operations insert plain text into the editor, losing any formatting information possibly available in the source text. Note: Paste from Word is not affected by this setting.') . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'forcePasteAsPlainText', '@url' => url('http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-forcePasteAsPlainText'))),
|
||||
);
|
||||
|
||||
if (version_compare($installed_version, '3.1.0', '>=')) {
|
||||
$form['paste']['pasteFromWord'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Paste from Word'),
|
||||
);
|
||||
|
||||
$form['paste']['pasteFromWord']['pasteFromWordNumberedHeadingToList'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Numbered heading to list'),
|
||||
'#default_value' => !empty($settings['pasteFromWordNumberedHeadingToList']),
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, transforms MS Word outline numbered headings into lists.'),
|
||||
);
|
||||
|
||||
$form['paste']['pasteFromWord']['pasteFromWordPromptCleanup'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Prompt on cleanup'),
|
||||
'#default_value' => !empty($settings['pasteFromWordPromptCleanup']),
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, prompts the user about the clean up of content being pasted from MS Word.'),
|
||||
);
|
||||
|
||||
$form['paste']['pasteFromWord']['pasteFromWordRemoveFontStyles'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Remove font styles'),
|
||||
'#default_value' => !empty($settings['pasteFromWordRemoveFontStyles']),
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, removes all font related formatting styles, including font size, font family, font foreground/background color.'),
|
||||
);
|
||||
|
||||
$form['paste']['pasteFromWord']['pasteFromWordRemoveStyles'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Remove styles'),
|
||||
'#default_value' => !empty($settings['pasteFromWordRemoveStyles']),
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, removes element styles that can not be managed with the editor, other than font specific styles.'),
|
||||
);
|
||||
}
|
||||
|
||||
if (version_compare($installed_version, '4.1.0', '>=')) {
|
||||
$form['output']['acf'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Advanced Content Filter'),
|
||||
'#description' => t('ACF limits and adapts input data (HTML code added in source mode or by the editor.setData method, pasted HTML code, etc.) so it matches the editor configuration in the best possible way. It may also deactivate features which generate HTML code that is not allowed by the configuration. See <a href="@url">@url</a> for details.', array('@url' => url('http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter'))),
|
||||
);
|
||||
$form['output']['acf']['acf_mode'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Mode'),
|
||||
'#options' => array(
|
||||
WYSIWYG_CKEDITOR_ACF_AUTOMATIC => t('Automatic'),
|
||||
WYSIWYG_CKEDITOR_ACF_CUSTOM => t('Custom'),
|
||||
WYSIWYG_CKEDITOR_ACF_DISABLED => t('Disabled'),
|
||||
),
|
||||
'#default_value' => isset($profile->settings['acf_mode']) ? $profile->settings['acf_mode'] : WYSIWYG_CKEDITOR_ACF_DISABLED,
|
||||
'#description' => t('If set to <em>Automatic</em> or <em>Custom</em>, the editor will strip out any content not explicitely allowed <strong>when the editor loads</strong>.'),
|
||||
);
|
||||
|
||||
$form['output']['acf']['acf_allowed_content'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Content Rules'),
|
||||
'#default_value' => isset($profile->settings['acf_allowed_content']) ? $profile->settings['acf_allowed_content'] : '',
|
||||
'#description' => t('Rules for whitelisting content for the advanced content filter. Both string and object formats accepted. Uses the <a href="@allowed_url">allowedContent</a> setting in <em>Custom</em> mode <strong>or</strong> the <a href="@extra_allwed_url">extraAllowedContent</a> settings in <em>Automatic</em> mode internally. See <a href="@info_url">@info_url</a> for details.', array('@info_url' => url('http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules'), '@allowed_url' => url('http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent'), '@allowed_extra_url' => url('http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-extraAllowedContent'))),
|
||||
'#states' => array(
|
||||
'visible' => array(
|
||||
':input[name="acf_mode"]' => array(
|
||||
array('value' => WYSIWYG_CKEDITOR_ACF_AUTOMATIC),
|
||||
array('value' => WYSIWYG_CKEDITOR_ACF_CUSTOM),
|
||||
),
|
||||
),
|
||||
),
|
||||
'#element_validate' => array('wysiwyg_ckeditor_settings_form_validate_allowed_content'),
|
||||
);
|
||||
}
|
||||
|
||||
if (version_compare($installed_version, '3.6.0', '>=')) {
|
||||
$form['appearance']['default_toolbar_grouping'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Use default toolbar button grouping'),
|
||||
'#default_value' => !empty($settings['default_toolbar_grouping']),
|
||||
'#return_value' => 1,
|
||||
'#description' => t('This option gives you the ability to enable/disable the usage of default groupings for toolbar buttons. If enabled, toolbar buttons will be placed into predetermined groups instead of all in a single group.'),
|
||||
);
|
||||
}
|
||||
|
||||
if (version_compare($installed_version, '3.2.1', '>=')) {
|
||||
// Versions below 3.2.1 do not support Font styles at all.
|
||||
$form['css']['css_classes']['#access'] = FALSE;
|
||||
$form['css']['stylesSet'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('CSS classes'),
|
||||
'#description' => t('Optionally define CSS classes for the "Font style" dropdown list.<br />Enter one class on each line in the format: !format. Example: !example<br />If left blank, CSS classes are automatically imported from loaded stylesheet(s).', array(
|
||||
'@url' => url('http://docs.ckeditor.com/#!/api/CKEDITOR.stylesSet'),
|
||||
'!format' => '<code>[label]=[element].[class]</code>',
|
||||
'!example' => '<code>Title=h1.title</code>',
|
||||
)) . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'stylesSet', '@url' => url('http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-stylesSet'))),
|
||||
'#default_value' => $settings['stylesSet'],
|
||||
'#element_validate' => array('wysiwyg_ckeditor_settings_form_validate_stylessets'),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
if (version_compare($installed_version, '4.6.0', '>=')) {
|
||||
$form['paste']['pasteFromWord']['pasteFromWordRemoveFontStyles']['#description'] .= '<br />' . t('This setting will be deprecated in the future. Use ACF to replicate the effect of enabling it.');
|
||||
unset($form['paste']['pasteFromWord']['pasteFromWordNumberedHeadingToList'],
|
||||
$form['paste']['pasteFromWord']['pasteFromWordRemoveStyles']);
|
||||
}
|
||||
|
||||
$form['css']['block_formats'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Block formats'),
|
||||
'#default_value' => $settings['block_formats'],
|
||||
'#size' => 40,
|
||||
'#maxlength' => 250,
|
||||
'#description' => t('Comma separated list of HTML block formats. Possible values: <code>@format-list</code>.', array('@format-list' => 'p,h1,h2,h3,h4,h5,h6,div,blockquote,address,pre,code,dt,dd and other block elements')) . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'block_formats', '@url' => url('http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-format_tags'))),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* #element_validate handler for ACF Allowed Content element altered by wysiwyg_ckeditor_settings_form().
|
||||
*/
|
||||
function wysiwyg_ckeditor_settings_form_validate_allowed_content($element, &$form_state) {
|
||||
if (_wysiwyg_ckeditor_settings_acf_is_obj($element['#value']) && json_decode($element['#value']) === NULL) {
|
||||
form_error($element, t('Allowed content is not valid JSON.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* #element_validate handler for CSS classes element altered by wysiwyg_ckeditor_settings_form().
|
||||
*/
|
||||
function wysiwyg_ckeditor_settings_form_validate_css_classes($element, &$form_state) {
|
||||
function wysiwyg_ckeditor_settings_form_validate_stylessets($element, &$form_state) {
|
||||
if (wysiwyg_ckeditor_settings_parse_styles($element['#value']) === FALSE) {
|
||||
form_error($element, t('The specified CSS classes are syntactically incorrect.'));
|
||||
}
|
||||
@@ -199,14 +473,16 @@ EOL;
|
||||
* Drupal.settings.wysiwyg.configs.{editor}
|
||||
*/
|
||||
function wysiwyg_ckeditor_settings($editor, $config, $theme) {
|
||||
$default_skin = (version_compare($editor['installed version'], '4.0.0', '<') ? 'kama' : (version_compare($editor['installed version'], '4.6.0', '<') ? 'moono' : 'moono-lisa'));
|
||||
$settings = array(
|
||||
// Needed to make relative paths work in the editor.
|
||||
'baseHref' => $GLOBALS['base_url'] . '/',
|
||||
'width' => 'auto',
|
||||
// For better compatibility with smaller textareas.
|
||||
'resize_minWidth' => 450,
|
||||
'height' => 420,
|
||||
// @todo Do not use skins as themes and add separate skin handling.
|
||||
'theme' => 'default',
|
||||
'skin' => !empty($theme) ? $theme : 'kama',
|
||||
'skin' => !empty($theme) ? $theme : $default_skin,
|
||||
// By default, CKEditor converts most characters into HTML entities. Since
|
||||
// it does not support a custom definition, but Drupal supports Unicode, we
|
||||
// disable at least the additional character sets. CKEditor always converts
|
||||
@@ -219,35 +495,61 @@ function wysiwyg_ckeditor_settings($editor, $config, $theme) {
|
||||
// Add HTML block format settings; common block formats are already predefined
|
||||
// by CKEditor.
|
||||
if (isset($config['block_formats'])) {
|
||||
$block_formats = explode(',', drupal_strtolower($config['block_formats']));
|
||||
$block_formats = explode(',', drupal_strtolower(preg_replace('@\s+@', '', $config['block_formats'])));
|
||||
$predefined_formats = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'pre', 'address', 'div');
|
||||
foreach (array_diff($block_formats, $predefined_formats) as $tag) {
|
||||
$tag = trim($tag);
|
||||
$settings["format_$tag"] = array('element' => $tag);
|
||||
$settings["format_$tag"] = array('element' => $tag, 'name' => strtoupper(substr($tag, 0, 1)) . substr($tag, 1));
|
||||
}
|
||||
$settings['format_tags'] = implode(';', $block_formats);
|
||||
}
|
||||
|
||||
if (isset($config['apply_source_formatting'])) {
|
||||
$settings['apply_source_formatting'] = $config['apply_source_formatting'];
|
||||
// Advanced Content Filter
|
||||
// @see http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter
|
||||
if (!isset($config['acf_mode']) || WYSIWYG_CKEDITOR_ACF_DISABLED == $config['acf_mode']) {
|
||||
$settings['allowedContent'] = TRUE;
|
||||
}
|
||||
else {
|
||||
if (_wysiwyg_ckeditor_settings_acf_is_obj($config['acf_allowed_content'])) {
|
||||
$acf_content = json_decode($config['acf_allowed_content']);
|
||||
}
|
||||
else {
|
||||
$acf_content = $config['acf_allowed_content'];
|
||||
}
|
||||
|
||||
if (WYSIWYG_CKEDITOR_ACF_CUSTOM == $config['acf_mode']) {
|
||||
$settings['allowedContent'] = $acf_content;
|
||||
}
|
||||
elseif (WYSIWYG_CKEDITOR_ACF_AUTOMATIC == $config['acf_mode']) {
|
||||
$settings['extraAllowedContent'] = $acf_content;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($config['css_setting'])) {
|
||||
// Versions below 3.0.1 could only handle one stylesheet.
|
||||
if (version_compare($editor['installed version'], '3.0.1.4391', '<')) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['contentsCss'] = reset(wysiwyg_get_css());
|
||||
$css = wysiwyg_get_css(isset($config['css_theme']) ? $config['css_theme'] : '');
|
||||
$settings['contentsCss'] = reset($css);
|
||||
}
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['contentsCss'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
$settings['contentsCss'] = strtr($config['css_path'], array(
|
||||
'%b' => base_path(),
|
||||
'%t' => drupal_get_path('theme', variable_get('theme_default', NULL)),
|
||||
'%q' => variable_get('css_js_query_string', ''),
|
||||
));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['contentsCss'] = wysiwyg_get_css();
|
||||
$settings['contentsCss'] = wysiwyg_get_css(isset($config['css_theme']) ? $config['css_theme'] : '');
|
||||
}
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['contentsCss'] = explode(',', strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL)))));
|
||||
$settings['contentsCss'] = explode(',', strtr($config['css_path'], array(
|
||||
'%b' => base_path(),
|
||||
'%t' => drupal_get_path('theme', variable_get('theme_default', NULL)),
|
||||
'%q' => variable_get('css_js_query_string', ''),
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -255,24 +557,36 @@ function wysiwyg_ckeditor_settings($editor, $config, $theme) {
|
||||
// Parse and define the styles set for the Styles plugin (3.2.1+).
|
||||
// @todo This should be a plugin setting, but Wysiwyg does not support
|
||||
// plugin-specific settings yet.
|
||||
if (!empty($config['buttons']['default']['Styles']) && version_compare($editor['installed version'], '3.2.1', '>=')) {
|
||||
if ($styles = wysiwyg_ckeditor_settings_parse_styles($config['css_classes'])) {
|
||||
if (!empty($config['buttons']['default']['Styles']) && version_compare($editor['installed version'], '3.2.1', '>=') && !empty($config['stylesSet'])) {
|
||||
if ($styles = wysiwyg_ckeditor_settings_parse_styles($config['stylesSet'])) {
|
||||
$settings['stylesSet'] = $styles;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($config['language'])) {
|
||||
$settings['language'] = $config['language'];
|
||||
$check_if_set = array(
|
||||
'forcePasteAsPlainText',
|
||||
'language',
|
||||
'pasteFromWordNumberedHeadingToList',
|
||||
'pasteFromWordPromptCleanup',
|
||||
'pasteFromWordRemoveFontStyles',
|
||||
'pasteFromWordRemoveStyles',
|
||||
'simple_source_formatting',
|
||||
'toolbarLocation',
|
||||
);
|
||||
foreach ($check_if_set as $setting_name) {
|
||||
if (isset($config[$setting_name])) {
|
||||
$settings[$setting_name] = $config[$setting_name];
|
||||
}
|
||||
}
|
||||
if (isset($config['resizing'])) {
|
||||
|
||||
if (isset($config['resize_enabled'])) {
|
||||
// CKEditor performs a type-agnostic comparison on this particular setting.
|
||||
$settings['resize_enabled'] = (bool) $config['resizing'];
|
||||
}
|
||||
if (isset($config['toolbar_loc'])) {
|
||||
$settings['toolbarLocation'] = $config['toolbar_loc'];
|
||||
$settings['resize_enabled'] = (bool) $config['resize_enabled'];
|
||||
}
|
||||
|
||||
$settings['toolbar'] = array();
|
||||
$supports_groups = version_compare($editor['installed version'], '3.6.0', '>=');
|
||||
$use_default_groups = $supports_groups && !empty($config['default_toolbar_grouping']);
|
||||
if (!empty($config['buttons'])) {
|
||||
$extra_plugins = array();
|
||||
$plugins = wysiwyg_get_plugins($editor['name']);
|
||||
@@ -286,7 +600,13 @@ function wysiwyg_ckeditor_settings($editor, $config, $theme) {
|
||||
}
|
||||
// Add buttons.
|
||||
if ($type == 'buttons') {
|
||||
$settings['toolbar'][] = $button;
|
||||
if ($use_default_groups) {
|
||||
$settings['toolbar'][_wysiwyg_ckeditor_group($button)][] = $button;
|
||||
}
|
||||
else {
|
||||
// Use one button row for backwards compatibility.
|
||||
$settings['toolbar'][] = $button;
|
||||
}
|
||||
}
|
||||
// Add external Drupal plugins to the list of extensions.
|
||||
if ($type == 'buttons' && !empty($plugins[$plugin]['proxy'])) {
|
||||
@@ -315,14 +635,29 @@ function wysiwyg_ckeditor_settings($editor, $config, $theme) {
|
||||
$settings['extraPlugins'] = implode(',', $extra_plugins);
|
||||
}
|
||||
}
|
||||
// For now, all buttons are placed into one row.
|
||||
$settings['toolbar'] = array($settings['toolbar']);
|
||||
|
||||
if ($use_default_groups) {
|
||||
// Organize groups to use lables to improves accessibility.
|
||||
// http://docs.ckeditor.com/#!/guide/dev_toolbar-section-3.
|
||||
$groups_toolbar = array();
|
||||
foreach ($settings['toolbar'] as $group => $items) {
|
||||
$groups_toolbar[] = array(
|
||||
'name' => $group,
|
||||
'items' => $items,
|
||||
);
|
||||
$settings['toolbar'] = $groups_toolbar;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// For now, all buttons are placed into one row.
|
||||
$settings['toolbar'] = array($settings['toolbar']);
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses CSS classes settings string into a stylesSet JavaScript settings array.
|
||||
* Parses stylesSet settings string into a stylesSet JavaScript settings array.
|
||||
*
|
||||
* @param string $css_classes
|
||||
* A string containing CSS class definitions to add to the Style dropdown
|
||||
@@ -367,45 +702,37 @@ function wysiwyg_ckeditor_settings_parse_styles($css_classes) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array of native external plugins that need to be loaded separately.
|
||||
* Build a JS settings array with global metadata for native external plugins.
|
||||
*/
|
||||
function wysiwyg_ckeditor_plugin_settings($editor, $profile, $plugins) {
|
||||
$settings = array();
|
||||
foreach ($plugins as $name => $plugin) {
|
||||
// Register all plugins that need to be loaded.
|
||||
if (!empty($plugin['load'])) {
|
||||
$settings[$name] = array();
|
||||
// Add path for native external plugins.
|
||||
if (empty($plugin['internal']) && isset($plugin['path'])) {
|
||||
$settings[$name]['path'] = base_path() . $plugin['path'] . '/';
|
||||
}
|
||||
// Force native internal plugins to use the standard path.
|
||||
else {
|
||||
$settings[$name]['path'] = base_path() . $editor['library path'] . '/plugins/' . $name . '/';
|
||||
}
|
||||
// CKEditor defaults to 'plugin.js' on its own when filename is not set.
|
||||
if (!empty($plugin['filename'])) {
|
||||
$settings[$name]['fileName'] = $plugin['filename'];
|
||||
}
|
||||
function _wysiwyg_ckeditor_plugin_meta($editor, $plugin) {
|
||||
$meta = array();
|
||||
$name = $plugin['name'];
|
||||
// Register all plugins that need to be loaded.
|
||||
if (!empty($plugin['load'])) {
|
||||
// Add path for native external plugins.
|
||||
if (empty($plugin['internal']) && isset($plugin['path'])) {
|
||||
$meta['path'] = base_path() . $plugin['path'] . '/';
|
||||
}
|
||||
// Force native internal plugins to use the standard path.
|
||||
else {
|
||||
$meta['path'] = base_path() . $editor['library path'] . '/plugins/' . $name . '/';
|
||||
}
|
||||
// CKEditor defaults to 'plugin.js' on its own when filename is not set.
|
||||
if (!empty($plugin['filename'])) {
|
||||
$meta['fileName'] = $plugin['filename'];
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array for Drupal plugins loaded via the proxy plugin.
|
||||
*/
|
||||
function wysiwyg_ckeditor_proxy_plugin_settings($editor, $profile, $plugins) {
|
||||
function _wysiwyg_ckeditor_proxy_plugin_settings($editor, $profile, $plugins) {
|
||||
$settings = array();
|
||||
foreach ($plugins as $name => $plugin) {
|
||||
// Populate required plugin settings.
|
||||
$settings[$name] = $plugin['dialog settings'] + array(
|
||||
'title' => $plugin['title'],
|
||||
'icon' => base_path() . $plugin['icon path'] . '/' . $plugin['icon file'],
|
||||
'iconTitle' => $plugin['icon title'],
|
||||
// @todo These should only be set if the plugin defined them.
|
||||
'css' => base_path() . $plugin['css path'] . '/' . $plugin['css file'],
|
||||
);
|
||||
// Just need a list of all enabled plugins for each instance.
|
||||
$settings[$name] = TRUE;
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
@@ -413,22 +740,22 @@ function wysiwyg_ckeditor_proxy_plugin_settings($editor, $profile, $plugins) {
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_ckeditor_plugins($editor) {
|
||||
function _wysiwyg_ckeditor_plugins($editor) {
|
||||
$plugins = array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
'Bold' => t('Bold'), 'Italic' => t('Italic'), 'Underline' => t('Underline'),
|
||||
'Strike' => t('Strike-through'),
|
||||
'JustifyLeft' => t('Align left'), 'JustifyCenter' => t('Align center'), 'JustifyRight' => t('Align right'), 'JustifyBlock' => t('Justify'),
|
||||
'Strike' => t('Strike through'),
|
||||
'JustifyLeft' => t('Align left'), 'JustifyCenter' => t('Center'), 'JustifyRight' => t('Align right'), 'JustifyBlock' => t('Justify'),
|
||||
'BulletedList' => t('Insert/Remove Bullet list'), 'NumberedList' => t('Insert/Remove Numbered list'),
|
||||
'BidiLtr' => t('Left-to-right'), 'BidiRtl' => t('Right-to-left'),
|
||||
'BulletedList' => t('Bullet list'), 'NumberedList' => t('Numbered list'),
|
||||
'Outdent' => t('Outdent'), 'Indent' => t('Indent'),
|
||||
'Undo' => t('Undo'), 'Redo' => t('Redo'),
|
||||
'Link' => t('Link'), 'Unlink' => t('Unlink'), 'Anchor' => t('Anchor'),
|
||||
'Image' => t('Image'),
|
||||
'TextColor' => t('Forecolor'), 'BGColor' => t('Backcolor'),
|
||||
'TextColor' => t('Text color'), 'BGColor' => t('Background color'),
|
||||
'Superscript' => t('Superscript'), 'Subscript' => t('Subscript'),
|
||||
'Blockquote' => t('Blockquote'), 'Source' => t('Source code'),
|
||||
'Blockquote' => t('Block quote'), 'Source' => t('Source code'),
|
||||
'HorizontalRule' => t('Horizontal rule'),
|
||||
'Cut' => t('Cut'), 'Copy' => t('Copy'), 'Paste' => t('Paste'),
|
||||
'PasteText' => t('Paste Text'), 'PasteFromWord' => t('Paste from Word'),
|
||||
@@ -440,10 +767,12 @@ function wysiwyg_ckeditor_plugins($editor) {
|
||||
'SelectAll' => t('Select all'), 'Find' => t('Search'), 'Replace' => t('Replace'),
|
||||
'Flash' => t('Flash'), 'Smiley' => t('Smiley'),
|
||||
'CreateDiv' => t('Div container'),
|
||||
'Iframe' => t('iFrame'),
|
||||
'Iframe' => t('IFrame'),
|
||||
'Maximize' => t('Maximize'),
|
||||
'SpellChecker' => t('Check spelling'), 'Scayt' => t('Check spelling as you type'),
|
||||
'SpellChecker' => t('Check spelling'), 'Scayt' => t('Spell check as you type'),
|
||||
'About' => t('About'),
|
||||
'Templates' => t('Templates'),
|
||||
'CopyFormatting' => t('Copy Formatting'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
),
|
||||
@@ -459,6 +788,118 @@ function wysiwyg_ckeditor_plugins($editor) {
|
||||
if (version_compare($editor['installed version'], '3.5.0.6260', '<')) {
|
||||
unset($plugins['default']['buttons']['Iframe']);
|
||||
}
|
||||
if (version_compare($editor['installed version'], '4.6.0', '<')) {
|
||||
unset($plugins['default']['CopyFormatting']);
|
||||
}
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define grouping for ckEditor buttons.
|
||||
*/
|
||||
function _wysiwyg_ckeditor_group($button) {
|
||||
switch ($button) {
|
||||
case 'Source':
|
||||
$group = 'document';
|
||||
break;
|
||||
|
||||
case 'Cut':
|
||||
case 'Copy':
|
||||
case 'Paste':
|
||||
case 'PasteText':
|
||||
case 'PasteFromWord':
|
||||
case 'Undo':
|
||||
case 'Redo':
|
||||
$group = 'clipboard';
|
||||
break;
|
||||
|
||||
case 'Find':
|
||||
case 'Replace':
|
||||
case 'SelectAll':
|
||||
case 'SpellChecker':
|
||||
case 'Scayt':
|
||||
$group = 'editing';
|
||||
break;
|
||||
|
||||
case 'Bold':
|
||||
case 'Italic':
|
||||
case 'Underline':
|
||||
case 'Strike':
|
||||
case 'Subscript':
|
||||
case 'Superscript':
|
||||
$group = 'basicstyles';
|
||||
break;
|
||||
|
||||
case 'RemoveFormat':
|
||||
case 'CopyFormatting':
|
||||
$group = 'cleanup';
|
||||
break;
|
||||
|
||||
case 'NumberedList':
|
||||
case 'BulletedList':
|
||||
case 'Outdent':
|
||||
case 'Indent':
|
||||
case 'Blockquote':
|
||||
case 'CreateDiv':
|
||||
case 'JustifyLeft':
|
||||
case 'JustifyCenter':
|
||||
case 'JustifyRight':
|
||||
case 'JustifyBlock':
|
||||
case 'BidiLtr':
|
||||
case 'BidiRtl':
|
||||
$group = 'paragraph';
|
||||
break;
|
||||
|
||||
case 'Link':
|
||||
case 'Unlink':
|
||||
case 'Anchor':
|
||||
$group = 'links';
|
||||
break;
|
||||
|
||||
case 'Image':
|
||||
case 'Flash':
|
||||
case 'Table':
|
||||
case 'HorizontalRule':
|
||||
case 'Smiley':
|
||||
case 'SpecialChar':
|
||||
case 'Iframe':
|
||||
case 'Templates':
|
||||
$group = 'insert';
|
||||
break;
|
||||
|
||||
case 'Styles':
|
||||
case 'Format':
|
||||
case 'Font':
|
||||
case 'FontSize':
|
||||
$group = 'styles';
|
||||
break;
|
||||
|
||||
case 'TextColor':
|
||||
case 'BGColor':
|
||||
$group = 'colors';
|
||||
break;
|
||||
|
||||
case 'Maximize':
|
||||
case 'ShowBlocks':
|
||||
case 'About':
|
||||
$group = 'tools';
|
||||
break;
|
||||
|
||||
default:
|
||||
$group = 'other';
|
||||
}
|
||||
return $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if string is supposed to be ACF obj format.
|
||||
*
|
||||
* @see http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules
|
||||
*/
|
||||
function _wysiwyg_ckeditor_settings_acf_is_obj($string) {
|
||||
if (strstr($string, ':') === FALSE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
/**
|
||||
* openWYSIWYG.
|
||||
*/
|
||||
table.tableTextareaEditor, table.tableTextareaEditor table {
|
||||
margin: 0;
|
||||
border-collapse: separate;
|
||||
}
|
||||
table.tableTextareaEditor td {
|
||||
padding: 0;
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
/**
|
||||
* TinyMCE 2.x
|
||||
*/
|
||||
table.mceEditor {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Align all buttons and separators in a single row, so they wrap into multiple
|
||||
* rows if required.
|
||||
*/
|
||||
.mceToolbarTop a, .mceToolbarBottom a {
|
||||
float: left;
|
||||
}
|
||||
.mceSeparatorLine {
|
||||
float: left;
|
||||
margin-top: 3px;
|
||||
}
|
||||
.mceSelectList {
|
||||
float: left;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
/* Place table plugin buttons into new row */
|
||||
#mce_editor_0_table, #mce_editor_1_table {
|
||||
clear: left;
|
||||
}
|
||||
Executable → Regular
@@ -0,0 +1,4 @@
|
||||
.mce-container.mce-toolbar > .mce-container-body > .mce-btn-group > div {
|
||||
/* Hack to make buttons wrap. */
|
||||
white-space: normal !important;
|
||||
}
|
||||
Executable → Regular
+14
-2
@@ -11,8 +11,8 @@
|
||||
function wysiwyg_epiceditor_editor() {
|
||||
$editor['epiceditor'] = array(
|
||||
'title' => 'EpicEditor',
|
||||
'vendor url' => 'http://oscargodson.github.com/EpicEditor',
|
||||
'download url' => 'http://oscargodson.github.com/EpicEditor/docs/downloads/EpicEditor-v0.1.1.zip',
|
||||
'vendor url' => 'http://epiceditor.com',
|
||||
'download url' => 'http://epiceditor.com',
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Minified',
|
||||
@@ -23,8 +23,10 @@ function wysiwyg_epiceditor_editor() {
|
||||
'files' => array('js/epiceditor.js'),
|
||||
),
|
||||
),
|
||||
'verified version range' => array('0.1.1', '0.2.2'),
|
||||
'version callback' => 'wysiwyg_epiceditor_version',
|
||||
'themes callback' => 'wysiwyg_epiceditor_themes',
|
||||
'settings form callback' => 'wysiwyg_epiceditor_settings_form',
|
||||
'settings callback' => 'wysiwyg_epiceditor_settings',
|
||||
'versions' => array(
|
||||
'0.1.1' => array(
|
||||
@@ -76,6 +78,16 @@ function wysiwyg_epiceditor_themes($editor, $profile) {
|
||||
//return array('preview-dark', 'github');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhances the editor profile settings form for EpicEditor.
|
||||
*
|
||||
*/
|
||||
function wysiwyg_epiceditor_settings_form(&$form, &$form_state) {
|
||||
$form['buttons']['#access'] = FALSE;
|
||||
$form['basic']['language']['#access'] = FALSE;
|
||||
$form['css']['#access'] = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return runtime editor settings for a given wysiwyg profile.
|
||||
*
|
||||
|
||||
Executable → Regular
+111
-35
@@ -19,18 +19,21 @@ function wysiwyg_fckeditor_editor() {
|
||||
'files' => array('fckeditor.js'),
|
||||
),
|
||||
),
|
||||
'verified version range' => array('2.6.0', '2.6.11'),
|
||||
'version callback' => 'wysiwyg_fckeditor_version',
|
||||
'themes callback' => 'wysiwyg_fckeditor_themes',
|
||||
'settings form callback' => 'wysiwyg_fckeditor_settings_form',
|
||||
'settings callback' => 'wysiwyg_fckeditor_settings',
|
||||
'plugin callback' => 'wysiwyg_fckeditor_plugins',
|
||||
'plugin settings callback' => 'wysiwyg_fckeditor_plugin_settings',
|
||||
'plugin callback' => '_wysiwyg_fckeditor_plugins',
|
||||
'plugin meta callback' => '_wysiwyg_fckeditor_plugin_meta',
|
||||
'plugin settings callback' => '_wysiwyg_fckeditor_plugin_settings',
|
||||
'proxy plugin' => array(
|
||||
'drupal' => array(
|
||||
'load' => TRUE,
|
||||
'proxy' => TRUE,
|
||||
),
|
||||
),
|
||||
'proxy plugin settings callback' => 'wysiwyg_fckeditor_proxy_plugin_settings',
|
||||
'proxy plugin settings callback' => '_wysiwyg_fckeditor_proxy_plugin_settings',
|
||||
'versions' => array(
|
||||
'2.6' => array(
|
||||
'js files' => array('fckeditor-2.6.js'),
|
||||
@@ -82,6 +85,68 @@ function wysiwyg_fckeditor_themes($editor, $profile) {
|
||||
return array('default', 'office2003', 'silver');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhances the editor profile settings form for FCKeditor.
|
||||
*
|
||||
* @see http://docs.cksource.com/FCKeditor_2.x/Developers_Guide/Configuration/Configuration_Options
|
||||
*/
|
||||
function wysiwyg_fckeditor_settings_form(&$form, &$form_state) {
|
||||
$profile = $form_state['wysiwyg_profile'];
|
||||
$settings = $profile->settings;
|
||||
$settings += array(
|
||||
'AutoDetectPasteFromWord' => TRUE,
|
||||
'ForcePasteAsPlainText' => FALSE,
|
||||
'FontFormats' => 'p;address;pre;h2;h3;h4;h5;h6;div',
|
||||
'FormatOutput' => TRUE,
|
||||
'FormatSource' => TRUE,
|
||||
);
|
||||
$form['output']['FormatSource'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Apply source formatting'),
|
||||
'#default_value' => $settings['FormatSource'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, the editor will re-format the HTML source code when switching to Source View.') . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'FormatSource', '@url' => url('http://docs.cksource.com/FCKeditor_2.x/Developers_Guide/Configuration/Configuration_Options/FormatSource'))),
|
||||
);
|
||||
$form['output']['FormatOutput'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Apply output formatting'),
|
||||
'#default_value' => $settings['FormatOutput'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, the editor will re-format the HTML source code output. Disabling this option could avoid conflicts with other input filters.') . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'FormatOutput', '@url' => url('http://docs.cksource.com/FCKeditor_2.x/Developers_Guide/Configuration/Configuration_Options/FormatOutput'))),
|
||||
);
|
||||
$form['css']['FontFormats'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Block formats'),
|
||||
'#default_value' => $settings['FontFormats'],
|
||||
'#size' => 40,
|
||||
'#maxlength' => 250,
|
||||
'#description' => t('Semicolon separated list of HTML block formats. Possible values: <code>@format-list</code>.', array('@format-list' => 'p;h1;h2;h3;h4;h5;h6;div;address;pre')) . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'FontFormats', '@url' => url('http://docs.cksource.com/FCKeditor_2.x/Developers_Guide/Configuration/Configuration_Options/FontFormats'))),
|
||||
);
|
||||
|
||||
$form['paste'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Paste plugin'),
|
||||
'#description' => t('Settings for the paste plugin.'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
'#group' => 'advanced',
|
||||
);
|
||||
$form['paste']['AutoDetectPasteFromWord'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Auto detect paste from Word'),
|
||||
'#default_value' => $settings['AutoDetectPasteFromWord'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, FCKeditor checks if pasted text comes from MS Word. If so the editor will launch the "Paste from Word" window. <strong>Only works in Internet Explorer.</strong>') . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'AutoDetectPasteFromWord', '@url' => url('http://docs.cksource.com/FCKeditor_2.x/Developers_Guide/Configuration/Configuration_Options/AutoDetectPasteFromWord'))),
|
||||
);
|
||||
$form['paste']['ForcePasteAsPlainText'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Force paste as plain text'),
|
||||
'#default_value' => $settings['ForcePasteAsPlainText'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, forces the editor to discard all formatting when pasting text. It will also disable the <strong>Paste from Word</strong> operation.') . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'ForcePasteAsPlainText', '@url' => url('http://docs.cksource.com/FCKeditor_2.x/Developers_Guide/Configuration/Configuration_Options/ForcePasteAsPlainText'))),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return runtime editor settings for a given wysiwyg profile.
|
||||
*
|
||||
@@ -102,7 +167,6 @@ function wysiwyg_fckeditor_settings($editor, $config, $theme) {
|
||||
'SkinPath' => base_path() . $editor['library path'] . '/editor/skins/' . $theme . '/',
|
||||
'CustomConfigurationsPath' => base_path() . drupal_get_path('module', 'wysiwyg') . '/editors/js/fckeditor.config.js',
|
||||
'Width' => '100%',
|
||||
'Height' => 420,
|
||||
'LinkBrowser' => FALSE,
|
||||
'LinkUpload' => FALSE,
|
||||
'ImageBrowser' => FALSE,
|
||||
@@ -117,22 +181,31 @@ function wysiwyg_fckeditor_settings($editor, $config, $theme) {
|
||||
'IncludeLatinEntities' => FALSE,
|
||||
'IncludeGreekEntities' => FALSE,
|
||||
);
|
||||
if (isset($config['block_formats'])) {
|
||||
$settings['FontFormats'] = strtr($config['block_formats'], array(',' => ';'));
|
||||
if (isset($config['FontFormats'])) {
|
||||
$settings['FontFormats'] = preg_replace('@\s+@', '', $config['FontFormats']);
|
||||
}
|
||||
if (isset($config['apply_source_formatting'])) {
|
||||
$settings['FormatOutput'] = $settings['FormatSource'] = $config['apply_source_formatting'];
|
||||
}
|
||||
if (isset($config['paste_auto_cleanup_on_paste'])) {
|
||||
$settings['AutoDetectPasteFromWord'] = $config['paste_auto_cleanup_on_paste'];
|
||||
$check_if_set = array(
|
||||
'AutoDetectPasteFromWord',
|
||||
'ForcePasteAsPlainText',
|
||||
'FormatOutput',
|
||||
'FormatSource',
|
||||
);
|
||||
foreach ($check_if_set as $setting_name) {
|
||||
if (isset($config[$setting_name])) {
|
||||
$settings[$setting_name] = $config[$setting_name];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['EditorAreaCSS'] = implode(',', wysiwyg_get_css());
|
||||
$settings['EditorAreaCSS'] = implode(',', wysiwyg_get_css(isset($config['css_theme']) ? $config['css_theme'] : ''));
|
||||
}
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['EditorAreaCSS'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
$settings['EditorAreaCSS'] = strtr($config['css_path'], array(
|
||||
'%b' => base_path(),
|
||||
'%t' => drupal_get_path('theme', variable_get('theme_default', NULL)),
|
||||
'%q' => variable_get('css_js_query_string', ''),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,22 +242,30 @@ function wysiwyg_fckeditor_settings($editor, $config, $theme) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array of native external plugins that need to be loaded separately.
|
||||
* Build a JS settings array with global metadata for native external plugins.
|
||||
*/
|
||||
function wysiwyg_fckeditor_plugin_settings($editor, $profile, $plugins) {
|
||||
function _wysiwyg_fckeditor_plugin_meta($editor, $plugin) {
|
||||
$meta = array();
|
||||
// Add path for native external plugins; internal ones do not need a path.
|
||||
if (empty($plugin['internal']) && isset($plugin['path'])) {
|
||||
// All native FCKeditor plugins use the filename fckplugin.js.
|
||||
$meta['path'] = base_path() . $plugin['path'] . '/';
|
||||
}
|
||||
if (!empty($plugin['languages'])) {
|
||||
$meta['languages'] = $plugin['languages'];
|
||||
}
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array for native external plugins.
|
||||
*/
|
||||
function _wysiwyg_fckeditor_plugin_settings($editor, $profile, $plugins) {
|
||||
$settings = array();
|
||||
foreach ($plugins as $name => $plugin) {
|
||||
// Register all plugins that need to be loaded.
|
||||
if (!empty($plugin['load'])) {
|
||||
$settings[$name] = array();
|
||||
// Add path for native external plugins; internal ones do not need a path.
|
||||
if (empty($plugin['internal']) && isset($plugin['path'])) {
|
||||
// All native FCKeditor plugins use the filename fckplugin.js.
|
||||
$settings[$name]['path'] = base_path() . $plugin['path'] . '/';
|
||||
}
|
||||
if (!empty($plugin['languages'])) {
|
||||
$settings[$name]['languages'] = $plugin['languages'];
|
||||
}
|
||||
// Just need a list of all enabled plugins for each instance.
|
||||
$settings[$name] = TRUE;
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
@@ -193,25 +274,20 @@ function wysiwyg_fckeditor_plugin_settings($editor, $profile, $plugins) {
|
||||
/**
|
||||
* Build a JS settings array for Drupal plugins loaded via the proxy plugin.
|
||||
*/
|
||||
function wysiwyg_fckeditor_proxy_plugin_settings($editor, $profile, $plugins) {
|
||||
function _wysiwyg_fckeditor_proxy_plugin_settings($editor, $profile, $plugins) {
|
||||
$settings = array();
|
||||
foreach ($plugins as $name => $plugin) {
|
||||
// Populate required plugin settings.
|
||||
$settings[$name] = $plugin['dialog settings'] + array(
|
||||
'title' => $plugin['title'],
|
||||
'icon' => base_path() . $plugin['icon path'] . '/' . $plugin['icon file'],
|
||||
'iconTitle' => $plugin['icon title'],
|
||||
// @todo These should only be set if the plugin defined them.
|
||||
'css' => base_path() . $plugin['css path'] . '/' . $plugin['css file'],
|
||||
);
|
||||
// Just need a list of all enabled plugins for each instance.
|
||||
$settings[$name] = TRUE;
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_fckeditor_plugins($editor) {
|
||||
function _wysiwyg_fckeditor_plugins($editor) {
|
||||
$plugins = array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
|
||||
Executable → Regular
+129
-78
@@ -1,36 +1,64 @@
|
||||
(function($) {
|
||||
|
||||
Drupal.wysiwyg.editor.init.ckeditor = function(settings) {
|
||||
// Plugins must only be loaded once. Only the settings from the first format
|
||||
// will be used but they're identical anyway.
|
||||
var registeredPlugins = {};
|
||||
for (var format in settings) {
|
||||
if (Drupal.settings.wysiwyg.plugins[format]) {
|
||||
// Register native external plugins.
|
||||
// Array syntax required; 'native' is a predefined token in JavaScript.
|
||||
for (var pluginName in Drupal.settings.wysiwyg.plugins[format]['native']) {
|
||||
if (!registeredPlugins[pluginName]) {
|
||||
var plugin = Drupal.settings.wysiwyg.plugins[format]['native'][pluginName];
|
||||
CKEDITOR.plugins.addExternal(pluginName, plugin.path, plugin.fileName);
|
||||
registeredPlugins[pluginName] = true;
|
||||
}
|
||||
}
|
||||
// Register Drupal plugins.
|
||||
for (var pluginName in Drupal.settings.wysiwyg.plugins[format].drupal) {
|
||||
if (!registeredPlugins[pluginName]) {
|
||||
Drupal.wysiwyg.editor.instance.ckeditor.addPlugin(pluginName, Drupal.settings.wysiwyg.plugins[format].drupal[pluginName], Drupal.settings.wysiwyg.plugins.drupal[pluginName]);
|
||||
registeredPlugins[pluginName] = true;
|
||||
}
|
||||
}
|
||||
CKEDITOR.disableAutoInline = true;
|
||||
|
||||
// Exclude every id starting with 'cke_' in ajax_html_ids during AJAX requests.
|
||||
Drupal.wysiwyg.excludeIdSelectors.wysiwyg_ckeditor = ['[id^="cke_"]'];
|
||||
|
||||
// Keeps track of private instance data.
|
||||
var instanceMap;
|
||||
|
||||
/**
|
||||
* Initialize the editor library.
|
||||
*
|
||||
* This method is called once the first time a library is needed. If new
|
||||
* WYSIWYG fieldsare added later, update() will be called instead.
|
||||
*
|
||||
* @param settings
|
||||
* An object containing editor settings for each input format.
|
||||
* @param pluginInfo
|
||||
* An object containing global plugin configuration.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.init.ckeditor = function(settings, pluginInfo) {
|
||||
instanceMap = {};
|
||||
// Nothing to do here other than register new plugins etc.
|
||||
Drupal.wysiwyg.editor.update.ckeditor(settings, pluginInfo);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the editor library when new settings are available.
|
||||
*
|
||||
* This method is called instead of init() when at least one new WYSIWYG field
|
||||
* has been added to the document and the library has already been initialized.
|
||||
*
|
||||
* $param settings
|
||||
* An object containing editor settings for each input format.
|
||||
* $param pluginInfo
|
||||
* An object containing global plugin configuration.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.update.ckeditor = function(settings, pluginInfo) {
|
||||
// Register native external plugins.
|
||||
// Array syntax required; 'native' is a predefined token in JavaScript.
|
||||
for (var pluginId in pluginInfo['native']) {
|
||||
if (pluginInfo['native'].hasOwnProperty(pluginId) && (!CKEDITOR.plugins.externals || !CKEDITOR.plugins.externals[pluginId])) {
|
||||
var plugin = pluginInfo['native'][pluginId];
|
||||
CKEDITOR.plugins.addExternal(pluginId, plugin.path, plugin.fileName);
|
||||
}
|
||||
// Register Font styles (versions 3.2.1 and above).
|
||||
if (Drupal.settings.wysiwyg.configs.ckeditor[format].stylesSet) {
|
||||
CKEDITOR.stylesSet.add(format, Drupal.settings.wysiwyg.configs.ckeditor[format].stylesSet);
|
||||
}
|
||||
// Build and register Drupal plugin wrappers.
|
||||
for (var pluginId in pluginInfo.drupal) {
|
||||
if (pluginInfo.drupal.hasOwnProperty(pluginId) && (!CKEDITOR.plugins.registered || !CKEDITOR.plugins.registered[pluginId])) {
|
||||
Drupal.wysiwyg.editor.instance.ckeditor.addPlugin(pluginId, pluginInfo.drupal[pluginId]);
|
||||
}
|
||||
}
|
||||
// Register Font styles (versions 3.2.1 and above).
|
||||
for (var format in settings) {
|
||||
if (settings[format].stylesSet && (!CKEDITOR.stylesSet || !CKEDITOR.stylesSet.registered[format])) {
|
||||
CKEDITOR.stylesSet.add(format, settings[format].stylesSet);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
@@ -38,8 +66,10 @@ Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
|
||||
// Apply editor instance settings.
|
||||
CKEDITOR.config.customConfig = '';
|
||||
|
||||
var $drupalToolbar = $('#toolbar', Drupal.overlayChild ? window.parent.document : document);
|
||||
|
||||
var $drupalToolbars = $('#toolbar, #admin-menu', Drupal.overlayChild ? window.parent.document : document);
|
||||
if (!settings.height) {
|
||||
settings.height = $('#' + params.field).height();
|
||||
}
|
||||
settings.on = {
|
||||
instanceReady: function(ev) {
|
||||
var editor = ev.editor;
|
||||
@@ -49,7 +79,7 @@ Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
|
||||
var tags = CKEDITOR.tools.extend({}, dtd.$block, dtd.$listItem, dtd.$tableContent);
|
||||
// Set source formatting rules for each listed tag except <pre>.
|
||||
// Linebreaks can be inserted before or after opening and closing tags.
|
||||
if (settings.apply_source_formatting) {
|
||||
if (settings.simple_source_formatting) {
|
||||
// Mimic FCKeditor output, by breaking lines between tags.
|
||||
for (var tag in tags) {
|
||||
if (tag == 'pre') {
|
||||
@@ -85,16 +115,18 @@ Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
|
||||
},
|
||||
|
||||
pluginsLoaded: function(ev) {
|
||||
var wysiwygInstance = instanceMap[this.name];
|
||||
var enabledPlugins = wysiwygInstance.pluginInfo.instances.drupal;
|
||||
// Override the conversion methods to let Drupal plugins modify the data.
|
||||
var editor = ev.editor;
|
||||
if (editor.dataProcessor && Drupal.settings.wysiwyg.plugins[params.format]) {
|
||||
if (editor.dataProcessor && enabledPlugins) {
|
||||
editor.dataProcessor.toHtml = CKEDITOR.tools.override(editor.dataProcessor.toHtml, function(originalToHtml) {
|
||||
// Convert raw data for display in WYSIWYG mode.
|
||||
return function(data, fixForBody) {
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
|
||||
for (var plugin in enabledPlugins) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
|
||||
data = Drupal.wysiwyg.plugins[plugin].attach(data, Drupal.settings.wysiwyg.plugins.drupal[plugin], editor.name);
|
||||
data = Drupal.wysiwyg.instances[params.field].prepareContent(data);
|
||||
data = Drupal.wysiwyg.plugins[plugin].attach(data, wysiwygInstance.pluginInfo.global.drupal[plugin], editor.name);
|
||||
data = wysiwygInstance.prepareContent(data);
|
||||
}
|
||||
}
|
||||
return originalToHtml.call(this, data, fixForBody);
|
||||
@@ -104,9 +136,9 @@ Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
|
||||
// Convert WYSIWYG mode content to raw data.
|
||||
return function(data, fixForBody) {
|
||||
data = originalToDataFormat.call(this, data, fixForBody);
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
|
||||
for (var plugin in enabledPlugins) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
|
||||
data = Drupal.wysiwyg.plugins[plugin].detach(data, Drupal.settings.wysiwyg.plugins.drupal[plugin], editor.name);
|
||||
data = Drupal.wysiwyg.plugins[plugin].detach(data, wysiwygInstance.pluginInfo.global.drupal[plugin], editor.name);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
@@ -116,16 +148,15 @@ Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
|
||||
},
|
||||
|
||||
selectionChange: function (event) {
|
||||
var pluginSettings = Drupal.settings.wysiwyg.plugins[params.format];
|
||||
if (pluginSettings && pluginSettings.drupal) {
|
||||
$.each(pluginSettings.drupal, function (name) {
|
||||
var plugin = Drupal.wysiwyg.plugins[name];
|
||||
if ($.isFunction(plugin.isNode)) {
|
||||
var node = event.data.selection.getSelectedElement();
|
||||
var state = plugin.isNode(node ? node.$ : null) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
|
||||
event.editor.getCommand(name).setState(state);
|
||||
}
|
||||
});
|
||||
var wysiwygInstance = instanceMap[this.name];
|
||||
var enabledPlugins = wysiwygInstance.pluginInfo.instances.drupal;
|
||||
for (var name in enabledPlugins) {
|
||||
var plugin = Drupal.wysiwyg.plugins[name];
|
||||
if ($.isFunction(plugin.isNode)) {
|
||||
var node = event.data.selection.getSelectedElement();
|
||||
var state = plugin.isNode(node ? node.$ : null) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
|
||||
event.editor.getCommand(name).setState(state);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -139,52 +170,46 @@ Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
|
||||
return;
|
||||
}
|
||||
if (ev.data.command.state == CKEDITOR.TRISTATE_ON) {
|
||||
$drupalToolbar.hide();
|
||||
$drupalToolbars.hide();
|
||||
}
|
||||
else {
|
||||
$drupalToolbar.show();
|
||||
$drupalToolbars.show();
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function (event) {
|
||||
// Free our reference to the private instance to not risk memory leaks.
|
||||
delete instanceMap[this.name];
|
||||
}
|
||||
};
|
||||
|
||||
instanceMap[params.field] = this;
|
||||
// Attach editor.
|
||||
CKEDITOR.replace(params.field, settings);
|
||||
var editorInstance = CKEDITOR.replace(params.field, settings);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*
|
||||
* @todo 3.x: editor.prototype.getInstances() should always return an array
|
||||
* containing all instances or the passed in params.field instance, but
|
||||
* always return an array to simplify all detach functions.
|
||||
* Detach a single editor instance.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.ckeditor = function (context, params, trigger) {
|
||||
var method = (trigger == 'serialize') ? 'updateElement' : 'destroy';
|
||||
if (typeof params != 'undefined') {
|
||||
var instance = CKEDITOR.instances[params.field];
|
||||
if (instance) {
|
||||
instance[method]();
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (var instanceName in CKEDITOR.instances) {
|
||||
if (CKEDITOR.instances.hasOwnProperty(instanceName)) {
|
||||
CKEDITOR.instances[instanceName][method]();
|
||||
}
|
||||
}
|
||||
var instance = CKEDITOR.instances[params.field];
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
instance[method]();
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.ckeditor = {
|
||||
addPlugin: function(pluginName, settings, pluginSettings) {
|
||||
addPlugin: function (pluginName, pluginSettings) {
|
||||
CKEDITOR.plugins.add(pluginName, {
|
||||
// Wrap Drupal plugin in a proxy pluygin.
|
||||
init: function(editor) {
|
||||
if (settings.css) {
|
||||
if (pluginSettings.css) {
|
||||
editor.on('mode', function(ev) {
|
||||
if (ev.editor.mode == 'wysiwyg') {
|
||||
// Inject CSS files directly into the editing area head tag.
|
||||
$('head', $('#cke_contents_' + ev.editor.name + ' iframe').eq(0).contents()).append('<link rel="stylesheet" href="' + settings.css + '" type="text/css" >');
|
||||
var iframe = $('#cke_contents_' + ev.editor.name + ' iframe, #' + ev.editor.id + '_contents iframe');
|
||||
$('head', iframe.eq(0).contents()).append('<link rel="stylesheet" href="' + pluginSettings.css + '" type="text/css" >');
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -199,12 +224,7 @@ Drupal.wysiwyg.editor.instance.ckeditor = {
|
||||
data.node = data.node.$;
|
||||
}
|
||||
if (selection.getType() == CKEDITOR.SELECTION_TEXT) {
|
||||
if (CKEDITOR.env.ie) {
|
||||
data.content = selection.getNative().createRange().text;
|
||||
}
|
||||
else {
|
||||
data.content = selection.getNative().toString();
|
||||
}
|
||||
data.content = selection.getSelectedText();
|
||||
}
|
||||
else if (data.node) {
|
||||
// content is supposed to contain the "outerHTML".
|
||||
@@ -217,9 +237,9 @@ Drupal.wysiwyg.editor.instance.ckeditor = {
|
||||
editor.addCommand(pluginName, pluginCommand);
|
||||
}
|
||||
editor.ui.addButton(pluginName, {
|
||||
label: settings.iconTitle,
|
||||
label: pluginSettings.title,
|
||||
command: pluginName,
|
||||
icon: settings.icon
|
||||
icon: pluginSettings.icon
|
||||
});
|
||||
|
||||
// @todo Add button state handling.
|
||||
@@ -233,7 +253,33 @@ Drupal.wysiwyg.editor.instance.ckeditor = {
|
||||
|
||||
insert: function(content) {
|
||||
content = this.prepareContent(content);
|
||||
CKEDITOR.instances[this.field].insertHtml(content);
|
||||
if (CKEDITOR.env.webkit || CKEDITOR.env.chrome || CKEDITOR.env.opera || CKEDITOR.env.safari) {
|
||||
// Works around a WebKit bug which removes wrapper elements.
|
||||
// @see https://drupal.org/node/1927968
|
||||
var tmp = new CKEDITOR.dom.element('div'), children, skip = 0, item;
|
||||
tmp.setHtml(content);
|
||||
children = tmp.getChildren();
|
||||
skip = 0;
|
||||
while (children.count() > skip) {
|
||||
item = children.getItem(skip);
|
||||
switch(item.type) {
|
||||
case 1:
|
||||
CKEDITOR.instances[this.field].insertElement(item);
|
||||
break;
|
||||
case 3:
|
||||
CKEDITOR.instances[this.field].insertText(item.getText());
|
||||
skip++;
|
||||
break;
|
||||
case 8:
|
||||
CKEDITOR.instances[this.field].insertHtml(item.getOuterHtml());
|
||||
skip++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
CKEDITOR.instances[this.field].insertHtml(content);
|
||||
}
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
@@ -242,6 +288,11 @@ Drupal.wysiwyg.editor.instance.ckeditor = {
|
||||
|
||||
getContent: function () {
|
||||
return CKEDITOR.instances[this.field].getData();
|
||||
},
|
||||
|
||||
isFullscreen: function () {
|
||||
var cmd = CKEDITOR.instances[this.field].commands.maximize;
|
||||
return !!(cmd && cmd.state == CKEDITOR.TRISTATE_ON);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Executable → Regular
+141
-12
@@ -4,10 +4,15 @@
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.epiceditor = function (context, params, settings) {
|
||||
var $target = $('#' + params.field);
|
||||
var containerId = params.field + '-epiceditor';
|
||||
var defaultContent = $target.val();
|
||||
$target.hide().after('<div id="' + containerId + '" />');
|
||||
var $target = $('#' + params.field),
|
||||
containerId = params.field + '-epiceditor',
|
||||
defaultContent = $target.val(),
|
||||
$container = $('<div id="' + containerId + '" />');
|
||||
$target.hide().after($container);
|
||||
if (!settings.height) {
|
||||
settings.height = $('#' + params.field).height();
|
||||
}
|
||||
$container.height(settings.height);
|
||||
|
||||
settings.container = containerId;
|
||||
settings.file = {
|
||||
@@ -16,23 +21,147 @@ Drupal.wysiwyg.editor.attach.epiceditor = function (context, params, settings) {
|
||||
settings.theme = {
|
||||
preview: '/themes/preview/preview-dark.css',
|
||||
editor: '/themes/editor/' + settings.theme + '.css'
|
||||
}
|
||||
};
|
||||
var editor = new EpicEditor(settings).load();
|
||||
$target.data('epiceditor', editor);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
* Detach a single edtor instance.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.epiceditor = function (context, params, trigger) {
|
||||
var $target = $('#' + params.field);
|
||||
var $target = $('#' + params.field, context);
|
||||
var editor = $target.data('epiceditor');
|
||||
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
// Save contents of the editor back into the textarea.
|
||||
$target.val(editor.exportFile());
|
||||
|
||||
editor.unload(function () {
|
||||
$target.show();
|
||||
});
|
||||
if (trigger !== 'serialize') {
|
||||
// Remove editor instance and container.
|
||||
editor.unload(function () {
|
||||
$target.show();
|
||||
$('#' + $target.attr('id') + '-epiceditor').remove();
|
||||
});
|
||||
$target.removeData('epiceditor');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if a DOM node is inside another or if they are the same.
|
||||
*/
|
||||
function isInside (innerNode, outerNode) {
|
||||
var found = false;
|
||||
if (innerNode === outerNode) {
|
||||
return true;
|
||||
}
|
||||
$(innerNode).parents().each(function (index, parent) {
|
||||
if (parent === outerNode) {
|
||||
found = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts HTML markup to plain text.
|
||||
*
|
||||
* EpicEditor isn't WYSIWYG and is meant to handle plain text though it does so
|
||||
* in a contentEditable element. This is taken from EpicEditor's internal
|
||||
* _setText() function in version 0.2.0.
|
||||
*/
|
||||
function toPlainText (content) {
|
||||
content = content.replace(/</g, '<');
|
||||
content = content.replace(/>/g, '>');
|
||||
content = content.replace(/\n/g, '<br>');
|
||||
content = content.replace(/\s\s/g, ' ')
|
||||
return content;
|
||||
}
|
||||
|
||||
Drupal.wysiwyg.editor.instance.epiceditor = {
|
||||
insert: function (content) {
|
||||
var instance = this.getInstance();
|
||||
var editingArea = instance.getElement('editor').body;
|
||||
// IE.
|
||||
// @todo Can't test this, EpicEditor breaks in IE.
|
||||
if (document.selection) {
|
||||
var sel = editingArea.selection;
|
||||
range = sel.createRange();
|
||||
// If the caret is not in the editing area, just append the content.
|
||||
if (!isInside(range.parentElement(), editingArea)) {
|
||||
editingArea.innerHTML += toPlainText(content);
|
||||
}
|
||||
else {
|
||||
// Insert content and set the caret after it.
|
||||
range.pasteHTML(content);
|
||||
range.select();
|
||||
range.collapse(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The code below doesn't work in IE, but it never gets here.
|
||||
var sel = editingArea.ownerDocument.getSelection();
|
||||
|
||||
// Convert selection to a range.
|
||||
// W3C compatible.
|
||||
if (sel.getRangeAt) {
|
||||
if (sel.rangeCount > 0) {
|
||||
range = sel.getRangeAt(0);
|
||||
}
|
||||
}
|
||||
// Safari.
|
||||
else {
|
||||
range = editingArea.ownerDocument.createRange();
|
||||
range.setStart(sel.anchorNode, sel.anchorOffset);
|
||||
range.setEnd(sel.focusNode, userSeletion.focusOffset);
|
||||
}
|
||||
// If the caret is not in the editing area, just append the content.
|
||||
if (sel.rangeCount == 0 || !isInside(range.commonAncestorContainer, editingArea)) {
|
||||
editingArea.innerHTML += toPlainText(content);
|
||||
return;
|
||||
}
|
||||
|
||||
var fragment = editingArea.ownerDocument.createDocumentFragment();
|
||||
// Fragments don't support innerHTML.
|
||||
var wrapper = editingArea.ownerDocument.createElement('div');
|
||||
wrapper.innerHTML = toPlainText(content);
|
||||
while (wrapper.firstChild) {
|
||||
fragment.appendChild(wrapper.firstChild);
|
||||
}
|
||||
// Append a temporary node to control caret position.
|
||||
var tn = editingArea.ownerDocument.createElement('span');
|
||||
fragment.appendChild(tn);
|
||||
range.deleteContents();
|
||||
// Only fragment children are inserted.
|
||||
range.insertNode(fragment);
|
||||
// Move caret to temp node and remove it.
|
||||
range.setStartBefore(tn);
|
||||
range.setEndBefore(tn);
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
tn.parentNode.removeChild(tn);
|
||||
}
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
this.getInstance().importFile(null, content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
return this.getInstance().exportFile();
|
||||
},
|
||||
|
||||
isFullscreen: function () {
|
||||
return this.getInstance().is('fullscreen');
|
||||
},
|
||||
|
||||
getInstance: function () {
|
||||
if (!this.editorInstance) {
|
||||
this.editorInstance = $('#' + this.field).data('epiceditor');
|
||||
}
|
||||
return this.editorInstance;
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
|
||||
Executable → Regular
+54
-52
@@ -4,7 +4,14 @@
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.fckeditor = function(context, params, settings) {
|
||||
if (!settings.Height) {
|
||||
settings.Height = $('#' + params.field).height();
|
||||
}
|
||||
var FCKinstance = new FCKeditor(params.field, settings.Width, settings.Height, settings.ToolbarSet);
|
||||
// Keep track of the settings for this instance.
|
||||
this.editorSettings = settings;
|
||||
// Temporarily store the private instance for use in the config file.
|
||||
$('#' + params.field, context).data('wysiwygInstance', this);
|
||||
// Apply editor instance settings.
|
||||
FCKinstance.BasePath = settings.EditorPath;
|
||||
FCKinstance.Config.wysiwygFormat = params.format;
|
||||
@@ -19,52 +26,46 @@ Drupal.wysiwyg.editor.attach.fckeditor = function(context, params, settings) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
* Detach a single editor instance.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.fckeditor = function (context, params, trigger) {
|
||||
var instances = [];
|
||||
if (typeof params != 'undefined' && typeof FCKeditorAPI != 'undefined') {
|
||||
var instance = FCKeditorAPI.GetInstance(params.field);
|
||||
if (instance) {
|
||||
instances[params.field] = instance;
|
||||
}
|
||||
var instanceName = params.field;
|
||||
var instance = FCKeditorAPI.GetInstance(instanceName);
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
instances = FCKeditorAPI.__Instances;
|
||||
instance.UpdateLinkedField();
|
||||
if (trigger == 'serialize') {
|
||||
// The editor is not being removed from the DOM, so updating the linked
|
||||
// field is the only action necessary.
|
||||
return;
|
||||
}
|
||||
|
||||
for (var instanceName in instances) {
|
||||
var instance = instances[instanceName];
|
||||
instance.UpdateLinkedField();
|
||||
if (trigger == 'serialize') {
|
||||
// The editor is not being removed from the DOM, so updating the linked
|
||||
// field is the only action necessary.
|
||||
continue;
|
||||
}
|
||||
// Since we already detach the editor and update the textarea, the submit
|
||||
// event handler needs to be removed to prevent data loss (in IE).
|
||||
// FCKeditor uses 2 nested iFrames; instance.EditingArea.Window is the
|
||||
// deepest. Its parent is the iFrame containing the editor.
|
||||
var instanceScope = instance.EditingArea.Window.parent;
|
||||
instanceScope.FCKTools.RemoveEventListener(instance.GetParentForm(), 'submit', instance.UpdateLinkedField);
|
||||
// Run cleanups before forcing an unload of the iFrames or IE crashes.
|
||||
// This also deletes the instance from the FCKeditorAPI.__Instances array.
|
||||
instanceScope.FCKTools.RemoveEventListener(instanceScope, 'unload', instanceScope.FCKeditorAPI_Cleanup);
|
||||
instanceScope.FCKTools.RemoveEventListener(instanceScope, 'beforeunload', instanceScope.FCKeditorAPI_ConfirmCleanup);
|
||||
if (jQuery.isFunction(instanceScope.FCKIECleanup_Cleanup)) {
|
||||
instanceScope.FCKIECleanup_Cleanup();
|
||||
}
|
||||
instanceScope.FCKeditorAPI_ConfirmCleanup();
|
||||
instanceScope.FCKeditorAPI_Cleanup();
|
||||
// Remove the editor elements.
|
||||
$('#' + instanceName + '___Config').remove();
|
||||
$('#' + instanceName + '___Frame').remove();
|
||||
$('#' + instanceName).show();
|
||||
// Since we already detach the editor and update the textarea, the submit
|
||||
// event handler needs to be removed to prevent data loss (in IE).
|
||||
// FCKeditor uses 2 nested iFrames; instance.EditingArea.Window is the
|
||||
// deepest. Its parent is the iFrame containing the editor.
|
||||
var instanceScope = instance.EditingArea.Window.parent;
|
||||
instanceScope.FCKTools.RemoveEventListener(instance.GetParentForm(), 'submit', instance.UpdateLinkedField);
|
||||
// Run cleanups before forcing an unload of the iFrames or IE crashes.
|
||||
// This also deletes the instance from the FCKeditorAPI.__Instances array.
|
||||
instanceScope.FCKTools.RemoveEventListener(instanceScope, 'unload', instanceScope.FCKeditorAPI_Cleanup);
|
||||
instanceScope.FCKTools.RemoveEventListener(instanceScope, 'beforeunload', instanceScope.FCKeditorAPI_ConfirmCleanup);
|
||||
if (jQuery.isFunction(instanceScope.FCKIECleanup_Cleanup)) {
|
||||
instanceScope.FCKIECleanup_Cleanup();
|
||||
}
|
||||
instanceScope.FCKeditorAPI_ConfirmCleanup();
|
||||
instanceScope.FCKeditorAPI_Cleanup();
|
||||
// Remove the editor elements.
|
||||
$('#' + instanceName + '___Config').remove();
|
||||
$('#' + instanceName + '___Frame').remove();
|
||||
$('#' + instanceName).show();
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.fckeditor = {
|
||||
init: function(instance) {
|
||||
var wysiwygInstance = instance.wysiwygInstance;
|
||||
var pluginInfo = wysiwygInstance.pluginInfo;
|
||||
var enabledPlugins = pluginInfo.instances.drupal;
|
||||
// Track which editor instance is active.
|
||||
instance.FCK.Events.AttachEvent('OnFocus', function(editorInstance) {
|
||||
Drupal.wysiwyg.activeId = editorInstance.Name;
|
||||
@@ -79,12 +80,10 @@ Drupal.wysiwyg.editor.instance.fckeditor = {
|
||||
// Called from SetData() with stripped comments/scripts, revert those
|
||||
// manipulations and attach Drupal plugins.
|
||||
var data = instance.FCKConfig.ProtectedSource.Revert(data);
|
||||
if (Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat] && Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal) {
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
|
||||
data = Drupal.wysiwyg.plugins[plugin].attach(data, Drupal.settings.wysiwyg.plugins.drupal[plugin], instance.FCK.Name);
|
||||
data = Drupal.wysiwyg.editor.instance.fckeditor.prepareContent(data);
|
||||
}
|
||||
for (var plugin in enabledPlugins) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
|
||||
data = Drupal.wysiwyg.plugins[plugin].attach(data, pluginInfo.global.drupal[plugin], instance.FCK.Name);
|
||||
data = Drupal.wysiwyg.editor.instance.fckeditor.prepareContent(data);
|
||||
}
|
||||
}
|
||||
// Re-protect the source and use the original data processor to convert it
|
||||
@@ -97,11 +96,9 @@ Drupal.wysiwyg.editor.instance.fckeditor = {
|
||||
// Called from GetData(), convert the content's DOM into a XHTML string
|
||||
// using the original data processor and detach Drupal plugins.
|
||||
var data = instance.FCKDataProcessor.prototype.ConvertToDataFormat.call(this, rootNode, excludeRoot, ignoreIfEmptyParagraph, format);
|
||||
if (Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat] && Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal) {
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
|
||||
data = Drupal.wysiwyg.plugins[plugin].detach(data, Drupal.settings.wysiwyg.plugins.drupal[plugin], instance.FCK.Name);
|
||||
}
|
||||
for (var plugin in enabledPlugins) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
|
||||
data = Drupal.wysiwyg.plugins[plugin].detach(data, pluginInfo.global.drupal[plugin], instance.FCK.Name);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
@@ -109,13 +106,13 @@ Drupal.wysiwyg.editor.instance.fckeditor = {
|
||||
instance.FCK.DataProcessor = new wysiwygDataProcessor();
|
||||
},
|
||||
|
||||
addPlugin: function(plugin, settings, pluginSettings, instance) {
|
||||
addPlugin: function(plugin, pluginSettings, instance) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal[plugin].css) {
|
||||
instance.FCKConfig.EditorAreaCSS += ',' + Drupal.settings.wysiwyg.plugins[instance.wysiwygFormat].drupal[plugin].css;
|
||||
if (pluginSettings.css) {
|
||||
instance.FCKConfig.EditorAreaCSS += ',' + pluginSettings.css;
|
||||
}
|
||||
|
||||
// @see fckcommands.js, fck_othercommands.js, fckpastewordcommand.js
|
||||
@@ -160,7 +157,7 @@ Drupal.wysiwyg.editor.instance.fckeditor = {
|
||||
|
||||
// Register the plugin button.
|
||||
// Arguments: commandName, label, tooltip, style, sourceView, contextSensitive, icon.
|
||||
instance.FCKToolbarItems.RegisterItem(plugin, new instance.FCKToolbarButton(plugin, settings.iconTitle, settings.iconTitle, null, false, true, settings.icon));
|
||||
instance.FCKToolbarItems.RegisterItem(plugin, new instance.FCKToolbarButton(plugin, pluginSettings.title, pluginSettings.title, null, false, true, pluginSettings.icon));
|
||||
},
|
||||
|
||||
openDialog: function(dialog, params) {
|
||||
@@ -190,6 +187,11 @@ Drupal.wysiwyg.editor.instance.fckeditor = {
|
||||
setContent: function (content) {
|
||||
var instance = FCKeditorAPI.GetInstance(this.field);
|
||||
instance.SetHTML(content);
|
||||
},
|
||||
|
||||
isFullscreen: function () {
|
||||
var cmd = FCKeditorAPI.GetInstance(this.field).Commands.LoadedCommands.FitWindow;
|
||||
return !!(cmd && cmd.IsMaximized);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Executable → Regular
+15
-11
@@ -8,9 +8,12 @@ Drupal = window.parent.Drupal;
|
||||
* Instance settings passed to FCKinstance.Config are temporarily stored in
|
||||
* FCKConfig.PageConfig.
|
||||
*/
|
||||
var wysiwygFormat = FCKConfig.PageConfig.wysiwygFormat;
|
||||
var wysiwygSettings = Drupal.settings.wysiwyg.configs.fckeditor[wysiwygFormat];
|
||||
var pluginSettings = (Drupal.settings.wysiwyg.plugins[wysiwygFormat] ? Drupal.settings.wysiwyg.plugins[wysiwygFormat] : { 'native': {}, 'drupal': {} });
|
||||
// Fetch the private instance and make sure nothing can tamper with it.
|
||||
var $field = window.parent.jQuery(FCK.LinkedField);
|
||||
var wysiwygInstance = $field.data('wysiwygInstance');
|
||||
$field.removeData('wysiwygInstance');
|
||||
var wysiwygSettings = wysiwygInstance.editorSettings;
|
||||
var pluginInfo = wysiwygInstance.pluginInfo;
|
||||
|
||||
/**
|
||||
* Apply format-specific settings.
|
||||
@@ -42,21 +45,21 @@ for (var setting in wysiwygSettings) {
|
||||
|
||||
// Fix Drupal toolbar obscuring editor toolbar in fullscreen mode.
|
||||
var oldFitWindowExecute = FCKFitWindow.prototype.Execute;
|
||||
var $drupalToolbar = window.parent.jQuery('#toolbar', Drupal.overlayChild ? window.parent.window.parent.document : window.parent.document);
|
||||
var $drupalToolbars = window.parent.jQuery('#toolbar, #admin-menu', Drupal.overlayChild ? window.parent.window.parent.document : window.parent.document);
|
||||
FCKFitWindow.prototype.Execute = function() {
|
||||
oldFitWindowExecute.apply(this, arguments);
|
||||
if (this.IsMaximized) {
|
||||
$drupalToolbar.hide();
|
||||
$drupalToolbars.hide();
|
||||
}
|
||||
else {
|
||||
$drupalToolbar.show();
|
||||
$drupalToolbars.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this editor instance.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.instance.fckeditor.init(window);
|
||||
wysiwygInstance.init(window);
|
||||
|
||||
/**
|
||||
* Register native plugins for this input format.
|
||||
@@ -66,9 +69,9 @@ Drupal.wysiwyg.editor.instance.fckeditor.init(window);
|
||||
* - Languages the plugin is available in.
|
||||
* - Location of the plugin folder; <plugin_name>/fckplugin.js is appended.
|
||||
*/
|
||||
for (var plugin in pluginSettings['native']) {
|
||||
for (var pluginId in pluginInfo.instances['native']) {
|
||||
// Languages and path may be undefined for internal plugins.
|
||||
FCKConfig.Plugins.Add(plugin, pluginSettings['native'][plugin].languages, pluginSettings['native'][plugin].path);
|
||||
FCKConfig.Plugins.Add(pluginId, pluginInfo.global['native'][pluginId].languages, pluginInfo.global['native'][pluginId].path);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +83,8 @@ for (var plugin in pluginSettings['native']) {
|
||||
* - General plugin settings.
|
||||
* - A reference to this window so the plugin setup can access FCKConfig.
|
||||
*/
|
||||
for (var plugin in pluginSettings.drupal) {
|
||||
Drupal.wysiwyg.editor.instance.fckeditor.addPlugin(plugin, pluginSettings.drupal[plugin], Drupal.settings.wysiwyg.plugins.drupal[plugin], window);
|
||||
for (var pluginId in pluginInfo.instances.drupal) {
|
||||
var plugin = pluginInfo.instances.drupal[pluginId];
|
||||
Drupal.wysiwyg.editor.instance.fckeditor.addPlugin(pluginId, pluginInfo.global.drupal[pluginId], window);
|
||||
}
|
||||
|
||||
|
||||
Executable → Regular
+2
-2
@@ -5,11 +5,11 @@
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.jwysiwyg = function(context, params, settings) {
|
||||
// Attach editor.
|
||||
$('#' + params.field).wysiwyg();
|
||||
$('#' + params.field).wysiwyg(settings);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
* Detach a single editor instance.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.jwysiwyg = function (context, params, trigger) {
|
||||
var $field = $('#' + params.field);
|
||||
|
||||
Executable → Regular
+1
-6
@@ -21,12 +21,7 @@ Drupal.wysiwyg.editor.detach.markitup = function (context, params, trigger) {
|
||||
if (trigger == 'serialize') {
|
||||
return;
|
||||
}
|
||||
if (typeof params != 'undefined') {
|
||||
$('#' + params.field, context).markItUpRemove();
|
||||
}
|
||||
else {
|
||||
$('.markItUpEditor', context).markItUpRemove();
|
||||
}
|
||||
$('#' + params.field, context).markItUpRemove();
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.markitup = {
|
||||
|
||||
Executable → Regular
+61
-38
@@ -26,62 +26,70 @@ Drupal.wysiwyg.editor.attach.nicedit = function(context, params, settings) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.detach.none() for a full description of this hook.
|
||||
* Detach a single editor instance.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.nicedit = function (context, params, trigger) {
|
||||
if (typeof params != 'undefined') {
|
||||
var instance = nicEditors.findEditor(params.field);
|
||||
if (instance) {
|
||||
if (trigger == 'serialize') {
|
||||
instance.saveContent();
|
||||
}
|
||||
else {
|
||||
instance.ne.removeInstance(params.field);
|
||||
instance.ne.removePanel();
|
||||
}
|
||||
}
|
||||
var instance = nicEditors.findEditor(params.field);
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
if (trigger === 'serialize') {
|
||||
instance.saveContent();
|
||||
}
|
||||
else {
|
||||
for (var e in nicEditors.editors) {
|
||||
// Save contents of all editors back into textareas.
|
||||
var instances = nicEditors.editors[e].nicInstances;
|
||||
for (var i = 0; i < instances.length; i++) {
|
||||
if (trigger == 'serialize') {
|
||||
instances[i].saveContent();
|
||||
}
|
||||
else {
|
||||
instances[i].remove();
|
||||
}
|
||||
}
|
||||
// Remove all editor instances.
|
||||
if (trigger != 'serialize') {
|
||||
nicEditors.editors[e].nicInstances = [];
|
||||
}
|
||||
}
|
||||
instance.ne.removeInstance(params.field);
|
||||
instance.ne.removePanel();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if a DOM node is inside another or if they are the same.
|
||||
*/
|
||||
function isInside (innerNode, outerNode) {
|
||||
var found = false;
|
||||
if (innerNode === outerNode) {
|
||||
return true;
|
||||
}
|
||||
$(innerNode).parents().each(function (index, parent) {
|
||||
if (parent === outerNode) {
|
||||
found = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instance methods for nicEdit.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.instance.nicedit = {
|
||||
insert: function (content) {
|
||||
var instance = nicEditors.findEditor(this.field);
|
||||
var editingArea = instance.getElm();
|
||||
var sel = instance.getSel();
|
||||
var instance = nicEditors.findEditor(this.field),
|
||||
editingArea = instance.getElm(),
|
||||
sel = instance.getSel(), range;
|
||||
// IE.
|
||||
if (document.selection) {
|
||||
editingArea.focus();
|
||||
sel.createRange().pasteHTML(content);
|
||||
range = sel.createRange();
|
||||
// If the caret is not in the editing area, just append the content.
|
||||
if (!isInside(range.parentElement(), editingArea)) {
|
||||
editingArea.innerHTML += content;
|
||||
}
|
||||
else {
|
||||
// Insert content and set the caret after it.
|
||||
range.pasteHTML(content);
|
||||
range.select();
|
||||
range.collapse(false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The code below doesn't work in IE, but it never gets here.
|
||||
|
||||
// Convert selection to a range.
|
||||
var range;
|
||||
// W3C compatible.
|
||||
if (sel.getRangeAt) {
|
||||
range = sel.getRangeAt(0);
|
||||
if (sel.rangeCount > 0) {
|
||||
range = sel.getRangeAt(0);
|
||||
}
|
||||
}
|
||||
// Safari.
|
||||
else {
|
||||
@@ -89,7 +97,13 @@ Drupal.wysiwyg.editor.instance.nicedit = {
|
||||
range.setStart(sel.anchorNode, sel.anchorOffset);
|
||||
range.setEnd(sel.focusNode, userSeletion.focusOffset);
|
||||
}
|
||||
// The code below doesn't work in IE, but it never gets here.
|
||||
|
||||
// If the caret is not in the editing area, just append the content.
|
||||
if (sel.rangeCount == 0 || !isInside(range.commonAncestorContainer, editingArea)) {
|
||||
editingArea.innerHTML += content;
|
||||
return;
|
||||
}
|
||||
|
||||
var fragment = editingArea.ownerDocument.createDocumentFragment();
|
||||
// Fragments don't support innerHTML.
|
||||
var wrapper = editingArea.ownerDocument.createElement('div');
|
||||
@@ -97,9 +111,18 @@ Drupal.wysiwyg.editor.instance.nicedit = {
|
||||
while (wrapper.firstChild) {
|
||||
fragment.appendChild(wrapper.firstChild);
|
||||
}
|
||||
// Append a temporary node to control caret position.
|
||||
var tn = editingArea.ownerDocument.createElement('span');
|
||||
fragment.appendChild(tn);
|
||||
range.deleteContents();
|
||||
// Only fragment children are inserted.
|
||||
range.insertNode(fragment);
|
||||
// Move caret to temp node and remove it.
|
||||
range.setStartBefore(tn);
|
||||
range.setEndBefore(tn);
|
||||
sel.removeAllRanges();
|
||||
sel.addRange(range);
|
||||
tn.parentNode.removeChild(tn);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
Executable → Regular
+11
-9
@@ -15,26 +15,28 @@
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.none = function(context, params, settings) {
|
||||
if (params.resizable) {
|
||||
var $wrapper = $('#' + params.field).parents('.form-textarea-wrapper:first');
|
||||
var $wrapper = $('#' + params.field, context).parents('.form-textarea-wrapper:first');
|
||||
$wrapper.addClass('resizable');
|
||||
if (Drupal.behaviors.textarea) {
|
||||
Drupal.behaviors.textarea.attach();
|
||||
Drupal.behaviors.textarea.attach(context);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
* Detach a single editor instance.
|
||||
*
|
||||
* The editor syncs its contents back to the original field before its instance
|
||||
* is removed.
|
||||
*
|
||||
* In here, 'this' is an instance of WysiwygInternalInstance.
|
||||
* See Drupal.wysiwyg.editor.instance.none for more details.
|
||||
*
|
||||
* @param context
|
||||
* A DOM element, supplied by Drupal.attachBehaviors().
|
||||
* @param params
|
||||
* (optional) An object containing input format parameters. If defined,
|
||||
* only the editor instance in params.field should be detached. Otherwise,
|
||||
* all editors should be detached and saved, so they can be submitted in
|
||||
* An object containing input format parameters. Only the editor instance in
|
||||
* params.field should be detached and saved, so its data can be submitted in
|
||||
* AJAX/AHAH applications.
|
||||
* @param trigger
|
||||
* A string describing why the editor is being detached.
|
||||
@@ -47,9 +49,9 @@ Drupal.wysiwyg.editor.attach.none = function(context, params, settings) {
|
||||
* @see Drupal.detachBehaviors
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.none = function (context, params, trigger) {
|
||||
if (typeof params != 'undefined' && (trigger != 'serialize')) {
|
||||
var $wrapper = $('#' + params.field).parents('.form-textarea-wrapper:first');
|
||||
$wrapper.removeOnce('textarea').removeClass('.resizable-textarea')
|
||||
if (trigger != 'serialize') {
|
||||
var $wrapper = $('#' + params.field, context).parents('.form-textarea-wrapper:first');
|
||||
$wrapper.removeOnce('textarea').removeClass('.resizable-textarea').removeClass('resizable')
|
||||
.find('.grippie').remove();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
|
||||
// Backup $ and reset it to jQuery.
|
||||
Drupal.wysiwyg._openwysiwyg = $;
|
||||
$ = jQuery;
|
||||
|
||||
// Wrap openWYSIWYG's methods to temporarily use its version of $.
|
||||
jQuery.each(WYSIWYG, function (key, value) {
|
||||
if (jQuery.isFunction(value)) {
|
||||
WYSIWYG[key] = function () {
|
||||
var old$ = $;
|
||||
$ = Drupal.wysiwyg._openwysiwyg;
|
||||
var result = value.apply(this, arguments);
|
||||
$ = old$;
|
||||
return result;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Override editor functions.
|
||||
WYSIWYG.getEditor = function (n) {
|
||||
return Drupal.wysiwyg._openwysiwyg("wysiwyg" + n);
|
||||
};
|
||||
|
||||
(function($) {
|
||||
|
||||
// Fix Drupal toolbar obscuring editor toolbar in fullscreen mode.
|
||||
var oldMaximize = WYSIWYG.maximize;
|
||||
WYSIWYG.maximize = function (n) {
|
||||
var $drupalToolbar = $('#toolbar', Drupal.overlayChild ? window.parent.document : document);
|
||||
oldMaximize.apply(this, arguments);
|
||||
if (this.maximized[n]) {
|
||||
$drupalToolbar.hide();
|
||||
}
|
||||
else {
|
||||
$drupalToolbar.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.openwysiwyg = function(context, params, settings) {
|
||||
// Initialize settings.
|
||||
settings.ImagesDir = settings.path + 'images/';
|
||||
settings.PopupsDir = settings.path + 'popups/';
|
||||
settings.CSSFile = settings.path + 'styles/wysiwyg.css';
|
||||
//settings.DropDowns = [];
|
||||
var config = new WYSIWYG.Settings();
|
||||
for (var setting in settings) {
|
||||
config[setting] = settings[setting];
|
||||
}
|
||||
// Attach editor.
|
||||
WYSIWYG.setSettings(params.field, config);
|
||||
WYSIWYG_Core.includeCSS(WYSIWYG.config[params.field].CSSFile);
|
||||
WYSIWYG._generate(params.field, config);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.openwysiwyg = function (context, params, trigger) {
|
||||
if (typeof params != 'undefined') {
|
||||
var instance = WYSIWYG.config[params.field];
|
||||
if (typeof instance != 'undefined') {
|
||||
WYSIWYG.updateTextArea(params.field);
|
||||
if (trigger != 'serialize') {
|
||||
jQuery('#wysiwyg_div_' + params.field).remove();
|
||||
delete instance;
|
||||
}
|
||||
}
|
||||
if (trigger != 'serialize') {
|
||||
jQuery('#' + params.field).show();
|
||||
}
|
||||
}
|
||||
else {
|
||||
jQuery.each(WYSIWYG.config, function(field) {
|
||||
WYSIWYG.updateTextArea(field);
|
||||
if (trigger != 'serialize') {
|
||||
jQuery('#wysiwyg_div_' + field).remove();
|
||||
delete this;
|
||||
jQuery('#' + field).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Instance methods for openWYSIWYG.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.instance.openwysiwyg = {
|
||||
insert: function (content) {
|
||||
// If IE has dropped focus content will be inserted at the top of the page.
|
||||
$('#wysiwyg' + this.field).contents().find('body').focus();
|
||||
WYSIWYG.insertHTML(content, this.field);
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
// Based on openWYSIWYG's _generate() method.
|
||||
var doc = WYSIWYG.getEditorWindow(this.field).document;
|
||||
if (WYSIWYG.config[this.field].ReplaceLineBreaks) {
|
||||
content = content.replace(/\n\r|\n/ig, '<br />');
|
||||
}
|
||||
if (WYSIWYG.viewTextMode[this.field]) {
|
||||
var html = document.createTextNode(content);
|
||||
doc.body.innerHTML = '';
|
||||
doc.body.appendChild(html);
|
||||
}
|
||||
else {
|
||||
doc.open();
|
||||
doc.write(content);
|
||||
doc.close();
|
||||
}
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
// Based on openWYSIWYG's updateTextarea() method.
|
||||
var content = '';
|
||||
var doc = WYSIWYG.getEditorWindow(this.field).document;
|
||||
if (WYSIWYG.viewTextMode[this.field]) {
|
||||
if (WYSIWYG_Core.isMSIE) {
|
||||
content = doc.body.innerText;
|
||||
}
|
||||
else {
|
||||
var range = doc.body.ownerDocument.createRange();
|
||||
range.selectNodeContents(doc.body);
|
||||
content = range.toString();
|
||||
}
|
||||
}
|
||||
else {
|
||||
content = doc.body.innerHTML;
|
||||
}
|
||||
content = WYSIWYG.stripURLPath(this.field, content);
|
||||
content = WYSIWYG_Core.replaceRGBWithHexColor(content);
|
||||
if (WYSIWYG.config[this.field].ReplaceLineBreaks) {
|
||||
content = content.replace(/(\r\n)|(\n)/ig, '');
|
||||
}
|
||||
return content;
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,203 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Initialize editor instances.
|
||||
*
|
||||
* This function needs to be called before the page is fully loaded, as
|
||||
* calling tinyMCE.init() after the page is loaded breaks IE6.
|
||||
*
|
||||
* @param editorSettings
|
||||
* An object containing editor settings for each input format.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.init.tinymce = function(settings) {
|
||||
// Initialize editor configurations.
|
||||
for (var format in settings) {
|
||||
tinyMCE.init(settings[format]);
|
||||
if (Drupal.settings.wysiwyg.plugins[format]) {
|
||||
// Load native external plugins.
|
||||
// Array syntax required; 'native' is a predefined token in JavaScript.
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[format]['native']) {
|
||||
tinyMCE.loadPlugin(plugin, Drupal.settings.wysiwyg.plugins[format]['native'][plugin]);
|
||||
}
|
||||
// Load Drupal plugins.
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[format].drupal) {
|
||||
Drupal.wysiwyg.editor.instance.tinymce.addPlugin(plugin, Drupal.settings.wysiwyg.plugins[format].drupal[plugin], Drupal.settings.wysiwyg.plugins.drupal[plugin]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.attach.none() for a full desciption of this hook.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) {
|
||||
// Configure editor settings for this input format.
|
||||
for (var setting in settings) {
|
||||
tinyMCE.settings[setting] = settings[setting];
|
||||
}
|
||||
|
||||
// Remove TinyMCE's internal mceItem class, which was incorrectly added to
|
||||
// submitted content by Wysiwyg <2.1. TinyMCE only temporarily adds the class
|
||||
// for placeholder elements. If preemptively set, the class prevents (native)
|
||||
// editor plugins from gaining an active state, so we have to manually remove
|
||||
// it prior to attaching the editor. This is done on the client-side instead
|
||||
// of the server-side, as Wysiwyg has no way to figure out where content is
|
||||
// stored, and the class only affects editing.
|
||||
$field = $('#' + params.field);
|
||||
$field.val($field.val().replace(/(<.+?\s+class=['"][\w\s]*?)\bmceItem\b([\w\s]*?['"].*?>)/ig, '$1$2'));
|
||||
|
||||
// Attach editor.
|
||||
tinyMCE.execCommand('mceAddControl', true, params.field);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.tinymce = function (context, params, trigger) {
|
||||
if (typeof params != 'undefined') {
|
||||
tinyMCE.removeMCEControl(tinyMCE.getEditorId(params.field));
|
||||
$('#' + params.field).removeAttr('style');
|
||||
}
|
||||
// else if (tinyMCE.activeEditor) {
|
||||
// tinyMCE.triggerSave();
|
||||
// tinyMCE.activeEditor.remove();
|
||||
// }
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
addPlugin: function(plugin, settings, pluginSettings) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') {
|
||||
return;
|
||||
}
|
||||
tinyMCE.addPlugin(plugin, {
|
||||
|
||||
// Register an editor command for this plugin, invoked by the plugin's button.
|
||||
execCommand: function(editor_id, element, command, user_interface, value) {
|
||||
switch (command) {
|
||||
case plugin:
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') {
|
||||
var ed = tinyMCE.getInstanceById(editor_id);
|
||||
var data = { format: 'html', node: ed.getFocusElement(), content: ed.getFocusElement() };
|
||||
Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, ed.formTargetElementId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Pass to next handler in chain.
|
||||
return false;
|
||||
},
|
||||
|
||||
// Register the plugin button.
|
||||
getControlHTML: function(control_name) {
|
||||
switch (control_name) {
|
||||
case plugin:
|
||||
return tinyMCE.getButtonHTML(control_name, settings.iconTitle, settings.icon, plugin);
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
// Load custom CSS for editor contents on startup.
|
||||
initInstance: function(ed) {
|
||||
if (settings.css) {
|
||||
tinyMCE.importCSS(ed.getDoc(), settings.css);
|
||||
}
|
||||
},
|
||||
|
||||
cleanup: function(type, content) {
|
||||
switch (type) {
|
||||
case 'insert_to_editor':
|
||||
// Attach: Replace plain text with HTML representations.
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
|
||||
content = Drupal.wysiwyg.plugins[plugin].attach(content, pluginSettings, tinyMCE.selectedInstance.editorId);
|
||||
content = Drupal.wysiwyg.editor.instance.tinymce.prepareContent(content);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'get_from_editor':
|
||||
// Detach: Replace HTML representations with plain text.
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
|
||||
content = Drupal.wysiwyg.plugins[plugin].detach(content, pluginSettings, tinyMCE.selectedInstance.editorId);
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Pass through to next handler in chain
|
||||
return content;
|
||||
},
|
||||
|
||||
// isNode: Return whether the plugin button should be enabled for the
|
||||
// current selection.
|
||||
handleNodeChange: function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) {
|
||||
if (node === null) {
|
||||
return;
|
||||
}
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
|
||||
if (Drupal.wysiwyg.plugins[plugin].isNode(node)) {
|
||||
tinyMCE.switchClass(editor_id + '_' + plugin, 'mceButtonSelected');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
tinyMCE.switchClass(editor_id + '_' + plugin, 'mceButtonNormal');
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return information about the plugin as a name/value array.
|
||||
*/
|
||||
getInfo: function() {
|
||||
return {
|
||||
longname: settings.title
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
openDialog: function(dialog, params) {
|
||||
var editor = tinyMCE.getInstanceById(this.field);
|
||||
tinyMCE.openWindow({
|
||||
file: dialog.url + '/' + this.field,
|
||||
width: dialog.width,
|
||||
height: dialog.height,
|
||||
inline: 1
|
||||
}, params);
|
||||
},
|
||||
|
||||
closeDialog: function(dialog) {
|
||||
var editor = tinyMCE.getInstanceById(this.field);
|
||||
tinyMCEPopup.close();
|
||||
},
|
||||
|
||||
prepareContent: function(content) {
|
||||
// Certain content elements need to have additional DOM properties applied
|
||||
// to prevent this editor from highlighting an internal button in addition
|
||||
// to the button of a Drupal plugin.
|
||||
var specialProperties = {
|
||||
img: { 'name': 'mce_drupal' }
|
||||
};
|
||||
var $content = $('<div>' + content + '</div>'); // No .outerHTML() in jQuery :(
|
||||
jQuery.each(specialProperties, function(element, properties) {
|
||||
$content.find(element).each(function() {
|
||||
for (var property in properties) {
|
||||
if (property == 'class') {
|
||||
$(this).addClass(properties[property]);
|
||||
}
|
||||
else {
|
||||
$(this).attr(property, properties[property]);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return $content.html();
|
||||
},
|
||||
|
||||
insert: function(content) {
|
||||
content = this.prepareContent(content);
|
||||
var editor = tinyMCE.getInstanceById(this.field);
|
||||
editor.execCommand('mceInsertContent', false, content);
|
||||
editor.repaint();
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
Executable → Regular
+58
-53
@@ -3,39 +3,46 @@
|
||||
/**
|
||||
* Initialize editor instances.
|
||||
*
|
||||
* @todo Is the following note still valid for 3.x?
|
||||
* This function needs to be called before the page is fully loaded, as
|
||||
* calling tinyMCE.init() after the page is loaded breaks IE6.
|
||||
*
|
||||
* @param editorSettings
|
||||
* An object containing editor settings for each input format.
|
||||
* @see Drupal.wysiwyg.editor.init.ckeditor()
|
||||
*/
|
||||
Drupal.wysiwyg.editor.init.tinymce = function(settings) {
|
||||
Drupal.wysiwyg.editor.init.tinymce = function(settings, pluginInfo) {
|
||||
// Fix Drupal toolbar obscuring editor toolbar in fullscreen mode.
|
||||
var $drupalToolbar = $('#toolbar', Drupal.overlayChild ? window.parent.document : document);
|
||||
var $drupalToolbars = $('#toolbar, #admin-menu', Drupal.overlayChild ? window.parent.document : document);
|
||||
tinyMCE.onAddEditor.add(function (mgr, ed) {
|
||||
if (ed.id == 'mce_fullscreen') {
|
||||
$drupalToolbar.hide();
|
||||
$drupalToolbars.hide();
|
||||
}
|
||||
});
|
||||
tinyMCE.onRemoveEditor.add(function (mgr, ed) {
|
||||
if (ed.id == 'mce_fullscreen') {
|
||||
$drupalToolbar.show();
|
||||
$drupalToolbars.show();
|
||||
}
|
||||
else {
|
||||
// Free our reference to the private instance to not risk memory leaks.
|
||||
delete ed._drupalWysiwygInstance;
|
||||
}
|
||||
});
|
||||
// Register new plugins.
|
||||
Drupal.wysiwyg.editor.update.tinymce(settings, pluginInfo);
|
||||
};
|
||||
|
||||
// Initialize editor configurations.
|
||||
for (var format in settings) {
|
||||
if (Drupal.settings.wysiwyg.plugins[format]) {
|
||||
// Load native external plugins.
|
||||
// Array syntax required; 'native' is a predefined token in JavaScript.
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[format]['native']) {
|
||||
tinymce.PluginManager.load(plugin, Drupal.settings.wysiwyg.plugins[format]['native'][plugin]);
|
||||
}
|
||||
// Load Drupal plugins.
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[format].drupal) {
|
||||
Drupal.wysiwyg.editor.instance.tinymce.addPlugin(plugin, Drupal.settings.wysiwyg.plugins[format].drupal[plugin], Drupal.settings.wysiwyg.plugins.drupal[plugin]);
|
||||
}
|
||||
/**
|
||||
* Update the editor library when new settings are available.
|
||||
*
|
||||
* @see Drupal.wysiwyg.editor.update.ckeditor()
|
||||
*/
|
||||
Drupal.wysiwyg.editor.update.tinymce = function(settings, pluginInfo) {
|
||||
// Load native external plugins.
|
||||
// Array syntax required; 'native' is a predefined token in JavaScript.
|
||||
for (var plugin in pluginInfo['native']) {
|
||||
if (!(plugin in tinymce.PluginManager.lookup || plugin in tinymce.PluginManager.urls)) {
|
||||
tinymce.PluginManager.load(plugin, pluginInfo['native'][plugin]);
|
||||
}
|
||||
}
|
||||
// Load Drupal plugins.
|
||||
for (var plugin in pluginInfo.drupal) {
|
||||
if (!(plugin in tinymce.PluginManager.lookup)) {
|
||||
Drupal.wysiwyg.editor.instance.tinymce.addPlugin(plugin, pluginInfo.drupal[plugin]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -48,6 +55,7 @@ Drupal.wysiwyg.editor.init.tinymce = function(settings) {
|
||||
Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) {
|
||||
// Configure editor settings for this input format.
|
||||
var ed = new tinymce.Editor(params.field, settings);
|
||||
ed._drupalWysiwygInstance = this;
|
||||
// Reset active instance id on any event.
|
||||
ed.onEvent.add(function(ed, e) {
|
||||
Drupal.wysiwyg.activeId = ed.id;
|
||||
@@ -71,46 +79,43 @@ Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) {
|
||||
// it prior to attaching the editor. This is done on the client-side instead
|
||||
// of the server-side, as Wysiwyg has no way to figure out where content is
|
||||
// stored, and the class only affects editing.
|
||||
$field = $('#' + params.field);
|
||||
var $field = $('#' + params.field);
|
||||
$field.val($field.val().replace(/(<.+?\s+class=['"][\w\s]*?)\bmceItem\b([\w\s]*?['"].*?>)/ig, '$1$2'));
|
||||
|
||||
// Attach editor.
|
||||
ed.render();
|
||||
if (tinymce.minorVersion == '5.7') {
|
||||
// Work around a TinyMCE bug hiding new instances when switching to them.
|
||||
// @see http://www.tinymce.com/develop/bugtracker_view.php?id=5510
|
||||
setTimeout(function () {
|
||||
tinymce.DOM.show(ed.editorContainer);
|
||||
}, 1);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
* Detach a single editor instance.
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.tinymce = function (context, params, trigger) {
|
||||
if (typeof params != 'undefined') {
|
||||
var instance = tinyMCE.get(params.field);
|
||||
if (instance) {
|
||||
instance.save();
|
||||
if (trigger != 'serialize') {
|
||||
instance.remove();
|
||||
}
|
||||
}
|
||||
var instance = tinyMCE.get(params.field);
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// Save contents of all editors back into textareas.
|
||||
tinyMCE.triggerSave();
|
||||
if (trigger != 'serialize') {
|
||||
// Remove all editor instances.
|
||||
for (var instance in tinyMCE.editors) {
|
||||
tinyMCE.editors[instance].remove();
|
||||
}
|
||||
}
|
||||
instance.save();
|
||||
if (trigger !== 'serialize') {
|
||||
// The onRemove event fires before this returns.
|
||||
instance.remove();
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
addPlugin: function(plugin, settings, pluginSettings) {
|
||||
addPlugin: function(plugin, pluginSettings) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') {
|
||||
return;
|
||||
}
|
||||
tinymce.create('tinymce.plugins.' + plugin, {
|
||||
tinymce.create('tinymce.plugins.drupal_' + plugin, {
|
||||
/**
|
||||
* Initialize the plugin, executed after the plugin has been created.
|
||||
*
|
||||
@@ -121,7 +126,7 @@ Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
*/
|
||||
init: function(ed, url) {
|
||||
// Register an editor command for this plugin, invoked by the plugin's button.
|
||||
ed.addCommand(plugin, function() {
|
||||
ed.addCommand('drupal_' + plugin, function() {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') {
|
||||
var data = { format: 'html', node: ed.selection.getNode(), content: ed.selection.getContent() };
|
||||
// TinyMCE creates a completely new instance for fullscreen mode.
|
||||
@@ -131,16 +136,16 @@ Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
});
|
||||
|
||||
// Register the plugin button.
|
||||
ed.addButton(plugin, {
|
||||
title : settings.iconTitle,
|
||||
cmd : plugin,
|
||||
image : settings.icon
|
||||
ed.addButton('drupal_' + plugin, {
|
||||
title : pluginSettings.title,
|
||||
cmd : 'drupal_' + plugin,
|
||||
image : pluginSettings.icon
|
||||
});
|
||||
|
||||
// Load custom CSS for editor contents on startup.
|
||||
ed.onInit.add(function() {
|
||||
if (settings.css) {
|
||||
ed.dom.loadCSS(settings.css);
|
||||
if (pluginSettings.css) {
|
||||
ed.dom.loadCSS(pluginSettings.css);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -149,7 +154,7 @@ Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
var editorId = (ed.id == 'mce_fullscreen' ? ed.getParam('fullscreen_editor_id') : ed.id);
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
|
||||
data.content = Drupal.wysiwyg.plugins[plugin].attach(data.content, pluginSettings, editorId);
|
||||
data.content = Drupal.wysiwyg.editor.instance.tinymce.prepareContent(data.content);
|
||||
data.content = ed._drupalWysiwygInstance.prepareContent(data.content);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -175,13 +180,13 @@ Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
*/
|
||||
getInfo: function() {
|
||||
return {
|
||||
longname: settings.title
|
||||
longname: pluginSettings.title
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Register plugin.
|
||||
tinymce.PluginManager.add(plugin, tinymce.plugins[plugin]);
|
||||
tinymce.PluginManager.add('drupal_' + plugin, tinymce.plugins['drupal_' + plugin]);
|
||||
},
|
||||
|
||||
openDialog: function(dialog, params) {
|
||||
|
||||
@@ -0,0 +1,245 @@
|
||||
(function ($) {
|
||||
|
||||
/**
|
||||
* Initialize editor instances.
|
||||
*
|
||||
* @see Drupal.wysiwyg.editor.init.ckeditor()
|
||||
*/
|
||||
Drupal.wysiwyg.editor.init.tinymce = function (settings, pluginInfo) {
|
||||
// Fix Drupal toolbar obscuring editor toolbar in fullscreen mode.
|
||||
var $drupalToolbars = $('#toolbar, #admin-menu', Drupal.overlayChild ? window.parent.document : document);
|
||||
tinymce.on('AddEditor', function (e) {
|
||||
e.editor.on('FullscreenStateChanged', function (e) {
|
||||
if (e.state) {
|
||||
$drupalToolbars.hide();
|
||||
}
|
||||
else {
|
||||
$drupalToolbars.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
// Register new plugins.
|
||||
Drupal.wysiwyg.editor.update.tinymce(settings, pluginInfo);
|
||||
};
|
||||
|
||||
/**
|
||||
* Update the editor library when new settings are available.
|
||||
*
|
||||
* @see Drupal.wysiwyg.editor.update.ckeditor()
|
||||
*/
|
||||
Drupal.wysiwyg.editor.update.tinymce = function (settings, pluginInfo) {
|
||||
// Load native external plugins.
|
||||
// Array syntax required; 'native' is a predefined token in JavaScript.
|
||||
var plugin;
|
||||
for (plugin in pluginInfo['native']) {
|
||||
if (!(plugin in tinymce.PluginManager.lookup || plugin in tinymce.PluginManager.urls)) {
|
||||
tinymce.PluginManager.load(plugin, pluginInfo['native'][plugin]);
|
||||
}
|
||||
}
|
||||
// Load Drupal plugins.
|
||||
for (plugin in pluginInfo.drupal) {
|
||||
if (!(plugin in tinymce.PluginManager.lookup)) {
|
||||
Drupal.wysiwyg.editor.instance.tinymce.addPlugin(plugin, pluginInfo.drupal[plugin]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.attach.none() for a full desciption of this hook.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.tinymce = function (context, params, settings) {
|
||||
// Remove TinyMCE's internal mceItem class, which was incorrectly added to
|
||||
// submitted content by Wysiwyg <2.1. TinyMCE only temporarily adds the class
|
||||
// for placeholder elements. If preemptively set, the class prevents (native)
|
||||
// editor plugins from gaining an active state, so we have to manually remove
|
||||
// it prior to attaching the editor. This is done on the client-side instead
|
||||
// of the server-side, as Wysiwyg has no way to figure out where content is
|
||||
// stored, and the class only affects editing.
|
||||
var $field = $('#' + params.field);
|
||||
$field.val($field.val().replace(/(<.+?\s+class=['"][\w\s]*?)\bmceItem\b([\w\s]*?['"].*?>)/ig, '$1$2'));
|
||||
|
||||
// Attach editor.
|
||||
settings.selector = '#' + params.field;
|
||||
var oldSetup = settings.setup;
|
||||
settings.setup = function (editor) {
|
||||
editor.on('focus', function (e) {
|
||||
Drupal.wysiwyg.activeId = this.id;
|
||||
});
|
||||
if (oldSetup) {
|
||||
oldSetup(editor);
|
||||
}
|
||||
};
|
||||
tinymce.init(settings);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.tinymce = function (context, params, trigger) {
|
||||
var instance;
|
||||
if (typeof params !== 'undefined') {
|
||||
instance = tinymce.get(params.field);
|
||||
if (instance) {
|
||||
instance.save();
|
||||
if (trigger !== 'serialize') {
|
||||
instance.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Save contents of all editors back into textareas.
|
||||
tinymce.triggerSave();
|
||||
if (trigger !== 'serialize') {
|
||||
// Remove all editor instances.
|
||||
for (instance in tinymce.editors) {
|
||||
if (!tinymce.editors.hasOwnProperty(instance)) {
|
||||
continue;
|
||||
}
|
||||
tinymce.editors[instance].remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
addPlugin: function (plugin, pluginSettings) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin] !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
// Register plugin.
|
||||
tinymce.PluginManager.add('drupal_' + plugin, function (editor) {
|
||||
var button = {
|
||||
title: pluginSettings.title,
|
||||
image: pluginSettings.icon,
|
||||
onPostRender: function () {
|
||||
var self = this;
|
||||
editor.on('nodeChange', function (e) {
|
||||
// isNode: Return whether the plugin button should be enabled for
|
||||
// the current selection.
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
|
||||
self.active(Drupal.wysiwyg.plugins[plugin].isNode(e.element));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') {
|
||||
button.onclick = function () {
|
||||
var data = {format: 'html', node: editor.selection.getNode(), content: editor.selection.getContent()};
|
||||
// TinyMCE creates a completely new instance for fullscreen mode.
|
||||
Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, editor.id);
|
||||
};
|
||||
}
|
||||
|
||||
// Register the plugin button.
|
||||
editor.addButton('drupal_' + plugin, button);
|
||||
|
||||
/**
|
||||
* Initialize the plugin, executed after the plugin has been created.
|
||||
*
|
||||
* @param ed
|
||||
* The tinymce.Editor instance the plugin is initialized in.
|
||||
* @param url
|
||||
* The absolute URL of the plugin location.
|
||||
*/
|
||||
editor.on('init', function (e) {
|
||||
// Load custom CSS for editor contents on startup.
|
||||
if (pluginSettings.css) {
|
||||
editor.dom.loadCSS(pluginSettings.css);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Attach: Replace plain text with HTML representations.
|
||||
editor.on('beforeSetContent', function (e) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].attach === 'function') {
|
||||
e.content = Drupal.wysiwyg.plugins[plugin].attach(e.content, pluginSettings, e.target.id);
|
||||
e.content = Drupal.wysiwyg.editor.instance.tinymce.prepareContent(e.content);
|
||||
}
|
||||
});
|
||||
|
||||
// Detach: Replace HTML representations with plain text.
|
||||
editor.on('getContent', function (e) {
|
||||
var editorId = (e.target.id === 'mce_fullscreen' ? e.target.getParam('fullscreen_editor_id') : e.target.id);
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
|
||||
e.content = Drupal.wysiwyg.plugins[plugin].detach(e.content, pluginSettings, editorId);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
openDialog: function (dialog, params) {
|
||||
var instanceId = this.getInstanceId();
|
||||
var editor = tinymce.get(instanceId);
|
||||
editor.windowManager.open({
|
||||
file: dialog.url + '/' + instanceId,
|
||||
width: dialog.width,
|
||||
height: dialog.height,
|
||||
inline: 1
|
||||
}, params);
|
||||
},
|
||||
|
||||
closeDialog: function (dialog) {
|
||||
var editor = tinymce.get(this.getInstanceId());
|
||||
editor.windowManager.close(dialog);
|
||||
},
|
||||
|
||||
prepareContent: function (content) {
|
||||
// Certain content elements need to have additional DOM properties applied
|
||||
// to prevent this editor from highlighting an internal button in addition
|
||||
// to the button of a Drupal plugin.
|
||||
var specialProperties = {
|
||||
img: {class: 'mceItem'}
|
||||
};
|
||||
// No .outerHTML() in jQuery :(
|
||||
var $content = $('<div>' + content + '</div>');
|
||||
// Find all placeholder/replacement content of Drupal plugins.
|
||||
$content.find('.drupal-content').each(function () {
|
||||
// Recursively process DOM elements below this element to apply special
|
||||
// properties.
|
||||
var $drupalContent = $(this);
|
||||
$.each(specialProperties, function (element, properties) {
|
||||
$drupalContent.find(element).andSelf().each(function () {
|
||||
for (var property in properties) {
|
||||
if (property === 'class') {
|
||||
$(this).addClass(properties[property]);
|
||||
}
|
||||
else {
|
||||
$(this).attr(property, properties[property]);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
return $content.html();
|
||||
},
|
||||
|
||||
insert: function (content) {
|
||||
content = this.prepareContent(content);
|
||||
tinymce.get(this.field).insertContent(content);
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
content = this.prepareContent(content);
|
||||
tinymce.get(this.field).setContent(content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
return tinymce.get(this.getInstanceId()).getContent();
|
||||
},
|
||||
|
||||
isFullscreen: function () {
|
||||
var editor = tinymce.get(this.field);
|
||||
return editor.plugins.fullscreen && editor.plugins.fullscreen.isFullscreen();
|
||||
},
|
||||
|
||||
getInstanceId: function () {
|
||||
return this.field;
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
Executable → Regular
+14
-22
@@ -72,9 +72,8 @@ Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
wysiwygWhizzywig.currentField = params.field;
|
||||
wysiwygWhizzywig.fields[wysiwygWhizzywig.currentField] = '';
|
||||
// Whizzywig needs to have the width set 'inline'.
|
||||
$field = $('#' + params.field);
|
||||
var originalValues = Drupal.wysiwyg.instances[params.field];
|
||||
originalValues.originalStyle = $field.attr('style');
|
||||
var $field = $('#' + params.field);
|
||||
this.originalStyle = $field.attr('style');
|
||||
$field.css('width', $field.width() + 'px');
|
||||
|
||||
// Attach editor.
|
||||
@@ -87,35 +86,27 @@ Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.whizzywig = function (context, params, trigger) {
|
||||
var detach = function (index) {
|
||||
var id = whizzies[index], $field = $('#' + id), instance = Drupal.wysiwyg.instances[id];
|
||||
for (var index = 0; index < whizzies.length; index++) {
|
||||
if (whizzies[index] !== this.field) {
|
||||
continue;
|
||||
}
|
||||
var $field = $('#' + this.field);
|
||||
|
||||
// Save contents of editor back into textarea.
|
||||
$field.val(instance.getContent());
|
||||
$field.val(this.getContent());
|
||||
// If the editor is just being serialized (not detached), our work is done.
|
||||
if (trigger == 'serialize') {
|
||||
return;
|
||||
}
|
||||
// Remove editor instance.
|
||||
$('#' + id + '-whizzywig').remove();
|
||||
$('#' + this.field + '-whizzywig').remove();
|
||||
whizzies.splice(index, 1);
|
||||
|
||||
// Restore original textarea styling.
|
||||
$field.removeAttr('style').attr('style', instance.originalStyle);
|
||||
};
|
||||
|
||||
if (typeof params != 'undefined') {
|
||||
for (var i = 0; i < whizzies.length; i++) {
|
||||
if (whizzies[i] == params.field) {
|
||||
detach(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (whizzies.length > 0) {
|
||||
detach(0);
|
||||
if ('originalStyle' in this) {
|
||||
$field.removeAttr('style').attr('style', this.originalStyle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -142,12 +133,13 @@ Drupal.wysiwyg.editor.instance.whizzywig = {
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
var $field = $('#' + this.field);
|
||||
// Whizzywig's tidyH() expects a document node. Clone the editing iframe's
|
||||
// document so tidyH() won't mess with it if this gets called while editing.
|
||||
var clone = $($('#whizzy' + this.field).contents()[0].documentElement).clone()[0].ownerDocument;
|
||||
// Whizzywig shows the original textarea in source mode so update the body.
|
||||
if ($field.css('display') == 'block') {
|
||||
clone.body.innerHTML = $('#' + this.field).val();
|
||||
clone.body.innerHTML = $field.val();
|
||||
}
|
||||
return tidyH(clone);
|
||||
}
|
||||
|
||||
Executable → Regular
+24
-23
@@ -21,9 +21,8 @@ Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
window.buttonPath = 'textbuttons';
|
||||
}
|
||||
// Whizzywig needs to have the width set 'inline'.
|
||||
$field = $('#' + params.field);
|
||||
var originalValues = Drupal.wysiwyg.instances[params.field];
|
||||
originalValues.originalStyle = $field.attr('style');
|
||||
var $field = $('#' + params.field);
|
||||
this.originalStyle = $field.attr('style');
|
||||
$field.css('width', $field.width() + 'px');
|
||||
|
||||
// Attach editor.
|
||||
@@ -33,41 +32,33 @@ Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
* Detach a single editor instance.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.whizzywig = function (context, params, trigger) {
|
||||
var detach = function (index) {
|
||||
var id = whizzies[index], $field = $('#' + id), instance = Drupal.wysiwyg.instances[id];
|
||||
for (var index = 0; index < whizzies.length; index++) {
|
||||
if (whizzies[index] !== this.field) {
|
||||
continue;
|
||||
}
|
||||
var $field = $('#' + this.field);
|
||||
|
||||
// Save contents of editor back into textarea.
|
||||
$field.val(instance.getContent());
|
||||
$field.val(this.getContent());
|
||||
// If the editor is just being serialized (not detached), our work is done.
|
||||
if (trigger == 'serialize') {
|
||||
return;
|
||||
}
|
||||
// Move original textarea back to its previous location.
|
||||
var $container = $('#CONTAINER' + id);
|
||||
var $container = $('#CONTAINER' + this.field);
|
||||
$field.insertBefore($container);
|
||||
// Remove editor instance.
|
||||
$container.remove();
|
||||
whizzies.splice(index, 1);
|
||||
|
||||
// Restore original textarea styling.
|
||||
$field.removeAttr('style').attr('style', instance.originalStyle);
|
||||
}
|
||||
|
||||
if (typeof params != 'undefined') {
|
||||
for (var i = 0; i < whizzies.length; i++) {
|
||||
if (whizzies[i] == params.field) {
|
||||
detach(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (whizzies.length > 0) {
|
||||
detach(0);
|
||||
if ('originalStyle' in this) {
|
||||
$field.removeAttr('style').attr('style', this.originalStyle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -94,14 +85,24 @@ Drupal.wysiwyg.editor.instance.whizzywig = {
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
var $field = $('#' + this.field);
|
||||
// Whizzywig's tidyH() expects a document node. Clone the editing iframe's
|
||||
// document so tidyH() won't mess with it if this gets called while editing.
|
||||
var clone = $($('#whizzy' + this.field).contents()[0].documentElement).clone()[0].ownerDocument;
|
||||
// Whizzywig shows the original textarea in source mode so update the body.
|
||||
if ($field.css('display') == 'block') {
|
||||
clone.body.innerHTML = $('#' + this.field).val();
|
||||
clone.body.innerHTML = $field.val();
|
||||
}
|
||||
return tidyH(clone);
|
||||
},
|
||||
|
||||
isFullscreen: function () {
|
||||
// This relies on a global function which uses a global variable...
|
||||
var idTa_old = idTa;
|
||||
idTa = this.field;
|
||||
var fullscreen = isFullscreen();
|
||||
idTa = idTa_old;
|
||||
return fullscreen;
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
||||
|
||||
Executable → Regular
+12
-21
@@ -63,9 +63,8 @@ Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
wysiwygWhizzywig.currentField = params.field;
|
||||
wysiwygWhizzywig.fields[wysiwygWhizzywig.currentField] = '';
|
||||
// Whizzywig needs to have the width set 'inline'.
|
||||
$field = $('#' + params.field);
|
||||
var originalValues = Drupal.wysiwyg.instances[params.field];
|
||||
originalValues.originalStyle = $field.attr('style');
|
||||
var $field = $('#' + params.field);
|
||||
this.originalStyle = $field.attr('style');
|
||||
$field.css('width', $field.width() + 'px');
|
||||
|
||||
// Attach editor.
|
||||
@@ -78,35 +77,27 @@ Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.whizzywig = function (context, params, trigger) {
|
||||
var detach = function (index) {
|
||||
var id = whizzies[index], $field = $('#' + id), instance = Drupal.wysiwyg.instances[id];
|
||||
for (var index = 0; index < whizzies.length; index++) {
|
||||
if (whizzies[index] !== this.field) {
|
||||
continue;
|
||||
}
|
||||
var $field = $('#' + this.field);
|
||||
|
||||
// Save contents of editor back into textarea.
|
||||
$field.val(instance.getContent());
|
||||
$field.val(this.getContent());
|
||||
// If the editor is just being serialized (not detached), our work is done.
|
||||
if (trigger == 'serialize') {
|
||||
return;
|
||||
}
|
||||
// Remove editor instance.
|
||||
$('#' + id + '-whizzywig').remove();
|
||||
$('#' + this.field + '-whizzywig').remove();
|
||||
whizzies.splice(index, 1);
|
||||
|
||||
// Restore original textarea styling.
|
||||
$field.removeAttr('style').attr('style', instance.originalStyle);
|
||||
};
|
||||
|
||||
if (typeof params != 'undefined') {
|
||||
for (var i = 0; i < whizzies.length; i++) {
|
||||
if (whizzies[i] == params.field) {
|
||||
detach(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (whizzies.length > 0) {
|
||||
detach(0);
|
||||
if ('originalStyle' in this) {
|
||||
$field.removeAttr('style').attr('style', this.originalStyle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Executable → Regular
+12
-25
@@ -17,34 +17,21 @@ Drupal.wysiwyg.editor.attach.wymeditor = function (context, params, settings) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
* Detach a single editor instance.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.wymeditor = function (context, params, trigger) {
|
||||
if (typeof params != 'undefined') {
|
||||
var $field = $('#' + params.field);
|
||||
var index = $field.data(WYMeditor.WYM_INDEX);
|
||||
if (typeof index != 'undefined') {
|
||||
var instance = WYMeditor.INSTANCES[index];
|
||||
instance.update();
|
||||
if (trigger != 'serialize') {
|
||||
$(instance._box).remove();
|
||||
$(instance._element).show();
|
||||
delete instance;
|
||||
}
|
||||
}
|
||||
if (trigger != 'serialize') {
|
||||
$field.show();
|
||||
}
|
||||
var $field = $('#' + params.field, context);
|
||||
var index = $field.data(WYMeditor.WYM_INDEX);
|
||||
if (typeof index == 'undefined' || !WYMeditor.INSTANCES[index]) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
jQuery.each(WYMeditor.INSTANCES, function () {
|
||||
this.update();
|
||||
if (trigger != 'serialize') {
|
||||
$(this._box).remove();
|
||||
$(this._element).show();
|
||||
delete this;
|
||||
}
|
||||
});
|
||||
var instance = WYMeditor.INSTANCES[index];
|
||||
instance.update();
|
||||
if (trigger != 'serialize') {
|
||||
$(instance._box).remove();
|
||||
$(instance._element).show();
|
||||
delete WYMeditor.INSTANCES[index];
|
||||
$field.show();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+50
-53
@@ -10,45 +10,53 @@ Drupal.wysiwyg.editor.attach.yui = function(context, params, settings) {
|
||||
// Apply theme.
|
||||
$('#' + params.field).parent().addClass('yui-skin-' + settings.theme);
|
||||
|
||||
var wysiwygInstance = this;
|
||||
var enabledPlugins = wysiwygInstance.pluginInfo.instances;
|
||||
// Load plugins stylesheet.
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
|
||||
settings.extracss += settings.extracss+' @import "'+Drupal.settings.wysiwyg.plugins[params.format].drupal[plugin].css+'"; ';
|
||||
for (var pluginId in enabledPlugins.drupal) {
|
||||
if (wysiwygInstance.pluginInfo.global.drupal[pluginId].css) {
|
||||
settings.extracss += ' @import "' + wysiwygInstance.pluginInfo.global.drupal[pluginId].css + '"; ';
|
||||
}
|
||||
}
|
||||
|
||||
// Attach editor.
|
||||
var editor = new YAHOO.widget.Editor(params.field, settings);
|
||||
|
||||
editor.on('toolbarLoaded', function() {
|
||||
// Load Drupal plugins.
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
|
||||
Drupal.wysiwyg.instances[params.field].addPlugin(plugin, Drupal.settings.wysiwyg.plugins[params.format].drupal[plugin], Drupal.settings.wysiwyg.plugins.drupal[plugin]);
|
||||
}
|
||||
});
|
||||
|
||||
// Allow plugins to act on setEditorHTML.
|
||||
var oldSetEditorHTML = editor.setEditorHTML;
|
||||
editor.setEditorHTML = function (content) {
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
|
||||
var pluginSettings = Drupal.settings.wysiwyg.plugins.drupal[plugin];
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
|
||||
content = Drupal.wysiwyg.plugins[plugin].attach(content, pluginSettings, params.field);
|
||||
content = Drupal.wysiwyg.instances[params.field].prepareContent(content);
|
||||
if (enabledPlugins) {
|
||||
editor.on('toolbarLoaded', function() {
|
||||
// 'this' will reference the toolbar while inside the event handler.
|
||||
var instanceId = params.field;
|
||||
// Load Drupal plugins.
|
||||
for (var plugin in enabledPlugins.drupal) {
|
||||
wysiwygInstance.addPlugin(plugin, wysiwygInstance.pluginInfo.global.drupal[plugin]);
|
||||
}
|
||||
}
|
||||
oldSetEditorHTML.call(this, content);
|
||||
};
|
||||
});
|
||||
|
||||
// Allow plugins to act on getEditorHTML.
|
||||
var oldGetEditorHTML = editor.getEditorHTML;
|
||||
editor.getEditorHTML = function () {
|
||||
var content = oldGetEditorHTML.call(this);
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
|
||||
var pluginSettings = Drupal.settings.wysiwyg.plugins.drupal[plugin];
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
|
||||
content = Drupal.wysiwyg.plugins[plugin].detach(content, pluginSettings, params.field);
|
||||
// Allow plugins to act on setEditorHTML.
|
||||
var oldSetEditorHTML = editor.setEditorHTML;
|
||||
editor.setEditorHTML = function (content) {
|
||||
for (var plugin in enabledPlugins.drupal) {
|
||||
var pluginSettings = wysiwygInstance.pluginInfo.global.drupal[plugin];
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
|
||||
content = Drupal.wysiwyg.plugins[plugin].attach(content, pluginSettings, params.field);
|
||||
content = wysiwygInstance.prepareContent(content);
|
||||
}
|
||||
}
|
||||
oldSetEditorHTML.call(this, content);
|
||||
};
|
||||
|
||||
// Allow plugins to act on getEditorHTML.
|
||||
var oldGetEditorHTML = editor.getEditorHTML;
|
||||
editor.getEditorHTML = function () {
|
||||
var content = oldGetEditorHTML.call(this);
|
||||
for (var plugin in enabledPlugins.drupal) {
|
||||
var pluginSettings = wysiwygInstance.pluginInfo.global.drupal[plugin];
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
|
||||
content = Drupal.wysiwyg.plugins[plugin].detach(content, pluginSettings, params.field);
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
// Reload the editor contents to give Drupal plugins a chance to act.
|
||||
@@ -57,7 +65,7 @@ Drupal.wysiwyg.editor.attach.yui = function(context, params, settings) {
|
||||
});
|
||||
|
||||
editor.on('afterNodeChange', function (e) {
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
|
||||
for (var plugin in enabledPlugins.drupal) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
|
||||
if (Drupal.wysiwyg.plugins[plugin].isNode(e.target._getSelectedElement())) {
|
||||
this.toolbar.selectButton(plugin);
|
||||
@@ -67,33 +75,22 @@ Drupal.wysiwyg.editor.attach.yui = function(context, params, settings) {
|
||||
});
|
||||
|
||||
editor.render();
|
||||
// This event never gets fired if loaded into a dialog, harmless otherwise.
|
||||
editor.fireEvent('contentReady');
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
|
||||
* Detach a single editor instance.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.yui = function (context, params, trigger) {
|
||||
var method = (trigger && trigger == 'serialize') ? 'saveHTML' : 'destroy';
|
||||
if (typeof params != 'undefined') {
|
||||
var instance = YAHOO.widget.EditorInfo._instances[params.field];
|
||||
if (instance) {
|
||||
instance[method]();
|
||||
if (method == 'destroy') {
|
||||
delete YAHOO.widget.EditorInfo._instances[params.field];
|
||||
}
|
||||
}
|
||||
var instance = YAHOO.widget.EditorInfo._instances[params.field];
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
for (var e in YAHOO.widget.EditorInfo._instances) {
|
||||
// Save contents of all editors back into textareas.
|
||||
var instance = YAHOO.widget.EditorInfo._instances[e];
|
||||
instance[method]();
|
||||
if (method == 'destroy') {
|
||||
delete YAHOO.widget.EditorInfo._instances[e];
|
||||
}
|
||||
}
|
||||
instance[method]();
|
||||
if (method != 'serialize') {
|
||||
delete YAHOO.widget.EditorInfo._instances[params.field];
|
||||
}
|
||||
};
|
||||
|
||||
@@ -101,13 +98,13 @@ Drupal.wysiwyg.editor.detach.yui = function (context, params, trigger) {
|
||||
* Instance methods for YUI Editor.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.instance.yui = {
|
||||
addPlugin: function (plugin, settings, pluginSettings) {
|
||||
addPlugin: function (plugin, pluginSettings) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') {
|
||||
return;
|
||||
}
|
||||
var editor = YAHOO.widget.EditorInfo.getEditorById(this.field);
|
||||
var button = editor.toolbar.getButtonByValue(plugin);
|
||||
$(button._button).parent().css('background', 'transparent url(' + settings.icon + ') no-repeat center');
|
||||
$(button._button).parent().css('background', 'transparent url(' + pluginSettings.icon + ') no-repeat center');
|
||||
// 'this' will reference the toolbar while inside the event handler.
|
||||
var instanceId = this.field;
|
||||
editor.toolbar.on(plugin + 'Click', function (e) {
|
||||
@@ -129,7 +126,7 @@ Drupal.wysiwyg.editor.instance.yui = {
|
||||
},
|
||||
|
||||
insert: function (content) {
|
||||
YAHOO.widget.EditorInfo.getEditorById(this.field).cmd_inserthtml(content);
|
||||
YAHOO.widget.EditorInfo.getEditorById(this.field).execCommand('inserthtml', content);
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
|
||||
Executable → Regular
+36
-7
@@ -11,23 +11,22 @@
|
||||
function wysiwyg_jwysiwyg_editor() {
|
||||
$editor['jwysiwyg'] = array(
|
||||
'title' => 'jWYSIWYG',
|
||||
'vendor url' => 'http://code.google.com/p/jwysiwyg/',
|
||||
'download url' => 'http://code.google.com/p/jwysiwyg/downloads/list',
|
||||
'vendor url' => 'http://github.com/akzhan/jwysiwyg',
|
||||
'download url' => 'http://github.com/akzhan/jwysiwyg/tags',
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array('jquery.wysiwyg.js'),
|
||||
),
|
||||
'pack' => array(
|
||||
'title' => 'Packed',
|
||||
'files' => array('jquery.wysiwyg.pack.js'),
|
||||
),
|
||||
),
|
||||
'verified version range' => array('0.5', '0.97'),
|
||||
'version callback' => 'wysiwyg_jwysiwyg_version',
|
||||
'settings form callback' => 'wysiwyg_jwysiwyg_settings_form',
|
||||
'settings callback' => 'wysiwyg_jwysiwyg_settings',
|
||||
// @todo Wrong property; add separate properties for editor requisites.
|
||||
'css path' => wysiwyg_get_path('jwysiwyg'),
|
||||
'versions' => array(
|
||||
'0.5' => array(
|
||||
'0.97' => array(
|
||||
'js files' => array('jwysiwyg.js'),
|
||||
'css files' => array('jquery.wysiwyg.css'),
|
||||
),
|
||||
@@ -36,6 +35,36 @@ function wysiwyg_jwysiwyg_editor() {
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhances the editor profile settings form for jWYSIWYG.
|
||||
*/
|
||||
function wysiwyg_jwysiwyg_settings_form(&$form, &$form_state) {
|
||||
$form['buttons']['#access'] = FALSE;
|
||||
$form['basic']['language']['#access'] = FALSE;
|
||||
$form['css']['#access'] = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return runtime editor settings for a given wysiwyg profile.
|
||||
*
|
||||
* @param $editor
|
||||
* A processed hook_editor() array of editor properties.
|
||||
* @param $config
|
||||
* An array containing wysiwyg editor profile settings.
|
||||
* @param $theme
|
||||
* The name of a theme/GUI/skin to use.
|
||||
*
|
||||
* @return
|
||||
* A settings array to be populated in
|
||||
* Drupal.settings.wysiwyg.configs.{editor}
|
||||
*/
|
||||
function wysiwyg_jwysiwyg_settings($editor, $config, $theme) {
|
||||
$settings = array(
|
||||
'initialContent' => '',
|
||||
);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
|
||||
Executable → Regular
+20
-2
@@ -24,10 +24,13 @@ function wysiwyg_markitup_editor() {
|
||||
'files' => array('markitup/jquery.markitup.pack.js'),
|
||||
),
|
||||
),
|
||||
'install note callback' => 'wysiwyg_markitup_install_note',
|
||||
'verified version range' => array('1.1.5', '1.1.14'),
|
||||
'version callback' => 'wysiwyg_markitup_version',
|
||||
'themes callback' => 'wysiwyg_markitup_themes',
|
||||
'settings form callback' => 'wysiwyg_markitup_settings_form',
|
||||
'settings callback' => 'wysiwyg_markitup_settings',
|
||||
'plugin callback' => 'wysiwyg_markitup_plugins',
|
||||
'plugin callback' => '_wysiwyg_markitup_plugins',
|
||||
'versions' => array(
|
||||
'1.1.5' => array(
|
||||
'js files' => array('markitup.js'),
|
||||
@@ -37,6 +40,13 @@ function wysiwyg_markitup_editor() {
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an install note.
|
||||
*/
|
||||
function wysiwyg_markitup_install_note() {
|
||||
return '<p class="warning">' . t('Only rename the extracted folder from "latest" to "markitup", no other changes needed.') . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
@@ -81,6 +91,14 @@ function wysiwyg_markitup_themes($editor, $profile) {
|
||||
return array('simple', 'markitup');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhances the editor profile settings form for markItUp.
|
||||
*/
|
||||
function wysiwyg_markitup_settings_form(&$form, &$form_state) {
|
||||
$form['basic']['language']['#access'] = FALSE;
|
||||
$form['css']['#access'] = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return runtime editor settings for a given wysiwyg profile.
|
||||
*
|
||||
@@ -171,7 +189,7 @@ function wysiwyg_markitup_settings($editor, $config, $theme) {
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_markitup_plugins($editor) {
|
||||
function _wysiwyg_markitup_plugins($editor) {
|
||||
return array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
|
||||
Executable → Regular
+22
-3
@@ -19,9 +19,11 @@ function wysiwyg_nicedit_editor() {
|
||||
'files' => array('nicEdit.js'),
|
||||
),
|
||||
),
|
||||
'verified version range' => array('0.9', '0.9'),
|
||||
'version callback' => 'wysiwyg_nicedit_version',
|
||||
'settings form callback' => 'wysiwyg_nicedit_settings_form',
|
||||
'settings callback' => 'wysiwyg_nicedit_settings',
|
||||
'plugin callback' => 'wysiwyg_nicedit_plugins',
|
||||
'plugin callback' => '_wysiwyg_nicedit_plugins',
|
||||
'versions' => array(
|
||||
'0.9' => array(
|
||||
'js files' => array('nicedit.js'),
|
||||
@@ -45,6 +47,18 @@ function wysiwyg_nicedit_version($editor) {
|
||||
return '0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhances the editor profile settings form for NicEdit.
|
||||
*
|
||||
* @see http://wiki.nicedit.com/w/page/515/Configuration%20Options
|
||||
*/
|
||||
function wysiwyg_nicedit_settings_form(&$form, &$form_state) {
|
||||
$form['basic']['language']['#access'] = FALSE;
|
||||
// NicEdit only supports loading a single stylesheet, and only in FF2.
|
||||
// This essentially means we're dropping stylesheet support for NiceEdit.
|
||||
$form['css']['#access'] = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return runtime editor settings for a given wysiwyg profile.
|
||||
*
|
||||
@@ -75,6 +89,7 @@ function wysiwyg_nicedit_settings($editor, $config, $theme) {
|
||||
}
|
||||
|
||||
// Add editor content stylesheet.
|
||||
// @todo Drop stylsheet support since it's only used in FF2.
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$css = drupal_get_path('theme', variable_get('theme_default', NULL)) . '/style.css';
|
||||
@@ -83,7 +98,11 @@ function wysiwyg_nicedit_settings($editor, $config, $theme) {
|
||||
}
|
||||
}
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['externalCSS'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
$settings['externalCSS'] = strtr($config['css_path'], array(
|
||||
'%b' => base_path(),
|
||||
'%t' => drupal_get_path('theme', variable_get('theme_default', NULL)),
|
||||
'%q' => variable_get('css_js_query_string', ''),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +112,7 @@ function wysiwyg_nicedit_settings($editor, $config, $theme) {
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_nicedit_plugins($editor) {
|
||||
function _wysiwyg_nicedit_plugins($editor) {
|
||||
return array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Editor integration functions for openWYSIWYG.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*/
|
||||
function wysiwyg_openwysiwyg_editor() {
|
||||
$editor['openwysiwyg'] = array(
|
||||
'title' => 'openWYSIWYG',
|
||||
'vendor url' => 'http://www.openwebware.com',
|
||||
'download url' => 'http://www.openwebware.com/download.shtml',
|
||||
'library path' => wysiwyg_get_path('openwysiwyg') . '/scripts',
|
||||
'libraries' => array(
|
||||
'src' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array('wysiwyg.js'),
|
||||
),
|
||||
),
|
||||
'version callback' => 'wysiwyg_openwysiwyg_version',
|
||||
'themes callback' => 'wysiwyg_openwysiwyg_themes',
|
||||
'settings callback' => 'wysiwyg_openwysiwyg_settings',
|
||||
'plugin callback' => 'wysiwyg_openwysiwyg_plugins',
|
||||
'versions' => array(
|
||||
'1.4.7' => array(
|
||||
'js files' => array('openwysiwyg.js'),
|
||||
'css files' => array('openwysiwyg.css'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
* @param $editor
|
||||
* An array containing editor properties as returned from hook_editor().
|
||||
*
|
||||
* @return
|
||||
* The installed editor version.
|
||||
*/
|
||||
function wysiwyg_openwysiwyg_version($editor) {
|
||||
// 'library path' has '/scripts' appended already.
|
||||
$changelog = $editor['editor path'] . '/changelog';
|
||||
if (!file_exists($changelog)) {
|
||||
return;
|
||||
}
|
||||
$changelog = fopen($changelog, 'r');
|
||||
$line = fgets($changelog, 20);
|
||||
if (preg_match('@v([\d\.]+)@', $line, $version)) {
|
||||
fclose($changelog);
|
||||
return $version[1];
|
||||
}
|
||||
fclose($changelog);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine available editor themes or check/reset a given one.
|
||||
*
|
||||
* @param $editor
|
||||
* A processed hook_editor() array of editor properties.
|
||||
* @param $profile
|
||||
* A wysiwyg editor profile.
|
||||
*
|
||||
* @return
|
||||
* An array of theme names. The first returned name should be the default
|
||||
* theme name.
|
||||
*/
|
||||
function wysiwyg_openwysiwyg_themes($editor, $profile) {
|
||||
return array('default');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return runtime editor settings for a given wysiwyg profile.
|
||||
*
|
||||
* @param $editor
|
||||
* A processed hook_editor() array of editor properties.
|
||||
* @param $config
|
||||
* An array containing wysiwyg editor profile settings.
|
||||
* @param $theme
|
||||
* The name of a theme/GUI/skin to use.
|
||||
*
|
||||
* @return
|
||||
* A settings array to be populated in
|
||||
* Drupal.settings.wysiwyg.configs.{editor}
|
||||
*/
|
||||
function wysiwyg_openwysiwyg_settings($editor, $config, $theme) {
|
||||
$settings = array(
|
||||
'path' => base_path() . $editor['editor path'] . '/',
|
||||
'Width' => '100%',
|
||||
);
|
||||
|
||||
if (isset($config['path_loc']) && $config['path_loc'] == 'none') {
|
||||
$settings['StatusBarEnabled'] = FALSE;
|
||||
}
|
||||
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['CSSFile'] = reset(wysiwyg_get_css());
|
||||
}
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['CSSFile'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
}
|
||||
}
|
||||
|
||||
$settings['Toolbar'] = array();
|
||||
if (!empty($config['buttons'])) {
|
||||
$plugins = wysiwyg_get_plugins($editor['name']);
|
||||
foreach ($config['buttons'] as $plugin => $buttons) {
|
||||
foreach ($buttons as $button => $enabled) {
|
||||
foreach (array('buttons', 'extensions') as $type) {
|
||||
// Skip unavailable plugins.
|
||||
if (!isset($plugins[$plugin][$type][$button])) {
|
||||
continue;
|
||||
}
|
||||
// Add buttons.
|
||||
if ($type == 'buttons') {
|
||||
$settings['Toolbar'][0][] = $button;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @todo
|
||||
// if (isset($config['block_formats'])) {
|
||||
// $settings['DropDowns']['headings']['elements'] = explode(',', $config['block_formats']);
|
||||
// }
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_openwysiwyg_plugins($editor) {
|
||||
$plugins = array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
'bold' => t('Bold'), 'italic' => t('Italic'), 'underline' => t('Underline'),
|
||||
'strikethrough' => t('Strike-through'),
|
||||
'justifyleft' => t('Align left'), 'justifycenter' => t('Align center'), 'justifyright' => t('Align right'), 'justifyfull' => t('Justify'),
|
||||
'unorderedlist' => t('Bullet list'), 'orderedlist' => t('Numbered list'),
|
||||
'outdent' => t('Outdent'), 'indent' => t('Indent'),
|
||||
'undo' => t('Undo'), 'redo' => t('Redo'),
|
||||
'createlink' => t('Link'),
|
||||
'insertimage' => t('Image'),
|
||||
'cleanup' => t('Clean-up'),
|
||||
'forecolor' => t('Forecolor'), 'backcolor' => t('Backcolor'),
|
||||
'superscript' => t('Sup'), 'subscript' => t('Sub'),
|
||||
'blockquote' => t('Blockquote'), 'viewSource' => t('Source code'),
|
||||
'hr' => t('Horizontal rule'),
|
||||
'cut' => t('Cut'), 'copy' => t('Copy'), 'paste' => t('Paste'),
|
||||
'visualaid' => t('Visual aid'),
|
||||
'removeformat' => t('Remove format'),
|
||||
'charmap' => t('Character map'),
|
||||
'headings' => t('HTML block format'), 'font' => t('Font'), 'fontsize' => t('Font size'),
|
||||
'maximize' => t('Fullscreen'),
|
||||
'preview' => t('Preview'),
|
||||
'print' => t('Print'),
|
||||
'inserttable' => t('Table'),
|
||||
'help' => t('Help'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
),
|
||||
);
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
Executable → Regular
+1110
-217
File diff suppressed because it is too large
Load Diff
Executable → Regular
+26
-4
@@ -16,15 +16,23 @@ function wysiwyg_whizzywig_editor() {
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Default',
|
||||
'files' => array('whizzywig.js', 'xhtml.js'),
|
||||
'files' => array('whizzywig.js'),
|
||||
),
|
||||
),
|
||||
'verified version range' => array('55', '63'),
|
||||
'version callback' => 'wysiwyg_whizzywig_version',
|
||||
'settings form callback' => 'wysiwyg_whizzywig_settings_form',
|
||||
'settings callback' => 'wysiwyg_whizzywig_settings',
|
||||
'plugin callback' => 'wysiwyg_whizzywig_plugins',
|
||||
'plugin callback' => '_wysiwyg_whizzywig_plugins',
|
||||
'versions' => array(
|
||||
'55' => array(
|
||||
'js files' => array('whizzywig.js'),
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Default',
|
||||
'files' => array('whizzywig.js', 'xhtml.js'),
|
||||
),
|
||||
),
|
||||
),
|
||||
'56' => array(
|
||||
'js files' => array('whizzywig-56.js'),
|
||||
@@ -62,6 +70,15 @@ function wysiwyg_whizzywig_version($editor) {
|
||||
fclose($script);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhances the editor profile settings form for Whizzywig.
|
||||
*/
|
||||
function wysiwyg_whizzywig_settings_form(&$form, &$form_state) {
|
||||
$form['basic']['language']['#access'] = FALSE;
|
||||
// @todo CSS settings are currently not used.
|
||||
$form['css']['#access'] = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return runtime editor settings for a given wysiwyg profile.
|
||||
*
|
||||
@@ -102,6 +119,7 @@ function wysiwyg_whizzywig_settings($editor, $config, $theme) {
|
||||
}
|
||||
|
||||
// Add editor content stylesheet.
|
||||
// @todo CSS settings are currently not used.
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$css = drupal_get_path('theme', variable_get('theme_default', NULL)) . '/style.css';
|
||||
@@ -110,7 +128,11 @@ function wysiwyg_whizzywig_settings($editor, $config, $theme) {
|
||||
}
|
||||
}
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['externalCSS'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
$settings['externalCSS'] = strtr($config['css_path'], array(
|
||||
'%b' => base_path(),
|
||||
'%t' => drupal_get_path('theme', variable_get('theme_default', NULL)),
|
||||
'%q' => variable_get('css_js_query_string', ''),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,7 +142,7 @@ function wysiwyg_whizzywig_settings($editor, $config, $theme) {
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_whizzywig_plugins($editor) {
|
||||
function _wysiwyg_whizzywig_plugins($editor) {
|
||||
return array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
|
||||
Executable → Regular
+41
-6
@@ -28,10 +28,12 @@ function wysiwyg_wymeditor_editor() {
|
||||
'files' => array('jquery.wymeditor.js'),
|
||||
),
|
||||
),
|
||||
'verified version range' => array('0.5', '1.0.0b5'),
|
||||
'version callback' => 'wysiwyg_wymeditor_version',
|
||||
'themes callback' => 'wysiwyg_wymeditor_themes',
|
||||
'settings form callback' => 'wysiwyg_wymeditor_settings_form',
|
||||
'settings callback' => 'wysiwyg_wymeditor_settings',
|
||||
'plugin callback' => 'wysiwyg_wymeditor_plugins',
|
||||
'plugin callback' => '_wysiwyg_wymeditor_plugins',
|
||||
'versions' => array(
|
||||
'0.5-rc1' => array(
|
||||
'js files' => array('wymeditor.js'),
|
||||
@@ -81,6 +83,30 @@ function wysiwyg_wymeditor_themes($editor, $profile) {
|
||||
return array('compact', 'default', 'minimal', 'silver', 'twopanels');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhances the editor profile settings form for WYMeditor.
|
||||
*
|
||||
* @see http://wymeditor.readthedocs.org/en/latest/version_1.0_and_0.5/getting_started/customize.html
|
||||
*/
|
||||
function wysiwyg_wymeditor_settings_form(&$form, &$form_state) {
|
||||
$profile = $form_state['wysiwyg_profile'];
|
||||
$settings = $profile->settings;
|
||||
$settings += array(
|
||||
'block_formats' => 'p,blockquote,pre,h2,h3,h4,h5,h6,div',
|
||||
);
|
||||
|
||||
$form['css']['#description'] = t('Note: WYMeditor can only load a single stylesheet into the editor.');
|
||||
|
||||
$form['css']['block_formats'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Block formats'),
|
||||
'#default_value' => $settings['block_formats'],
|
||||
'#size' => 40,
|
||||
'#maxlength' => 250,
|
||||
'#description' => t('Comma separated list of HTML block formats. Possible values: <code>@format-list</code>.', array('@format-list' => 'p,h1,h2,h3,h4,h5,h6,blockquote,pre,th')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return runtime editor settings for a given wysiwyg profile.
|
||||
*
|
||||
@@ -103,7 +129,11 @@ function wysiwyg_wymeditor_settings($editor, $config, $theme) {
|
||||
'wymPath' => $editor['libraries'][$library]['files'][0],
|
||||
// @todo Does not work in Drupal; jQuery can live anywhere.
|
||||
'jQueryPath' => base_path() . 'misc/jquery.js',
|
||||
'updateSelector' => '.form-submit',
|
||||
// WYMeditor's update event handler will revert the field contents if
|
||||
// changes were made after it was detached. Wysiwyg takes care of submit
|
||||
// events anyway so make sure WYMeditor does not bind it anywhere.
|
||||
'updateSelector' => '#wysiwyg-no-element',
|
||||
'updateEvent' => 'wysiwyg-no-event',
|
||||
'skin' => $theme,
|
||||
);
|
||||
|
||||
@@ -158,7 +188,7 @@ function wysiwyg_wymeditor_settings($editor, $config, $theme) {
|
||||
'blockquote' => 'Blockquote',
|
||||
'th' => 'Table_Header',
|
||||
);
|
||||
foreach (explode(',', $config['block_formats']) as $tag) {
|
||||
foreach (explode(',', preg_replace('@\s+@', '', $config['block_formats'])) as $tag) {
|
||||
if (isset($containers[$tag])) {
|
||||
$settings['containersItems'][] = array(
|
||||
'name' => strtoupper($tag),
|
||||
@@ -169,14 +199,19 @@ function wysiwyg_wymeditor_settings($editor, $config, $theme) {
|
||||
}
|
||||
}
|
||||
|
||||
// Add editor content stylesheet.
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
// WYMeditor only supports one CSS file currently.
|
||||
$css = wysiwyg_get_css();
|
||||
$css = wysiwyg_get_css(isset($config['css_theme']) ? $config['css_theme'] : '');
|
||||
$settings['stylesheet'] = reset($css);
|
||||
}
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['stylesheet'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
$settings['stylesheet'] = strtr($config['css_path'], array(
|
||||
'%b' => base_path(),
|
||||
'%t' => drupal_get_path('theme', variable_get('theme_default', NULL)),
|
||||
'%q' => variable_get('css_js_query_string', ''),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,7 +221,7 @@ function wysiwyg_wymeditor_settings($editor, $config, $theme) {
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_wymeditor_plugins($editor) {
|
||||
function _wysiwyg_wymeditor_plugins($editor) {
|
||||
$plugins = array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
|
||||
Executable → Regular
+67
-32
@@ -40,19 +40,22 @@ function wysiwyg_yui_editor() {
|
||||
),
|
||||
),
|
||||
),
|
||||
'install note callback' => 'wysiwyg_yui_install_note',
|
||||
'verified version range' => array('2.7.0', '2.9.0'),
|
||||
'version callback' => 'wysiwyg_yui_version',
|
||||
'themes callback' => 'wysiwyg_yui_themes',
|
||||
'settings form callback' => 'wysiwyg_yui_settings_form',
|
||||
'load callback' => 'wysiwyg_yui_load',
|
||||
'settings callback' => 'wysiwyg_yui_settings',
|
||||
'plugin callback' => 'wysiwyg_yui_plugins',
|
||||
'plugin settings callback' => 'wysiwyg_yui_plugin_settings',
|
||||
'plugin callback' => '_wysiwyg_yui_plugins',
|
||||
'plugin meta callback' => '_wysiwyg_yui_plugin_meta',
|
||||
'proxy plugin' => array(
|
||||
'drupal' => array(
|
||||
'load' => TRUE,
|
||||
'proxy' => TRUE,
|
||||
),
|
||||
),
|
||||
'proxy plugin settings callback' => 'wysiwyg_yui_proxy_plugin_settings',
|
||||
'proxy plugin settings callback' => '_wysiwyg_yui_proxy_plugin_settings',
|
||||
'versions' => array(
|
||||
'2.7.0' => array(
|
||||
'js files' => array('yui.js'),
|
||||
@@ -62,6 +65,14 @@ function wysiwyg_yui_editor() {
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an install note.
|
||||
*/
|
||||
function wysiwyg_yui_install_note() {
|
||||
$output = '<p class="warning">' . t('YUI 3 is not supported because it does not contain a complete editor.') . '</p>';
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
@@ -104,6 +115,39 @@ function wysiwyg_yui_themes($editor, $profile) {
|
||||
return array('sam');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhances the editor profile settings form for YUI.
|
||||
*
|
||||
* @see http://developer.yahoo.com/yui/docs/YAHOO.widget.Editor.html
|
||||
*/
|
||||
function wysiwyg_yui_settings_form(&$form, &$form_state) {
|
||||
$profile = $form_state['wysiwyg_profile'];
|
||||
$settings = $profile->settings;
|
||||
$settings += array(
|
||||
'autoHeight' => FALSE,
|
||||
'block_formats' => 'p,h1,h2,h3,h4,h5,h6',
|
||||
);
|
||||
|
||||
$form['basic']['language']['#access'] = FALSE;
|
||||
|
||||
$form['appearance']['autoHeight'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Enable automatic height'),
|
||||
'#default_value' => $settings['autoHeight'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('When enabled, removes the scrollbars from the edit area and resizes it to fit the content.') . ' ' . t('Uses the <a href="@url">@setting</a> setting internally.', array('@setting' => 'autoHeight', '@url' => url('http://developer.yahoo.com/yui/docs/YAHOO.widget.SimpleEditor.html#config_autoHeight'))),
|
||||
);
|
||||
|
||||
$form['css']['block_formats'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Block formats'),
|
||||
'#default_value' => $settings['block_formats'],
|
||||
'#size' => 40,
|
||||
'#maxlength' => 250,
|
||||
'#description' => t('Comma separated list of HTML block formats. Possible values: <code>@format-list</code>.', array('@format-list' => 'p,h1,h2,h3,h4,h5,h6,')),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform additional actions upon loading this editor.
|
||||
*
|
||||
@@ -143,11 +187,7 @@ function wysiwyg_yui_settings($editor, $config, $theme) {
|
||||
'ptags' => TRUE,
|
||||
);
|
||||
|
||||
if (isset($config['path_loc']) && $config['path_loc'] != 'none') {
|
||||
$settings['dompath'] = $config['path_loc'];
|
||||
}
|
||||
// Enable auto-height feature when editor should be resizable.
|
||||
if (!empty($config['resizing'])) {
|
||||
if (!empty($config['autoHeight'])) {
|
||||
$settings['autoHeight'] = TRUE;
|
||||
}
|
||||
|
||||
@@ -178,7 +218,7 @@ function wysiwyg_yui_settings($editor, $config, $theme) {
|
||||
'h5' => array('text' => 'Heading 5', 'value' => 'h5'),
|
||||
'h6' => array('text' => 'Heading 6', 'value' => 'h6'),
|
||||
);
|
||||
foreach (explode(',', $config['block_formats']) as $tag) {
|
||||
foreach (explode(',', preg_replace('@\s+@', '', $config['block_formats'])) as $tag) {
|
||||
if (isset($headings[$tag])) {
|
||||
$extra['menu'][] = $headings[$tag];
|
||||
}
|
||||
@@ -208,10 +248,14 @@ function wysiwyg_yui_settings($editor, $config, $theme) {
|
||||
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['extracss'] = wysiwyg_get_css();
|
||||
$settings['extracss'] = wysiwyg_get_css(isset($config['css_theme']) ? $config['css_theme'] : '');
|
||||
}
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['extracss'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
$settings['extracss'] = strtr($config['css_path'], array(
|
||||
'%b' => base_path(),
|
||||
'%t' => drupal_get_path('theme', variable_get('theme_default', NULL)),
|
||||
'%q' => variable_get('css_js_query_string', ''),
|
||||
));
|
||||
$settings['extracss'] = explode(',', $settings['extracss']);
|
||||
}
|
||||
// YUI only supports inline CSS, so we need to use @import directives.
|
||||
@@ -277,36 +321,27 @@ function wysiwyg_yui_button_setting($editor, $plugin, $button, $extra = array())
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array of native external plugins that need to be loaded separately.
|
||||
* Build a JS settings array with global metadata for native external plugins.
|
||||
*/
|
||||
function wysiwyg_yui_plugin_settings($editor, $profile, $plugins) {
|
||||
$settings = array();
|
||||
foreach ($plugins as $name => $plugin) {
|
||||
if (!empty($plugin['load'])) {
|
||||
// Add path for native external plugins; internal ones are loaded
|
||||
// automatically.
|
||||
if (empty($plugin['internal']) && isset($plugin['path'])) {
|
||||
$settings[$name] = base_path() . $plugin['path'];
|
||||
}
|
||||
function _wysiwyg_yui_plugin_meta($editor, $plugin) {
|
||||
$meta = NULL;
|
||||
if (!empty($plugin['load'])) {
|
||||
// Add path for native external plugins; internal ones are loaded
|
||||
// automatically.
|
||||
if (empty($plugin['internal']) && isset($plugin['path'])) {
|
||||
$meta = base_path() . $plugin['path'];
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array for Drupal plugins loaded via the proxy plugin.
|
||||
*/
|
||||
function wysiwyg_yui_proxy_plugin_settings($editor, $profile, $plugins) {
|
||||
function _wysiwyg_yui_proxy_plugin_settings($editor, $profile, $plugins) {
|
||||
$settings = array();
|
||||
foreach ($plugins as $name => $plugin) {
|
||||
// Populate required plugin settings.
|
||||
$settings[$name] = $plugin['dialog settings'] + array(
|
||||
'title' => $plugin['title'],
|
||||
'icon' => base_path() . $plugin['icon path'] . '/' . $plugin['icon file'],
|
||||
'iconTitle' => $plugin['icon title'],
|
||||
// @todo These should only be set if the plugin defined them.
|
||||
'css' => base_path() . $plugin['css path'] . '/' . $plugin['css file'],
|
||||
);
|
||||
$settings[$name] = array();
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
@@ -314,7 +349,7 @@ function wysiwyg_yui_proxy_plugin_settings($editor, $profile, $plugins) {
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_yui_plugins($editor) {
|
||||
function _wysiwyg_yui_plugins($editor) {
|
||||
return array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* Handles adding theme stylesheets into WYSIWYG editors.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A simple page callback for a checking if a theme is active.
|
||||
*
|
||||
* A theme the user does not have permission to use can not be set active.
|
||||
*
|
||||
* @see _wysiwyg_theme_callback()
|
||||
* @see _wysiwyg_delivery_dummy()
|
||||
*/
|
||||
function _wysiwyg_theme_check_active($theme) {
|
||||
global $theme_key;
|
||||
return $theme === $theme_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple page delivery dummy implementation.
|
||||
*
|
||||
* Acts like a normal HTML delivery mechanism but only "renders" a dummy string
|
||||
* and prints a short string telling if the page callback result was "true".
|
||||
*
|
||||
* Useful for returning the results of an access check, performed by the page
|
||||
* callback. The actual page callback return value is never printed.
|
||||
*
|
||||
* Success:
|
||||
* - Status header: "200 OK"
|
||||
* - Content: "OK"
|
||||
*
|
||||
* Failure:
|
||||
* - Status header: "403 Forbidden"
|
||||
* - Content: "Forbidden"
|
||||
*
|
||||
* @see _wysiwyg_theme_check_active()
|
||||
*/
|
||||
function _wysiwyg_delivery_dummy($page_callback_result) {
|
||||
global $theme_key;
|
||||
drupal_add_http_header('Content-Language', 'en');
|
||||
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
|
||||
if ($page_callback_result) {
|
||||
drupal_add_http_header('Status', '200 OK');
|
||||
}
|
||||
else {
|
||||
drupal_add_http_header('Status', '403 Forbidden');
|
||||
}
|
||||
// Make sure the theme is always initialized.
|
||||
drupal_theme_initialize();
|
||||
// Render a completely themed empty page to catch as many stylesheets as
|
||||
// possible, but don't actually return anything to speed up the response.
|
||||
$rendered = drupal_render_page('Dummy');
|
||||
// In case headers aren't enough, put the status in the response body.
|
||||
print ($page_callback_result ? 'OK' : 'Forbidden');
|
||||
// Cleanup and session handling.
|
||||
drupal_page_footer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Theme callback to simply suggest a theme based on the page arugment.
|
||||
*/
|
||||
function _wysiwyg_theme_callback($theme) {
|
||||
return $theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* A filtering pre render callback for style elements.
|
||||
*
|
||||
* Invokes hook_wysiwyg_editor_stules_alter() to allow other code to filter the
|
||||
* list of stylesheets which will be used inside the editors in WYSIWYG mode.
|
||||
*
|
||||
* Intended to run before Core sorts/groups/aggregates stylesheets.
|
||||
*/
|
||||
function _wysiwyg_filter_editor_styles(&$elements) {
|
||||
global $theme_key;
|
||||
if (strpos(current_path(), 'wysiwyg_theme/') !== 0) {
|
||||
return $elements;
|
||||
}
|
||||
$context = array('theme' => $theme_key);
|
||||
drupal_alter('wysiwyg_editor_styles', $elements, $context); $css = array();
|
||||
return $elements;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a cache of the stylesheets used by the currently set theme.
|
||||
*
|
||||
* Since this is a pre render callback for the styles element, it should run
|
||||
* late enough to catch all the stylesheets added just before the actual markup
|
||||
* for them is rendered.
|
||||
*
|
||||
* The first time this runs for a theme it's too late for a module to have any
|
||||
* use of the cache, so wysiwyg_get_css() uses drupal_http_request() to fetch a
|
||||
* dummy page, filling the cache before the original response is sent.
|
||||
*
|
||||
* Intended to run after Core has sorted/grouped/aggregated stylesheets.
|
||||
*/
|
||||
function _wysiwyg_pre_render_styles($elements) {
|
||||
global $theme_key;
|
||||
if (strpos(current_path(), 'wysiwyg_theme/') !== 0) {
|
||||
return $elements;
|
||||
}
|
||||
$cached = cache_get('wysiwyg_css');
|
||||
foreach (element_children($elements) as $child) {
|
||||
if ($elements['#groups'][$child]['group'] != CSS_THEME) {
|
||||
continue;
|
||||
}
|
||||
switch ($elements[$child]['#tag']) {
|
||||
case 'link':
|
||||
$css[] = $elements[$child]['#attributes']['href'];
|
||||
break;
|
||||
case 'style':
|
||||
if (!empty($elements[$child]['#attributes']['href'])) {
|
||||
$css[] = $elements[$child]['#attributes']['href'];
|
||||
}
|
||||
elseif (!empty($elements[$child]['#value'])){
|
||||
preg_match_all('/\@import url\("([^"]+)"\);/', $elements[$child]['#value'], $matches, PREG_SET_ORDER);
|
||||
foreach ($matches as $val) {
|
||||
$css[] = $val[1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
$all = empty($cached->data) ? array() : $cached->data;
|
||||
$all[$theme_key] = array('files' => $css, 'aggregated' => variable_get('preprocess_css', FALSE));
|
||||
}
|
||||
$all['_css_js_query_string'] = variable_get('css_js_query_string');
|
||||
cache_set('wysiwyg_css', $all);
|
||||
return $elements;
|
||||
}
|
||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
|
Before Width: | Height: | Size: 108 B After Width: | Height: | Size: 108 B |
Executable → Regular
|
Before Width: | Height: | Size: 255 B After Width: | Height: | Size: 255 B |
Executable → Regular
|
Before Width: | Height: | Size: 43 B After Width: | Height: | Size: 43 B |
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
+3
-3
@@ -6,9 +6,9 @@ hidden = TRUE
|
||||
dependencies[] = wysiwyg
|
||||
files[] = wysiwyg_test.module
|
||||
|
||||
; Information added by drupal.org packaging script on 2012-10-02
|
||||
version = "7.x-2.2"
|
||||
; Information added by Drupal.org packaging script on 2016-12-31
|
||||
version = "7.x-2.3"
|
||||
core = "7.x"
|
||||
project = "wysiwyg"
|
||||
datestamp = "1349213776"
|
||||
datestamp = "1483223295"
|
||||
|
||||
|
||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
+526
-251
File diff suppressed because it is too large
Load Diff
Executable → Regular
+22
@@ -95,3 +95,25 @@ Drupal.wysiwyg.plugins.awesome = {
|
||||
return '<img src="' + settings.path + '/images/spacer.gif" alt="<--break->" title="<--break-->" class="wysiwyg-break drupal-content" />';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Because some editors add a lot of new elements with the id attribute set,
|
||||
* Wysiwyg provides a way to exclude such ids from the ajax_html_ids[] parameter
|
||||
* sent in AJAX requests. Serverside POST limits such as PHP's max_input_vars
|
||||
* could otherwise cause the request to be rejected.
|
||||
*
|
||||
* The filter gathers a list of jQuery selectors from a global list in
|
||||
* Drupal.wysiwyg.excludeIdSelectors, joins them with a comma separator and
|
||||
* wraps them in "[id]:not[...]", which is then run on the document the same way
|
||||
* Drupal core gathers the ids on every AJAX request.
|
||||
*
|
||||
* To add to the filter, set a unique key to Drupal.wysiwyg.excludeIdSelectors
|
||||
* and set its value to an Array holding one or more selector strings which
|
||||
* would match the element(s) to exclude.
|
||||
*
|
||||
* Beware not to match elements which are not removed before the actual request
|
||||
* is performed, or Drupal may accidentally reuse the same id for new elements.
|
||||
*
|
||||
* Below is a sample from ckeditor.inc matching every id starting with 'cke_'.
|
||||
*/
|
||||
Drupal.wysiwyg.excludeIdSelectors.wysiwyg_ckeditor = ['[id^="cke_"]'];
|
||||
|
||||
Executable → Regular
+68
-3
@@ -53,6 +53,8 @@ function hook_wysiwyg_plugin($editor, $version) {
|
||||
// A list of buttons provided by this native plugin. The key has to
|
||||
// match the corresponding JavaScript implementation. The value is
|
||||
// is displayed on the editor configuration form only.
|
||||
// CKEditor-specific note: The internal button name/key is
|
||||
// capitalized, i.e. Img_assist.
|
||||
'buttons' => array(
|
||||
'img_assist' => t('Image Assist'),
|
||||
),
|
||||
@@ -75,7 +77,7 @@ function hook_wysiwyg_plugin($editor, $version) {
|
||||
// Most plugins should define TRUE here.
|
||||
'load' => TRUE,
|
||||
// Boolean whether this plugin is a native plugin, i.e. shipped with
|
||||
// the editor. Definition must be ommitted for plugins provided by
|
||||
// the editor. Definition must be omitted for plugins provided by
|
||||
// other modules. TRUE means 'path' and 'filename' above are ignored
|
||||
// and the plugin is instead loaded from the editor's plugin folder.
|
||||
'internal' => TRUE,
|
||||
@@ -204,6 +206,19 @@ function hook_INCLUDE_editor() {
|
||||
// (optional) A callback to invoke to return additional notes for installing
|
||||
// the editor library in the administrative list/overview.
|
||||
'install note callback' => 'wysiwyg_ckeditor_install_note',
|
||||
// The minimum and maximum versions the implemetation has been tested with.
|
||||
// Users will be notified if installing a version not within this range.
|
||||
'verified version range' => array('1.2.3', '3.4.5'),
|
||||
// (optional) A callback to perform migrations of the settings stored in a
|
||||
// profile when a library change has been detected. Takes a reference to a
|
||||
// settings object, the processed editor definition, the profile version and
|
||||
// the installed library version. Migrations should be performed in the
|
||||
// order changes were introduced by library versions, and the last version
|
||||
// migrated to should be returned, or FALSE if no migration was possible.
|
||||
// The returned version should be less than or equal to the highest version
|
||||
// ( and >= the lowest version) defined in 'verified version range' and
|
||||
// be as close as possible to, without passing, the installed version.
|
||||
'migrate settings callback' => 'wysiwyg_ckeditor_migrate_settings',
|
||||
// A callback to determine the library's version.
|
||||
'version callback' => 'wysiwyg_ckeditor_version',
|
||||
// A callback to return available themes/skins for the editor library.
|
||||
@@ -224,8 +239,10 @@ function hook_INCLUDE_editor() {
|
||||
'settings callback' => 'wysiwyg_ckeditor_settings',
|
||||
// A callback to supply definitions of available editor plugins.
|
||||
'plugin callback' => 'wysiwyg_ckeditor_plugins',
|
||||
// A callback to convert administrative plugin settings for a editor profile
|
||||
// into JavaScript settings.
|
||||
// A callback to supply global metadata for a single native external plugin.
|
||||
'plugin meta callback' => 'wysiwyg_ckeditor_plugin_meta',
|
||||
// A callback to convert administrative plugin settings for an editor
|
||||
// profile into JavaScript settings per profile.
|
||||
'plugin settings callback' => 'wysiwyg_ckeditor_plugin_settings',
|
||||
// (optional) Defines the proxy plugin that handles plugins provided by
|
||||
// Drupal modules, which work in all editors that support proxy plugins.
|
||||
@@ -249,6 +266,16 @@ function hook_INCLUDE_editor() {
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alter editor definitions defined by other modules.
|
||||
*
|
||||
* @param array $editors
|
||||
* The Editors to alter.
|
||||
*/
|
||||
function hook_wysiwyg_editor_alter(&$editors) {
|
||||
$editors['editor']['version callback'] = 'my_own_version_callback';
|
||||
}
|
||||
|
||||
/**
|
||||
* Act on editor profile settings.
|
||||
*
|
||||
@@ -279,5 +306,43 @@ function hook_wysiwyg_editor_settings_alter(&$settings, $context) {
|
||||
if ($context['profile']->editor == 'tinymce') {
|
||||
// Supported values to JSON data types.
|
||||
$settings['cleanup_on_startup'] = TRUE;
|
||||
// Function references (callbacks) need special care.
|
||||
// @see wysiwyg_wrap_js_callback()
|
||||
$settings['file_browser_callback'] = wysiwyg_wrap_js_callback('myFileBrowserCallback');
|
||||
// Regular Expressions need special care.
|
||||
// @see wysiwyg_wrap_js_regexp()
|
||||
$settings['stylesheetParser_skipSelectors'] = wysiwyg_wrap_js_regexp('(^body\.|^caption\.|\.high|^\.)', 'i');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Act on stylesheets used in WYSIWYG mode.
|
||||
*
|
||||
* This hook acts like a pre-render callback to the style element normally
|
||||
* output in the document header. It is invoked before Core has
|
||||
* sorted/grouped/aggregated stylehsheets and changes made here will only have
|
||||
* an effect on the stylesheets used in an editor's WYSIWYG mode.
|
||||
* Wysiwyg will only keep items if their type is 'file' or 'inline' and only if
|
||||
* they are in the group CSS_THEME.
|
||||
*
|
||||
* This hook may be invoked several times in a row with slightly different or
|
||||
* altered stylesheets if something like Color module is used by a theme.
|
||||
* Wysiwyg will cache the final list of stylesheets so this hook will only be
|
||||
* called while the cache is being rebuilt.
|
||||
*
|
||||
* Messages set in this hook will not be displayed because the processing is
|
||||
* done in an internal HTTP request and the page output is ignored.
|
||||
*
|
||||
* @param $elements
|
||||
* The style element which will be rendered. Added stylesheets are found in
|
||||
* $element['#items']['path/to/stylesheet.css'].
|
||||
* @param $context
|
||||
* An array with the following keys:
|
||||
* - theme: The name of the theme which was used when the list of stylesheets
|
||||
* was generated.
|
||||
*/
|
||||
function hook_wysiwyg_editor_styles_alter(&$element, $context) {
|
||||
if ($context['theme'] == 'alpha') {
|
||||
unset($element['#items']['sites/all/themes/omega/alpha/css/alpha-debug.css']);
|
||||
}
|
||||
}
|
||||
|
||||
Executable → Regular
Executable → Regular
+27
@@ -78,6 +78,27 @@ function wysiwyg_features_revert($module) {
|
||||
function wysiwyg_features_rebuild($module) {
|
||||
if ($defaults = features_get_default('wysiwyg', $module)) {
|
||||
foreach ($defaults as $profile) {
|
||||
if (empty($profile['settings']['_profile_preferences'])) {
|
||||
$settings = &$profile['settings'];
|
||||
// Importing an older profile, move state to its own section.
|
||||
$preferences = array(
|
||||
'add_to_summaries' => $settings['add_to_summaries'],
|
||||
'default' => $settings['default'],
|
||||
'show_toggle' => $settings['show_toggle'],
|
||||
'user_choose' => $settings['user_choose'],
|
||||
'version' => NULL,
|
||||
);
|
||||
unset($settings['add_to_summaries'], $settings['default'], $settings['show_toggle'], $settings['user_choose']);
|
||||
if (!empty($settings['library'])) {
|
||||
$prefereces['library'] = $settings['library'];
|
||||
unset($settings['library']);
|
||||
}
|
||||
$editor = wysiwyg_get_editor($profile->editor);
|
||||
if ($editor['installed']) {
|
||||
$preferences['version'] = $editor['installed version'];
|
||||
}
|
||||
$settings['_profile_preferences'] = $preferences;
|
||||
}
|
||||
db_merge('wysiwyg')
|
||||
->key(array('format' => $profile['format']))
|
||||
->fields(array(
|
||||
@@ -85,6 +106,12 @@ function wysiwyg_features_rebuild($module) {
|
||||
'settings' => serialize($profile['settings']),
|
||||
))
|
||||
->execute();
|
||||
// Clear the editing caches.
|
||||
if (module_exists('ctools')) {
|
||||
ctools_include('object-cache');
|
||||
ctools_object_cache_clear_all('wysiwyg_profile', 'format' . $profile['format']);
|
||||
}
|
||||
cache_clear_all('wysiwyg_profile:format' . $profile['format'], 'cache');
|
||||
}
|
||||
wysiwyg_profile_cache_clear();
|
||||
}
|
||||
|
||||
Executable → Regular
+3
-3
@@ -9,9 +9,9 @@ configure = admin/config/content/wysiwyg
|
||||
files[] = wysiwyg.module
|
||||
files[] = tests/wysiwyg.test
|
||||
|
||||
; Information added by drupal.org packaging script on 2012-10-02
|
||||
version = "7.x-2.2"
|
||||
; Information added by Drupal.org packaging script on 2016-12-31
|
||||
version = "7.x-2.3"
|
||||
core = "7.x"
|
||||
project = "wysiwyg"
|
||||
datestamp = "1349213776"
|
||||
datestamp = "1483223295"
|
||||
|
||||
|
||||
Executable → Regular
+2
-2
@@ -1,7 +1,7 @@
|
||||
|
||||
Drupal.wysiwyg = Drupal.wysiwyg || { 'instances': {} };
|
||||
Drupal.wysiwyg = Drupal.wysiwyg || { 'instances': {}, 'excludeIdSelectors': { 'tokens': ['[id^="token-"]'] } };
|
||||
|
||||
Drupal.wysiwyg.editor = Drupal.wysiwyg.editor || { 'init': {}, 'attach': {}, 'detach': {}, 'instance': {} };
|
||||
Drupal.wysiwyg.editor = Drupal.wysiwyg.editor || { 'init': {}, 'update': {}, 'attach': {}, 'detach': {}, 'instance': {} };
|
||||
|
||||
Drupal.wysiwyg.plugins = Drupal.wysiwyg.plugins || {};
|
||||
|
||||
|
||||
Executable → Regular
+224
-112
@@ -55,7 +55,7 @@ function wysiwyg_schema() {
|
||||
'description' => 'The {filter_format}.format of the text format.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'status' => array(
|
||||
'description' => 'Boolean indicating whether the format is enabled by default.',
|
||||
@@ -66,9 +66,9 @@ function wysiwyg_schema() {
|
||||
'size' => 'tiny',
|
||||
),
|
||||
),
|
||||
'primary key' => array('uid', 'format'),
|
||||
'indexes' => array(
|
||||
'uid' => array('uid'),
|
||||
'format' => array('format'),
|
||||
),
|
||||
'foreign keys' => array(
|
||||
'uid' => array(
|
||||
@@ -130,117 +130,14 @@ function wysiwyg_update_dependencies() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of input formats to associate profiles to.
|
||||
* Implements hook_update_last_removed().
|
||||
*/
|
||||
function _wysiwyg_install_get_formats() {
|
||||
$formats = array();
|
||||
$result = db_query("SELECT format, name FROM {filter_formats}");
|
||||
while ($format = db_fetch_object($result)) {
|
||||
// Build a list of all formats.
|
||||
$formats[$format->format] = $format->name;
|
||||
// Fetch filters.
|
||||
$result2 = db_query("SELECT module, delta FROM {filters} WHERE format = %d", $format->format);
|
||||
while ($filter = db_fetch_object($result2)) {
|
||||
// If PHP filter is enabled, remove this format.
|
||||
if ($filter->module == 'php') {
|
||||
unset($formats[$format->format]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $formats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associate Wysiwyg profiles with input formats.
|
||||
*
|
||||
* Since there was no association yet, we can only assume that there is one
|
||||
* profile only, and that profile must be duplicated and assigned to all input
|
||||
* formats (except PHP code format). Also, input formats already have
|
||||
* titles/names, so Wysiwyg profiles do not need an own.
|
||||
*
|
||||
* Because input formats are already granted to certain user roles only, we can
|
||||
* remove our custom Wysiwyg profile permissions. A 1:1 relationship between
|
||||
* input formats and permissions makes plugin_count obsolete, too.
|
||||
*
|
||||
* Since the resulting table is completely different, a new schema is installed.
|
||||
*/
|
||||
function wysiwyg_update_6001() {
|
||||
$ret = array();
|
||||
if (db_table_exists('wysiwyg')) {
|
||||
return $ret;
|
||||
}
|
||||
// Install new schema.
|
||||
db_create_table($ret, 'wysiwyg', array(
|
||||
'fields' => array(
|
||||
'format' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
|
||||
'editor' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''),
|
||||
'settings' => array('type' => 'text', 'size' => 'normal'),
|
||||
),
|
||||
'primary key' => array('format'),
|
||||
));
|
||||
|
||||
// Fetch all input formats.
|
||||
$formats = _wysiwyg_install_get_formats();
|
||||
|
||||
// Fetch all profiles.
|
||||
$result = db_query("SELECT name, settings FROM {wysiwyg_profile}");
|
||||
while ($profile = db_fetch_object($result)) {
|
||||
$profile->settings = unserialize($profile->settings);
|
||||
// Extract editor name from profile settings.
|
||||
$profile->editor = $profile->settings['editor'];
|
||||
// Clean-up.
|
||||
unset($profile->settings['editor']);
|
||||
unset($profile->settings['old_name']);
|
||||
unset($profile->settings['name']);
|
||||
unset($profile->settings['rids']);
|
||||
// Sorry. There Can Be Only One. ;)
|
||||
break;
|
||||
}
|
||||
|
||||
if ($profile) {
|
||||
// Rebuild profiles and associate with input formats.
|
||||
foreach ($formats as $format => $name) {
|
||||
// Insert profiles.
|
||||
// We can't use update_sql() here because of curly braces in serialized
|
||||
// array.
|
||||
db_query("INSERT INTO {wysiwyg} (format, editor, settings) VALUES (%d, '%s', '%s')", $format, $profile->editor, serialize($profile->settings));
|
||||
$ret[] = array(
|
||||
'success' => TRUE,
|
||||
'query' => strtr('Wysiwyg profile %profile converted and associated with input format %format.', array('%profile' => check_plain($profile->name), '%format' => check_plain($name))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Drop obsolete tables {wysiwyg_profile} and {wysiwyg_role}.
|
||||
db_drop_table($ret, 'wysiwyg_profile');
|
||||
db_drop_table($ret, 'wysiwyg_role');
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear JS/CSS caches to ensure that clients load fresh copies.
|
||||
*/
|
||||
function wysiwyg_update_6200() {
|
||||
$ret = array();
|
||||
// Change query-strings on css/js files to enforce reload for all users.
|
||||
_drupal_flush_css_js();
|
||||
|
||||
drupal_clear_css_cache();
|
||||
drupal_clear_js_cache();
|
||||
|
||||
// Rebuild the menu to remove old admin/settings/wysiwyg/profile item.
|
||||
menu_rebuild();
|
||||
|
||||
// Flush content caches.
|
||||
cache_clear_all();
|
||||
|
||||
$ret[] = array(
|
||||
'success' => TRUE,
|
||||
'query' => 'Caches have been flushed.',
|
||||
);
|
||||
return $ret;
|
||||
function wysiwyg_update_last_removed() {
|
||||
// Users should upgrade to the latest 6.x-2.x release before upgrading to
|
||||
// 7.x-2.x. Some 7xxx functions duplicate work from 6xxx functions in 6.x-2.x
|
||||
// because both branches are supported in parallel, but changes will only be
|
||||
// applied once anyway because of safeguards.
|
||||
return 6202;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -311,3 +208,218 @@ function wysiwyg_update_7200() {
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update enabled font plugin buttons to default plugin in TinyMCE profiles.
|
||||
*/
|
||||
function wysiwyg_update_7201() {
|
||||
$query = db_select('wysiwyg', 'w')
|
||||
->fields('w', array('format', 'settings'))
|
||||
->condition('editor', 'tinymce');
|
||||
foreach ($query->execute() as $profile) {
|
||||
$settings = unserialize($profile->settings);
|
||||
// Move enabled 'font' buttons into 'default' plugin buttons.
|
||||
$changed = FALSE;
|
||||
foreach (array('formatselect', 'fontselect', 'fontsizeselect', 'styleselect') as $button) {
|
||||
if (isset($settings['buttons']['font'][$button])) {
|
||||
$settings['buttons']['default'][$button] = $settings['buttons']['font'][$button];
|
||||
unset($settings['buttons']['font'][$button]);
|
||||
$changed = TRUE;
|
||||
}
|
||||
}
|
||||
if ($changed) {
|
||||
db_update('wysiwyg')
|
||||
->condition('format', $profile->format)
|
||||
->fields(array(
|
||||
'settings' => serialize($settings),
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update internal names of settings.
|
||||
*/
|
||||
function wysiwyg_update_7202() {
|
||||
$query = db_select('wysiwyg', 'w')
|
||||
->fields('w', array('format', 'editor', 'settings'));
|
||||
foreach ($query->execute() as $profile) {
|
||||
$settings = unserialize($profile->settings);
|
||||
$changed = FALSE;
|
||||
switch ($profile->editor) {
|
||||
case 'tinymce':
|
||||
if (isset($settings['path_loc'])) {
|
||||
$settings['theme_advanced_statusbar_location'] = $settings['path_loc'];
|
||||
unset($settings['path_loc']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
if (isset($settings['toolbar_loc'])) {
|
||||
$settings['theme_advanced_toolbar_location'] = $settings['toolbar_loc'];
|
||||
unset($settings['toolbar_loc']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
if (isset($settings['toolbar_align'])) {
|
||||
$settings['theme_advanced_toolbar_align'] = $settings['toolbar_align'];
|
||||
unset($settings['toolbar_align']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
if (isset($settings['block_formats'])) {
|
||||
$settings['theme_advanced_blockformats'] = $settings['block_formats'];
|
||||
unset($settings['block_formats']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
if (isset($settings['css_classes'])) {
|
||||
$settings['theme_advanced_styles'] = $settings['css_classes'];
|
||||
unset($settings['css_classes']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
if (isset($settings['resizing'])) {
|
||||
$settings['theme_advanced_resizing'] = $settings['resizing'];
|
||||
unset($settings['resizing']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
break;
|
||||
case 'ckeditor':
|
||||
if (isset($settings['apply_source_formatting'])) {
|
||||
$settings['simple_source_formatting'] = $settings['apply_source_formatting'];
|
||||
unset($settings['apply_source_formatting']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
if (isset($settings['resizing'])) {
|
||||
$settings['resize_enabled'] = $settings['resizing'];
|
||||
unset($settings['resizing']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
if (isset($settings['toolbar_loc'])) {
|
||||
$settings['toolbarLocation'] = $settings['toolbar_loc'];
|
||||
unset($settings['toolbar_loc']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
if (isset($settings['paste_auto_cleanup_on_paste'])) {
|
||||
$settings['forcePasteAsPlainText'] = $settings['paste_auto_cleanup_on_paste'];
|
||||
unset($settings['paste_auto_cleanup_on_paste']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
if (isset($settings['css_classes'])) {
|
||||
$settings['stylesSet'] = $settings['css_classes'];
|
||||
unset($settings['css_classes']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
break;
|
||||
case 'fckeditor':
|
||||
if (isset($settings['apply_source_formatting'])) {
|
||||
$settings['FormatSource'] = $settings['FormatOutput'] = $settings['apply_source_formatting'];
|
||||
unset($settings['apply_source_formatting']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
if (isset($settings['paste_auto_cleanup_on_paste'])) {
|
||||
$settings['ForcePasteAsPlainText'] = $settings['paste_auto_cleanup_on_paste'];
|
||||
unset($settings['paste_auto_cleanup_on_paste']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
if (isset($settings['block_formats'])) {
|
||||
$settings['FontFormats'] = strtr($settings['block_formats'], array(',' => ';'));
|
||||
unset($settings['block_formats']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
break;
|
||||
case 'yui':
|
||||
// The resizing setting is triggering autoHeight instead of resize.
|
||||
if (isset($settings['resizing'])) {
|
||||
$settings['autoHeight'] = $settings['resizing'];
|
||||
unset($settings['resizing']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
break;
|
||||
case 'openwysiwyg':
|
||||
if (isset($settings['path_loc'])) {
|
||||
$settings['StatusBarEnabled'] = ($settings['path_loc'] != 'none' );
|
||||
unset($settings['path_loc']);
|
||||
$changed = TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// Do not touch any other profiles since the extra settings won't hurt.
|
||||
}
|
||||
if ($changed) {
|
||||
db_update('wysiwyg')
|
||||
->condition('format', $profile->format)
|
||||
->fields(array(
|
||||
'settings' => serialize($settings),
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add primary index to {wysiwyg_user}.
|
||||
*/
|
||||
function wysiwyg_update_7203() {
|
||||
db_drop_index('wysiwyg_user', 'uid');
|
||||
db_drop_index('wysiwyg_user', 'format');
|
||||
db_change_field('wysiwyg_user', 'format', 'format',
|
||||
array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
),
|
||||
array(
|
||||
'primary key' => array('uid', 'format'),
|
||||
'indexes' => array(
|
||||
'uid' => array('uid'),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove empty editor profiles and update existing profiles.
|
||||
*/
|
||||
function wysiwyg_update_7204() {
|
||||
// Remove unused profiles.
|
||||
$query = db_delete('wysiwyg')
|
||||
->condition('editor', '')
|
||||
->execute();
|
||||
$query = db_select('wysiwyg', 'w')
|
||||
->fields('w', array('format', 'editor', 'settings'));
|
||||
foreach ($query->execute() as $profile) {
|
||||
// Clear the editing caches.
|
||||
if (module_exists('ctools')) {
|
||||
ctools_include('object-cache');
|
||||
ctools_object_cache_clear_all('wysiwyg_profile', 'format' . $profile->format);
|
||||
}
|
||||
cache_clear_all('wysiwyg_profile:format' . $profile->format, 'cache');
|
||||
// Move profile state to its own section.
|
||||
$settings = unserialize($profile->settings);
|
||||
if (!empty($settings['_profile_preferences'])) {
|
||||
// Skip in case of re-run.
|
||||
continue;
|
||||
}
|
||||
$preferences = array(
|
||||
'add_to_summaries' => $settings['add_to_summaries'],
|
||||
'default' => $settings['default'],
|
||||
'show_toggle' => $settings['show_toggle'],
|
||||
'user_choose' => $settings['user_choose'],
|
||||
'version' => NULL,
|
||||
);
|
||||
unset($settings['add_to_summaries'], $settings['default'], $settings['show_toggle'], $settings['user_choose']);
|
||||
if (!empty($settings['library'])) {
|
||||
$prefereces['library'] = $settings['library'];
|
||||
unset($settings['library']);
|
||||
}
|
||||
$editor = wysiwyg_get_editor($profile->editor);
|
||||
if ($editor['installed']) {
|
||||
$preferences['version'] = $editor['installed version'];
|
||||
}
|
||||
$settings['_profile_preferences'] = $preferences;
|
||||
db_update('wysiwyg')
|
||||
->condition('format', $profile->format)
|
||||
->fields(array(
|
||||
'settings' => serialize($settings),
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
wysiwyg_profile_cache_clear();
|
||||
}
|
||||
|
||||
Executable → Regular
+780
-149
File diff suppressed because it is too large
Load Diff
Executable → Regular
+472
-166
@@ -4,6 +4,7 @@
|
||||
* @file
|
||||
* Integrates client-side editors with Drupal.
|
||||
*/
|
||||
require_once 'includes/styling.inc';
|
||||
|
||||
/**
|
||||
* Implements hook_entity_info().
|
||||
@@ -35,7 +36,21 @@ class WysiwygProfileController extends DrupalDefaultEntityController {
|
||||
function attachLoad(&$queried_entities, $revision_id = FALSE) {
|
||||
// Unserialize the profile settings.
|
||||
foreach ($queried_entities as $key => $record) {
|
||||
$queried_entities[$key]->settings = unserialize($record->settings);
|
||||
$settings = unserialize($record->settings);
|
||||
// Profile preferences are stored with the editor settings to avoid adding
|
||||
// an extra table column.
|
||||
if (isset($settings['_profile_preferences'])) {
|
||||
$preferences = $settings['_profile_preferences'];
|
||||
unset($settings['_profile_preferences']);
|
||||
}
|
||||
else {
|
||||
$preferences = array();
|
||||
}
|
||||
$queried_entities[$key]->settings = $settings;
|
||||
$queried_entities[$key]->preferences = $preferences;
|
||||
// @todo Store the name in the profile when allowing more than one per
|
||||
// format.
|
||||
$queried_entities[$key]->name = 'format' . $record->format;
|
||||
}
|
||||
// Call the default attachLoad() method.
|
||||
parent::attachLoad($queried_entities, $revision_id);
|
||||
@@ -54,31 +69,40 @@ function wysiwyg_menu() {
|
||||
'access arguments' => array('administer filters'),
|
||||
'file' => 'wysiwyg.admin.inc',
|
||||
);
|
||||
$items['admin/config/content/wysiwyg/profile'] = array(
|
||||
$items['admin/config/content/wysiwyg/list'] = array(
|
||||
'title' => 'List',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
'weight' => -10,
|
||||
);
|
||||
$items['admin/config/content/wysiwyg/profile/%wysiwyg_profile/edit'] = array(
|
||||
'title' => 'Edit',
|
||||
$items['admin/config/content/wysiwyg/profile/%wysiwyg_ui_profile_cache'] = array(
|
||||
'title callback' => 'wysiwyg_admin_profile_title',
|
||||
'title arguments' => array(5),
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('wysiwyg_profile_form', 5),
|
||||
'access arguments' => array('administer filters'),
|
||||
'file' => 'wysiwyg.admin.inc',
|
||||
'tab_root' => 'admin/config/content/wysiwyg/profile',
|
||||
'tab_parent' => 'admin/config/content/wysiwyg/profile/%wysiwyg_profile',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
);
|
||||
$items['admin/config/content/wysiwyg/profile/%wysiwyg_profile/delete'] = array(
|
||||
$items['admin/config/content/wysiwyg/profile/%wysiwyg_ui_profile_cache/edit'] = array(
|
||||
'title' => 'Edit',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
);
|
||||
$items['admin/config/content/wysiwyg/profile/%wysiwyg_ui_profile_cache/delete'] = array(
|
||||
'title' => 'Remove',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('wysiwyg_profile_delete_confirm', 5),
|
||||
'access arguments' => array('administer filters'),
|
||||
'file' => 'wysiwyg.admin.inc',
|
||||
'tab_root' => 'admin/config/content/wysiwyg/profile',
|
||||
'tab_parent' => 'admin/config/content/wysiwyg/profile/%wysiwyg_profile',
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'weight' => 10,
|
||||
);
|
||||
$items['admin/config/content/wysiwyg/profile/%wysiwyg_ui_profile_cache/break-lock'] = array(
|
||||
'title' => 'Break lock',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('wysiwyg_profile_break_lock_confirm', 5),
|
||||
'access arguments' => array('administer filters'),
|
||||
'file' => 'wysiwyg.admin.inc',
|
||||
'type' => MENU_VISIBLE_IN_BREADCRUMB,
|
||||
);
|
||||
// @see wysiwyg_dialog()
|
||||
$items['wysiwyg/%'] = array(
|
||||
'page callback' => 'wysiwyg_dialog',
|
||||
@@ -88,9 +112,52 @@ function wysiwyg_menu() {
|
||||
'type' => MENU_CALLBACK,
|
||||
'file' => 'wysiwyg.dialog.inc',
|
||||
);
|
||||
$items['wysiwyg_theme/%'] = array(
|
||||
'theme callback' => '_wysiwyg_theme_callback',
|
||||
'theme arguments' => array(1),
|
||||
'page callback' => '_wysiwyg_theme_check_active',
|
||||
'page arguments' => array(1),
|
||||
'delivery callback' => '_wysiwyg_delivery_dummy',
|
||||
'access arguments' => array('access content'),
|
||||
'type' => MENU_CALLBACK,
|
||||
);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an editor profile title.
|
||||
*
|
||||
* @param $profile
|
||||
* An editor profile object.
|
||||
*
|
||||
* @return
|
||||
* The unfiltered name of an editor profile.
|
||||
* Currently the same as the text format name.
|
||||
*/
|
||||
function wysiwyg_admin_profile_title($profile) {
|
||||
$format = filter_format_load($profile->format);
|
||||
return $format->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_admin_menu_map().
|
||||
*/
|
||||
function wysiwyg_admin_menu_map() {
|
||||
if (!user_access('administer filters')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$profiles = wysiwyg_profile_load_all();
|
||||
$map['admin/config/content/wysiwyg/profile/%wysiwyg_profile'] = array(
|
||||
'parent' => 'admin/config/content/wysiwyg',
|
||||
'hide' => 'admin/config/content/wysiwyg/list',
|
||||
'arguments' => array(
|
||||
array('%wysiwyg_profile' => array_keys($profiles)),
|
||||
),
|
||||
);
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_element_info().
|
||||
*/
|
||||
@@ -138,23 +205,18 @@ function wysiwyg_help($path, $arg) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_form_alter().
|
||||
*/
|
||||
function wysiwyg_form_alter(&$form, &$form_state) {
|
||||
// Teaser splitter is unconditionally removed and NOT supported.
|
||||
if (isset($form['body_field'])) {
|
||||
unset($form['body_field']['teaser_js']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_element_info_alter().
|
||||
*/
|
||||
function wysiwyg_element_info_alter(&$types) {
|
||||
$types['text_format']['#pre_render'][] = 'wysiwyg_pre_render_text_format';
|
||||
// For filtering stylesheets before Core aggregates them.
|
||||
array_unshift($types['styles']['#pre_render'], '_wysiwyg_filter_editor_styles');
|
||||
// For recording and caching the added stylesheets.
|
||||
$types['styles']['#pre_render'][] = '_wysiwyg_pre_render_styles';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Process a text format widget to load and attach editors.
|
||||
*
|
||||
@@ -164,7 +226,8 @@ function wysiwyg_pre_render_text_format($element) {
|
||||
// filter_process_format() copies properties to the expanded 'value' child
|
||||
// element. Skip this text format widget, if it contains no 'format' or when
|
||||
// the current user does not have access to edit the value.
|
||||
if (!isset($element['format']) || !empty($element['value']['#disabled'])) {
|
||||
// Simplify module creates an extra incomplete 'format' on the base field.
|
||||
if (!isset($element['format']['format']) || !empty($element['value']['#disabled'])) {
|
||||
return $element;
|
||||
}
|
||||
// Allow modules to programmatically enforce no client-side editor by setting
|
||||
@@ -179,36 +242,46 @@ function wysiwyg_pre_render_text_format($element) {
|
||||
'field' => $field['#id'],
|
||||
);
|
||||
|
||||
// If this textarea is #resizable and we will load at least one
|
||||
// editor, then only load the behavior and let the 'none' editor
|
||||
// attach/detach it to avoid hi-jacking the UI. Due to our CSS class
|
||||
// parsing, we can add arbitrary parameters for each input format.
|
||||
// The #resizable property will be removed below, if at least one
|
||||
// profile has been loaded.
|
||||
$resizable = 0;
|
||||
// If this textarea is #resizable the 'none' editor will attach/detach it to
|
||||
// avoid hi-jacking the UI.
|
||||
if (!empty($field['#resizable'])) {
|
||||
$resizable = 1;
|
||||
drupal_add_js('misc/textarea.js');
|
||||
$settings['resizable'] = 1;
|
||||
}
|
||||
if (isset($element['summary']) && $element['summary']['#type'] == 'textarea') {
|
||||
$settings['summary'] = $element['summary']['#id'];
|
||||
}
|
||||
|
||||
if (!$format_field['format']['#access'] || (isset($format_field['#access']) && !$format_field['#access'])) {
|
||||
// Directly specify which the single available format is.
|
||||
$available_formats = array($format_field['format']['#value'] => $format_field['format']['#options'][$format_field['format']['#value']]);
|
||||
$settings['activeFormat'] = $format_field['format']['#value'];
|
||||
}
|
||||
else {
|
||||
// Let the client check the selectbox for the active format.
|
||||
$available_formats = $format_field['format']['#options'];
|
||||
$settings['select'] = $format_field['format']['#id'];
|
||||
}
|
||||
// Determine the available text formats.
|
||||
foreach ($format_field['format']['#options'] as $format_id => $format_name) {
|
||||
foreach ($available_formats as $format_id => $format_name) {
|
||||
$format = 'format' . $format_id;
|
||||
// Initialize default settings, defaulting to 'none' editor.
|
||||
$settings[$format] = array(
|
||||
'editor' => 'none',
|
||||
'status' => 1,
|
||||
'toggle' => 1,
|
||||
'resizable' => $resizable,
|
||||
);
|
||||
|
||||
// Fetch the profile associated to this text format.
|
||||
$profile = wysiwyg_get_profile($format_id);
|
||||
if ($profile) {
|
||||
// Initialize default settings, defaulting to 'none' editor.
|
||||
$settings[$format] = array(
|
||||
'editor' => 'none',
|
||||
'status' => 1,
|
||||
'toggle' => 1,
|
||||
);
|
||||
$loaded = TRUE;
|
||||
if (isset($profile->settings['add_to_summaries']) && !$profile->settings['add_to_summaries']) {
|
||||
$settings[$format]['skip_summary'] = 1;
|
||||
}
|
||||
$settings[$format]['editor'] = $profile->editor;
|
||||
$settings[$format]['status'] = (int) wysiwyg_user_get_status($profile);
|
||||
if (isset($profile->settings['show_toggle'])) {
|
||||
$settings[$format]['toggle'] = (int) $profile->settings['show_toggle'];
|
||||
if (isset($profile->preferences['show_toggle'])) {
|
||||
$settings[$format]['toggle'] = (int) $profile->preferences['show_toggle'];
|
||||
}
|
||||
// Check editor theme (and reset it if not/no longer available).
|
||||
$theme = wysiwyg_get_editor_themes($profile, (isset($profile->settings['theme']) ? $profile->settings['theme'] : ''));
|
||||
@@ -219,49 +292,17 @@ function wysiwyg_pre_render_text_format($element) {
|
||||
wysiwyg_add_editor_settings($profile, $theme);
|
||||
}
|
||||
}
|
||||
// Use a hidden element for a single text format.
|
||||
if (!$format_field['format']['#access']) {
|
||||
$format_field['wysiwyg'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#name' => $format_field['format']['#name'],
|
||||
'#value' => $format_id,
|
||||
'#attributes' => array(
|
||||
'id' => $format_field['format']['#id'],
|
||||
'class' => array('wysiwyg'),
|
||||
),
|
||||
);
|
||||
$format_field['wysiwyg']['#attached']['js'][] = array(
|
||||
'data' => array(
|
||||
'wysiwyg' => array(
|
||||
'triggers' => array(
|
||||
$format_field['format']['#id'] => $settings,
|
||||
),
|
||||
$element['value']['#attributes']['class'][] = 'wysiwyg';
|
||||
$element['#attached']['js'][] = array(
|
||||
'data' => array(
|
||||
'wysiwyg' => array(
|
||||
'triggers' => array(
|
||||
$element['value']['#id'] => $settings,
|
||||
),
|
||||
),
|
||||
'type' => 'setting',
|
||||
);
|
||||
}
|
||||
// Otherwise, attach to text format selector.
|
||||
else {
|
||||
$format_field['format']['#attributes']['class'][] = 'wysiwyg';
|
||||
$format_field['format']['#attached']['js'][] = array(
|
||||
'data' => array(
|
||||
'wysiwyg' => array(
|
||||
'triggers' => array(
|
||||
$format_field['format']['#id'] => $settings,
|
||||
),
|
||||
),
|
||||
),
|
||||
'type' => 'setting',
|
||||
);
|
||||
}
|
||||
|
||||
// If we loaded at least one editor, then the 'none' editor will
|
||||
// handle resizable textareas instead of core.
|
||||
if (isset($loaded) && $resizable) {
|
||||
$field['#resizable'] = FALSE;
|
||||
}
|
||||
|
||||
),
|
||||
'type' => 'setting',
|
||||
);
|
||||
return $element;
|
||||
}
|
||||
|
||||
@@ -319,8 +360,8 @@ function wysiwyg_load_editor($profile) {
|
||||
);
|
||||
// Determine library files to load.
|
||||
// @todo Allow to configure the library/execMode to use.
|
||||
if (isset($profile->settings['library']) && isset($editor['libraries'][$profile->settings['library']])) {
|
||||
$library = $profile->settings['library'];
|
||||
if (isset($profile->preferences['library']) && isset($editor['libraries'][$profile->preferences['library']])) {
|
||||
$library = $profile->preferences['library'];
|
||||
$files = $editor['libraries'][$library]['files'];
|
||||
}
|
||||
else {
|
||||
@@ -348,7 +389,7 @@ function wysiwyg_load_editor($profile) {
|
||||
drupal_add_js($init, array('type' => 'inline') + $default_library_options);
|
||||
}
|
||||
else {
|
||||
drupal_add_js(file_create_url($uri), $default_library_options);
|
||||
drupal_add_js($uri, $default_library_options);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -390,6 +431,11 @@ function wysiwyg_load_editor($profile) {
|
||||
}
|
||||
}
|
||||
|
||||
// Check if settings were already added on the page that makes an AJAX call.
|
||||
if (isset($_POST['ajax_page_state']) && !empty($_POST['ajax_page_state']['js'][$path . '/wysiwyg.js'])) {
|
||||
$settings_added = TRUE;
|
||||
}
|
||||
|
||||
// Add basic Wysiwyg settings if any editor has been added.
|
||||
if (!isset($settings_added) && $loaded[$name]) {
|
||||
drupal_add_js(array('wysiwyg' => array(
|
||||
@@ -491,24 +537,32 @@ function wysiwyg_add_plugin_settings($profile) {
|
||||
$proxy = (isset($editor['proxy plugin']) ? key($editor['proxy plugin']) : '');
|
||||
|
||||
// Process native editor plugins.
|
||||
if (isset($editor['plugin settings callback'])) {
|
||||
// @todo Require PHP 5.1 in 3.x and use array_intersect_key().
|
||||
$profile_plugins_native = array();
|
||||
foreach ($plugins[$editor['name']] as $plugin => $meta) {
|
||||
// Skip Drupal plugins (handled below).
|
||||
if ($plugin === $proxy) {
|
||||
continue;
|
||||
}
|
||||
// Only keep native plugins that are enabled in this profile.
|
||||
if (isset($profile->settings['buttons'][$plugin])) {
|
||||
$profile_plugins_native[$plugin] = $meta;
|
||||
$profile_plugins_native = array();
|
||||
foreach ($plugins[$editor['name']] as $plugin => $meta) {
|
||||
// Skip Drupal plugins (handled below) and 'core' functionality.
|
||||
if ($plugin === $proxy || $plugin === 'default') {
|
||||
continue;
|
||||
}
|
||||
// Only keep native plugins that are enabled in this profile.
|
||||
if (isset($profile->settings['buttons'][$plugin])) {
|
||||
$profile_plugins_native[$plugin] = $meta;
|
||||
if (!isset($processed_plugins[$editor['name']][$plugin])) {
|
||||
if (isset($editor['plugin meta callback'])) {
|
||||
// Invoke the editor's plugin meta callback, so it can populate the
|
||||
// global metadata for native plugins with required values.
|
||||
$meta['name'] = $plugin;
|
||||
if (($native_meta = call_user_func($editor['plugin meta callback'], $editor, $meta))) {
|
||||
drupal_add_js(array('wysiwyg' => array('plugins' => array('native' => array($editor['name'] => array($plugin => $native_meta))))), 'setting');
|
||||
}
|
||||
}
|
||||
$processed_plugins[$editor['name']][$plugin] = $meta;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($profile_plugins_native) && isset($editor['plugin settings callback'])) {
|
||||
// Invoke the editor's plugin settings callback, so it can populate the
|
||||
// settings for native external plugins with required values.
|
||||
$settings_native = call_user_func($editor['plugin settings callback'], $editor, $profile, $profile_plugins_native);
|
||||
|
||||
if ($settings_native) {
|
||||
// format specific settings for native plugins with required values.
|
||||
if (($settings_native = call_user_func($editor['plugin settings callback'], $editor, $profile, $profile_plugins_native))) {
|
||||
drupal_add_js(array('wysiwyg' => array('plugins' => array('format' . $profile->format => array('native' => $settings_native)))), 'setting');
|
||||
}
|
||||
}
|
||||
@@ -526,9 +580,13 @@ function wysiwyg_add_plugin_settings($profile) {
|
||||
// Load the Drupal plugin's JavaScript.
|
||||
drupal_add_js($meta['js path'] . '/' . $meta['js file']);
|
||||
// Add plugin-specific settings.
|
||||
if (isset($meta['settings'])) {
|
||||
drupal_add_js(array('wysiwyg' => array('plugins' => array('drupal' => array($plugin => $meta['settings'])))), 'setting');
|
||||
$settings = (isset($meta['settings']) ? $meta['settings'] : array());
|
||||
$settings['title'] = $meta['title'];
|
||||
$settings['icon'] = base_path() . $meta['icon path'] . '/' . $meta['icon file'];
|
||||
if (!empty($meta['css path']) && !empty($meta['css file'])) {
|
||||
$settings['css'] = base_path() . $meta['css path'] . '/' . $meta['css file'];
|
||||
}
|
||||
drupal_add_js(array('wysiwyg' => array('plugins' => array('drupal' => array($plugin => $settings)))), 'setting');
|
||||
}
|
||||
else {
|
||||
$profile_plugins_drupal[$plugin] = $processed_plugins[$proxy][$plugin];
|
||||
@@ -622,8 +680,22 @@ function wysiwyg_get_plugins($editor_name) {
|
||||
function wysiwyg_get_editor_config($profile, $theme) {
|
||||
$editor = wysiwyg_get_editor($profile->editor);
|
||||
$settings = array();
|
||||
$installed_version = $editor['installed version'];
|
||||
$settings = $profile->settings;
|
||||
if (!empty($editor['settings callback']) && function_exists($editor['settings callback'])) {
|
||||
$settings = $editor['settings callback']($editor, $profile->settings, $theme);
|
||||
if (!empty($profile->preferences['version']) && !empty($installed_version)) {
|
||||
$profile_version = $profile->preferences['version'];
|
||||
$version_status = version_compare($profile_version, $installed_version);
|
||||
if ($version_status !== 0) {
|
||||
// Installed version is different from profile version. Silently migrate
|
||||
// the stored editor settings to the installed version if possible.
|
||||
$migrated = FALSE;
|
||||
if (!empty($editor['migrate settings callback']) && function_exists($editor['migrate settings callback'])) {
|
||||
$migrated = $editor['migrate settings callback']($settings, $editor, $profile_version, $installed_version);
|
||||
}
|
||||
}
|
||||
}
|
||||
$settings = $editor['settings callback']($editor, $settings, $theme);
|
||||
|
||||
// Allow other modules to alter the editor settings for this format.
|
||||
$context = array('editor' => $editor, 'profile' => $profile, 'theme' => $theme);
|
||||
@@ -638,32 +710,104 @@ function wysiwyg_get_editor_config($profile, $theme) {
|
||||
* This assumes that the content editing area only needs stylesheets defined
|
||||
* for the scope 'theme'.
|
||||
*
|
||||
* Performs a background request of a dummy page to cache as many of a theme's
|
||||
* stylesheets as possible before returning the cached list.
|
||||
*
|
||||
* Note: if set to explicitly use the current admin theme by name, no access
|
||||
* check on the 'view the administration theme' permission is performed.
|
||||
*
|
||||
* @param $theme
|
||||
* The id of a theme to get stylesheets for. Defaults to the current theme.
|
||||
*
|
||||
* @return
|
||||
* An array containing CSS files, including proper base path.
|
||||
*/
|
||||
function wysiwyg_get_css() {
|
||||
static $files;
|
||||
|
||||
if (isset($files)) {
|
||||
return $files;
|
||||
function wysiwyg_get_css($theme = NULL) {
|
||||
// Default to the node edit theme, if the user has access.
|
||||
if (empty($theme)) {
|
||||
$theme = variable_get('node_admin_theme') && user_access('view the administration theme') ? variable_get('admin_theme') : variable_get('theme_default', 'bartik');
|
||||
}
|
||||
// In node form previews, the theme has not been initialized yet.
|
||||
if (!empty($_POST)) {
|
||||
// If set to use the admin theme, ensure the user has access.
|
||||
elseif ($theme == 'wysiwyg_theme_admin' && user_access('view the administration theme') && $admin_theme = variable_get('admin_theme')) {
|
||||
$theme = $admin_theme;
|
||||
}
|
||||
// Make sure the theme system is initialized.
|
||||
$themes = list_themes();
|
||||
if (!isset($themes[$theme])) {
|
||||
drupal_theme_initialize();
|
||||
}
|
||||
|
||||
$files = array();
|
||||
foreach (drupal_add_css() as $filepath => $info) {
|
||||
if ($info['group'] >= CSS_THEME && $info['media'] != 'print') {
|
||||
if ($info['type'] == 'external') {
|
||||
$files[] = $filepath;
|
||||
}
|
||||
elseif (file_exists($filepath)) {
|
||||
$files[] = base_path() . $filepath;
|
||||
}
|
||||
// Ensure the selected theme is enabled (or is the admin theme).
|
||||
if (!drupal_theme_access($theme)) {
|
||||
$theme = variable_get('theme_default', 'bartik');
|
||||
}
|
||||
$cached = cache_get('wysiwyg_css');
|
||||
$css = array();
|
||||
// Trigger a cache update if:
|
||||
// this is NOT the wysiwyg_theme page (avoid loop),
|
||||
// the cache is empty or does not have the current theme,
|
||||
// the CSS/JS cache-busting query string has changed,
|
||||
// or the theme's aggregation state has changed.
|
||||
$update_cache = strpos(current_path(), 'wysiwyg_theme/') === FALSE && (
|
||||
!$cached || (
|
||||
empty($cached->data[$theme])
|
||||
|| $cached->data[$theme]['aggregated'] != variable_get('preprocess_css', FALSE))
|
||||
|| $cached->data['_css_js_query_string'] != variable_get('css_js_query_string'));
|
||||
if ($update_cache) {
|
||||
$url = url('wysiwyg_theme/' . $theme, array('absolute' => TRUE, 'max_redirects' => 0));
|
||||
$response = drupal_http_request($url);;
|
||||
$cached = cache_get('wysiwyg_css');
|
||||
if ($cached && !empty($cached->data[$theme])) {
|
||||
$css = $cached->data[$theme]['files'];
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
elseif (!empty($cached->data[$theme])) {
|
||||
$css = $cached->data[$theme]['files'];
|
||||
}
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_themes_enabled().
|
||||
*/
|
||||
function wysiwyg_themes_enabled($theme_list) {
|
||||
$cached = cache_get('wysiwyg_css');
|
||||
foreach ($theme_list as $theme) {
|
||||
if ($cached && !empty($cached->data)) {
|
||||
$css = $cached->data;
|
||||
unset($css[$theme]);
|
||||
}
|
||||
}
|
||||
cache_set('wysiwyg_css', $css);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_form_FORM_ID_alter().
|
||||
*
|
||||
* Alters the system's theme settings form to react when themes change.
|
||||
*/
|
||||
function wysiwyg_form_system_theme_settings_alter(&$form, &$form_state, $form_id) {
|
||||
$form['#submit'][] = '_wysiwyg_system_theme_settings_submit';
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit callback for the theme settings form.
|
||||
*
|
||||
* Removes the edited theme from the cache.
|
||||
*/
|
||||
function _wysiwyg_system_theme_settings_submit($form, &$form_state) {
|
||||
$theme = NULL;
|
||||
if ($form_state['build_info']['form_id'] == 'system_theme_settings' && !empty($form_state['build_info']['args'])) {
|
||||
$theme = $form_state['build_info']['args'][0];
|
||||
}
|
||||
if ($theme !== NULL) {
|
||||
$cached = cache_get('wysiwyg_css');
|
||||
if ($cached && !empty($cached->data)) {
|
||||
$css = $cached->data;
|
||||
unset($css[$theme]);
|
||||
cache_set('wysiwyg_css', $css);
|
||||
}
|
||||
}
|
||||
wysiwyg_get_css($theme);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -672,6 +816,11 @@ function wysiwyg_get_css() {
|
||||
* Since there are commonly not many text formats, and each text format-enabled
|
||||
* form element will possibly have to load every single profile, all existing
|
||||
* profiles are loaded and cached once to reduce the amount of database queries.
|
||||
*
|
||||
* @param $format
|
||||
* The machine-name of a text format.
|
||||
*
|
||||
* @return A profile if found, else FALSE.
|
||||
*/
|
||||
function wysiwyg_profile_load($format) {
|
||||
$profiles = wysiwyg_profile_load_all();
|
||||
@@ -680,6 +829,8 @@ function wysiwyg_profile_load($format) {
|
||||
|
||||
/**
|
||||
* Loads all profiles.
|
||||
*
|
||||
* @return An array of profiles keyed by format name.
|
||||
*/
|
||||
function wysiwyg_profile_load_all() {
|
||||
// entity_load(..., FALSE) does not re-use its own static cache upon
|
||||
@@ -694,20 +845,107 @@ function wysiwyg_profile_load_all() {
|
||||
}
|
||||
else {
|
||||
$profiles = entity_load('wysiwyg_profile', FALSE);
|
||||
$formats = filter_formats();
|
||||
foreach ($profiles as $key => $profile) {
|
||||
if (empty($profile->editor) || !isset($formats[$profile->format])) {
|
||||
unset($profiles[$key]);
|
||||
}
|
||||
}
|
||||
cache_set('wysiwyg_profiles', $profiles);
|
||||
}
|
||||
}
|
||||
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a profile from the database.
|
||||
*/
|
||||
function wysiwyg_profile_delete($format) {
|
||||
function wysiwyg_profile_delete($profile) {
|
||||
db_delete('wysiwyg')
|
||||
->condition('format', $format)
|
||||
->condition('format', $profile->format)
|
||||
->execute();
|
||||
// Clear the editing caches.
|
||||
if (module_exists('ctools')) {
|
||||
ctools_include('object-cache');
|
||||
ctools_object_cache_clear_all('wysiwyg_profile', $profile->name);
|
||||
}
|
||||
else {
|
||||
cache_clear_all('wysiwyg_profile:' . $profile->name, 'cache');
|
||||
}
|
||||
wysiwyg_profile_cache_clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized menu callback to load a profile and check its locked status.
|
||||
*
|
||||
* @param $name
|
||||
* The machine name of the profile.
|
||||
*
|
||||
* @return
|
||||
* The profile object, with a "locked" property indicating whether or not
|
||||
* someone else is already editing the profile.
|
||||
*/
|
||||
function wysiwyg_ui_profile_cache_load($format) {
|
||||
$original_profile = wysiwyg_profile_load($format);
|
||||
$profile = FALSE;
|
||||
$name = ($original_profile ? $original_profile->name : 'format' . $format);
|
||||
$profile = wysiwyg_ui_profile_cache_get($name);
|
||||
if (empty($profile)) {
|
||||
$profile = $original_profile;
|
||||
}
|
||||
if (!empty($profile)) {
|
||||
$profile->editing = TRUE;
|
||||
return $profile;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized cache function to load a profile from the editing cache.
|
||||
*
|
||||
* @param $name
|
||||
* The name of a profile to load. Currently the format name prefixed by
|
||||
* 'format'.
|
||||
* @return
|
||||
* The profile object, with a "locked" property indicating whether or not
|
||||
* someone else is already editing the profile, or FALSE if not cached.
|
||||
*/
|
||||
function wysiwyg_ui_profile_cache_get($name) {
|
||||
$profile = FALSE;
|
||||
if (module_exists('ctools')) {
|
||||
ctools_include('object-cache');
|
||||
$profile = ctools_object_cache_get('wysiwyg_profile', $name);
|
||||
if ($profile) {
|
||||
$profile->locked = ctools_object_cache_test('wysiwyg_profile', $name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Fall back on simple caching in its own bin without locking.
|
||||
$cached = cache_get('wysiwyg_profile:' . $name);
|
||||
if ($cached) {
|
||||
$profile = $cached->data;
|
||||
$profile->locked = FALSE;
|
||||
}
|
||||
}
|
||||
return $profile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized cache function to add a profile to the editing cache.
|
||||
*/
|
||||
function wysiwyg_ui_profile_cache_set(&$profile) {
|
||||
if (!empty($profile->locked)) {
|
||||
drupal_set_message(t('Changes can not be made to a locked profile.'), 'error');
|
||||
return;
|
||||
}
|
||||
$profile->changed = TRUE;
|
||||
if (module_exists('ctools')) {
|
||||
ctools_include('object-cache');
|
||||
ctools_object_cache_set('wysiwyg_profile', $profile->name, $profile);
|
||||
}
|
||||
else {
|
||||
cache_set('wysiwyg_profile:' . $profile->name, $profile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -723,13 +961,16 @@ function wysiwyg_profile_cache_clear() {
|
||||
* Implements hook_form_FORM_ID_alter().
|
||||
*/
|
||||
function wysiwyg_form_user_profile_form_alter(&$form, &$form_state, $form_id) {
|
||||
if ($form['#user_category'] != 'account') {
|
||||
return;
|
||||
}
|
||||
$account = $form['#user'];
|
||||
$user_formats = filter_formats($account);
|
||||
$options = array();
|
||||
$options_default = array();
|
||||
foreach (wysiwyg_profile_load_all() as $format => $profile) {
|
||||
// Only show profiles that have user_choose enabled.
|
||||
if (!empty($profile->settings['user_choose']) && isset($user_formats[$format])) {
|
||||
if (!empty($profile->preferences['user_choose']) && isset($user_formats[$format])) {
|
||||
$options[$format] = check_plain($user_formats[$format]->name);
|
||||
if (wysiwyg_user_get_status($profile, $account)) {
|
||||
$options_default[] = $format;
|
||||
@@ -793,11 +1034,11 @@ function wysiwyg_user_get_status($profile, $account = NULL) {
|
||||
))->fetchAllKeyed();
|
||||
}
|
||||
|
||||
if (!empty($profile->settings['user_choose']) && isset($account->wysiwyg_status[$profile->format])) {
|
||||
if (!empty($profile->preferences['user_choose']) && isset($account->wysiwyg_status[$profile->format])) {
|
||||
$status = $account->wysiwyg_status[$profile->format];
|
||||
}
|
||||
else {
|
||||
$status = isset($profile->settings['default']) ? $profile->settings['default'] : TRUE;
|
||||
$status = isset($profile->preferences['default']) ? $profile->preferences['default'] : TRUE;
|
||||
}
|
||||
|
||||
return (bool) $status;
|
||||
@@ -860,25 +1101,33 @@ function wysiwyg_get_all_editors() {
|
||||
if (!($editors[$editor]['installed'] = file_exists($editors[$editor]['library path']))) {
|
||||
continue;
|
||||
}
|
||||
$installed_version = NULL;
|
||||
// Detect library version.
|
||||
if (function_exists($editors[$editor]['version callback'])) {
|
||||
$editors[$editor]['installed version'] = $editors[$editor]['version callback']($editors[$editor]);
|
||||
$installed_version = $editors[$editor]['installed version'] = $editors[$editor]['version callback']($editors[$editor]);
|
||||
}
|
||||
if (empty($editors[$editor]['installed version'])) {
|
||||
if (empty($installed_version)) {
|
||||
$editors[$editor]['error'] = t('The version of %editor could not be detected.', array('%editor' => $properties['title']));
|
||||
$editors[$editor]['installed'] = FALSE;
|
||||
continue;
|
||||
}
|
||||
$editors[$editor]['installed version verified'] = TRUE;
|
||||
if (!empty($editors[$editor]['verified version range'])) {
|
||||
$version_range = $editors[$editor]['verified version range'];
|
||||
if (version_compare($installed_version, $version_range[0], '<') || version_compare($installed_version, $version_range[1], '>')) {
|
||||
$editors[$editor]['installed version verified'] = FALSE;
|
||||
}
|
||||
}
|
||||
// Determine to which supported version the installed version maps.
|
||||
ksort($editors[$editor]['versions']);
|
||||
$version = 0;
|
||||
foreach ($editors[$editor]['versions'] as $supported_version => $version_properties) {
|
||||
if (version_compare($editors[$editor]['installed version'], $supported_version, '>=')) {
|
||||
if (version_compare($installed_version, $supported_version, '>=')) {
|
||||
$version = $supported_version;
|
||||
}
|
||||
}
|
||||
if (!$version) {
|
||||
$editors[$editor]['error'] = t('The installed version %version of %editor is not supported.', array('%version' => $editors[$editor]['installed version'], '%editor' => $editors[$editor]['title']));
|
||||
$editors[$editor]['error'] = t('The installed version %version of %editor is not supported.', array('%version' => $installed_version, '%editor' => $editors[$editor]['title']));
|
||||
$editors[$editor]['installed'] = FALSE;
|
||||
continue;
|
||||
}
|
||||
@@ -886,6 +1135,9 @@ function wysiwyg_get_all_editors() {
|
||||
$editors[$editor] = array_merge($editors[$editor], $editors[$editor]['versions'][$version]);
|
||||
unset($editors[$editor]['versions']);
|
||||
}
|
||||
|
||||
drupal_alter('wysiwyg_editor', $editors);
|
||||
|
||||
return $editors;
|
||||
}
|
||||
|
||||
@@ -1011,51 +1263,56 @@ function wysiwyg_get_path($library, $base_path = FALSE) {
|
||||
* @ingroup libraries
|
||||
*/
|
||||
function wysiwyg_get_libraries() {
|
||||
global $profile;
|
||||
|
||||
// When this function is called during Drupal's initial installation process,
|
||||
// the name of the profile that is about to be installed is stored in the
|
||||
// global $profile variable. At all other times, the regular system variable
|
||||
// contains the name of the current profile, and we can call variable_get()
|
||||
// to determine the profile.
|
||||
if (!isset($profile)) {
|
||||
$profile = variable_get('install_profile', 'default');
|
||||
if (function_exists('libraries_get_libraries')) {
|
||||
$directories = libraries_get_libraries();
|
||||
}
|
||||
else {
|
||||
global $profile;
|
||||
|
||||
$directory = 'libraries';
|
||||
$searchdir = array();
|
||||
$config = conf_path();
|
||||
// When this function is called during Drupal's initial installation process,
|
||||
// the name of the profile that is about to be installed is stored in the
|
||||
// global $profile variable. At all other times, the regular system variable
|
||||
// contains the name of the current profile, and we can call variable_get()
|
||||
// to determine the profile.
|
||||
if (!isset($profile)) {
|
||||
$profile = variable_get('install_profile', 'default');
|
||||
}
|
||||
|
||||
// The 'profiles' directory contains pristine collections of modules and
|
||||
// themes as organized by a distribution. It is pristine in the same way
|
||||
// that /modules is pristine for core; users should avoid changing anything
|
||||
// there in favor of sites/all or sites/<domain> directories.
|
||||
if (file_exists("profiles/$profile/$directory")) {
|
||||
$searchdir[] = "profiles/$profile/$directory";
|
||||
}
|
||||
$directory = 'libraries';
|
||||
$searchdir = array();
|
||||
$config = conf_path();
|
||||
|
||||
// Always search sites/all/*.
|
||||
$searchdir[] = 'sites/all/' . $directory;
|
||||
// The 'profiles' directory contains pristine collections of modules and
|
||||
// themes as organized by a distribution. It is pristine in the same way
|
||||
// that /modules is pristine for core; users should avoid changing anything
|
||||
// there in favor of sites/all or sites/<domain> directories.
|
||||
if (file_exists("profiles/$profile/$directory")) {
|
||||
$searchdir[] = "profiles/$profile/$directory";
|
||||
}
|
||||
|
||||
// Also search sites/<domain>/*.
|
||||
if (file_exists("$config/$directory")) {
|
||||
$searchdir[] = "$config/$directory";
|
||||
}
|
||||
// Always search sites/all/*.
|
||||
$searchdir[] = 'sites/all/' . $directory;
|
||||
|
||||
// Retrieve list of directories.
|
||||
// @todo Core: Allow to scan for directories.
|
||||
$directories = array();
|
||||
$nomask = array('CVS');
|
||||
foreach ($searchdir as $dir) {
|
||||
if (is_dir($dir) && $handle = opendir($dir)) {
|
||||
while (FALSE !== ($file = readdir($handle))) {
|
||||
if (!in_array($file, $nomask) && $file[0] != '.') {
|
||||
if (is_dir("$dir/$file")) {
|
||||
$directories[$file] = "$dir/$file";
|
||||
// Also search sites/<domain>/*.
|
||||
if (file_exists("$config/$directory")) {
|
||||
$searchdir[] = "$config/$directory";
|
||||
}
|
||||
|
||||
// Retrieve list of directories.
|
||||
// @todo Core: Allow to scan for directories.
|
||||
$directories = array();
|
||||
$nomask = array('CVS');
|
||||
foreach ($searchdir as $dir) {
|
||||
if (is_dir($dir) && $handle = opendir($dir)) {
|
||||
while (FALSE !== ($file = readdir($handle))) {
|
||||
if (!in_array($file, $nomask) && $file[0] != '.') {
|
||||
if (is_dir("$dir/$file")) {
|
||||
$directories[$file] = "$dir/$file";
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
closedir($handle);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1085,6 +1342,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.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user