Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66ff837039 | ||
|
|
626ec7eabc | ||
|
|
691ecd7d61 | ||
|
|
930913e764 | ||
|
|
ad30a381f9 | ||
|
|
951be207ab | ||
|
|
8ec280d5fa |
-345
@@ -1,345 +0,0 @@
|
||||
|
||||
Wysiwyg 7.x-2.x, xxxx-xx-xx
|
||||
---------------------------
|
||||
#1388224 by ksenzee, sun, TwoD: Fixed editors detaching on form submissions.
|
||||
#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.
|
||||
#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.
|
||||
#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.
|
||||
#1125582 by TwoD: Fixed TinyMCE fullscreen plugin deletes content.
|
||||
#1078834 by sun: Fixed coding standards errors.
|
||||
#1173476 by jim0203, sun: Fixed installation instructions in README.txt.
|
||||
|
||||
|
||||
Wysiwyg 7.x-2.1, 2011-06-19
|
||||
---------------------------
|
||||
#679056 by TwoD: Fixed patch for pressing enter in autocomplete, new jQuery API.
|
||||
#524126 by sun: Re-added #wysiwyg property to enforce no editor via code.
|
||||
#1153458 by Deciphered: Fixed TinyMCE 'Verify HTML' setting being ignored.
|
||||
#1079694 by TwoD: Fixed Whizzywig not restoring textarea styles when detached.
|
||||
#1132142 by tacituseu, TwoD, sun: Fixed nicEdit not removing its submit handler.
|
||||
#1143104 by EugenMayer: Fixed CKEditor 3.5.4 version detection.
|
||||
#1009880 by AndyF: Fixed another CKEditor selection handling issue.
|
||||
#1048556 by cousin_itt, TwoD: Fixed TinyMCE insertdatetime plugin setting.
|
||||
#1036900 by mattyoung: Minor code clean-up in wysiwyg_tinymce_version().
|
||||
#1026088 by sun: Fixed installation instructions in README.txt.
|
||||
by sun: Merged in module baseline to facilitate testing.
|
||||
#1034476 by quartsize, sun: Changed Wysiwyg profiles into entities.
|
||||
|
||||
|
||||
Wysiwyg 7.x-2.0, 2010-01-06
|
||||
---------------------------
|
||||
#950216 by TwoD, sun: Fixed missing editor for a single text format.
|
||||
#1007630 by aspilicious: Removed files[] declarations from .info file.
|
||||
#612954 by sun: Reverted 'buttons' change in profile configuration form.
|
||||
#975546 by TwoD, sun: Fixed markItUp CSS loaded with wrong weight.
|
||||
#659428 by TwoD, sun: Fixed editor is attached to disabled text format widgets.
|
||||
#975490 by Gábor Hojtsy: Updated for 'group' API change in drupal_add_js().
|
||||
#974604 by CrookedNumber, Gábor Hojtsy: Fixed theme CSS not loaded in editors.
|
||||
#931374 by TwoD, ksenzee: Updated for text format schema change.
|
||||
#826914 by catch, sun: Added database cache for wysiwyg_profile_load().
|
||||
#941230 by sun: Fixed missing Configuration link on Modules page.
|
||||
#739558 by sun, TwoD: Updated for new #type text_format.
|
||||
#612954 by TwoD: Fixed broken editor settings.
|
||||
#585932 by sun: Ported to Drupal 7.
|
||||
|
||||
|
||||
Wysiwyg 6.x-2.3, 2011-01-30
|
||||
---------------------------
|
||||
#1025296 by TwoD: Updated CKEditor to support iFrame button.
|
||||
#737318 by TwoD: Fixed CKEditor default skin array not being reindexed.
|
||||
by sun: Fixed coding style in wysiwyg_schema().
|
||||
#964978 by sun, TwoD: Added hook_wysiwyg_editor_settings_alter() documentation.
|
||||
#775972 by TwoD, Agileware, sun: Fixed broken user default status preferences.
|
||||
#1007066 by TwoD, penguin25: Fixed CKEditor ignores resizable option.
|
||||
#613944 by TwoD, sun: Fixed data.node not always present in CKEditor.
|
||||
#1009880 by TwoD: Fixed selection handling broken in CKEditor.
|
||||
|
||||
|
||||
Wysiwyg 6.x-2.2, 2010-12-20
|
||||
---------------------------
|
||||
#613944 by TwoD, sun: Fixed data.node not available in CKEditor.
|
||||
#748888 by TwoD, sun: Fixed isNode() not called in CKEditor.
|
||||
#767550 by TwoD, sun, ungeek: Fixed invalid API docs and logic for
|
||||
$plugin['filename'].
|
||||
#988200 by sun: Changed static language list to ISO 639 defaults of Drupal core.
|
||||
#973808 by David_Rothstein: Fixed CKEditor incorrectly formatting the <br> tag.
|
||||
#773856 by Roi Danton: Added CSS path and file documentation.
|
||||
#735186 by TwoD, torbs: Fixed missing Norwegian language code.
|
||||
#678580 by TwoD, sun: Fixed Drupal.wysiwygAttachToggleLink breaks click events.
|
||||
#497654 by TwoD: Fixed Drupal plugins disabled in FCKeditor/WebKit browsers.
|
||||
#735624 by sun: Fixed enabling one button removes default editor toolbar.
|
||||
#755610 by sun, TwoD, BrightBold: Fixed white-space in block formats setting
|
||||
breaks editors.
|
||||
#713942 by TwoD, sun: Fixed jQuery closure breaks OpenWYSIWYG.
|
||||
#679056 by sun, TwoD: Fixed pressing enter in autocomplete detaches editors.
|
||||
#80170 by sun: Changed dialog/plugin API for Inline API compatibility.
|
||||
#803466 by hotspoons: Fixed TinyMCE image map support in advimage plugin.
|
||||
#922436 by TwoD: Fixed Whizzywig Uncaught TypeError in Chrome.
|
||||
#922520 by TwoD: Fixed Whizzywig is not detached properly.
|
||||
#907186 by TwoD: Fixed Whizzywig v60+ compatibility.
|
||||
#765292 by TwoD: Added TinyMCE WordCount plugin.
|
||||
#768726 by TwoD: Added TinyMCE AutoResize plugin.
|
||||
#781086 by TwoD: Fixed TinyMCE plugin options merged wrongly.
|
||||
#767628 by TwoD: Fixed 'The version of markItUp could not be detected' error.
|
||||
#651490 by TwoD: Fixed Whizzywig width.
|
||||
#715228 by TwoD: Fixed TinyMCE image popups not launching for existing images.
|
||||
#606952 by TwoD: Fixed inserting content in fullscreen TinyMCE.
|
||||
#593008 by TwoD: Fixed third-party scripts breaking Wysiwyg.
|
||||
#695398 by RichieB, Cl1mh4224rd, mcpuddin: Fixed TinyMCE 3.3.9.1 detection.
|
||||
#737318 by dboune: Fixed CKEditor default skin depends on filesystem order.
|
||||
#775608 by TwoD: Fixed FCKEditor crashes IE on save.
|
||||
#824710 by TwoD: CKEditor not disabled upon enabling.
|
||||
#752516 by nquocbao, sun: Fixed openwysiwyg version callback.
|
||||
#753536 by TwoD: Fixed version detection for Whizzywig.
|
||||
#752516 by nquocbao, sun: Fixed file stream warnings in version callbacks.
|
||||
|
||||
|
||||
Wysiwyg 6.x-2.1, 2010-03-08
|
||||
---------------------------
|
||||
#628110 by quicksketch, sun, markus_petrux: Added editor settings alter hook.
|
||||
#689218 by wwalc, TwoD, sun: Improved support for CKEditor.
|
||||
#695398 by TwoD: Updated support for TinyMCE 3.3.
|
||||
#613096 by Scott Reynolds: Fixed no editor appearing for user signature field.
|
||||
#696040 by Dave Reid: Fixed missing Cancel link on profile form.
|
||||
#594322 by TwoD: Added insert method for NicEdit.
|
||||
#659200 by TwoD: Fixed YUI Editor content lost in IE.
|
||||
#594928 by ericbellot, TwoD, sun: Fixed 'attribs' button missing in TinyMCE.
|
||||
#557090 by TwoD: Fixed Whizzywig 56 instance not removed on detach().
|
||||
#667848 by TwoD, kaakuu: Fixed FCKeditor is not properly detached in IE.
|
||||
#695768 by sun: Fixed #resizable removed when no editor profiles are loaded.
|
||||
#631494 by TwoD: Fixed multi-site libraries directory failure for WYMeditor.
|
||||
#660080 by TwoD: Fixed Notice: Undefined offset.
|
||||
#613922 by TwoD, sun: Fixed PHP warning when saving profiles.
|
||||
#582298 by dereine: Added auto-paste from Word detection for FCKeditor.
|
||||
#597852 by sun: Fixed missing Turkish in language list.
|
||||
#620176 by sun: Fixed missing Ukrainian in language list.
|
||||
#613480 by TwoD, Dave Reid: Fixed PHP 5.3 compatibility.
|
||||
#462146 by TwoD: Cleaned up CKEditor implementation.
|
||||
#380586 by SimonEast: Updated YUI editor: Version detection not working.
|
||||
#610132 by TwoD: Updated CKEditor 3.0.1, stylesheets and version check.
|
||||
#620858 by quicksketch: Fixed focus event not firing for CKeditor.
|
||||
#585932 by sun: Synced various clean-ups from 7.x.
|
||||
#489156 by sun: Removed orphan global 'showToggle' JS setting.
|
||||
#462146 by sun, Niels Hackius: Fixed version detection for CKeditor.
|
||||
#545210 by sun: Fixed default value for editor toggle link.
|
||||
#372826 by Roi Danton, sun: Added Wysiwyg API developer documentation.
|
||||
by sun: Fixed PHP notice.
|
||||
#514912 by Likeless, sun: Added plugin/button handling for WYMeditor.
|
||||
#538996 by darktygur: Fixed 404 errors for non-existing theme CSS files.
|
||||
#509570 by Rob Loach, sun: Added forced detaching of editor upon form submit.
|
||||
#526644 by Darren Oh: Fixed broken editor theme validation.
|
||||
#490914 by sun: Fixed JS/CSS not updated after update with caching enabled.
|
||||
#522440 by authentictech, sun: UX: Fixed user interface for Wysiwyg profiles.
|
||||
#507608 by jfh: Added WYMeditor instance API methods.
|
||||
by sun: Fixed form_build_id not removed from serialized profile settings.
|
||||
#496744 by TwoD: Fixed FCKeditor: "Apply source formatting" not working.
|
||||
#462146 by TwoD, et al: Added support for CKeditor.
|
||||
#490270 by sun: Fixed openWYSIWYG displays no buttons by default.
|
||||
#490266 by sun: Fixed JS error when wysiwyg profile contains no buttons.
|
||||
#400482 by sun: Fixed editor.instance.prepareContent() breaks editor's native
|
||||
markup handling. Drupal plugin authors should add the CSS class
|
||||
'drupal-content' to prevent the editor selection to activate internal editor
|
||||
buttons.
|
||||
#394068 by kswan: Fixed missing button icons in markItUp.
|
||||
|
||||
|
||||
Wysiwyg 6.x-2.0, 2009-06-10
|
||||
---------------------------
|
||||
#474908 by TwoD: Fixed Teaser break causing error in IE8.
|
||||
by sun: Major code clean-up.
|
||||
#331089 by wwalc: Fixed FCKeditor toolbar buttons do not wrap.
|
||||
#407014 by sun: Fixed/removed migration from other editor integration modules.
|
||||
#485264 by sun: Changed installation instructions to be more concise.
|
||||
#479514 by sun: Fixed native plugin loading for TinyMCE (follow-up).
|
||||
#434590 by sun: Fixed path admin/settings/wysiwyg not found.
|
||||
#479514 by TwoD, sun: Added native plugin support for FCKeditor.
|
||||
#341054 by sun: Fixed toggle link configuration setting not working.
|
||||
by sun: Fixed markItUp button icons are not displayed.
|
||||
by sun: Added openWYSIWYG editor support.
|
||||
#362137 by jfh, sun: Fixed WYMeditor broken when JS/CSS aggregation is enabled.
|
||||
#328252 by sun: Added TinyMCE plugin BBCode for 3.x.
|
||||
#429926 by TwoD, sun: Fixed TinyMCE broken due to renamed Flash/Media plugin.
|
||||
#342864 by davexoxide, sun: Added YUI editor support.
|
||||
#332139 by sun: Fixed editor must not be changed when profile is configured.
|
||||
#362137 by jfh: Added WYMeditor support.
|
||||
#470928 by jfh, sun: Fixed Drupal.wysiwyg.clone turns arrays into objects.
|
||||
#445826 by TwoD: Fixed FCKeditor: Drupal.wysiwyg.activeId not updated.
|
||||
#478324 by jeffschuler: Fixed typo in profile configuration form.
|
||||
#373542 by sun: Fixed encoding of HTML entities for certain languages.
|
||||
#320562 by sun: Changed location for external editor libraries.
|
||||
#449134 by sun: Fixed stylesheets of theme missing in node form previews.
|
||||
|
||||
|
||||
Wysiwyg 6.x-2.0-ALPHA1, 2009-05-17
|
||||
----------------------------------
|
||||
#403728 by jfduchesneau: Fixed none.js breaks if textarea.js is not loaded.
|
||||
#454992 by sun: Fixed drupal_get_js() query string 'q' breaks plugin loading.
|
||||
#419696 by sun: Fixed native plugins plugins are not loaded for all profiles.
|
||||
#414768 by sun: Fixed Wysiwyg API not working in Konqueror.
|
||||
#293803 by sun: Fixed "Show summary in full view" checkbox not displayed.
|
||||
#416742 by sun: Fixed type casting of $profile in profile configuration form.
|
||||
#404532 by TwoD: Fixed Teaser break comment stripped in IE.
|
||||
#380698 by TwoD: Added Drupal plugin support for FCKeditor.
|
||||
#380698 by TwoD, sun: Added Drupal plugin support for FCKeditor (part I).
|
||||
#398848 by sun: Added support for TinyMCE 3.1.
|
||||
#394068 by StephaneC: markItUp: Fixed icons not displayed due to #385736.
|
||||
#385974 by sun: Fixed form element description for CSS path (for Define CSS).
|
||||
#390460 by sun: Fixed broken plugin loading due to #359626.
|
||||
#385736 by sun: Fixed markItUp: Wrong editor library location.
|
||||
#308912 by sun: Fixed TinyMCE: Buttons do not wrap in IE/Chrome.
|
||||
#380586 by sun, hass: YUI editor: Fixed version detection.
|
||||
#390224 by hass: Fixed JS error YAHOO.widget.Editor is not a constructor.
|
||||
#359626 by sun: Fixed external/Drupal plugins are not loaded for all profiles.
|
||||
#369115 by sun: Fixed TinyMCE's URL conversion magic breaks some input filters.
|
||||
#376400 by TwoD: Fixed bad grammar in help text on profile overview page.
|
||||
#367632 by sun: Fixed $this and i JavaScript variables defined in global scope.
|
||||
#319363 by sun: Fixed missing spacer.gif for Teaser break plugin.
|
||||
#373672 by chawl: Added (native) xhtmlextras plugin for TinyMCE 3.
|
||||
#287025 by sun: Fixed native editor plugin options for TinyMCE and FCKeditor.
|
||||
#373542 by sun: Fixed TinyMCE: entity_encoding 'raw' removes HTML entities.
|
||||
#372806 by sun: Fixed block format configuration form element description.
|
||||
#370277 by sun: Fixed "Uncaught SyntaxError: Unexpected token" in IE/Chrome.
|
||||
#367632 by sun: Fixed "Unexpected identifier, string or number" error in IE.
|
||||
#367632 by sun: Fixed invalid JavaScript syntax.
|
||||
#319363 by sun: Follow-up: Synced 1.x with 2.x where possible.
|
||||
#319363 by sun, quicksketch: Rewrote editor plugin API. The new plugin API
|
||||
allows Drupal modules to expose editor plugins for ANY editor without
|
||||
implementing editor-specific code. Major milestone for better content-editing
|
||||
in Drupal.
|
||||
#364782 by sun: Fixed theme stylesheets not properly loaded.
|
||||
#352938 by sun: Fixed JS error (blank page) in IE when plugins are loaded.
|
||||
#331089 by wwalc, sun: Added custom toolbar configuration support for FCKeditor.
|
||||
#331089 by sun: Fixed PHP notice for 'user_choose'; FCKeditor clean-up.
|
||||
#344230 by wwalc: Fixed wrong editor base path setting for FCKeditor.
|
||||
#361289 by sun: Fixed CSS files do not need to use media 'screen'.
|
||||
#360696 by sun: Fixed IE does not trigger onChange event when selecting an input
|
||||
format.
|
||||
#342376 by sun: Extended API to allow "preprocess" JavaScript option for some
|
||||
editors.
|
||||
#352295 by sun: Added markItUp editor support.
|
||||
#352703 by sun: Fixed wrong default configuration options for TinyMCE 3.2.1+.
|
||||
#348317 by sun: Fixed TinyMCE's extended_valid_elements for advlink/advimage
|
||||
plugin.
|
||||
#348986 by sun: Added CSS class for toggle link container.
|
||||
#342864 by davexoxide, sun: Added YUI editor support.
|
||||
#343217 by sun: Fixed improperly capitalized library script name for nicEdit.
|
||||
#341267 by sun: Fixed improper test for internal editor plugins.
|
||||
#341996 by sun: Fixed editor cannot be re-enabled with one input format only.
|
||||
#341267 by sun: Added support for extensions that do not need to be loaded.
|
||||
|
||||
|
||||
Wysiwyg 6.x-0.5, 2008-12-01
|
||||
---------------------------
|
||||
#340758 by sun: Changed installation instructions to be displayed permanently.
|
||||
#322657 by sun: Fixed "Enabled by default" option does not work when disabled.
|
||||
#328052 by sun: Fixed switching input formats leads to wrong editor/state.
|
||||
#337569 by sun: Fixed different profiles for same editor are not respected.
|
||||
#340195 by sun: Fixed #after_build function not invoked on all forms.
|
||||
#333521 by sun: Fixed TinyMCE version detection to look at the actual script.
|
||||
#329657 by svendecabooter, sun: Added Whizzywig support.
|
||||
#333521 by sun: Fixed TinyMCE version detection docs.
|
||||
#327100 by sun: Changed access permission for settings page to 'administer
|
||||
filters' to prevent incomplete updates.
|
||||
#322731 by sun: Fixed improper use of t() in module install file.
|
||||
#329410 by sun: Fixed editor not loaded if there is only one input format.
|
||||
#324366 by sun: Fixed "Illegal offset type" error on custom content-types.
|
||||
#328948 by sun: Fixed PHP notices when editors are assigned, but not configured.
|
||||
#327710 by sun: Fixed nicEdit version could not be detected.
|
||||
#328116 by sun: Added Safari plugin for TinyMCE 3.
|
||||
#327710 by sun: Added nicEdit support.
|
||||
#323855 by sun: Increased supported version of jWYSIWYG to 0.5.
|
||||
#323671 by sun: Fixed TinyMCE editor not resized when browser is resized.
|
||||
#327152 by sun: Fixed breadcrumbs for profile configuration pages.
|
||||
#323855 by Rob Loach, sun: Added jWYSIWYG support.
|
||||
#327100 by sun: Associate editors/profiles with input formats. Major milestone.
|
||||
#325980 by markus_petrux: Added Spanish/Catalan translation for Break plugin.
|
||||
#323795 by sun: Removed obsolete Wysiwyg Editor module files.
|
||||
#308912 by sun: Fixed alignment of editor buttons in TinyMCE 3.
|
||||
#316507 by sun: Fixed TinyMCE 3 not detached properly from AJAX contents.
|
||||
#320559 by markus_petrux, sun: Added confirmation form to delete profiles.
|
||||
|
||||
|
||||
Wysiwyg 6.x-0.4, 2008-10-14
|
||||
---------------------------
|
||||
#321216 by sun: Replaced Wysiwyg Editor module with Wysiwyg module.
|
||||
#321086 by sun: Fixed (old-style) Teaser break plugin breaks TinyMCE 3.
|
||||
#316507 by sun: Code clean-up; editor settings should be cloned for init, too.
|
||||
#282717 by sun: Fixed FCKeditor default settings while FCKeditor maintainers get
|
||||
up and running.
|
||||
#319363 by sun: Changed JS settings namespace 'wysiwygEditor' to 'wysiwyg'.
|
||||
#319363 by sun: Code clean-up; fixed missing namespace change in tinymce-3.js.
|
||||
#273408 by quicksketch: Added blockquote button for TinyMCE 3.
|
||||
#319363 by sun: Changed JavaScript namespaces and centralized namespace
|
||||
initialization.
|
||||
#270780 by sun: Fixed TinyMCE 3 support for external plugins.
|
||||
#309832 by sun: Fixed README.txt.
|
||||
#253600 by sun: Changed editor integration so that client-side editors attach to
|
||||
input formats instead of textareas and are invoked for input format enabled
|
||||
textareas only.
|
||||
#282717 by sun: Added (basic) FCKeditor support.
|
||||
#316507 by sun: Added Drupal.wysiwyg function stacks to execute editor library
|
||||
specific actions upon initializing, attaching, detaching, and toggling an
|
||||
editor. Editor specific JavaScript resides in separate files now, as specified
|
||||
and returned by implementations of hook_editor().
|
||||
Wysiwyg is a real API finally, supporting multiple editors and editor versions.
|
||||
#316507 by sun: Rewrote Wysiwyg API's internal architecture to support multiple
|
||||
editors.
|
||||
|
||||
|
||||
Wysiwyg 6.x-0.3, 2008-09-12
|
||||
---------------------------
|
||||
#125267 by sun: Removed Safari browser warning configuration option.
|
||||
#304243 by sun: Fixed profile configuration improperly passed to JavaScript.
|
||||
#304243 by sun: Code clean-up for wysiwyg_editor_profile_overview().
|
||||
#289218 by gustav: Fixed E^ALL notice if node has no body field.
|
||||
#304243 by sun: Code clean-up for wysiwyg_editor_user_status().
|
||||
#299108 by toniw: Added setting for TinyMCE's auto-cleanup paste feature.
|
||||
#293916 by sun: Clarified TinyMCE compatibility in README.txt.
|
||||
#293425 by sun: Fixed foreach warning during upgrade from TinyMCE module.
|
||||
#292517 by sun: Fixed SQL error during upgrade from TinyMCE module.
|
||||
#286470 by chayner, sun: Fixed wrong editorBasePath in editor configuration.
|
||||
#227687 by sun: Fixed improperly capitalized package name.
|
||||
#288028 by Matthew Davidson: Fixed outdated check for PHP input filter.
|
||||
#280727 by sun: Removed gzip compressor from installation instructions.
|
||||
|
||||
|
||||
Wysiwyg 5.x-0.2, 2008-07-16
|
||||
---------------------------
|
||||
by sun: Fixed JavaScript errors when JS aggregation/compression is enabled.
|
||||
#268562 by sun: Code clean-up; changed format for custom defined CSS classes
|
||||
and removed error-prone auto-layout of buttons in favor of aligning them in
|
||||
one row with a stylesheet; may break existing profiles.
|
||||
#270730 by hass, sun: Added German translation for Teaser break plugin.
|
||||
#268838 by sun: Fixed PHP warning if no buttons are enabled for a profile.
|
||||
#268838 by sun: Ported to Drupal 6.x.
|
||||
#152046 by sun: Added hook_wysiwyg_plugin().
|
||||
#268562 by sun: Code clean-up.
|
||||
#60667 by sun: Fixed wrong editor profile is loaded when user is granted access
|
||||
to more than one profile.
|
||||
#264739 by sun: Fixed missing t() around some profile settings options.
|
||||
|
||||
|
||||
Wysiwyg 5.x-0.1, 2008-06-07
|
||||
---------------------------
|
||||
#264739 by sun: Improved output strings.
|
||||
#264739 by hass, sun: Fixed potx error due to wrong t() string.
|
||||
#264411 by sun: Cleaned coding-style using coder_format script.
|
||||
#264411 by sun: Moved admin functions into separate include file.
|
||||
#264411 by sun: Added TinyMCE data import upon installation.
|
||||
#264411 by sun: Renamed module to Wysiwyg Editor.
|
||||
#118747 by nedjo, sun: Upgraded code for jQuery.
|
||||
Initial fork of TinyMCE module (2008-05-30).
|
||||
|
||||
|
||||
+228
-293
@@ -1,339 +1,274 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
Version 2, June 1991
|
||||
|
||||
Preamble
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave,
|
||||
Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute
|
||||
verbatim copies of this license document, but changing it is not allowed.
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
Preamble
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
The licenses for most software are designed to take away your freedom to
|
||||
share and change it. By contrast, the GNU General Public License is
|
||||
intended to guarantee your freedom to share and change free software--to
|
||||
make sure the software is free for all its users. This General Public License
|
||||
applies to most of the Free Software Foundation's software and to any other
|
||||
program whose authors commit to using it. (Some other Free Software
|
||||
Foundation software is covered by the GNU Library General Public License
|
||||
instead.) You can apply it to your programs, too.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
When we speak of free software, we are referring to freedom, not price. Our
|
||||
General Public Licenses are designed to make sure that you have the
|
||||
freedom to distribute copies of free software (and charge for this service if
|
||||
you wish), that you receive source code or can get it if you want it, that you
|
||||
can change the software or use pieces of it in new free programs; and that
|
||||
you know you can do these things.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
To protect your rights, we need to make restrictions that forbid anyone to
|
||||
deny you these rights or to ask you to surrender the rights. These restrictions
|
||||
translate to certain responsibilities for you if you distribute copies of the
|
||||
software, or if you modify it.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
For example, if you distribute copies of such a program, whether gratis or for
|
||||
a fee, you must give the recipients all the rights that you have. You must make
|
||||
sure that they, too, receive or can get the source code. And you must show
|
||||
them these terms so they know their rights.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
We protect your rights with two steps: (1) copyright the software, and (2)
|
||||
offer you this license which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
Also, for each author's protection and ours, we want to make certain that
|
||||
everyone understands that there is no warranty for this free software. If the
|
||||
software is modified by someone else and passed on, we want its recipients
|
||||
to know that what they have is not the original, so that any problems
|
||||
introduced by others will not reflect on the original authors' reputations.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
Finally, any free program is threatened constantly by software patents. We
|
||||
wish to avoid the danger that redistributors of a free program will individually
|
||||
obtain patent licenses, in effect making the program proprietary. To prevent
|
||||
this, we have made it clear that any patent must be licensed for everyone's
|
||||
free use or not licensed at all.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow.
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
|
||||
MODIFICATION
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
0. This License applies to any program or other work which contains a notice
|
||||
placed by the copyright holder saying it may be distributed under the terms
|
||||
of this General Public License. The "Program", below, refers to any such
|
||||
program or work, and a "work based on the Program" means either the
|
||||
Program or any derivative work under copyright law: that is to say, a work
|
||||
containing the Program or a portion of it, either verbatim or with
|
||||
modifications and/or translated into another language. (Hereinafter, translation
|
||||
is included without limitation in the term "modification".) Each licensee is
|
||||
addressed as "you".
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
Activities other than copying, distribution and modification are not covered
|
||||
by this License; they are outside its scope. The act of running the Program is
|
||||
not restricted, and the output from the Program is covered only if its contents
|
||||
constitute a work based on the Program (independent of having been made
|
||||
by running the Program). Whether that is true depends on what the Program
|
||||
does.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
1. You may copy and distribute verbatim copies of the Program's source
|
||||
code as you receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice and
|
||||
disclaimer of warranty; keep intact all the notices that refer to this License
|
||||
and to the absence of any warranty; and give any other recipients of the
|
||||
Program a copy of this License along with the Program.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
You may charge a fee for the physical act of transferring a copy, and you
|
||||
may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
2. You may modify your copy or copies of the Program or any portion of it,
|
||||
thus forming a work based on the Program, and copy and distribute such
|
||||
modifications or work under the terms of Section 1 above, provided that you
|
||||
also meet all of these conditions:
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
a) You must cause the modified files to carry prominent notices stating that
|
||||
you changed the files and the date of any change.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
b) You must cause any work that you distribute or publish, that in whole or in
|
||||
part contains or is derived from the Program or any part thereof, to be
|
||||
licensed as a whole at no charge to all third parties under the terms of this
|
||||
License.
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
c) If the modified program normally reads commands interactively when run,
|
||||
you must cause it, when started running for such interactive use in the most
|
||||
ordinary way, to print or display an announcement including an appropriate
|
||||
copyright notice and a notice that there is no warranty (or else, saying that
|
||||
you provide a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this License.
|
||||
(Exception: if the Program itself is interactive but does not normally print such
|
||||
an announcement, your work based on the Program is not required to print
|
||||
an announcement.)
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
These requirements apply to the modified work as a whole. If identifiable
|
||||
sections of that work are not derived from the Program, and can be
|
||||
reasonably considered independent and separate works in themselves, then
|
||||
this License, and its terms, do not apply to those sections when you distribute
|
||||
them as separate works. But when you distribute the same sections as part
|
||||
of a whole which is a work based on the Program, the distribution of the
|
||||
whole must be on the terms of this License, whose permissions for other
|
||||
licensees extend to the entire whole, and thus to each and every part
|
||||
regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest your rights to
|
||||
work written entirely by you; rather, the intent is to exercise the right to
|
||||
control the distribution of derivative or collective works based on the
|
||||
Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
with the Program (or with a work based on the Program) on a volume of a
|
||||
storage or distribution medium does not bring the other work under the scope
|
||||
of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
3. You may copy and distribute the Program (or a work based on it, under
|
||||
Section 2) in object code or executable form under the terms of Sections 1
|
||||
and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
a) Accompany it with the complete corresponding machine-readable source
|
||||
code, which must be distributed under the terms of Sections 1 and 2 above
|
||||
on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
b) Accompany it with a written offer, valid for at least three years, to give
|
||||
any third party, for a charge no more than your cost of physically performing
|
||||
source distribution, a complete machine-readable copy of the corresponding
|
||||
source code, to be distributed under the terms of Sections 1 and 2 above on
|
||||
a medium customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
c) Accompany it with the information you received as to the offer to distribute
|
||||
corresponding source code. (This alternative is allowed only for
|
||||
noncommercial distribution and only if you received the program in object
|
||||
code or executable form with such an offer, in accord with Subsection b
|
||||
above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
making modifications to it. For an executable work, complete source code
|
||||
means all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation and
|
||||
installation of the executable. However, as a special exception, the source
|
||||
code distributed need not include anything that is normally distributed (in
|
||||
either source or binary form) with the major components (compiler, kernel,
|
||||
and so on) of the operating system on which the executable runs, unless that
|
||||
component itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
If distribution of executable or object code is made by offering access to
|
||||
copy from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place counts as distribution of the source code,
|
||||
even though third parties are not compelled to copy the source along with the
|
||||
object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
4. You may not copy, modify, sublicense, or distribute the Program except as
|
||||
expressly provided under this License. Any attempt otherwise to copy,
|
||||
modify, sublicense or distribute the Program is void, and will automatically
|
||||
terminate your rights under this License. However, parties who have received
|
||||
copies, or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
5. You are not required to accept this License, since you have not signed it.
|
||||
However, nothing else grants you permission to modify or distribute the
|
||||
Program or its derivative works. These actions are prohibited by law if you
|
||||
do not accept this License. Therefore, by modifying or distributing the
|
||||
Program (or any work based on the Program), you indicate your acceptance
|
||||
of this License to do so, and all its terms and conditions for copying,
|
||||
distributing or modifying the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the original
|
||||
licensor to copy, distribute or modify the Program subject to these terms and
|
||||
conditions. You may not impose any further restrictions on the recipients'
|
||||
exercise of the rights granted herein. You are not responsible for enforcing
|
||||
compliance by third parties to this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues), conditions
|
||||
are imposed on you (whether by court order, agreement or otherwise) that
|
||||
contradict the conditions of this License, they do not excuse you from the
|
||||
conditions of this License. If you cannot distribute so as to satisfy
|
||||
simultaneously your obligations under this License and any other pertinent
|
||||
obligations, then as a consequence you may not distribute the Program at all.
|
||||
For example, if a patent license would not permit royalty-free redistribution
|
||||
of the Program by all those who receive copies directly or indirectly through
|
||||
you, then the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply and
|
||||
the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
It is not the purpose of this section to induce you to infringe any patents or
|
||||
other property right claims or to contest validity of any such claims; this
|
||||
section has the sole purpose of protecting the integrity of the free software
|
||||
distribution system, which is implemented by public license practices. Many
|
||||
people have made generous contributions to the wide range of software
|
||||
distributed through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing to
|
||||
distribute software through any other system and a licensee cannot impose
|
||||
that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
This section is intended to make thoroughly clear what is believed to be a
|
||||
consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
8. If the distribution and/or use of the Program is restricted in certain
|
||||
countries either by patents or by copyrighted interfaces, the original copyright
|
||||
holder who places the Program under this License may add an explicit
|
||||
geographical distribution limitation excluding those countries, so that
|
||||
distribution is permitted only in or among countries not thus excluded. In such
|
||||
case, this License incorporates the limitation as if written in the body of this
|
||||
License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will be
|
||||
similar in spirit to the present version, but may differ in detail to address new
|
||||
problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
Each version is given a distinguishing version number. If the Program specifies
|
||||
a version number of this License which applies to it and "any later version",
|
||||
you have the option of following the terms and conditions either of that
|
||||
version or of any later version published by the Free Software Foundation. If
|
||||
the Program does not specify a version number of this License, you may
|
||||
choose any version ever published by the Free Software Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
10. If you wish to incorporate parts of the Program into other free programs
|
||||
whose distribution conditions are different, write to the author to ask for
|
||||
permission. For software which is copyrighted by the Free Software
|
||||
Foundation, write to the Free Software Foundation; we sometimes make
|
||||
exceptions for this. Our decision will be guided by the two goals of
|
||||
preserving the free status of all derivatives of our free software and of
|
||||
promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE,
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT
|
||||
PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
|
||||
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
|
||||
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
|
||||
PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||||
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR
|
||||
AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR
|
||||
ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
|
||||
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL,
|
||||
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES
|
||||
ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
|
||||
OR DATA BEING RENDERED INACCURATE OR LOSSES
|
||||
SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
|
||||
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN
|
||||
IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
|
||||
THE POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
+1
-54
@@ -1,54 +1 @@
|
||||
|
||||
-- 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
|
||||
editor libraries, most often based on JavaScript.
|
||||
|
||||
For a full description of the module, visit the project page:
|
||||
http://drupal.org/project/wysiwyg
|
||||
To submit bug reports and feature suggestions, or to track changes:
|
||||
http://drupal.org/project/issues/wysiwyg
|
||||
|
||||
|
||||
-- REQUIREMENTS --
|
||||
|
||||
* None.
|
||||
|
||||
|
||||
-- INSTALLATION --
|
||||
|
||||
* Install as usual, see
|
||||
http://drupal.org/documentation/install/modules-themes/modules-7
|
||||
|
||||
* Go to Administration » Configuration » Content authoring » Wysiwyg,
|
||||
and follow the displayed installation instructions to download and install one
|
||||
of the supported editors.
|
||||
|
||||
|
||||
-- CONFIGURATION --
|
||||
|
||||
* 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".
|
||||
|
||||
- or add a new text format, assign it to trusted roles, and ensure that above
|
||||
mentioned input filters are disabled.
|
||||
|
||||
* Setup editor profiles in Administration » Configuration » Content authoring
|
||||
» Wysiwyg.
|
||||
|
||||
|
||||
-- CONTACT --
|
||||
|
||||
Current maintainers:
|
||||
* Daniel F. Kudwien (sun) - http://drupal.org/user/54136
|
||||
* Henrik Danielsson (TwoD) - http://drupal.org/user/244227
|
||||
|
||||
This project has been sponsored by:
|
||||
* UNLEASHED MIND
|
||||
Specialized in consulting and planning of Drupal powered sites, UNLEASHED
|
||||
MIND offers installation, development, theming, customization, and hosting
|
||||
to get you started. Visit http://www.unleashedmind.com for more information.
|
||||
|
||||
!!! this module is not ready tu use !!!
|
||||
@@ -1,464 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Editor integration functions for CKEditor.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*/
|
||||
function wysiwyg_ckeditor_editor() {
|
||||
$editor['ckeditor'] = array(
|
||||
'title' => 'CKEditor',
|
||||
'vendor url' => 'http://ckeditor.com',
|
||||
'download url' => 'http://ckeditor.com/download',
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Default',
|
||||
'files' => array(
|
||||
'ckeditor.js' => array('preprocess' => FALSE),
|
||||
),
|
||||
),
|
||||
'src' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array(
|
||||
'ckeditor_source.js' => array('preprocess' => FALSE),
|
||||
),
|
||||
),
|
||||
),
|
||||
'install note callback' => 'wysiwyg_ckeditor_install_note',
|
||||
'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',
|
||||
'proxy plugin' => array(
|
||||
'drupal' => array(
|
||||
'load' => TRUE,
|
||||
'proxy' => TRUE,
|
||||
),
|
||||
),
|
||||
'proxy plugin settings callback' => 'wysiwyg_ckeditor_proxy_plugin_settings',
|
||||
'versions' => array(
|
||||
'3.0.0.3665' => array(
|
||||
'js files' => array('ckeditor-3.0.js'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an install note.
|
||||
*/
|
||||
function wysiwyg_ckeditor_install_note() {
|
||||
return '<p class="warning">' . t('Do NOT download the "CKEditor for Drupal" edition.') . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
* @param $editor
|
||||
* An array containing editor properties as returned from hook_editor().
|
||||
*
|
||||
* @return
|
||||
* The installed editor version.
|
||||
*/
|
||||
function wysiwyg_ckeditor_version($editor) {
|
||||
$library = $editor['library path'] . '/ckeditor.js';
|
||||
if (!file_exists($library)) {
|
||||
return;
|
||||
}
|
||||
$library = fopen($library, 'r');
|
||||
$max_lines = 8;
|
||||
while ($max_lines && $line = fgets($library, 500)) {
|
||||
// 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)) {
|
||||
fclose($library);
|
||||
// Version numbers need to have three parts since 3.0.1.
|
||||
$version[1] = preg_replace('/^(\d+)\.(\d+)$/', '${1}.${2}.0', $version[1]);
|
||||
return $version[1] . '.' . $version[2];
|
||||
}
|
||||
$max_lines--;
|
||||
}
|
||||
fclose($library);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_ckeditor_themes($editor, $profile) {
|
||||
// @todo Skins are not themes but this will do for now.
|
||||
$path = $editor['library path'] . '/skins/';
|
||||
if (file_exists($path) && ($dir_handle = opendir($path))) {
|
||||
$themes = array();
|
||||
while ($file = readdir($dir_handle)) {
|
||||
if (is_dir($path . $file) && substr($file, 0, 1) != '.' && $file != 'CVS') {
|
||||
$themes[] = $file;
|
||||
}
|
||||
}
|
||||
closedir($dir_handle);
|
||||
natcasesort($themes);
|
||||
$themes = array_values($themes);
|
||||
return !empty($themes) ? $themes : array('default');
|
||||
}
|
||||
else {
|
||||
return array('default');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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';
|
||||
}
|
||||
else {
|
||||
// Versions below 3.2.1 do not support Font styles at all.
|
||||
$form['css']['css_classes']['#access'] = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* #element_validate handler for CSS classes element altered by wysiwyg_ckeditor_settings_form().
|
||||
*/
|
||||
function wysiwyg_ckeditor_settings_form_validate_css_classes($element, &$form_state) {
|
||||
if (wysiwyg_ckeditor_settings_parse_styles($element['#value']) === FALSE) {
|
||||
form_error($element, t('The specified CSS classes are syntactically incorrect.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an initialization JavaScript for this editor library.
|
||||
*
|
||||
* @param array $editor
|
||||
* The editor library definition.
|
||||
* @param string $library
|
||||
* The library variant key from $editor['libraries'].
|
||||
* @param object $profile
|
||||
* The (first) wysiwyg editor profile.
|
||||
*
|
||||
* @return string
|
||||
* A string containing inline JavaScript to execute before the editor library
|
||||
* script is loaded.
|
||||
*/
|
||||
function wysiwyg_ckeditor_init($editor) {
|
||||
// CKEditor unconditionally searches for its library filename in SCRIPT tags
|
||||
// on the page upon loading the library in order to determine the base path to
|
||||
// itself. When JavaScript aggregation is enabled, this search fails and all
|
||||
// relative constructed paths within CKEditor are broken. The library has a
|
||||
// CKEditor.basePath property, but it is not publicly documented and thus not
|
||||
// reliable. The official documentation suggests to solve the issue through
|
||||
// the global window variable.
|
||||
// @see http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Specifying_the_Editor_Path
|
||||
$library_path = base_path() . $editor['library path'] . '/';
|
||||
return <<<EOL
|
||||
window.CKEDITOR_BASEPATH = '$library_path';
|
||||
EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_ckeditor_settings($editor, $config, $theme) {
|
||||
$settings = array(
|
||||
'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',
|
||||
// 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
|
||||
// XML default characters '&', '<', '>'.
|
||||
// @todo Check whether completely disabling ProcessHTMLEntities is an option.
|
||||
'entities_latin' => FALSE,
|
||||
'entities_greek' => FALSE,
|
||||
);
|
||||
|
||||
// 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']));
|
||||
$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_tags'] = implode(';', $block_formats);
|
||||
}
|
||||
|
||||
if (isset($config['apply_source_formatting'])) {
|
||||
$settings['apply_source_formatting'] = $config['apply_source_formatting'];
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
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))));
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['contentsCss'] = wysiwyg_get_css();
|
||||
}
|
||||
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)))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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'])) {
|
||||
$settings['stylesSet'] = $styles;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($config['language'])) {
|
||||
$settings['language'] = $config['language'];
|
||||
}
|
||||
if (isset($config['resizing'])) {
|
||||
// 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['toolbar'] = array();
|
||||
if (!empty($config['buttons'])) {
|
||||
$extra_plugins = array();
|
||||
$plugins = wysiwyg_get_plugins($editor['name']);
|
||||
foreach ($config['buttons'] as $plugin => $buttons) {
|
||||
foreach ($buttons as $button => $enabled) {
|
||||
// Iterate separately over buttons and extensions properties.
|
||||
foreach (array('buttons', 'extensions') as $type) {
|
||||
// Skip unavailable plugins.
|
||||
if (!isset($plugins[$plugin][$type][$button])) {
|
||||
continue;
|
||||
}
|
||||
// Add buttons.
|
||||
if ($type == 'buttons') {
|
||||
$settings['toolbar'][] = $button;
|
||||
}
|
||||
// Add external Drupal plugins to the list of extensions.
|
||||
if ($type == 'buttons' && !empty($plugins[$plugin]['proxy'])) {
|
||||
$extra_plugins[] = $button;
|
||||
}
|
||||
// Add external plugins to the list of extensions.
|
||||
elseif ($type == 'buttons' && empty($plugins[$plugin]['internal'])) {
|
||||
$extra_plugins[] = $plugin;
|
||||
}
|
||||
// Add internal buttons that also need to be loaded as extension.
|
||||
elseif ($type == 'buttons' && !empty($plugins[$plugin]['load'])) {
|
||||
$extra_plugins[] = $plugin;
|
||||
}
|
||||
// Add plain extensions.
|
||||
elseif ($type == 'extensions' && !empty($plugins[$plugin]['load'])) {
|
||||
$extra_plugins[] = $plugin;
|
||||
}
|
||||
// Allow plugins to add or override global configuration settings.
|
||||
if (!empty($plugins[$plugin]['options'])) {
|
||||
$settings = array_merge($settings, $plugins[$plugin]['options']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($extra_plugins)) {
|
||||
$settings['extraPlugins'] = implode(',', $extra_plugins);
|
||||
}
|
||||
}
|
||||
// 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.
|
||||
*
|
||||
* @param string $css_classes
|
||||
* A string containing CSS class definitions to add to the Style dropdown
|
||||
* list, separated by newlines.
|
||||
*
|
||||
* @return array|false
|
||||
* An array containing the parsed stylesSet definition, or FALSE on parse
|
||||
* error.
|
||||
*
|
||||
* @see wysiwyg_ckeditor_settings_form()
|
||||
* @see wysiwyg_ckeditor_settings_form_validate_css_classes()
|
||||
*
|
||||
* @todo This should be a plugin setting, but Wysiwyg does not support
|
||||
* plugin-specific settings yet.
|
||||
*/
|
||||
function wysiwyg_ckeditor_settings_parse_styles($css_classes) {
|
||||
$set = array();
|
||||
$input = trim($css_classes);
|
||||
if (empty($input)) {
|
||||
return $set;
|
||||
}
|
||||
// Handle both Unix and Windows line-endings.
|
||||
foreach (explode("\n", str_replace("\r", '', $input)) as $line) {
|
||||
$line = trim($line);
|
||||
// [label]=[element].[class][.[class]][...] pattern expected.
|
||||
if (!preg_match('@^.+= *[a-zA-Z0-9]+(\.[a-zA-Z0-9_ -]+)*$@', $line)) {
|
||||
return FALSE;
|
||||
}
|
||||
list($label, $selector) = explode('=', $line, 2);
|
||||
$classes = explode('.', $selector);
|
||||
$element = array_shift($classes);
|
||||
|
||||
$style = array();
|
||||
$style['name'] = trim($label);
|
||||
$style['element'] = trim($element);
|
||||
if (!empty($classes)) {
|
||||
$style['attributes']['class'] = implode(' ', array_map('trim', $classes));
|
||||
}
|
||||
$set[] = $style;
|
||||
}
|
||||
return $set;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array of native external plugins that need to be loaded separately.
|
||||
*/
|
||||
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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array for Drupal plugins loaded via the proxy plugin.
|
||||
*/
|
||||
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'],
|
||||
);
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
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'),
|
||||
'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'),
|
||||
'Superscript' => t('Superscript'), 'Subscript' => t('Subscript'),
|
||||
'Blockquote' => t('Blockquote'), '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'),
|
||||
'ShowBlocks' => t('Show blocks'),
|
||||
'RemoveFormat' => t('Remove format'),
|
||||
'SpecialChar' => t('Character map'),
|
||||
'Format' => t('HTML block format'), 'Font' => t('Font'), 'FontSize' => t('Font size'), 'Styles' => t('Font style'),
|
||||
'Table' => t('Table'),
|
||||
'SelectAll' => t('Select all'), 'Find' => t('Search'), 'Replace' => t('Replace'),
|
||||
'Flash' => t('Flash'), 'Smiley' => t('Smiley'),
|
||||
'CreateDiv' => t('Div container'),
|
||||
'Iframe' => t('iFrame'),
|
||||
'Maximize' => t('Maximize'),
|
||||
'SpellChecker' => t('Check spelling'), 'Scayt' => t('Check spelling as you type'),
|
||||
'About' => t('About'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
),
|
||||
);
|
||||
|
||||
if (version_compare($editor['installed version'], '3.1.0.4885', '<')) {
|
||||
unset($plugins['default']['buttons']['CreateDiv']);
|
||||
}
|
||||
if (version_compare($editor['installed version'], '3.4.0.5808', '<')) {
|
||||
unset($plugins['default']['buttons']['BidiLtr']);
|
||||
unset($plugins['default']['buttons']['BidiRtl']);
|
||||
}
|
||||
if (version_compare($editor['installed version'], '3.5.0.6260', '<')) {
|
||||
unset($plugins['default']['buttons']['Iframe']);
|
||||
}
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
|
||||
/**
|
||||
* TinyMCE 3.x
|
||||
*/
|
||||
table.mceLayout {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Align all buttons and separators in a single row, so they wrap into multiple
|
||||
* rows if required.
|
||||
*/
|
||||
.mceToolbar td {
|
||||
display: inline;
|
||||
}
|
||||
.mceToolbar a,
|
||||
.mceSeparator {
|
||||
float: left;
|
||||
}
|
||||
.mceListBox,
|
||||
.mceSplitButton {
|
||||
float: left;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.o2k7Skin .mceToolbar .mceToolbarStart span {float: left;}
|
||||
.o2k7Skin .mceToolbar .mceToolbarEnd span {float: left;}
|
||||
@@ -1,102 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Editor integration functions for EpicEditor.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*/
|
||||
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',
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Minified',
|
||||
'files' => array('js/epiceditor.min.js'),
|
||||
),
|
||||
'src' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array('js/epiceditor.js'),
|
||||
),
|
||||
),
|
||||
'version callback' => 'wysiwyg_epiceditor_version',
|
||||
'themes callback' => 'wysiwyg_epiceditor_themes',
|
||||
'settings callback' => 'wysiwyg_epiceditor_settings',
|
||||
'versions' => array(
|
||||
'0.1.1' => array(
|
||||
'js files' => array('epiceditor.js'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
* @param $editor
|
||||
* An array containing editor properties as returned from hook_editor().
|
||||
*
|
||||
* @return
|
||||
* The installed editor version.
|
||||
*/
|
||||
function wysiwyg_epiceditor_version($editor) {
|
||||
$library = $editor['library path'] . '/js/epiceditor.js';
|
||||
if (!file_exists($library)) {
|
||||
return;
|
||||
}
|
||||
// @todo Do not load the entire file; use fgets() instead.
|
||||
$library = file_get_contents($library, 'r');
|
||||
$version = preg_match('%EpicEditor\.version = \'(.*)\'\;%', $library, $matches);
|
||||
if (!isset($matches[1])) {
|
||||
return;
|
||||
}
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_epiceditor_themes($editor, $profile) {
|
||||
return array('epic-dark', 'epic-light');
|
||||
// @todo Use the preview themes somewhere.
|
||||
//return array('preview-dark', 'github');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_epiceditor_settings($editor, $config, $theme) {
|
||||
$settings = array(
|
||||
'basePath' => base_path() . $editor['library path'],
|
||||
'clientSideStorage' => FALSE,
|
||||
'theme' => $theme,
|
||||
//'preview_theme' => '',
|
||||
);
|
||||
return $settings;
|
||||
}
|
||||
|
||||
@@ -1,292 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Editor integration functions for FCKeditor.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*/
|
||||
function wysiwyg_fckeditor_editor() {
|
||||
$editor['fckeditor'] = array(
|
||||
'title' => 'FCKeditor',
|
||||
'vendor url' => 'http://www.fckeditor.net',
|
||||
'download url' => 'http://www.fckeditor.net/download',
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Default',
|
||||
'files' => array('fckeditor.js'),
|
||||
),
|
||||
),
|
||||
'version callback' => 'wysiwyg_fckeditor_version',
|
||||
'themes callback' => 'wysiwyg_fckeditor_themes',
|
||||
'settings callback' => 'wysiwyg_fckeditor_settings',
|
||||
'plugin callback' => 'wysiwyg_fckeditor_plugins',
|
||||
'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',
|
||||
'versions' => array(
|
||||
'2.6' => array(
|
||||
'js files' => array('fckeditor-2.6.js'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
* @param $editor
|
||||
* An array containing editor properties as returned from hook_editor().
|
||||
*
|
||||
* @return
|
||||
* The installed editor version.
|
||||
*/
|
||||
function wysiwyg_fckeditor_version($editor) {
|
||||
$library = $editor['library path'] . '/fckeditor.js';
|
||||
if (!file_exists($library)) {
|
||||
return;
|
||||
}
|
||||
$library = fopen($library, 'r');
|
||||
$max_lines = 100;
|
||||
while ($max_lines && $line = fgets($library, 60)) {
|
||||
if (preg_match('@^FCKeditor.prototype.Version\s*= \'([\d\.]+)@', $line, $version)) {
|
||||
fclose($library);
|
||||
return $version[1];
|
||||
}
|
||||
$max_lines--;
|
||||
}
|
||||
fclose($library);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_fckeditor_themes($editor, $profile) {
|
||||
return array('default', 'office2003', 'silver');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_fckeditor_settings($editor, $config, $theme) {
|
||||
$settings = array(
|
||||
'EditorPath' => base_path() . $editor['library path'] . '/',
|
||||
'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,
|
||||
'ImageUpload' => FALSE,
|
||||
'FlashBrowser' => FALSE,
|
||||
'FlashUpload' => FALSE,
|
||||
// By default, FCKeditor 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. FCKeditor always converts
|
||||
// XML default characters '&', '<', '>'.
|
||||
// @todo Check whether completely disabling ProcessHTMLEntities is an option.
|
||||
'IncludeLatinEntities' => FALSE,
|
||||
'IncludeGreekEntities' => FALSE,
|
||||
);
|
||||
if (isset($config['block_formats'])) {
|
||||
$settings['FontFormats'] = strtr($config['block_formats'], array(',' => ';'));
|
||||
}
|
||||
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'];
|
||||
}
|
||||
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['EditorAreaCSS'] = implode(',', wysiwyg_get_css());
|
||||
}
|
||||
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))));
|
||||
}
|
||||
}
|
||||
|
||||
// Use our custom toolbar set.
|
||||
$settings['ToolbarSet'] = 'Wysiwyg';
|
||||
// Populate our custom toolbar set for fckeditor.config.js.
|
||||
$settings['buttons'] = array();
|
||||
if (!empty($config['buttons'])) {
|
||||
$plugins = wysiwyg_get_plugins($editor['name']);
|
||||
foreach ($config['buttons'] as $plugin => $buttons) {
|
||||
foreach ($buttons as $button => $enabled) {
|
||||
// Iterate separately over buttons and extensions properties.
|
||||
foreach (array('buttons', 'extensions') as $type) {
|
||||
// Skip unavailable plugins.
|
||||
if (!isset($plugins[$plugin][$type][$button])) {
|
||||
continue;
|
||||
}
|
||||
// Add buttons.
|
||||
if ($type == 'buttons') {
|
||||
$settings['buttons'][] = $button;
|
||||
}
|
||||
// Allow plugins to add or override global configuration settings.
|
||||
if (!empty($plugins[$plugin]['options'])) {
|
||||
$settings = array_merge($settings, $plugins[$plugin]['options']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// For now, all buttons are placed into one row.
|
||||
$settings['buttons'] = array($settings['buttons']);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array of native external plugins that need to be loaded separately.
|
||||
*/
|
||||
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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array for Drupal plugins loaded via the proxy plugin.
|
||||
*/
|
||||
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'],
|
||||
);
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_fckeditor_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'),
|
||||
'Link' => t('Link'), 'Unlink' => t('Unlink'), 'Anchor' => t('Anchor'),
|
||||
'Image' => t('Image'),
|
||||
'TextColor' => t('Forecolor'), 'BGColor' => t('Backcolor'),
|
||||
'Superscript' => t('Superscript'), 'Subscript' => t('Subscript'),
|
||||
'Blockquote' => t('Blockquote'), 'Source' => t('Source code'),
|
||||
'Rule' => t('Horizontal rule'),
|
||||
'Cut' => t('Cut'), 'Copy' => t('Copy'), 'Paste' => t('Paste'),
|
||||
'PasteText' => t('Paste Text'), 'PasteWord' => t('Paste from Word'),
|
||||
'ShowBlocks' => t('Show blocks'),
|
||||
'RemoveFormat' => t('Remove format'),
|
||||
'SpecialChar' => t('Character map'),
|
||||
'About' => t('About'),
|
||||
'FontFormat' => t('HTML block format'), 'FontName' => t('Font'), 'FontSize' => t('Font size'), 'Style' => t('Font style'),
|
||||
'Table' => t('Table'),
|
||||
'Find' => t('Search'), 'Replace' => t('Replace'), 'SelectAll' => t('Select all'),
|
||||
'CreateDiv' => t('Create DIV container'),
|
||||
'Flash' => t('Flash'), 'Smiley' => t('Smiley'),
|
||||
'FitWindow' => t('FitWindow'),
|
||||
'SpellCheck' => t('Check spelling'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
),
|
||||
'autogrow' => array(
|
||||
'path' => $editor['library path'] . '/editor/plugins',
|
||||
'extensions' => array(
|
||||
'autogrow' => t('Autogrow'),
|
||||
),
|
||||
'options' => array(
|
||||
'AutoGrowMax' => 800,
|
||||
),
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'bbcode' => array(
|
||||
'path' => $editor['library path'] . '/editor/plugins',
|
||||
'extensions' => array(
|
||||
'bbcode' => t('BBCode'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'dragresizetable' => array(
|
||||
'path' => $editor['library path'] . '/editor/plugins',
|
||||
'extensions' => array(
|
||||
'dragresizetable' => t('Table drag/resize'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'tablecommands' => array(
|
||||
'path' => $editor['library path'] . '/editor/plugins',
|
||||
'buttons' => array(
|
||||
'TableCellProp' => t('Table: Cell properties'),
|
||||
'TableInsertRowAfter' => t('Table: Insert row after'),
|
||||
'TableInsertColumnAfter' => t('Table: Insert column after'),
|
||||
'TableInsertCellAfter' => t('Table: Insert cell after'),
|
||||
'TableDeleteRows' => t('Table: Delete rows'),
|
||||
'TableDeleteColumns' => t('Table: Delete columns'),
|
||||
'TableDeleteCells' => t('Table: Delete cells'),
|
||||
'TableMergeCells' => t('Table: Merge cells'),
|
||||
'TableHorizontalSplitCell' => t('Table: Horizontal split cell'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
);
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
@@ -1,248 +0,0 @@
|
||||
(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
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);
|
||||
|
||||
settings.on = {
|
||||
instanceReady: function(ev) {
|
||||
var editor = ev.editor;
|
||||
// Get a list of block, list and table tags from CKEditor's XHTML DTD.
|
||||
// @see http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Output_Formatting.
|
||||
var dtd = CKEDITOR.dtd;
|
||||
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) {
|
||||
// Mimic FCKeditor output, by breaking lines between tags.
|
||||
for (var tag in tags) {
|
||||
if (tag == 'pre') {
|
||||
continue;
|
||||
}
|
||||
this.dataProcessor.writer.setRules(tag, {
|
||||
indent: true,
|
||||
breakBeforeOpen: true,
|
||||
breakAfterOpen: false,
|
||||
breakBeforeClose: false,
|
||||
breakAfterClose: true
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
// CKEditor adds default formatting to <br>, so we want to remove that
|
||||
// here too.
|
||||
tags.br = 1;
|
||||
// No indents or linebreaks;
|
||||
for (var tag in tags) {
|
||||
if (tag == 'pre') {
|
||||
continue;
|
||||
}
|
||||
this.dataProcessor.writer.setRules(tag, {
|
||||
indent: false,
|
||||
breakBeforeOpen: false,
|
||||
breakAfterOpen: false,
|
||||
breakBeforeClose: false,
|
||||
breakAfterClose: false
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
pluginsLoaded: function(ev) {
|
||||
// Override the conversion methods to let Drupal plugins modify the data.
|
||||
var editor = ev.editor;
|
||||
if (editor.dataProcessor && Drupal.settings.wysiwyg.plugins[params.format]) {
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
return originalToHtml.call(this, data, fixForBody);
|
||||
};
|
||||
});
|
||||
editor.dataProcessor.toDataFormat = CKEDITOR.tools.override(editor.dataProcessor.toDataFormat, function(originalToDataFormat) {
|
||||
// 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) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
|
||||
data = Drupal.wysiwyg.plugins[plugin].detach(data, Drupal.settings.wysiwyg.plugins.drupal[plugin], editor.name);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
focus: function(ev) {
|
||||
Drupal.wysiwyg.activeId = ev.editor.name;
|
||||
},
|
||||
|
||||
afterCommandExec: function(ev) {
|
||||
// Fix Drupal toolbar obscuring editor toolbar in fullscreen mode.
|
||||
if (ev.data.name != 'maximize') {
|
||||
return;
|
||||
}
|
||||
if (ev.data.command.state == CKEDITOR.TRISTATE_ON) {
|
||||
$drupalToolbar.hide();
|
||||
}
|
||||
else {
|
||||
$drupalToolbar.show();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Attach editor.
|
||||
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.
|
||||
*/
|
||||
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]();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.ckeditor = {
|
||||
addPlugin: function(pluginName, settings, pluginSettings) {
|
||||
CKEDITOR.plugins.add(pluginName, {
|
||||
// Wrap Drupal plugin in a proxy pluygin.
|
||||
init: function(editor) {
|
||||
if (settings.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" >');
|
||||
}
|
||||
});
|
||||
}
|
||||
if (typeof Drupal.wysiwyg.plugins[pluginName].invoke == 'function') {
|
||||
var pluginCommand = {
|
||||
exec: function (editor) {
|
||||
var data = { format: 'html', node: null, content: '' };
|
||||
var selection = editor.getSelection();
|
||||
if (selection) {
|
||||
data.node = selection.getSelectedElement();
|
||||
if (data.node) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
else if (data.node) {
|
||||
// content is supposed to contain the "outerHTML".
|
||||
data.content = data.node.parentNode.innerHTML;
|
||||
}
|
||||
}
|
||||
Drupal.wysiwyg.plugins[pluginName].invoke(data, pluginSettings, editor.name);
|
||||
}
|
||||
};
|
||||
editor.addCommand(pluginName, pluginCommand);
|
||||
}
|
||||
editor.ui.addButton(pluginName, {
|
||||
label: settings.iconTitle,
|
||||
command: pluginName,
|
||||
icon: settings.icon
|
||||
});
|
||||
|
||||
// @todo Add button state handling.
|
||||
}
|
||||
});
|
||||
},
|
||||
prepareContent: function(content) {
|
||||
// @todo Don't know if we need this yet.
|
||||
return content;
|
||||
},
|
||||
|
||||
insert: function(content) {
|
||||
content = this.prepareContent(content);
|
||||
CKEDITOR.instances[this.field].insertHtml(content);
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
CKEDITOR.instances[this.field].setData(content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
return CKEDITOR.instances[this.field].getData();
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,38 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* 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 + '" />');
|
||||
|
||||
settings.container = containerId;
|
||||
settings.file = {
|
||||
defaultContent: defaultContent
|
||||
};
|
||||
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.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.epiceditor = function (context, params, trigger) {
|
||||
var $target = $('#' + params.field);
|
||||
var editor = $target.data('epiceditor');
|
||||
|
||||
$target.val(editor.exportFile());
|
||||
|
||||
editor.unload(function () {
|
||||
$target.show();
|
||||
});
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,196 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.fckeditor = function(context, params, settings) {
|
||||
var FCKinstance = new FCKeditor(params.field, settings.Width, settings.Height, settings.ToolbarSet);
|
||||
// Apply editor instance settings.
|
||||
FCKinstance.BasePath = settings.EditorPath;
|
||||
FCKinstance.Config.wysiwygFormat = params.format;
|
||||
FCKinstance.Config.CustomConfigurationsPath = settings.CustomConfigurationsPath;
|
||||
|
||||
// Load Drupal plugins and apply format specific settings.
|
||||
// @see fckeditor.config.js
|
||||
// @see Drupal.wysiwyg.editor.instance.fckeditor.init()
|
||||
|
||||
// Attach editor.
|
||||
FCKinstance.ReplaceTextarea();
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
else {
|
||||
instances = FCKeditorAPI.__Instances;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.fckeditor = {
|
||||
init: function(instance) {
|
||||
// Track which editor instance is active.
|
||||
instance.FCK.Events.AttachEvent('OnFocus', function(editorInstance) {
|
||||
Drupal.wysiwyg.activeId = editorInstance.Name;
|
||||
});
|
||||
|
||||
// Create a custom data processor to wrap the default one and allow Drupal
|
||||
// plugins modify the editor contents.
|
||||
var wysiwygDataProcessor = function() {};
|
||||
wysiwygDataProcessor.prototype = new instance.FCKDataProcessor();
|
||||
// Attach: Convert text into HTML.
|
||||
wysiwygDataProcessor.prototype.ConvertToHtml = function(data) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Re-protect the source and use the original data processor to convert it
|
||||
// into XHTML.
|
||||
data = instance.FCKConfig.ProtectedSource.Protect(data);
|
||||
return instance.FCKDataProcessor.prototype.ConvertToHtml.call(this, data);
|
||||
};
|
||||
// Detach: Convert HTML into text.
|
||||
wysiwygDataProcessor.prototype.ConvertToDataFormat = function(rootNode, excludeRoot, ignoreIfEmptyParagraph, format) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
return data;
|
||||
};
|
||||
instance.FCK.DataProcessor = new wysiwygDataProcessor();
|
||||
},
|
||||
|
||||
addPlugin: function(plugin, settings, 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;
|
||||
}
|
||||
|
||||
// @see fckcommands.js, fck_othercommands.js, fckpastewordcommand.js
|
||||
instance.FCKCommands.RegisterCommand(plugin, {
|
||||
// Invoke the plugin's button.
|
||||
Execute: function () {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') {
|
||||
var data = { format: 'html', node: instance.FCKSelection.GetParentElement() };
|
||||
// @todo This is NOT the same as data.node.
|
||||
data.content = data.node.innerHTML;
|
||||
Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, instance.FCK.Name);
|
||||
}
|
||||
},
|
||||
|
||||
// isNode: Return whether the plugin button should be enabled for the
|
||||
// current selection.
|
||||
// @see FCKUnlinkCommand.prototype.GetState()
|
||||
GetState: function () {
|
||||
// Always disabled if not in WYSIWYG mode.
|
||||
if (instance.FCK.EditMode != FCK_EDITMODE_WYSIWYG) {
|
||||
return FCK_TRISTATE_DISABLED;
|
||||
}
|
||||
var state = instance.FCK.GetNamedCommandState(this.Name);
|
||||
// FCKeditor sets the wrong state in WebKit browsers.
|
||||
if (!$.support.queryCommandEnabled && state == FCK_TRISTATE_DISABLED) {
|
||||
state = FCK_TRISTATE_OFF;
|
||||
}
|
||||
if (state == FCK_TRISTATE_OFF && instance.FCK.EditMode == FCK_EDITMODE_WYSIWYG) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
|
||||
var node = instance.FCKSelection.GetSelectedElement();
|
||||
state = Drupal.wysiwyg.plugins[plugin].isNode(node) ? FCK_TRISTATE_ON : FCK_TRISTATE_OFF;
|
||||
}
|
||||
}
|
||||
return state;
|
||||
},
|
||||
|
||||
/**
|
||||
* Return information about the plugin as a name/value array.
|
||||
*/
|
||||
Name: plugin
|
||||
});
|
||||
|
||||
// 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));
|
||||
},
|
||||
|
||||
openDialog: function(dialog, params) {
|
||||
// @todo Implement open dialog.
|
||||
},
|
||||
|
||||
closeDialog: function(dialog) {
|
||||
// @todo Implement close dialog.
|
||||
},
|
||||
|
||||
prepareContent: function(content) {
|
||||
// @todo Not needed for FCKeditor?
|
||||
return content;
|
||||
},
|
||||
|
||||
insert: function(content) {
|
||||
var instance = FCKeditorAPI.GetInstance(this.field);
|
||||
// @see FCK.InsertHtml(), FCK.InsertElement()
|
||||
instance.InsertHtml(content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
var instance = FCKeditorAPI.GetInstance(this.field);
|
||||
return instance.GetData();
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
var instance = FCKeditorAPI.GetInstance(this.field);
|
||||
instance.SetHTML(content);
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,86 +0,0 @@
|
||||
|
||||
Drupal = window.parent.Drupal;
|
||||
|
||||
/**
|
||||
* Fetch and provide original editor settings as local variable.
|
||||
*
|
||||
* FCKeditor does not support to pass complex variable types to the editor.
|
||||
* 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': {} });
|
||||
|
||||
/**
|
||||
* Apply format-specific settings.
|
||||
*/
|
||||
for (var setting in wysiwygSettings) {
|
||||
if (setting == 'buttons') {
|
||||
// Apply custom Wysiwyg toolbar for this format.
|
||||
// FCKConfig.ToolbarSets['Wysiwyg'] = wysiwygSettings.buttons;
|
||||
|
||||
// Temporarily stack buttons into multiple button groups and remove
|
||||
// separators until #277954 is solved.
|
||||
FCKConfig.ToolbarSets['Wysiwyg'] = [];
|
||||
for (var i = 0; i < wysiwygSettings.buttons[0].length; i++) {
|
||||
FCKConfig.ToolbarSets['Wysiwyg'].push([wysiwygSettings.buttons[0][i]]);
|
||||
}
|
||||
FCKTools.AppendStyleSheet(document, '#xToolbar .TB_Start { display:none; }');
|
||||
// Set valid height of select element in silver and office2003 skins.
|
||||
if (FCKConfig.SkinPath.match(/\/office2003\/$/)) {
|
||||
FCKTools.AppendStyleSheet(document, '#xToolbar .SC_FieldCaption { height: 24px; } #xToolbar .TB_End { display: none; }');
|
||||
}
|
||||
else if (FCKConfig.SkinPath.match(/\/silver\/$/)) {
|
||||
FCKTools.AppendStyleSheet(document, '#xToolbar .SC_FieldCaption { height: 27px; }');
|
||||
}
|
||||
}
|
||||
else {
|
||||
FCKConfig[setting] = wysiwygSettings[setting];
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
FCKFitWindow.prototype.Execute = function() {
|
||||
oldFitWindowExecute.apply(this, arguments);
|
||||
if (this.IsMaximized) {
|
||||
$drupalToolbar.hide();
|
||||
}
|
||||
else {
|
||||
$drupalToolbar.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this editor instance.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.instance.fckeditor.init(window);
|
||||
|
||||
/**
|
||||
* Register native plugins for this input format.
|
||||
*
|
||||
* Parameters to Plugins.Add are:
|
||||
* - Plugin name.
|
||||
* - Languages the plugin is available in.
|
||||
* - Location of the plugin folder; <plugin_name>/fckplugin.js is appended.
|
||||
*/
|
||||
for (var plugin in pluginSettings['native']) {
|
||||
// Languages and path may be undefined for internal plugins.
|
||||
FCKConfig.Plugins.Add(plugin, pluginSettings['native'][plugin].languages, pluginSettings['native'][plugin].path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Drupal plugins for this input format.
|
||||
*
|
||||
* Parameters to addPlugin() are:
|
||||
* - Plugin name.
|
||||
* - Format specific plugin settings.
|
||||
* - 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);
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.jwysiwyg = function(context, params, settings) {
|
||||
// Attach editor.
|
||||
$('#' + params.field).wysiwyg();
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.jwysiwyg = function (context, params, trigger) {
|
||||
var $field = $('#' + params.field);
|
||||
var editor = $field.data('wysiwyg');
|
||||
if (typeof editor != 'undefined') {
|
||||
editor.saveContent();
|
||||
if (trigger != 'serialize') {
|
||||
editor.element.remove();
|
||||
}
|
||||
}
|
||||
$field.removeData('wysiwyg');
|
||||
if (trigger != 'serialize') {
|
||||
$field.show();
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.jwysiwyg = {
|
||||
insert: function (content) {
|
||||
$('#' + this.field).wysiwyg('insertHtml', content);
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
$('#' + this.field).wysiwyg('setContent', content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
return $('#' + this.field).wysiwyg('getContent');
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,46 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.markitup = function(context, params, settings) {
|
||||
$('#' + params.field, context).markItUp(settings);
|
||||
|
||||
// Adjust CSS for editor buttons.
|
||||
$.each(settings.markupSet, function (button) {
|
||||
$('.' + settings.nameSpace + ' .' + this.className + ' a')
|
||||
.css({ backgroundImage: 'url(' + settings.root + 'sets/default/images/' + button + '.png' + ')' })
|
||||
.parents('li').css({ backgroundImage: 'none' });
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.markitup = {
|
||||
insert: function (content) {
|
||||
$.markItUp({ replaceWith: content });
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
$('#' + this.field).val(content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
return $('#' + this.field).val();
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,115 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.nicedit = function(context, params, settings) {
|
||||
// Intercept and ignore submit handlers or they will revert changes made
|
||||
// since the instance was removed. The handlers are anonymous and hidden out
|
||||
// of scope in a closure so we can't unbind them. The same operations are
|
||||
// performed when the instance is detached anyway.
|
||||
var oldAddEvent = bkLib.addEvent;
|
||||
bkLib.addEvent = function(obj, type, fn) {
|
||||
if (type != 'submit') {
|
||||
oldAddEvent(obj, type, fn);
|
||||
}
|
||||
}
|
||||
// Attach editor.
|
||||
var editor = new nicEditor(settings);
|
||||
editor.panelInstance(params.field);
|
||||
// The old addEvent() must be restored after creating a new instance, as
|
||||
// plugins with dialogs use it to bind submit handlers to their forms.
|
||||
bkLib.addEvent = oldAddEvent;
|
||||
editor.addEvent('focus', function () {
|
||||
Drupal.wysiwyg.activeId = params.field;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.detach.none() for a full description of this hook.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
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 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();
|
||||
// IE.
|
||||
if (document.selection) {
|
||||
editingArea.focus();
|
||||
sel.createRange().pasteHTML(content);
|
||||
}
|
||||
else {
|
||||
// Convert selection to a range.
|
||||
var range;
|
||||
// W3C compatible.
|
||||
if (sel.getRangeAt) {
|
||||
range = sel.getRangeAt(0);
|
||||
}
|
||||
// Safari.
|
||||
else {
|
||||
range = editingArea.ownerDocument.createRange();
|
||||
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.
|
||||
var fragment = editingArea.ownerDocument.createDocumentFragment();
|
||||
// Fragments don't support innerHTML.
|
||||
var wrapper = editingArea.ownerDocument.createElement('div');
|
||||
wrapper.innerHTML = content;
|
||||
while (wrapper.firstChild) {
|
||||
fragment.appendChild(wrapper.firstChild);
|
||||
}
|
||||
range.deleteContents();
|
||||
// Only fragment children are inserted.
|
||||
range.insertNode(fragment);
|
||||
}
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
nicEditors.findEditor(this.field).setContent(content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
return nicEditors.findEditor(this.field).getContent();
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,91 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*
|
||||
* @param context
|
||||
* A DOM element, supplied by Drupal.attachBehaviors().
|
||||
* @param params
|
||||
* An object containing input format parameters. Default parameters are:
|
||||
* - editor: The internal editor name.
|
||||
* - theme: The name/key of the editor theme/profile to use.
|
||||
* - field: The CSS id of the target element.
|
||||
* @param settings
|
||||
* An object containing editor settings for all enabled editor themes.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.none = function(context, params, settings) {
|
||||
if (params.resizable) {
|
||||
var $wrapper = $('#' + params.field).parents('.form-textarea-wrapper:first');
|
||||
$wrapper.addClass('resizable');
|
||||
if (Drupal.behaviors.textarea) {
|
||||
Drupal.behaviors.textarea.attach();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*
|
||||
* The editor syncs its contents back to the original field before its instance
|
||||
* is removed.
|
||||
*
|
||||
* @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
|
||||
* AJAX/AHAH applications.
|
||||
* @param trigger
|
||||
* A string describing why the editor is being detached.
|
||||
* Possible triggers are:
|
||||
* - unload: (default) Another or no editor is about to take its place.
|
||||
* - move: Currently expected to produce the same result as unload.
|
||||
* - serialize: The form is about to be serialized before an AJAX request or
|
||||
* a normal form submission. If possible, perform a quick detach and leave
|
||||
* the editor's GUI elements in place to avoid flashes or scrolling issues.
|
||||
* @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')
|
||||
.find('.grippie').remove();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Instance methods for plain text areas.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.instance.none = {
|
||||
insert: function(content) {
|
||||
var editor = document.getElementById(this.field);
|
||||
|
||||
// IE support.
|
||||
if (document.selection) {
|
||||
editor.focus();
|
||||
var sel = document.selection.createRange();
|
||||
sel.text = content;
|
||||
}
|
||||
// Mozilla/Firefox/Netscape 7+ support.
|
||||
else if (editor.selectionStart || editor.selectionStart == '0') {
|
||||
var startPos = editor.selectionStart;
|
||||
var endPos = editor.selectionEnd;
|
||||
editor.value = editor.value.substring(0, startPos) + content + editor.value.substring(endPos, editor.value.length);
|
||||
}
|
||||
// Fallback, just add to the end of the content.
|
||||
else {
|
||||
editor.value += content;
|
||||
}
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
$('#' + this.field).val(content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
return $('#' + this.field).val();
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -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);
|
||||
@@ -1,256 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.init.tinymce = function(settings) {
|
||||
// Fix Drupal toolbar obscuring editor toolbar in fullscreen mode.
|
||||
var $drupalToolbar = $('#toolbar', Drupal.overlayChild ? window.parent.document : document);
|
||||
tinyMCE.onAddEditor.add(function (mgr, ed) {
|
||||
if (ed.id == 'mce_fullscreen') {
|
||||
$drupalToolbar.hide();
|
||||
}
|
||||
});
|
||||
tinyMCE.onRemoveEditor.add(function (mgr, ed) {
|
||||
if (ed.id == 'mce_fullscreen') {
|
||||
$drupalToolbar.show();
|
||||
}
|
||||
});
|
||||
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
var ed = new tinymce.Editor(params.field, settings);
|
||||
// Reset active instance id on any event.
|
||||
ed.onEvent.add(function(ed, e) {
|
||||
Drupal.wysiwyg.activeId = ed.id;
|
||||
});
|
||||
// Indicate that the DOM has been loaded (in case of Ajax).
|
||||
tinymce.dom.Event.domLoaded = true;
|
||||
// Make toolbar buttons wrappable (required for IE).
|
||||
ed.onPostRender.add(function (ed) {
|
||||
var $toolbar = $('<div class="wysiwygToolbar"></div>');
|
||||
$('#' + ed.editorContainer + ' table.mceToolbar > tbody > tr > td').each(function () {
|
||||
$('<div></div>').addClass(this.className).append($(this).children()).appendTo($toolbar);
|
||||
});
|
||||
$('#' + ed.editorContainer + ' table.mceLayout td.mceToolbar').append($toolbar);
|
||||
$('#' + ed.editorContainer + ' table.mceToolbar').remove();
|
||||
});
|
||||
|
||||
// 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.
|
||||
ed.render();
|
||||
};
|
||||
|
||||
/**
|
||||
* 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') {
|
||||
var 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 (var instance in tinyMCE.editors) {
|
||||
tinyMCE.editors[instance].remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
addPlugin: function(plugin, settings, pluginSettings) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') {
|
||||
return;
|
||||
}
|
||||
tinymce.create('tinymce.plugins.' + plugin, {
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
init: function(ed, url) {
|
||||
// Register an editor command for this plugin, invoked by the plugin's button.
|
||||
ed.addCommand(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.
|
||||
var instanceId = ed.id == 'mce_fullscreen' ? ed.getParam('fullscreen_editor_id') : ed.id;
|
||||
Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, instanceId);
|
||||
}
|
||||
});
|
||||
|
||||
// Register the plugin button.
|
||||
ed.addButton(plugin, {
|
||||
title : settings.iconTitle,
|
||||
cmd : plugin,
|
||||
image : settings.icon
|
||||
});
|
||||
|
||||
// Load custom CSS for editor contents on startup.
|
||||
ed.onInit.add(function() {
|
||||
if (settings.css) {
|
||||
ed.dom.loadCSS(settings.css);
|
||||
}
|
||||
});
|
||||
|
||||
// Attach: Replace plain text with HTML representations.
|
||||
ed.onBeforeSetContent.add(function(ed, data) {
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
// Detach: Replace HTML representations with plain text.
|
||||
ed.onGetContent.add(function(ed, data) {
|
||||
var editorId = (ed.id == 'mce_fullscreen' ? ed.getParam('fullscreen_editor_id') : ed.id);
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
|
||||
data.content = Drupal.wysiwyg.plugins[plugin].detach(data.content, pluginSettings, editorId);
|
||||
}
|
||||
});
|
||||
|
||||
// isNode: Return whether the plugin button should be enabled for the
|
||||
// current selection.
|
||||
ed.onNodeChange.add(function(ed, command, node) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
|
||||
command.setActive(plugin, Drupal.wysiwyg.plugins[plugin].isNode(node));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Return information about the plugin as a name/value array.
|
||||
*/
|
||||
getInfo: function() {
|
||||
return {
|
||||
longname: settings.title
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Register plugin.
|
||||
tinymce.PluginManager.add(plugin, tinymce.plugins[plugin]);
|
||||
},
|
||||
|
||||
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' }
|
||||
};
|
||||
var $content = $('<div>' + content + '</div>'); // No .outerHTML() in jQuery :(
|
||||
// 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.execInstanceCommand(this.getInstanceId(), 'mceInsertContent', false, content);
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
content = this.prepareContent(content);
|
||||
tinyMCE.execInstanceCommand(this.getInstanceId(), 'mceSetContent', false, content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
return tinyMCE.get(this.getInstanceId()).getContent();
|
||||
},
|
||||
|
||||
isFullscreen: function() {
|
||||
// TinyMCE creates a completely new instance for fullscreen mode.
|
||||
return tinyMCE.activeEditor.id == 'mce_fullscreen' && tinyMCE.activeEditor.getParam('fullscreen_editor_id') == this.field;
|
||||
},
|
||||
|
||||
getInstanceId: function () {
|
||||
return this.isFullscreen() ? 'mce_fullscreen' : this.field;
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,155 +0,0 @@
|
||||
|
||||
var wysiwygWhizzywig = { currentField: null, fields: {} };
|
||||
var buttonPath = null;
|
||||
|
||||
/**
|
||||
* Override Whizzywig's document.write() function.
|
||||
*
|
||||
* Whizzywig uses document.write() by default, which leads to a blank page when
|
||||
* invoked in jQuery.ready(). Luckily, Whizzywig developers implemented a
|
||||
* shorthand w() substitute function that we can override to redirect the output
|
||||
* into the global wysiwygWhizzywig variable.
|
||||
*
|
||||
* @see o()
|
||||
*/
|
||||
var w = function (string) {
|
||||
if (string) {
|
||||
wysiwygWhizzywig.fields[wysiwygWhizzywig.currentField] += string;
|
||||
}
|
||||
return wysiwygWhizzywig.fields[wysiwygWhizzywig.currentField];
|
||||
};
|
||||
|
||||
/**
|
||||
* Override Whizzywig's document.getElementById() function.
|
||||
*
|
||||
* Since we redirect the output of w() into a temporary string upon attaching
|
||||
* an editor, we also have to override the o() shorthand substitute function
|
||||
* for document.getElementById() to search in the document or our container.
|
||||
* This override function also inserts the editor instance when Whizzywig
|
||||
* tries to access its IFRAME, so it has access to the full/regular window
|
||||
* object.
|
||||
*
|
||||
* @see w()
|
||||
*/
|
||||
var o = function (id) {
|
||||
// Upon first access to "whizzy" + id, Whizzywig tries to access its IFRAME,
|
||||
// so we need to insert the editor into the DOM.
|
||||
if (id == 'whizzy' + wysiwygWhizzywig.currentField && wysiwygWhizzywig.fields[wysiwygWhizzywig.currentField]) {
|
||||
jQuery('#' + wysiwygWhizzywig.currentField).after('<div id="' + wysiwygWhizzywig.currentField + '-whizzywig"></div>');
|
||||
// Iframe's .contentWindow becomes null in Webkit if inserted via .after().
|
||||
jQuery('#' + wysiwygWhizzywig.currentField + '-whizzywig').html(w());
|
||||
// Prevent subsequent invocations from inserting the editor multiple times.
|
||||
wysiwygWhizzywig.fields[wysiwygWhizzywig.currentField] = '';
|
||||
}
|
||||
// If id exists in the regular window.document, return it.
|
||||
if (jQuery('#' + id).size()) {
|
||||
return jQuery('#' + id).get(0);
|
||||
}
|
||||
// Otherwise return id from our container.
|
||||
return jQuery('#' + id, w()).get(0);
|
||||
};
|
||||
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
// Previous versions used per-button images found in this location,
|
||||
// now it is only used for custom buttons.
|
||||
if (settings.buttonPath) {
|
||||
window.buttonPath = settings.buttonPath;
|
||||
}
|
||||
// Assign the toolbar image path used for native buttons, if available.
|
||||
if (settings.toolbarImagePath) {
|
||||
btn._f = settings.toolbarImagePath;
|
||||
}
|
||||
// Fall back to text labels for all buttons.
|
||||
else {
|
||||
window.buttonPath = 'textbuttons';
|
||||
}
|
||||
// Create Whizzywig container.
|
||||
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');
|
||||
$field.css('width', $field.width() + 'px');
|
||||
|
||||
// Attach editor.
|
||||
makeWhizzyWig(params.field, (settings.buttons ? settings.buttons : 'all'));
|
||||
// Whizzywig fails to detect and set initial textarea contents.
|
||||
$('#whizzy' + params.field).contents().find('body').html(tidyD($field.val()));
|
||||
};
|
||||
|
||||
/**
|
||||
* 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];
|
||||
|
||||
// Save contents of editor back into textarea.
|
||||
$field.val(instance.getContent());
|
||||
// If the editor is just being serialized (not detached), our work is done.
|
||||
if (trigger == 'serialize') {
|
||||
return;
|
||||
}
|
||||
// Remove editor instance.
|
||||
$('#' + id + '-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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Instance methods for Whizzywig.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.instance.whizzywig = {
|
||||
insert: function (content) {
|
||||
// Whizzywig executes any string beginning with 'js:'.
|
||||
insHTML(content.replace(/^js:/, 'js:'));
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
// Whizzywig shows the original textarea in source mode.
|
||||
if ($field.css('display') == 'block') {
|
||||
$('#' + this.field).val(content);
|
||||
}
|
||||
else {
|
||||
var doc = $('#whizzy' + this.field).contents()[0];
|
||||
doc.open();
|
||||
doc.write(content);
|
||||
doc.close();
|
||||
}
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
// 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();
|
||||
}
|
||||
return tidyH(clone);
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
||||
@@ -1,107 +0,0 @@
|
||||
|
||||
var buttonPath = null;
|
||||
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
// Previous versions used per-button images found in this location,
|
||||
// now it is only used for custom buttons.
|
||||
if (settings.buttonPath) {
|
||||
window.buttonPath = settings.buttonPath;
|
||||
}
|
||||
// Assign the toolbar image path used for native buttons, if available.
|
||||
if (settings.toolbarImagePath) {
|
||||
btn._f = settings.toolbarImagePath;
|
||||
}
|
||||
// Fall back to text labels for all buttons.
|
||||
else {
|
||||
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');
|
||||
$field.css('width', $field.width() + 'px');
|
||||
|
||||
// Attach editor.
|
||||
makeWhizzyWig(params.field, (settings.buttons ? settings.buttons : 'all'));
|
||||
// Whizzywig fails to detect and set initial textarea contents.
|
||||
$('#whizzy' + params.field).contents().find('body').html(tidyD($field.val()));
|
||||
};
|
||||
|
||||
/**
|
||||
* 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];
|
||||
|
||||
// Save contents of editor back into textarea.
|
||||
$field.val(instance.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);
|
||||
$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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Instance methods for Whizzywig.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.instance.whizzywig = {
|
||||
insert: function (content) {
|
||||
// Whizzywig executes any string beginning with 'js:'.
|
||||
insHTML(content.replace(/^js:/, 'js:'));
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
// Whizzywig shows the original textarea in source mode.
|
||||
if ($field.css('display') == 'block') {
|
||||
$('#' + this.field).val(content);
|
||||
}
|
||||
else {
|
||||
var doc = $('#whizzy' + this.field).contents()[0];
|
||||
doc.open();
|
||||
doc.write(content);
|
||||
doc.close();
|
||||
}
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
// 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();
|
||||
}
|
||||
return tidyH(clone);
|
||||
}
|
||||
};
|
||||
})(jQuery);
|
||||
@@ -1,154 +0,0 @@
|
||||
|
||||
var wysiwygWhizzywig = { currentField: null, fields: {} };
|
||||
var buttonPath = null;
|
||||
|
||||
/**
|
||||
* Override Whizzywig's document.write() function.
|
||||
*
|
||||
* Whizzywig uses document.write() by default, which leads to a blank page when
|
||||
* invoked in jQuery.ready(). Luckily, Whizzywig developers implemented a
|
||||
* shorthand w() substitute function that we can override to redirect the output
|
||||
* into the global wysiwygWhizzywig variable.
|
||||
*
|
||||
* @see o()
|
||||
*/
|
||||
var w = function (string) {
|
||||
if (string) {
|
||||
wysiwygWhizzywig.fields[wysiwygWhizzywig.currentField] += string;
|
||||
}
|
||||
return wysiwygWhizzywig.fields[wysiwygWhizzywig.currentField];
|
||||
};
|
||||
|
||||
/**
|
||||
* Override Whizzywig's document.getElementById() function.
|
||||
*
|
||||
* Since we redirect the output of w() into a temporary string upon attaching
|
||||
* an editor, we also have to override the o() shorthand substitute function
|
||||
* for document.getElementById() to search in the document or our container.
|
||||
* This override function also inserts the editor instance when Whizzywig
|
||||
* tries to access its IFRAME, so it has access to the full/regular window
|
||||
* object.
|
||||
*
|
||||
* @see w()
|
||||
*/
|
||||
var o = function (id) {
|
||||
// Upon first access to "whizzy" + id, Whizzywig tries to access its IFRAME,
|
||||
// so we need to insert the editor into the DOM.
|
||||
if (id == 'whizzy' + wysiwygWhizzywig.currentField && wysiwygWhizzywig.fields[wysiwygWhizzywig.currentField]) {
|
||||
jQuery('#' + wysiwygWhizzywig.currentField).after('<div id="' + wysiwygWhizzywig.currentField + '-whizzywig"></div>');
|
||||
// Iframe's .contentWindow becomes null in Webkit if inserted via .after().
|
||||
jQuery('#' + wysiwygWhizzywig.currentField + '-whizzywig').html(w());
|
||||
// Prevent subsequent invocations from inserting the editor multiple times.
|
||||
wysiwygWhizzywig.fields[wysiwygWhizzywig.currentField] = '';
|
||||
}
|
||||
// If id exists in the regular window.document, return it.
|
||||
if (jQuery('#' + id).size()) {
|
||||
return jQuery('#' + id).get(0);
|
||||
}
|
||||
// Otherwise return id from our container.
|
||||
return jQuery('#' + id, w()).get(0);
|
||||
};
|
||||
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
// Assign button images path, if available.
|
||||
if (settings.buttonPath) {
|
||||
window.buttonPath = settings.buttonPath;
|
||||
}
|
||||
// Create Whizzywig container.
|
||||
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');
|
||||
$field.css('width', $field.width() + 'px');
|
||||
|
||||
// Attach editor.
|
||||
makeWhizzyWig(params.field, (settings.buttons ? settings.buttons : 'all'));
|
||||
// Whizzywig fails to detect and set initial textarea contents.
|
||||
$('#whizzy' + params.field).contents().find('body').html(tidyD($field.val()));
|
||||
};
|
||||
|
||||
/**
|
||||
* 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];
|
||||
|
||||
// Save contents of editor back into textarea.
|
||||
$field.val(instance.getContent());
|
||||
// If the editor is just being serialized (not detached), our work is done.
|
||||
if (trigger == 'serialize') {
|
||||
return;
|
||||
}
|
||||
// Remove editor instance.
|
||||
$('#' + id + '-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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Instance methods for Whizzywig.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.instance.whizzywig = {
|
||||
insert: function (content) {
|
||||
// Whizzywig executes any string beginning with 'js:'.
|
||||
insHTML(content.replace(/^js:/, 'js:'));
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
var $field = $('#' + this.field);
|
||||
// Whizzywig shows the original textarea in source mode.
|
||||
if ($field.css('display') == 'block') {
|
||||
$field.val(content);
|
||||
}
|
||||
else {
|
||||
var doc = $('#whizzy' + this.field).contents()[0];
|
||||
doc.open();
|
||||
doc.write(content);
|
||||
doc.close();
|
||||
}
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
var $field = $('#' + this.field),
|
||||
// Whizzywig shows the original textarea in source mode.
|
||||
content = ($field.css('display') == 'block' ?
|
||||
$field.val() : $('#whizzy' + this.field).contents().find('body').html()
|
||||
);
|
||||
|
||||
content = tidyH(content);
|
||||
// Whizzywig's get_xhtml() addon, if defined, expects a DOM node.
|
||||
if ($.isFunction(window.get_xhtml)) {
|
||||
var pre = document.createElement('pre');
|
||||
pre.innerHTML = content;
|
||||
content = get_xhtml(pre);
|
||||
}
|
||||
return content.replace(location.href + '#', '#');
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,74 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.wymeditor = function (context, params, settings) {
|
||||
// Prepend basePath to wymPath.
|
||||
settings.wymPath = settings.basePath + settings.wymPath;
|
||||
// Update activeId on focus.
|
||||
settings.postInit = function (instance) {
|
||||
$(instance._doc).focus(function () {
|
||||
Drupal.wysiwyg.activeId = params.field;
|
||||
});
|
||||
};
|
||||
// Attach editor.
|
||||
$('#' + params.field).wymeditor(settings);
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
else {
|
||||
jQuery.each(WYMeditor.INSTANCES, function () {
|
||||
this.update();
|
||||
if (trigger != 'serialize') {
|
||||
$(this._box).remove();
|
||||
$(this._element).show();
|
||||
delete this;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Drupal.wysiwyg.editor.instance.wymeditor = {
|
||||
insert: function (content) {
|
||||
this.getInstance().insert(content);
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
this.getInstance().html(content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
return this.getInstance().xhtml();
|
||||
},
|
||||
|
||||
getInstance: function () {
|
||||
var $field = $('#' + this.field);
|
||||
var index = $field.data(WYMeditor.WYM_INDEX);
|
||||
if (typeof index != 'undefined') {
|
||||
return WYMeditor.INSTANCES[index];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
Vendored
-145
@@ -1,145 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Attach this editor to a target element.
|
||||
*
|
||||
* Since buttons must be added before the editor is rendered, we add plugins
|
||||
* buttons on attach event rather than in init.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.attach.yui = function(context, params, settings) {
|
||||
// Apply theme.
|
||||
$('#' + params.field).parent().addClass('yui-skin-' + settings.theme);
|
||||
|
||||
// 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+'"; ';
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
// Reload the editor contents to give Drupal plugins a chance to act.
|
||||
editor.on('editorContentLoaded', function (e) {
|
||||
e.target.setEditorHTML(oldGetEditorHTML.call(e.target));
|
||||
});
|
||||
|
||||
editor.on('afterNodeChange', function (e) {
|
||||
for (var plugin in Drupal.settings.wysiwyg.plugins[params.format].drupal) {
|
||||
if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
|
||||
if (Drupal.wysiwyg.plugins[plugin].isNode(e.target._getSelectedElement())) {
|
||||
this.toolbar.selectButton(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
editor.render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
|
||||
*/
|
||||
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];
|
||||
}
|
||||
}
|
||||
}
|
||||
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 methods for YUI Editor.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.instance.yui = {
|
||||
addPlugin: function (plugin, settings, 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');
|
||||
// 'this' will reference the toolbar while inside the event handler.
|
||||
var instanceId = this.field;
|
||||
editor.toolbar.on(plugin + 'Click', function (e) {
|
||||
var selectedElement = editor._getSelectedElement();
|
||||
// @todo Using .html() will cause XTHML vs HTML conflicts.
|
||||
var data = {
|
||||
format: 'html',
|
||||
node: selectedElement,
|
||||
content: $(selectedElement).html()
|
||||
};
|
||||
Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, instanceId);
|
||||
});
|
||||
},
|
||||
|
||||
prepareContent: function (content) {
|
||||
var editor = YAHOO.widget.EditorInfo.getEditorById(this.field);
|
||||
content = editor.cleanHTML(content);
|
||||
return content;
|
||||
},
|
||||
|
||||
insert: function (content) {
|
||||
YAHOO.widget.EditorInfo.getEditorById(this.field).cmd_inserthtml(content);
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
YAHOO.widget.EditorInfo.getEditorById(this.field).setEditorHTML(content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
var instance = YAHOO.widget.EditorInfo.getEditorById(this.field);
|
||||
return instance.cleanHTML(instance.getEditorHTML(content));
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,62 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Editor integration functions for jWYSIWYG.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*/
|
||||
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',
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array('jquery.wysiwyg.js'),
|
||||
),
|
||||
'pack' => array(
|
||||
'title' => 'Packed',
|
||||
'files' => array('jquery.wysiwyg.pack.js'),
|
||||
),
|
||||
),
|
||||
'version callback' => 'wysiwyg_jwysiwyg_version',
|
||||
// @todo Wrong property; add separate properties for editor requisites.
|
||||
'css path' => wysiwyg_get_path('jwysiwyg'),
|
||||
'versions' => array(
|
||||
'0.5' => array(
|
||||
'js files' => array('jwysiwyg.js'),
|
||||
'css files' => array('jquery.wysiwyg.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_jwysiwyg_version($editor) {
|
||||
$script = $editor['library path'] . '/jquery.wysiwyg.js';
|
||||
if (!file_exists($script)) {
|
||||
return;
|
||||
}
|
||||
$script = fopen($script, 'r');
|
||||
fgets($script);
|
||||
$line = fgets($script);
|
||||
if (preg_match('@([0-9\.]+)$@', $line, $version)) {
|
||||
fclose($script);
|
||||
return $version[1];
|
||||
}
|
||||
fclose($script);
|
||||
}
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Editor integration functions for markItUp.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*/
|
||||
function wysiwyg_markitup_editor() {
|
||||
$editor['markitup'] = array(
|
||||
'title' => 'markItUp',
|
||||
'vendor url' => 'http://markitup.jaysalvat.com',
|
||||
'download url' => 'http://markitup.jaysalvat.com/downloads',
|
||||
'library path' => wysiwyg_get_path('markitup'),
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array('markitup/jquery.markitup.js'),
|
||||
),
|
||||
'pack' => array(
|
||||
'title' => 'Packed',
|
||||
'files' => array('markitup/jquery.markitup.pack.js'),
|
||||
),
|
||||
),
|
||||
'version callback' => 'wysiwyg_markitup_version',
|
||||
'themes callback' => 'wysiwyg_markitup_themes',
|
||||
'settings callback' => 'wysiwyg_markitup_settings',
|
||||
'plugin callback' => 'wysiwyg_markitup_plugins',
|
||||
'versions' => array(
|
||||
'1.1.5' => array(
|
||||
'js files' => array('markitup.js'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
* @param $editor
|
||||
* An array containing editor properties as returned from hook_editor().
|
||||
*
|
||||
* @return
|
||||
* The installed editor version.
|
||||
*/
|
||||
function wysiwyg_markitup_version($editor) {
|
||||
// Changelog was in markitup/markitup/readme.txt <= 1.1.5.
|
||||
$changelog = $editor['library path'] . '/markitup/readme.txt';
|
||||
if (!file_exists($changelog)) {
|
||||
// Changelog was moved up to markitup/CHANGELOG.md after 1.1.5.
|
||||
$changelog = $editor['library path'] . '/CHANGELOG.md';
|
||||
if (!file_exists($changelog)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$changelog = fopen($changelog, 'r');
|
||||
$line = fgets($changelog);
|
||||
if (preg_match('@([0-9\.]+)@', $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_markitup_themes($editor, $profile) {
|
||||
return array('simple', 'markitup');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_markitup_settings($editor, $config, $theme) {
|
||||
drupal_add_css($editor['library path'] . '/markitup/skins/' . $theme . '/style.css', array(
|
||||
// Specify an alternate basename; otherwise, style.css would override a
|
||||
// commonly used style.css file of the theme.
|
||||
'basename' => 'markitup.' . $theme . '.style.css',
|
||||
'group' => CSS_THEME,
|
||||
));
|
||||
|
||||
$settings = array(
|
||||
'root' => base_path() . $editor['library path'] . '/markitup/',
|
||||
'nameSpace' => $theme,
|
||||
'markupSet' => array(),
|
||||
);
|
||||
|
||||
// Add configured buttons or all available.
|
||||
$default_buttons = array(
|
||||
'bold' => array(
|
||||
'name' => t('Bold'),
|
||||
'className' => 'markitup-bold',
|
||||
'key' => 'B',
|
||||
'openWith' => '(!(<strong>|!|<b>)!)',
|
||||
'closeWith' => '(!(</strong>|!|</b>)!)',
|
||||
),
|
||||
'italic' => array(
|
||||
'name' => t('Italic'),
|
||||
'className' => 'markitup-italic',
|
||||
'key' => 'I',
|
||||
'openWith' => '(!(<em>|!|<i>)!)',
|
||||
'closeWith' => '(!(</em>|!|</i>)!)',
|
||||
),
|
||||
'stroke' => array(
|
||||
'name' => t('Strike-through'),
|
||||
'className' => 'markitup-stroke',
|
||||
'key' => 'S',
|
||||
'openWith' => '<del>',
|
||||
'closeWith' => '</del>',
|
||||
),
|
||||
'image' => array(
|
||||
'name' => t('Image'),
|
||||
'className' => 'markitup-image',
|
||||
'key' => 'P',
|
||||
'replaceWith' => '<img src="[![Source:!:http://]!]" alt="[![Alternative text]!]" />',
|
||||
),
|
||||
'link' => array(
|
||||
'name' => t('Link'),
|
||||
'className' => 'markitup-link',
|
||||
'key' => 'K',
|
||||
'openWith' => '<a href="[![Link:!:http://]!]"(!( title="[![Title]!]")!)>',
|
||||
'closeWith' => '</a>',
|
||||
'placeHolder' => 'Your text to link...',
|
||||
),
|
||||
// @todo
|
||||
// 'cleanup' => array('name' => t('Clean-up'), 'className' => 'markitup-cleanup', 'replaceWith' => 'function(markitup) { return markitup.selection.replace(/<(.*?)>/g, "") }'),
|
||||
'preview' => array(
|
||||
'name' => t('Preview'),
|
||||
'className' => 'markitup-preview',
|
||||
'call' => 'preview',
|
||||
),
|
||||
);
|
||||
$settings['markupSet'] = array();
|
||||
if (!empty($config['buttons'])) {
|
||||
foreach ($config['buttons'] as $plugin) {
|
||||
foreach ($plugin as $button => $enabled) {
|
||||
if (isset($default_buttons[$button])) {
|
||||
$settings['markupSet'][$button] = $default_buttons[$button];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_markitup_plugins($editor) {
|
||||
return array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
'bold' => t('Bold'), 'italic' => t('Italic'),
|
||||
'stroke' => t('Strike-through'),
|
||||
'link' => t('Link'),
|
||||
'image' => t('Image'),
|
||||
// 'cleanup' => t('Clean-up'),
|
||||
'preview' => t('Preview'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Editor integration functions for NicEdit.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*/
|
||||
function wysiwyg_nicedit_editor() {
|
||||
$editor['nicedit'] = array(
|
||||
'title' => 'NicEdit',
|
||||
'vendor url' => 'http://nicedit.com',
|
||||
'download url' => 'http://nicedit.com/download.php',
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array('nicEdit.js'),
|
||||
),
|
||||
),
|
||||
'version callback' => 'wysiwyg_nicedit_version',
|
||||
'settings callback' => 'wysiwyg_nicedit_settings',
|
||||
'plugin callback' => 'wysiwyg_nicedit_plugins',
|
||||
'versions' => array(
|
||||
'0.9' => array(
|
||||
'js files' => array('nicedit.js'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
* @param $editor
|
||||
* An array containing editor properties as returned from hook_editor().
|
||||
*
|
||||
* @return
|
||||
* The installed editor version.
|
||||
*/
|
||||
function wysiwyg_nicedit_version($editor) {
|
||||
// @see http://nicedit.com/forums/viewtopic.php?t=425
|
||||
return '0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_nicedit_settings($editor, $config, $theme) {
|
||||
$settings = array(
|
||||
'iconsPath' => base_path() . $editor['library path'] . '/nicEditorIcons.gif',
|
||||
);
|
||||
|
||||
// Add configured buttons or all available.
|
||||
$settings['buttonList'] = array();
|
||||
if (!empty($config['buttons'])) {
|
||||
$buttons = array();
|
||||
foreach ($config['buttons'] as $plugin) {
|
||||
$buttons = array_merge($buttons, $plugin);
|
||||
}
|
||||
$settings['buttonList'] = array_keys($buttons);
|
||||
}
|
||||
|
||||
// Add editor content stylesheet.
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$css = drupal_get_path('theme', variable_get('theme_default', NULL)) . '/style.css';
|
||||
if (file_exists($css)) {
|
||||
$settings['externalCSS'] = base_path() . $css;
|
||||
}
|
||||
}
|
||||
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))));
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_nicedit_plugins($editor) {
|
||||
return array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
'bold' => t('Bold'), 'italic' => t('Italic'), 'underline' => t('Underline'),
|
||||
'strikethrough' => t('Strike-through'),
|
||||
'left' => t('Align left'), 'center' => t('Align center'), 'right' => t('Align right'),
|
||||
'ul' => t('Bullet list'), 'ol' => t('Numbered list'),
|
||||
'outdent' => t('Outdent'), 'indent' => t('Indent'),
|
||||
'image' => t('Image'),
|
||||
'forecolor' => t('Forecolor'), 'bgcolor' => t('Backcolor'),
|
||||
'superscript' => t('Superscript'), 'subscript' => t('Subscript'),
|
||||
'hr' => t('Horizontal rule'),
|
||||
// @todo New challenge: Optional internal plugins packaged into editor
|
||||
// library.
|
||||
'link' => t('Link'), 'unlink' => t('Unlink'),
|
||||
'fontFormat' => t('HTML block format'), 'fontFamily' => t('Font'), 'fontSize' => t('Font size'),
|
||||
'xhtml' => t('Source code'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,653 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Editor integration functions for TinyMCE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*
|
||||
* @todo wysiwyg_<editor>_alter() to add/inject optional libraries like gzip.
|
||||
*/
|
||||
function wysiwyg_tinymce_editor() {
|
||||
$editor['tinymce'] = array(
|
||||
'title' => 'TinyMCE',
|
||||
'vendor url' => 'http://tinymce.moxiecode.com',
|
||||
'download url' => 'http://tinymce.moxiecode.com/download.php',
|
||||
'library path' => wysiwyg_get_path('tinymce') . '/jscripts/tiny_mce',
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Minified',
|
||||
'files' => array('tiny_mce.js'),
|
||||
),
|
||||
'src' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array('tiny_mce_src.js'),
|
||||
),
|
||||
),
|
||||
'version callback' => 'wysiwyg_tinymce_version',
|
||||
'themes callback' => 'wysiwyg_tinymce_themes',
|
||||
'init callback' => 'wysiwyg_tinymce_init',
|
||||
'settings callback' => 'wysiwyg_tinymce_settings',
|
||||
'plugin callback' => 'wysiwyg_tinymce_plugins',
|
||||
'plugin settings callback' => 'wysiwyg_tinymce_plugin_settings',
|
||||
'proxy plugin' => array(
|
||||
'drupal' => array(
|
||||
'load' => TRUE,
|
||||
'proxy' => TRUE,
|
||||
),
|
||||
),
|
||||
'proxy plugin settings callback' => 'wysiwyg_tinymce_proxy_plugin_settings',
|
||||
'versions' => array(
|
||||
'2.1' => array(
|
||||
'js files' => array('tinymce-2.js'),
|
||||
'css files' => array('tinymce-2.css'),
|
||||
'download url' => 'http://sourceforge.net/project/showfiles.php?group_id=103281&package_id=111430&release_id=557383',
|
||||
),
|
||||
// @todo Starting from 3.3, tiny_mce.js may support JS aggregation.
|
||||
'3.1' => array(
|
||||
'js files' => array('tinymce-3.js'),
|
||||
'css files' => array('tinymce-3.css'),
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Minified',
|
||||
'files' => array(
|
||||
'tiny_mce.js' => array('preprocess' => FALSE),
|
||||
),
|
||||
),
|
||||
'jquery' => array(
|
||||
'title' => 'jQuery',
|
||||
'files' => array('tiny_mce_jquery.js'),
|
||||
),
|
||||
'src' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array('tiny_mce_src.js'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
* @param $editor
|
||||
* An array containing editor properties as returned from hook_editor().
|
||||
*
|
||||
* @return
|
||||
* The installed editor version.
|
||||
*/
|
||||
function wysiwyg_tinymce_version($editor) {
|
||||
$script = $editor['library path'] . '/tiny_mce.js';
|
||||
if (!file_exists($script)) {
|
||||
return;
|
||||
}
|
||||
$script = fopen($script, 'r');
|
||||
// Version is contained in the first 200 chars.
|
||||
$line = fgets($script, 200);
|
||||
fclose($script);
|
||||
// 2.x: this.majorVersion="2";this.minorVersion="1.3"
|
||||
// 3.x: majorVersion:'3',minorVersion:'2.0.1'
|
||||
if (preg_match('@majorVersion[=:]["\'](\d).+?minorVersion[=:]["\']([\d\.]+)@', $line, $version)) {
|
||||
return $version[1] . '.' . $version[2];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_tinymce_themes($editor, $profile) {
|
||||
/*
|
||||
$themes = array();
|
||||
$dir = $editor['library path'] . '/themes/';
|
||||
if (is_dir($dir) && $dh = opendir($dir)) {
|
||||
while (($file = readdir($dh)) !== FALSE) {
|
||||
if (!in_array($file, array('.', '..', 'CVS', '.svn')) && is_dir($dir . $file)) {
|
||||
$themes[$file] = $file;
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
asort($themes);
|
||||
}
|
||||
return $themes;
|
||||
*/
|
||||
return array('advanced', 'simple');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an initialization JavaScript for this editor library.
|
||||
*
|
||||
* @param array $editor
|
||||
* The editor library definition.
|
||||
* @param string $library
|
||||
* The library variant key from $editor['libraries'].
|
||||
* @param object $profile
|
||||
* The (first) wysiwyg editor profile.
|
||||
*
|
||||
* @return string
|
||||
* A string containing inline JavaScript to execute before the editor library
|
||||
* script is loaded.
|
||||
*/
|
||||
function wysiwyg_tinymce_init($editor, $library) {
|
||||
// TinyMCE unconditionally searches for its library filename in SCRIPT tags on
|
||||
// on the page upon loading the library in order to determine the base path to
|
||||
// itself. When JavaScript aggregation is enabled, this search fails and all
|
||||
// relative constructed paths within TinyMCE are broken. The library has a
|
||||
// tinyMCE.baseURL property, but it is not publicly documented and thus not
|
||||
// reliable. The official support forum suggests to solve the issue through
|
||||
// the global window.tinyMCEPreInit variable also used by various serverside
|
||||
// compressor scrips available from the official website.
|
||||
// @see http://www.tinymce.com/forum/viewtopic.php?id=23286
|
||||
$settings = drupal_json_encode(array(
|
||||
'base' => base_path() . $editor['library path'],
|
||||
'suffix' => (strpos($library, 'src') !== FALSE || strpos($library, 'dev') !== FALSE ? '_src' : ''),
|
||||
'query' => '',
|
||||
));
|
||||
return <<<EOL
|
||||
window.tinyMCEPreInit = $settings;
|
||||
EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_tinymce_settings($editor, $config, $theme) {
|
||||
$settings = array(
|
||||
'button_tile_map' => TRUE, // @todo Add a setting for this.
|
||||
'document_base_url' => base_path(),
|
||||
'mode' => 'none',
|
||||
'plugins' => array(),
|
||||
#'theme' => $theme,
|
||||
'theme' => 'advanced',
|
||||
'skin' => 'o2k7',
|
||||
'skin_variant' => "silver",
|
||||
'width' => '100%',
|
||||
// Strict loading mode must be enabled; otherwise TinyMCE would use
|
||||
// document.write() in IE and Chrome.
|
||||
'strict_loading_mode' => TRUE,
|
||||
// TinyMCE's URL conversion magic breaks Drupal modules that use a special
|
||||
// syntax for paths. This makes 'relative_urls' obsolete.
|
||||
'convert_urls' => FALSE,
|
||||
// The default entity_encoding ('named') converts too many characters in
|
||||
// languages (like Greek). Since Drupal supports Unicode, we only convert
|
||||
// HTML control characters and invisible characters. TinyMCE always converts
|
||||
// XML default characters '&', '<', '>'.
|
||||
'entities' => '160,nbsp,173,shy,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm',
|
||||
);
|
||||
if (isset($config['apply_source_formatting'])) {
|
||||
$settings['apply_source_formatting'] = $config['apply_source_formatting'];
|
||||
}
|
||||
if (isset($config['convert_fonts_to_spans'])) {
|
||||
$settings['convert_fonts_to_spans'] = $config['convert_fonts_to_spans'];
|
||||
}
|
||||
if (isset($config['language'])) {
|
||||
$settings['language'] = $config['language'];
|
||||
}
|
||||
if (isset($config['paste_auto_cleanup_on_paste'])) {
|
||||
$settings['paste_auto_cleanup_on_paste'] = $config['paste_auto_cleanup_on_paste'];
|
||||
}
|
||||
if (isset($config['preformatted'])) {
|
||||
$settings['preformatted'] = $config['preformatted'];
|
||||
}
|
||||
if (isset($config['remove_linebreaks'])) {
|
||||
$settings['remove_linebreaks'] = $config['remove_linebreaks'];
|
||||
}
|
||||
if (isset($config['verify_html'])) {
|
||||
// TinyMCE performs a type-agnostic comparison on this particular setting.
|
||||
$settings['verify_html'] = (bool) $config['verify_html'];
|
||||
}
|
||||
|
||||
if (!empty($config['css_classes'])) {
|
||||
$settings['theme_advanced_styles'] = implode(';', array_filter(explode("\n", str_replace("\r", '', $config['css_classes']))));
|
||||
}
|
||||
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['content_css'] = implode(',', wysiwyg_get_css());
|
||||
}
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['content_css'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
}
|
||||
}
|
||||
|
||||
// Find the enabled buttons and the button row they belong on.
|
||||
// Also map the plugin metadata for each button.
|
||||
// @todo What follows is a pain; needs a rewrite.
|
||||
// $settings['buttons'] are stacked into $settings['theme_advanced_buttons1']
|
||||
// later.
|
||||
$settings['buttons'] = array();
|
||||
if (!empty($config['buttons']) && is_array($config['buttons'])) {
|
||||
// Only array keys in $settings['extensions'] matter; added to
|
||||
// $settings['plugins'] later.
|
||||
$settings['extensions'] = array();
|
||||
// $settings['extended_valid_elements'] are just stacked, unique'd later,
|
||||
// and transformed into a comma-separated string in
|
||||
// wysiwyg_add_editor_settings().
|
||||
// @todo Needs a complete plugin API redesign using arrays for
|
||||
// tag => attributes definitions and array_merge_recursive().
|
||||
$settings['extended_valid_elements'] = array();
|
||||
|
||||
$plugins = wysiwyg_get_plugins($editor['name']);
|
||||
foreach ($config['buttons'] as $plugin => $buttons) {
|
||||
foreach ($buttons as $button => $enabled) {
|
||||
// Iterate separately over buttons and extensions properties.
|
||||
foreach (array('buttons', 'extensions') as $type) {
|
||||
// Skip unavailable plugins.
|
||||
if (!isset($plugins[$plugin][$type][$button])) {
|
||||
continue;
|
||||
}
|
||||
// Add buttons.
|
||||
if ($type == 'buttons') {
|
||||
$settings['buttons'][] = $button;
|
||||
}
|
||||
// Add external Drupal plugins to the list of extensions.
|
||||
if ($type == 'buttons' && !empty($plugins[$plugin]['proxy'])) {
|
||||
$settings['extensions'][_wysiwyg_tinymce_plugin_name('add', $button)] = 1;
|
||||
}
|
||||
// Add external plugins to the list of extensions.
|
||||
elseif ($type == 'buttons' && empty($plugins[$plugin]['internal'])) {
|
||||
$settings['extensions'][_wysiwyg_tinymce_plugin_name('add', $plugin)] = 1;
|
||||
}
|
||||
// Add internal buttons that also need to be loaded as extension.
|
||||
elseif ($type == 'buttons' && !empty($plugins[$plugin]['load'])) {
|
||||
$settings['extensions'][$plugin] = 1;
|
||||
}
|
||||
// Add plain extensions.
|
||||
elseif ($type == 'extensions' && !empty($plugins[$plugin]['load'])) {
|
||||
$settings['extensions'][$plugin] = 1;
|
||||
}
|
||||
// Allow plugins to add valid HTML elements.
|
||||
if (!empty($plugins[$plugin]['extended_valid_elements'])) {
|
||||
$settings['extended_valid_elements'] = array_merge($settings['extended_valid_elements'], $plugins[$plugin]['extended_valid_elements']);
|
||||
}
|
||||
// Allow plugins to add or override global configuration settings.
|
||||
if (!empty($plugins[$plugin]['options'])) {
|
||||
$settings = array_merge($settings, $plugins[$plugin]['options']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Clean-up.
|
||||
$settings['extended_valid_elements'] = array_unique($settings['extended_valid_elements']);
|
||||
if ($settings['extensions']) {
|
||||
$settings['plugins'] = array_keys($settings['extensions']);
|
||||
}
|
||||
unset($settings['extensions']);
|
||||
}
|
||||
|
||||
// Add theme-specific settings.
|
||||
switch ($theme) {
|
||||
case 'advanced':
|
||||
$settings += array(
|
||||
'theme_advanced_resize_horizontal' => FALSE,
|
||||
'theme_advanced_resizing_use_cookie' => FALSE,
|
||||
'theme_advanced_statusbar_location' => isset($config['path_loc']) ? $config['path_loc'] : 'bottom',
|
||||
'theme_advanced_resizing' => isset($config['resizing']) ? $config['resizing'] : 1,
|
||||
'theme_advanced_toolbar_location' => isset($config['toolbar_loc']) ? $config['toolbar_loc'] : 'top',
|
||||
'theme_advanced_toolbar_align' => isset($config['toolbar_align']) ? $config['toolbar_align'] : 'left',
|
||||
);
|
||||
if (isset($config['block_formats'])) {
|
||||
$settings['theme_advanced_blockformats'] = $config['block_formats'];
|
||||
}
|
||||
if (isset($settings['buttons'])) {
|
||||
// These rows explicitly need to be set to be empty, otherwise TinyMCE
|
||||
// loads its default buttons of the advanced theme for each row.
|
||||
$settings += array(
|
||||
'theme_advanced_buttons1' => array(),
|
||||
'theme_advanced_buttons2' => array(),
|
||||
'theme_advanced_buttons3' => array(),
|
||||
);
|
||||
// @todo Allow to sort/arrange editor buttons.
|
||||
for ($i = 0; $i < count($settings['buttons']); $i++) {
|
||||
$settings['theme_advanced_buttons1'][] = $settings['buttons'][$i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
unset($settings['buttons']);
|
||||
|
||||
// Convert the config values into the form expected by TinyMCE.
|
||||
$csv_settings = array('plugins', 'extended_valid_elements', 'theme_advanced_buttons1', 'theme_advanced_buttons2', 'theme_advanced_buttons3');
|
||||
foreach ($csv_settings as $key) {
|
||||
if (isset($settings[$key]) && is_array($settings[$key])) {
|
||||
$settings[$key] = implode(',', $settings[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array of native external plugins that need to be loaded separately.
|
||||
*
|
||||
* TinyMCE requires that external plugins (i.e. not residing in the editor's
|
||||
* directory) are loaded (once) upon initializing the editor.
|
||||
*/
|
||||
function wysiwyg_tinymce_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['filename'])) {
|
||||
$settings[$name] = base_path() . $plugin['path'] . '/' . $plugin['filename'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array for Drupal plugins loaded via the proxy plugin.
|
||||
*/
|
||||
function wysiwyg_tinymce_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'],
|
||||
);
|
||||
if (isset($plugin['css file'])) {
|
||||
$settings[$name]['css'] = base_path() . $plugin['css path'] . '/' . $plugin['css file'];
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or remove leading hiven to/of external plugin names.
|
||||
*
|
||||
* TinyMCE requires that external plugins, which should not be loaded from
|
||||
* its own plugin repository are prefixed with a hiven in the name.
|
||||
*
|
||||
* @param string $op
|
||||
* Operation to perform, 'add' or 'remove' (hiven).
|
||||
* @param string $name
|
||||
* A plugin name.
|
||||
*/
|
||||
function _wysiwyg_tinymce_plugin_name($op, $name) {
|
||||
if ($op == 'add') {
|
||||
if (strpos($name, '-') !== 0) {
|
||||
return '-' . $name;
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
elseif ($op == 'remove') {
|
||||
if (strpos($name, '-') === 0) {
|
||||
return substr($name, 1);
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_tinymce_plugins($editor) {
|
||||
$plugins = array(
|
||||
'default' => array(
|
||||
'path' => $editor['library path'] . '/themes/advanced',
|
||||
'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'),
|
||||
'bullist' => t('Bullet list'), 'numlist' => 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'),
|
||||
'cleanup' => t('Clean-up'),
|
||||
'formatselect' => t('Block format'), 'styleselect' => t('Styles'),
|
||||
'fontselect' => t('Font'), 'fontsizeselect' => t('Font size'),
|
||||
'forecolor' => t('Forecolor'), 'backcolor' => t('Backcolor'),
|
||||
'sup' => t('Superscript'), 'sub' => t('Subscript'),
|
||||
'blockquote' => t('Blockquote'), 'code' => 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'),
|
||||
'help' => t('Help'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
),
|
||||
'advhr' => array(
|
||||
'path' => $editor['library path'] . '/plugins/advhr',
|
||||
'buttons' => array('advhr' => t('Advanced horizontal rule')),
|
||||
'extended_valid_elements' => array('hr[class|width|size|noshade]'),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:advhr',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'advimage' => array(
|
||||
'path' => $editor['library path'] . '/plugins/advimage',
|
||||
'extensions' => array('advimage' => t('Advanced image')),
|
||||
'extended_valid_elements' => array('img[src|alt|title|align|width|height|usemap|hspace|vspace|border|style|class|onmouseover|onmouseout|id|name|longdesc]'),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:advimage',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'advlink' => array(
|
||||
'path' => $editor['library path'] . '/plugins/advlink',
|
||||
'extensions' => array('advlink' => t('Advanced link')),
|
||||
'extended_valid_elements' => array('a[name|href|target|title|class|onfocus|onblur|onclick|ondlbclick|onmousedown|onmouseup|onmouseover|onmouseout|onkeypress|onkeydown|onkeyup|id|style|rel]'),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:advlink',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'autosave' => array(
|
||||
'path' => $editor['library path'] . '/plugins/autosave',
|
||||
'extensions' => array('autosave' => t('Auto save')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:autosave',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'contextmenu' => array(
|
||||
'path' => $editor['library path'] . '/plugins/contextmenu',
|
||||
'extensions' => array('contextmenu' => t('Context menu')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:contextmenu',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'directionality' => array(
|
||||
'path' => $editor['library path'] . '/plugins/directionality',
|
||||
'buttons' => array('ltr' => t('Left-to-right'), 'rtl' => t('Right-to-left')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:directionality',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'emotions' => array(
|
||||
'path' => $editor['library path'] . '/plugins/emotions',
|
||||
'buttons' => array('emotions' => t('Emotions')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:emotions',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'fullscreen' => array(
|
||||
'path' => $editor['library path'] . '/plugins/fullscreen',
|
||||
'buttons' => array('fullscreen' => t('Fullscreen')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:fullscreen',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'inlinepopups' => array(
|
||||
'path' => $editor['library path'] . '/plugins/inlinepopups',
|
||||
'extensions' => array('inlinepopups' => t('Inline popups')),
|
||||
'options' => array(
|
||||
'dialog_type' => array('modal'),
|
||||
),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:inlinepopups',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'insertdatetime' => array(
|
||||
'path' => $editor['library path'] . '/plugins/insertdatetime',
|
||||
'buttons' => array('insertdate' => t('Insert date'), 'inserttime' => t('Insert time')),
|
||||
'options' => array(
|
||||
'plugin_insertdate_dateFormat' => '%Y-%m-%d',
|
||||
'plugin_insertdate_timeFormat' => '%H:%M:%S',
|
||||
),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:insertdatetime',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'layer' => array(
|
||||
'path' => $editor['library path'] . '/plugins/layer',
|
||||
'buttons' => array('insertlayer' => t('Insert layer'), 'moveforward' => t('Move forward'), 'movebackward' => t('Move backward'), 'absolute' => t('Absolute')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:layer',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'paste' => array(
|
||||
'path' => $editor['library path'] . '/plugins/paste',
|
||||
'buttons' => array('pastetext' => t('Paste text'), 'pasteword' => t('Paste from Word'), 'selectall' => t('Select all')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:paste',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'preview' => array(
|
||||
'path' => $editor['library path'] . '/plugins/preview',
|
||||
'buttons' => array('preview' => t('Preview')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:preview',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'print' => array(
|
||||
'path' => $editor['library path'] . '/plugins/print',
|
||||
'buttons' => array('print' => t('Print')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:print',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'searchreplace' => array(
|
||||
'path' => $editor['library path'] . '/plugins/searchreplace',
|
||||
'buttons' => array('search' => t('Search'), 'replace' => t('Replace')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:searchreplace',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'style' => array(
|
||||
'path' => $editor['library path'] . '/plugins/style',
|
||||
'buttons' => array('styleprops' => t('Advanced CSS styles')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:style',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'table' => array(
|
||||
'path' => $editor['library path'] . '/plugins/table',
|
||||
'buttons' => array('tablecontrols' => t('Table')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:table',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
);
|
||||
if (version_compare($editor['installed version'], '3', '<')) {
|
||||
$plugins['flash'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/flash',
|
||||
'buttons' => array('flash' => t('Flash')),
|
||||
'extended_valid_elements' => array('img[class|src|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name|obj|param|embed]'),
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
}
|
||||
if (version_compare($editor['installed version'], '2.0.6', '>')) {
|
||||
$plugins['media'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/media',
|
||||
'buttons' => array('media' => t('Media')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:media',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
$plugins['xhtmlxtras'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/xhtmlxtras',
|
||||
'buttons' => array('cite' => t('Citation'), 'del' => t('Deleted'), 'abbr' => t('Abbreviation'), 'acronym' => t('Acronym'), 'ins' => t('Inserted'), 'attribs' => t('HTML attributes')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:xhtmlxtras',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
}
|
||||
if (version_compare($editor['installed version'], '3', '>')) {
|
||||
$plugins['bbcode'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/bbcode',
|
||||
'extensions' => array('bbcode' => t('BBCode')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:bbcode',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
if (version_compare($editor['installed version'], '3.3', '<')) {
|
||||
$plugins['safari'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/safari',
|
||||
'extensions' => array('safari' => t('Safari compatibility')),
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (version_compare($editor['installed version'], '3.2.5', '>=')) {
|
||||
$plugins['autoresize'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/autoresize',
|
||||
'extensions' => array('autoresize' => t('Auto resize')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:autoresize',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
}
|
||||
if (version_compare($editor['installed version'], '3.3', '>=')) {
|
||||
$plugins['advlist'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/advlist',
|
||||
'extensions' => array('advlist' => t('Advanced list')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:advlist',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
}
|
||||
if (version_compare($editor['installed version'], '3.2.6', '>=')) {
|
||||
$plugins['wordcount'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/wordcount',
|
||||
'extensions' => array('wordcount' => t('Word count')),
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
}
|
||||
if (version_compare($editor['installed version'], '3.4.1', '>=')) {
|
||||
$plugins['lists'] = array(
|
||||
'path' => $editor['library path'] . 'plugins/lists',
|
||||
'extensions' => array('lists' => t('List normalizer')),
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:lists',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
'extended_valid_elements' => array(
|
||||
'li[class|dir|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|type|value]',
|
||||
'ol[class|compact|dir|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|start|style|title|type]',
|
||||
'ul[class|compact|dir|id|lang|onclick|ondblclick|onkeydown|onkeypress|onkeyup|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup|style|title|type]',
|
||||
),
|
||||
);
|
||||
}
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Editor integration functions for Whizzywig.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*/
|
||||
function wysiwyg_whizzywig_editor() {
|
||||
$editor['whizzywig'] = array(
|
||||
'title' => 'Whizzywig',
|
||||
'vendor url' => 'http://www.unverse.net',
|
||||
'download url' => 'http://www.unverse.net/whizzywig-download.html',
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Default',
|
||||
'files' => array('whizzywig.js', 'xhtml.js'),
|
||||
),
|
||||
),
|
||||
'version callback' => 'wysiwyg_whizzywig_version',
|
||||
'settings callback' => 'wysiwyg_whizzywig_settings',
|
||||
'plugin callback' => 'wysiwyg_whizzywig_plugins',
|
||||
'versions' => array(
|
||||
'55' => array(
|
||||
'js files' => array('whizzywig.js'),
|
||||
),
|
||||
'56' => array(
|
||||
'js files' => array('whizzywig-56.js'),
|
||||
),
|
||||
'60' => array(
|
||||
'js files' => array('whizzywig-60.js'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
* @param $editor
|
||||
* An array containing editor properties as returned from hook_editor().
|
||||
*
|
||||
* @return
|
||||
* The installed editor version.
|
||||
*/
|
||||
function wysiwyg_whizzywig_version($editor) {
|
||||
$script = $editor['library path'] . '/whizzywig.js';
|
||||
if (!file_exists($script)) {
|
||||
return;
|
||||
}
|
||||
$script = fopen($script, 'r');
|
||||
$line = fgets($script, 43);
|
||||
// 55: Whizzywig v55i
|
||||
// 60: Whizzywig 60
|
||||
if (preg_match('@Whizzywig v?([0-9]+)@', $line, $version)) {
|
||||
fclose($script);
|
||||
return $version[1];
|
||||
}
|
||||
fclose($script);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_whizzywig_settings($editor, $config, $theme) {
|
||||
$settings = array();
|
||||
|
||||
// Add path to button images, if available.
|
||||
if (is_dir($editor['library path'] . '/btn')) {
|
||||
$settings['buttonPath'] = base_path() . $editor['library path'] . '/btn/';
|
||||
}
|
||||
if (file_exists($editor['library path'] . '/WhizzywigToolbar.png')) {
|
||||
$settings['toolbarImagePath'] = base_path() . $editor['library path'] . '/WhizzywigToolbar.png';
|
||||
}
|
||||
// Filename changed in version 60.
|
||||
elseif (file_exists($editor['library path'] . '/icons.png')) {
|
||||
$settings['toolbarImagePath'] = base_path() . $editor['library path'] . '/icons.png';
|
||||
}
|
||||
|
||||
// Add configured buttons or all available.
|
||||
$settings['buttons'] = array();
|
||||
if (!empty($config['buttons'])) {
|
||||
$buttons = array();
|
||||
foreach ($config['buttons'] as $plugin) {
|
||||
$buttons = array_merge($buttons, $plugin);
|
||||
}
|
||||
$settings['buttons'] = implode(' ', array_keys($buttons));
|
||||
}
|
||||
|
||||
// Add editor content stylesheet.
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$css = drupal_get_path('theme', variable_get('theme_default', NULL)) . '/style.css';
|
||||
if (file_exists($css)) {
|
||||
$settings['externalCSS'] = base_path() . $css;
|
||||
}
|
||||
}
|
||||
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))));
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_whizzywig_plugins($editor) {
|
||||
return array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
'formatblock' => t('HTML block format'), 'fontname' => t('Font'), 'fontsize' => t('Font size'),
|
||||
'bold' => t('Bold'), 'italic' => t('Italic'), 'underline' => t('Underline'),
|
||||
'left' => t('Align left'), 'center' => t('Align center'), 'right' => t('Align right'),
|
||||
'bullet' => t('Bullet list'), 'number' => t('Numbered list'),
|
||||
'outdent' => t('Outdent'), 'indent' => t('Indent'),
|
||||
'undo' => t('Undo'), 'redo' => t('Redo'),
|
||||
'image' => t('Image'),
|
||||
'color' => t('Forecolor'), 'hilite' => t('Backcolor'),
|
||||
'rule' => t('Horizontal rule'),
|
||||
'link' => t('Link'),
|
||||
'image' => t('Image'),
|
||||
'table' => t('Table'),
|
||||
'clean' => t('Clean-up'),
|
||||
'html' => t('Source code'),
|
||||
'spellcheck' => t('Spell check'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,234 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Editor integration functions for WYMeditor.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*/
|
||||
function wysiwyg_wymeditor_editor() {
|
||||
$editor['wymeditor'] = array(
|
||||
'title' => 'WYMeditor',
|
||||
'vendor url' => 'http://www.wymeditor.org/',
|
||||
'download url' => 'http://www.wymeditor.org/download/',
|
||||
'library path' => wysiwyg_get_path('wymeditor') . '/wymeditor',
|
||||
'libraries' => array(
|
||||
'min' => array(
|
||||
'title' => 'Minified',
|
||||
'files' => array('jquery.wymeditor.min.js'),
|
||||
),
|
||||
'pack' => array(
|
||||
'title' => 'Packed',
|
||||
'files' => array('jquery.wymeditor.pack.js'),
|
||||
),
|
||||
'src' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array('jquery.wymeditor.js'),
|
||||
),
|
||||
),
|
||||
'version callback' => 'wysiwyg_wymeditor_version',
|
||||
'themes callback' => 'wysiwyg_wymeditor_themes',
|
||||
'settings callback' => 'wysiwyg_wymeditor_settings',
|
||||
'plugin callback' => 'wysiwyg_wymeditor_plugins',
|
||||
'versions' => array(
|
||||
'0.5-rc1' => array(
|
||||
'js files' => array('wymeditor.js'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
* @param $editor
|
||||
* An array containing editor properties as returned from hook_editor().
|
||||
*
|
||||
* @return
|
||||
* The installed editor version.
|
||||
*/
|
||||
function wysiwyg_wymeditor_version($editor) {
|
||||
$script = $editor['library path'] . '/jquery.wymeditor.js';
|
||||
if (!file_exists($script)) {
|
||||
return;
|
||||
}
|
||||
$script = fopen($script, 'r');
|
||||
fgets($script);
|
||||
$line = fgets($script);
|
||||
if (preg_match('@version\s+([0-9a-z\.-]+)@', $line, $version)) {
|
||||
fclose($script);
|
||||
return $version[1];
|
||||
}
|
||||
fclose($script);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_wymeditor_themes($editor, $profile) {
|
||||
return array('compact', 'default', 'minimal', 'silver', 'twopanels');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_wymeditor_settings($editor, $config, $theme) {
|
||||
// @todo Setup $library in wysiwyg_load_editor() already.
|
||||
$library = (isset($editor['library']) ? $editor['library'] : key($editor['libraries']));
|
||||
$settings = array(
|
||||
'basePath' => base_path() . $editor['library path'] . '/',
|
||||
'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',
|
||||
'skin' => $theme,
|
||||
);
|
||||
|
||||
if (isset($config['language'])) {
|
||||
$settings['lang'] = $config['language'];
|
||||
}
|
||||
|
||||
// Add configured buttons.
|
||||
$settings['toolsItems'] = array();
|
||||
if (!empty($config['buttons'])) {
|
||||
$buttoninfo = _wysiwyg_wymeditor_button_info();
|
||||
$plugins = wysiwyg_get_plugins($editor['name']);
|
||||
foreach ($config['buttons'] as $plugin => $buttons) {
|
||||
foreach ($buttons as $button => $enabled) {
|
||||
// Iterate separately over buttons and extensions properties.
|
||||
foreach (array('buttons', 'extensions') as $type) {
|
||||
// Skip unavailable plugins.
|
||||
if (!isset($plugins[$plugin][$type][$button])) {
|
||||
continue;
|
||||
}
|
||||
// Add buttons.
|
||||
if ($type == 'buttons') {
|
||||
// Merge meta-data for internal default buttons.
|
||||
if (isset($buttoninfo[$button])) {
|
||||
$buttoninfo[$button] += array('name' => $button);
|
||||
$settings['toolsItems'][] = $buttoninfo[$button];
|
||||
}
|
||||
// For custom buttons, try to provide a valid button definition.
|
||||
else {
|
||||
$settings['toolsItems'][] = array(
|
||||
'name' => $button,
|
||||
'title' => $plugins[$plugin][$type][$button],
|
||||
'css' => 'wym_tools_' . $button,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($config['block_formats'])) {
|
||||
$containers = array(
|
||||
'p' => 'Paragraph',
|
||||
'h1' => 'Heading_1',
|
||||
'h2' => 'Heading_2',
|
||||
'h3' => 'Heading_3',
|
||||
'h4' => 'Heading_4',
|
||||
'h5' => 'Heading_5',
|
||||
'h6' => 'Heading_6',
|
||||
'pre' => 'Preformatted',
|
||||
'blockquote' => 'Blockquote',
|
||||
'th' => 'Table_Header',
|
||||
);
|
||||
foreach (explode(',', $config['block_formats']) as $tag) {
|
||||
if (isset($containers[$tag])) {
|
||||
$settings['containersItems'][] = array(
|
||||
'name' => strtoupper($tag),
|
||||
'title' => $containers[$tag],
|
||||
'css' => 'wym_containers_' . $tag,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
// WYMeditor only supports one CSS file currently.
|
||||
$css = wysiwyg_get_css();
|
||||
$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))));
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_wymeditor_plugins($editor) {
|
||||
$plugins = array(
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
'Bold' => t('Bold'), 'Italic' => t('Italic'),
|
||||
'InsertOrderedList' => t('Numbered list'), 'InsertUnorderedList' => t('Bullet list'),
|
||||
'Outdent' => t('Outdent'), 'Indent' => t('Indent'),
|
||||
'Undo' => t('Undo'), 'Redo' => t('Redo'),
|
||||
'CreateLink' => t('Link'), 'Unlink' => t('Unlink'),
|
||||
'InsertImage' => t('Image'),
|
||||
'Superscript' => t('Superscript'), 'Subscript' => t('Subscript'),
|
||||
'ToggleHtml' => t('Source code'),
|
||||
'Paste' => t('Paste'),
|
||||
'InsertTable' => t('Table'),
|
||||
'Preview' => t('Preview'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
),
|
||||
);
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to provide additional meta-data for internal default buttons.
|
||||
*/
|
||||
function _wysiwyg_wymeditor_button_info() {
|
||||
return array(
|
||||
'Bold' => array('title' => 'Strong', 'css' => 'wym_tools_strong'),
|
||||
'Italic' => array('title' => 'Emphasis', 'css' => 'wym_tools_emphasis'),
|
||||
'Superscript' => array('title' => 'Superscript', 'css' => 'wym_tools_superscript'),
|
||||
'Subscript' => array('title' => 'Subscript', 'css' => 'wym_tools_subscript'),
|
||||
'InsertOrderedList' => array('title' => 'Ordered_List', 'css' => 'wym_tools_ordered_list'),
|
||||
'InsertUnorderedList' => array('title' => 'Unordered_List', 'css' => 'wym_tools_unordered_list'),
|
||||
'Indent' => array('title' => 'Indent', 'css' => 'wym_tools_indent'),
|
||||
'Outdent' => array('title' => 'Outdent', 'css' => 'wym_tools_outdent'),
|
||||
'Undo' => array('title' => 'Undo', 'css' => 'wym_tools_undo'),
|
||||
'Redo' => array('title' => 'Redo', 'css' => 'wym_tools_redo'),
|
||||
'CreateLink' => array('title' => 'Link', 'css' => 'wym_tools_link'),
|
||||
'Unlink' => array('title' => 'Unlink', 'css' => 'wym_tools_unlink'),
|
||||
'InsertImage' => array('title' => 'Image', 'css' => 'wym_tools_image'),
|
||||
'InsertTable' => array('title' => 'Table', 'css' => 'wym_tools_table'),
|
||||
'Paste' => array('title' => 'Paste_From_Word', 'css' => 'wym_tools_paste'),
|
||||
'ToggleHtml' => array('title' => 'HTML', 'css' => 'wym_tools_html'),
|
||||
'Preview' => array('title' => 'Preview', 'css' => 'wym_tools_preview'),
|
||||
);
|
||||
}
|
||||
-339
@@ -1,339 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Editor integration functions for YUI editor.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Plugin implementation of hook_editor().
|
||||
*/
|
||||
function wysiwyg_yui_editor() {
|
||||
$editor['yui'] = array(
|
||||
'title' => 'YUI editor',
|
||||
'vendor url' => 'http://developer.yahoo.com/yui/editor/',
|
||||
'download url' => 'http://developer.yahoo.com/yui/download/',
|
||||
'library path' => wysiwyg_get_path('yui') . '/build',
|
||||
'libraries' => array(
|
||||
'min' => array(
|
||||
'title' => 'Minified',
|
||||
'files' => array(
|
||||
'yahoo-dom-event/yahoo-dom-event.js',
|
||||
'animation/animation-min.js',
|
||||
'element/element-min.js',
|
||||
'container/container-min.js',
|
||||
'menu/menu-min.js',
|
||||
'button/button-min.js',
|
||||
'editor/editor-min.js',
|
||||
),
|
||||
),
|
||||
'src' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array(
|
||||
'yahoo-dom-event/yahoo-dom-event.js',
|
||||
'animation/animation.js',
|
||||
'element/element.js',
|
||||
'container/container.js',
|
||||
'menu/menu.js',
|
||||
'button/button.js',
|
||||
'editor/editor.js',
|
||||
),
|
||||
),
|
||||
),
|
||||
'version callback' => 'wysiwyg_yui_version',
|
||||
'themes callback' => 'wysiwyg_yui_themes',
|
||||
'load callback' => 'wysiwyg_yui_load',
|
||||
'settings callback' => 'wysiwyg_yui_settings',
|
||||
'plugin callback' => 'wysiwyg_yui_plugins',
|
||||
'plugin settings callback' => 'wysiwyg_yui_plugin_settings',
|
||||
'proxy plugin' => array(
|
||||
'drupal' => array(
|
||||
'load' => TRUE,
|
||||
'proxy' => TRUE,
|
||||
),
|
||||
),
|
||||
'proxy plugin settings callback' => 'wysiwyg_yui_proxy_plugin_settings',
|
||||
'versions' => array(
|
||||
'2.7.0' => array(
|
||||
'js files' => array('yui.js'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect editor version.
|
||||
*
|
||||
* @param $editor
|
||||
* An array containing editor properties as returned from hook_editor().
|
||||
*
|
||||
* @return
|
||||
* The installed editor version.
|
||||
*/
|
||||
function wysiwyg_yui_version($editor) {
|
||||
$library = $editor['library path'] . '/editor/editor.js';
|
||||
if (!file_exists($library)) {
|
||||
return;
|
||||
}
|
||||
$library = fopen($library, 'r');
|
||||
$max_lines = 10;
|
||||
while ($max_lines && $line = fgets($library, 60)) {
|
||||
if (preg_match('@version:\s([0-9\.]+)@', $line, $version)) {
|
||||
fclose($library);
|
||||
return $version[1];
|
||||
}
|
||||
$max_lines--;
|
||||
}
|
||||
fclose($library);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_yui_themes($editor, $profile) {
|
||||
return array('sam');
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform additional actions upon loading this editor.
|
||||
*
|
||||
* @param $editor
|
||||
* A processed hook_editor() array of editor properties.
|
||||
* @param $library
|
||||
* The internal library name (array key) to use.
|
||||
*/
|
||||
function wysiwyg_yui_load($editor, $library) {
|
||||
drupal_add_css($editor['library path'] . '/menu/assets/skins/sam/menu.css');
|
||||
drupal_add_css($editor['library path'] . '/button/assets/skins/sam/button.css');
|
||||
drupal_add_css($editor['library path'] . '/fonts/fonts-min.css');
|
||||
drupal_add_css($editor['library path'] . '/container/assets/skins/sam/container.css');
|
||||
drupal_add_css($editor['library path'] . '/editor/assets/skins/sam/editor.css');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_yui_settings($editor, $config, $theme) {
|
||||
$settings = array(
|
||||
'theme' => $theme,
|
||||
'animate' => TRUE,
|
||||
'handleSubmit' => TRUE,
|
||||
'markup' => 'xhtml',
|
||||
'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'])) {
|
||||
$settings['autoHeight'] = TRUE;
|
||||
}
|
||||
|
||||
$settings += array(
|
||||
'toolbar' => array(
|
||||
'collapse' => FALSE,
|
||||
'draggable' => TRUE,
|
||||
'buttonType' => 'advanced',
|
||||
'buttons' => array(),
|
||||
),
|
||||
);
|
||||
if (!empty($config['buttons'])) {
|
||||
$buttons = array();
|
||||
foreach ($config['buttons'] as $plugin => $enabled_buttons) {
|
||||
foreach ($enabled_buttons as $button => $enabled) {
|
||||
$extra = array();
|
||||
if ($button == 'heading') {
|
||||
$extra = array('menu' => array(
|
||||
array('text' => 'Normal', 'value' => 'none', 'checked' => TRUE),
|
||||
));
|
||||
if (!empty($config['block_formats'])) {
|
||||
$headings = array(
|
||||
'p' => array('text' => 'Paragraph', 'value' => 'p'),
|
||||
'h1' => array('text' => 'Heading 1', 'value' => 'h1'),
|
||||
'h2' => array('text' => 'Heading 2', 'value' => 'h2'),
|
||||
'h3' => array('text' => 'Heading 3', 'value' => 'h3'),
|
||||
'h4' => array('text' => 'Heading 4', 'value' => 'h4'),
|
||||
'h5' => array('text' => 'Heading 5', 'value' => 'h5'),
|
||||
'h6' => array('text' => 'Heading 6', 'value' => 'h6'),
|
||||
);
|
||||
foreach (explode(',', $config['block_formats']) as $tag) {
|
||||
if (isset($headings[$tag])) {
|
||||
$extra['menu'][] = $headings[$tag];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($button == 'fontname') {
|
||||
$extra = array('menu' => array(
|
||||
array('text' => 'Arial', 'checked' => TRUE),
|
||||
array('text' => 'Arial Black'),
|
||||
array('text' => 'Comic Sans MS'),
|
||||
array('text' => 'Courier New'),
|
||||
array('text' => 'Lucida Console'),
|
||||
array('text' => 'Tahoma'),
|
||||
array('text' => 'Times New Roman'),
|
||||
array('text' => 'Trebuchet MS'),
|
||||
array('text' => 'Verdana'),
|
||||
));
|
||||
}
|
||||
$buttons[] = wysiwyg_yui_button_setting($editor, $plugin, $button, $extra);
|
||||
}
|
||||
}
|
||||
// Group buttons in a dummy group.
|
||||
$buttons = array('group' => 'default', 'label' => '', 'buttons' => $buttons);
|
||||
$settings['toolbar']['buttons'] = array($buttons);
|
||||
}
|
||||
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['extracss'] = wysiwyg_get_css();
|
||||
}
|
||||
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'] = explode(',', $settings['extracss']);
|
||||
}
|
||||
// YUI only supports inline CSS, so we need to use @import directives.
|
||||
// Syntax: '@import "/base/path/to/theme/style.css"; '
|
||||
if (!empty($settings['extracss'])) {
|
||||
$settings['extracss'] = '@import "' . implode('"; @import "', $settings['extracss']) . '";';
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the JavaScript structure for a YUI button.
|
||||
*
|
||||
* @param $editor
|
||||
* A processed hook_editor() array of editor properties.
|
||||
* @param $plugin
|
||||
* The internal name of a plugin.
|
||||
* @param $button
|
||||
* The internal name of a button, defined by $plugin.
|
||||
* @param $extra
|
||||
* (optional) An array containing arbitrary other elements to add to the
|
||||
* resulting button.
|
||||
*/
|
||||
function wysiwyg_yui_button_setting($editor, $plugin, $button, $extra = array()) {
|
||||
static $plugins;
|
||||
|
||||
if (!isset($plugins)) {
|
||||
$plugins = wysiwyg_get_plugins($editor['name']);
|
||||
}
|
||||
|
||||
// Return a simple separator.
|
||||
if ($button === 'separator') {
|
||||
return array('type' => 'separator');
|
||||
}
|
||||
// Setup defaults.
|
||||
$type = 'push';
|
||||
$label = $plugins[$plugin]['buttons'][$button];
|
||||
|
||||
// Special handling for certain buttons.
|
||||
if (in_array($button, array('heading', 'fontname'))) {
|
||||
$type = 'select';
|
||||
$label = $extra['menu'][0]['text'];
|
||||
}
|
||||
elseif (in_array($button, array('fontsize'))) {
|
||||
$type = 'spin';
|
||||
}
|
||||
elseif (in_array($button, array('forecolor', 'backcolor'))) {
|
||||
$type = 'color';
|
||||
}
|
||||
|
||||
$button = array(
|
||||
'type' => $type,
|
||||
'label' => $label,
|
||||
'value' => $button,
|
||||
);
|
||||
// Add arbitrary other elements, if defined.
|
||||
if (!empty($extra)) {
|
||||
$button = array_merge($button, $extra);
|
||||
}
|
||||
return $button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array of native external plugins that need to be loaded separately.
|
||||
*/
|
||||
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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a JS settings array for Drupal plugins loaded via the proxy plugin.
|
||||
*/
|
||||
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'],
|
||||
);
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return internal plugins for this editor; semi-implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_yui_plugins($editor) {
|
||||
return 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'),
|
||||
'insertunorderedlist' => t('Bullet list'), 'insertorderedlist' => t('Numbered list'),
|
||||
'outdent' => t('Outdent'), 'indent' => t('Indent'),
|
||||
'undo' => t('Undo'), 'redo' => t('Redo'),
|
||||
'createlink' => t('Link'),
|
||||
'insertimage' => t('Image'),
|
||||
'forecolor' => t('Font Color'), 'backcolor' => t('Background Color'),
|
||||
'superscript' => t('Sup'), 'subscript' => t('Sub'),
|
||||
'hiddenelements' => t('Show/hide hidden elements'),
|
||||
'removeformat' => t('Remove format'),
|
||||
'heading' => t('HTML block format'), 'fontname' => t('Font'), 'fontsize' => t('Font size'),
|
||||
),
|
||||
'internal' => TRUE,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Wysiwyg API integration on behalf of Node module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of hook_wysiwyg_plugin().
|
||||
*/
|
||||
function wysiwyg_break_plugin() {
|
||||
$plugins['break'] = array(
|
||||
'title' => t('Teaser break'),
|
||||
'vendor url' => 'http://drupal.org/project/wysiwyg',
|
||||
'icon file' => 'break.gif',
|
||||
'icon title' => t('Separate the teaser and body of this content'),
|
||||
'settings' => array(),
|
||||
);
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
|
||||
.wysiwyg-break {
|
||||
display: block;
|
||||
border: 0;
|
||||
border-top: 1px dotted #ccc;
|
||||
margin-top: 1em;
|
||||
width: 100%;
|
||||
height: 12px;
|
||||
background: transparent url(images/breaktext.gif) no-repeat center top;
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
(function ($) {
|
||||
|
||||
// @todo Array syntax required; 'break' is a predefined token in JavaScript.
|
||||
Drupal.wysiwyg.plugins['break'] = {
|
||||
|
||||
/**
|
||||
* Return whether the passed node belongs to this plugin.
|
||||
*/
|
||||
isNode: function(node) {
|
||||
return ($(node).is('img.wysiwyg-break'));
|
||||
},
|
||||
|
||||
/**
|
||||
* Execute the button.
|
||||
*/
|
||||
invoke: function(data, settings, instanceId) {
|
||||
if (data.format == 'html') {
|
||||
// Prevent duplicating a teaser break.
|
||||
if ($(data.node).is('img.wysiwyg-break')) {
|
||||
return;
|
||||
}
|
||||
var content = this._getPlaceholder(settings);
|
||||
}
|
||||
else {
|
||||
// Prevent duplicating a teaser break.
|
||||
// @todo data.content is the selection only; needs access to complete content.
|
||||
if (data.content.match(/<!--break-->/)) {
|
||||
return;
|
||||
}
|
||||
var content = '<!--break-->';
|
||||
}
|
||||
if (typeof content != 'undefined') {
|
||||
Drupal.wysiwyg.instances[instanceId].insert(content);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Replace all <!--break--> tags with images.
|
||||
*/
|
||||
attach: function(content, settings, instanceId) {
|
||||
content = content.replace(/<!--break-->/g, this._getPlaceholder(settings));
|
||||
return content;
|
||||
},
|
||||
|
||||
/**
|
||||
* Replace images with <!--break--> tags in content upon detaching editor.
|
||||
*/
|
||||
detach: function(content, settings, instanceId) {
|
||||
var $content = $('<div>' + content + '</div>'); // No .outerHTML() in jQuery :(
|
||||
// #404532: document.createComment() required or IE will strip the comment.
|
||||
// #474908: IE 8 breaks when using jQuery methods to replace the elements.
|
||||
// @todo Add a generic implementation for all Drupal plugins for this.
|
||||
$.each($('img.wysiwyg-break', $content), function (i, elem) {
|
||||
elem.parentNode.insertBefore(document.createComment('break'), elem);
|
||||
elem.parentNode.removeChild(elem);
|
||||
});
|
||||
return $content.html();
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper function to return a HTML placeholder.
|
||||
*/
|
||||
_getPlaceholder: function (settings) {
|
||||
return '<img src="' + settings.path + '/images/spacer.gif" alt="<--break->" title="<--break-->" class="wysiwyg-break drupal-content" />';
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 108 B |
Binary file not shown.
|
Before Width: | Height: | Size: 255 B |
Binary file not shown.
|
Before Width: | Height: | Size: 43 B |
@@ -1,6 +0,0 @@
|
||||
|
||||
tinyMCE.addToLang('break', {
|
||||
title: 'Inserir marcador de document retallat',
|
||||
desc: 'Generar el punt de separació entre la versió retallada del document i la resta del contingut'
|
||||
});
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
tinyMCE.addToLang('break', {
|
||||
title: 'Anrisstext trennen',
|
||||
desc: 'Separiert den Anrisstext und Textkörper des Inhalts an dieser Stelle'
|
||||
});
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
tinyMCE.addToLang('break', {
|
||||
title: 'Insert teaser break',
|
||||
desc: 'Separate teaser and body of this content'
|
||||
});
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
tinyMCE.addToLang('break', {
|
||||
title: 'Insertar marcador de documento recortado',
|
||||
desc: 'Generar el punto de separación entre la versión recortada del documento y el resto del contenido'
|
||||
});
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
!!! this module is not ready tu use !!!
|
||||
@@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Tests for Wysiwyg module.
|
||||
*/
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
name = Wysiwyg testing
|
||||
description = Tests Wysiwyg module functionality. Do not enable.
|
||||
core = 7.x
|
||||
package = Testing
|
||||
hidden = TRUE
|
||||
dependencies[] = wysiwyg
|
||||
files[] = wysiwyg_test.module
|
||||
|
||||
; Information added by drupal.org packaging script on 2012-10-02
|
||||
version = "7.x-2.2"
|
||||
core = "7.x"
|
||||
project = "wysiwyg"
|
||||
datestamp = "1349213776"
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Installation functionality for Wysiwyg testing module.
|
||||
*/
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Testing functionality for Wysiwyg module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_menu().
|
||||
*/
|
||||
function wysiwyg_test_menu() {
|
||||
$items['wysiwyg-test/ajax'] = array(
|
||||
'title' => 'Ajaxified form',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('wysiwyg_test_ajax_form'),
|
||||
'access callback' => TRUE,
|
||||
);
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Form constructor for an ajaxified form lazy-loading a textarea.
|
||||
*/
|
||||
function wysiwyg_test_ajax_form($form, &$form_state) {
|
||||
$form['enable'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => 'Load textarea',
|
||||
'#ajax' => array(
|
||||
'callback' => 'wysiwyg_test_ajax_form_callback',
|
||||
'wrapper' => 'ajax-wrapper',
|
||||
),
|
||||
);
|
||||
$form['wrapper'] = array(
|
||||
'#type' => 'container',
|
||||
'#id' => 'ajax-wrapper',
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* #ajax callback for wysiwyg_test_ajax_form().
|
||||
*/
|
||||
function wysiwyg_test_ajax_form_callback($form, &$form_state) {
|
||||
$form['body'] = array(
|
||||
'#type' => 'text_format',
|
||||
'#default_value' => '',
|
||||
);
|
||||
form_builder($form['form_id']['#value'], $form, $form_state);
|
||||
return $form['body'];
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
.ctu-term-edit-form-box{border: 1px solid #ddd; padding:0.5em;}
|
||||
#node-form fieldset.tcu-advanced-options,
|
||||
#node-form fieldset.tcu-term-fields{width:45%; display:inline-block; vertical-align: top;}
|
||||
@@ -0,0 +1,9 @@
|
||||
name = Tode
|
||||
description = First time this field will be used, it will create a new term with the value inserted in the textfield, after that, the term (tid) will always be the same, just update term name by updating the value of the field. You can keep synchronized a fixe term with a node, you can set an auto title from this field, The required, number of value at 1 and term_node synch of global field are required
|
||||
project = "Tode"
|
||||
dependencies[] = taxonomy
|
||||
dependencies[] = field
|
||||
package = gui
|
||||
version = "7.x-0.dev"
|
||||
core = "7.x"
|
||||
|
||||
+704
@@ -0,0 +1,704 @@
|
||||
<?php
|
||||
/**
|
||||
* developed by www.g-u-i.net
|
||||
* 2011
|
||||
* First time this field will be used, it will create a new term with the value inserted in the textfield,
|
||||
* after that, the term (tid) will always be the same, just update term name by updating the value of the field.
|
||||
* You can keep synchronized a fixe term with a node,
|
||||
* you can set an auto title from this field, The required,
|
||||
* number of value at 1 and term_node synch of global field are required
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of hook_menu().
|
||||
*/
|
||||
/*
|
||||
function tode_menu() {
|
||||
$items = array();
|
||||
|
||||
// $items['node/%node/tode/%term'] = array(
|
||||
// 'title' => 'Taxonomy Term',
|
||||
// 'type' => MENU_LOCAL_TASK,
|
||||
// 'access callback' => 'tode_node_tab_access',
|
||||
// 'access arguments' => array(2),
|
||||
// 'page callback' => 'tode_tab_page',
|
||||
// 'page arguments' => array(2),
|
||||
// 'file' => 'tode.pages.inc',
|
||||
// 'weight' => 2,
|
||||
// );
|
||||
|
||||
return $items;
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of hook_theme().
|
||||
*/
|
||||
function tode_theme() {
|
||||
return array(
|
||||
'tode' => array(
|
||||
'arguments' => array('element' => NULL),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_init().
|
||||
*/
|
||||
function tode_init() {
|
||||
// File hooks and callbacks may be used by any module.
|
||||
drupal_add_css(drupal_get_path('module', 'tode') .'/tode.css');
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_field_widget_info().
|
||||
*/
|
||||
function tode_field_widget_info() {
|
||||
|
||||
return array(
|
||||
'tode' => array(
|
||||
'label' => t('Tode (create then update one unique term)'),
|
||||
'field types' => array('taxonomy_term_reference'),
|
||||
'behaviors' => array(
|
||||
'multiple values' => FIELD_BEHAVIOR_DEFAULT,
|
||||
'default value' => FIELD_BEHAVIOR_NONE,
|
||||
),
|
||||
'settings' => array(
|
||||
'size' => 60,
|
||||
'show_term_form'=> -1,
|
||||
'choose_term_parent'=> -1,
|
||||
'maxlength'=> 255,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_widget_settings
|
||||
*/
|
||||
function tode_field_widget_settings_form($field, $instance){
|
||||
// dsm($instance, 'tode_field_widget_settings_form : $instance');
|
||||
// dsm($field, 'field');
|
||||
|
||||
$widget = $instance['widget'];
|
||||
$settings = $widget['settings'];
|
||||
|
||||
|
||||
// '#description' => t('First time this field will be used, it will create a new term with the value inserted in the textfield, after that, the term (tid) will always be the same, just update term name by updating the value of the field. You can keep synchronized a fixe term with a node, you can set an auto title from this field, The required, number of value at 1 and term_node synch of global field are required')
|
||||
|
||||
$form['maxlength'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Maximum length of term'),
|
||||
'#default_value' => $settings['maxlength'],
|
||||
'#element_validate' => array('_tode_widget_settings_maxlength_validate'),
|
||||
'#required' => TRUE,
|
||||
'#description' => t('Defines how many characters can be typed into the text field. For values higher than 255, remember that one term name can not be longer than 255 (would be cutted).'),
|
||||
);
|
||||
|
||||
/*
|
||||
TODO complete the all flow of this
|
||||
*/
|
||||
$form['show_term_form'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Show taxonomy term edit form ?'),
|
||||
'#default_value' => $settings['show_term_form'],
|
||||
);
|
||||
|
||||
$form['choose_term_parent'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Enable taxonomy term parent selection ?'),
|
||||
'#default_value' => $settings['choose_term_parent'],
|
||||
);
|
||||
|
||||
return $form;
|
||||
|
||||
}
|
||||
|
||||
function _tode_widget_settings_maxlength_validate($element, &$form_state) {
|
||||
// dsm('_tode_widget_settings_maxlength_validate');
|
||||
// dsm($element, '$element');
|
||||
// dsm($form_state, '$form_state');
|
||||
$widget = $form_state['values']['instance']['widget'];
|
||||
$value = $widget['settings']['maxlength'];
|
||||
if (!is_numeric($value) || intval($value) != $value || $value <= 0) {
|
||||
form_error($element, t('"Maximum length" must be a positive integer.'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of FAPI hook_elements().
|
||||
*
|
||||
* Any FAPI callbacks needed for individual widgets can be declared here,
|
||||
* and the element will be passed to those callbacks for processing.
|
||||
*
|
||||
* Drupal will automatically theme the element using a theme with
|
||||
* the same name as the hook_elements key.
|
||||
*
|
||||
* Autocomplete_path is not used by text_widget but other widgets can use it
|
||||
* (see nodereference and userreference).
|
||||
*
|
||||
* http://drupal.org/node/224333#hook_element_info
|
||||
*
|
||||
*/
|
||||
#hook_element_info() WHY ??
|
||||
/*
|
||||
function tode_element_info(){
|
||||
return array(
|
||||
'tode' => array(
|
||||
'#input' => TRUE,
|
||||
'#columns' => array('value'),
|
||||
'#delta' => 0,
|
||||
'#process' => array('tode_element_process'),
|
||||
),
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of hook_field_widget_form().
|
||||
*/
|
||||
function tode_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
|
||||
// dsm('- - - - tode_field_widget_form');
|
||||
// dsm($form, '&$form');
|
||||
// dsm($form_state, '&$form_state');
|
||||
// dsm($items, 'items');
|
||||
// dsm($element, '$element');
|
||||
// dsm($field, '$field');
|
||||
// dsm($instance, '$instance');
|
||||
|
||||
|
||||
$node = $form_state['node'];
|
||||
// dsm($node, '$node');
|
||||
|
||||
if(isset($items[$delta])){
|
||||
$term = taxonomy_term_load($items[$delta]['tid']);
|
||||
// $term = i18n_taxonomy_term_get_translation($term, $node->language); // marche pas avec localized term
|
||||
// dsm($term, '$term');
|
||||
$term_parents = taxonomy_get_parents($term->tid);
|
||||
// dsm($term_parents, '$term_parents');
|
||||
$term_parent = array_pop($term_parents);
|
||||
}
|
||||
|
||||
# no need of $node->translation_source because with node translation (not entity fields translation) tid remains
|
||||
# just have to translate term name on submit
|
||||
// if( !isset($node->id) && isset($node->translation_source) ){
|
||||
// }
|
||||
|
||||
$form['tode_tid'] = array('#type' => 'hidden', '#value' => isset($term) ? $term->tid : 0,'#delta' => $element['#delta'],);
|
||||
|
||||
# parent
|
||||
if( $instance['widget']['settings']['choose_term_parent'] ){
|
||||
// add parent form autocomplete if activated
|
||||
$vocabularies = array();
|
||||
foreach ($field['settings']['allowed_values'] as $tree)
|
||||
if ($vocabulary = taxonomy_vocabulary_machine_name_load($tree['vocabulary']))
|
||||
$vocabularies[$vocabulary->vid] = $vocabulary;
|
||||
|
||||
$vocabulary = reset($vocabularies);
|
||||
// dsm($vocabulary, '$vocabulary');
|
||||
|
||||
$form['tode_vid'] = array('#type' => 'hidden', '#value' => $vocabulary->vid,'#delta' => $element['#delta'],);
|
||||
|
||||
$form['tode_parent_term'] = array(
|
||||
'#title' => 'Parent ' . $vocabulary->name . ' (optional)',
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => isset($term_parent) ? $term_parent->name : '',
|
||||
'#autocomplete_path' => 'taxonomy/autocomplete' . '/' . $field['field_name'],
|
||||
'#size' => 60,
|
||||
'#maxlength' => 1024,
|
||||
'#element_validate' => array('tode_parent_autocomplete_validate'),
|
||||
);
|
||||
|
||||
}else{
|
||||
// if parent selection not enabled set the current parent as hidden input
|
||||
$form['tode_parent_term'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#value' => isset($term_parent) ? $term_parent->name : '',
|
||||
'#delta' => $element['#delta'],
|
||||
);
|
||||
}
|
||||
|
||||
// set element form item
|
||||
$element += array(
|
||||
'#type' => 'textfield',
|
||||
'#default_value' => isset($term) ? i18n_taxonomy_term_name($term, $node->language) : '',
|
||||
'#size' => $instance['widget']['settings']['size'],
|
||||
'#maxlength' => $instance['widget']['settings']['maxlength'],
|
||||
'#element_validate' => array('tode_validate'),
|
||||
);
|
||||
|
||||
|
||||
# add the term edit form
|
||||
if(isset($term))
|
||||
_tode_add_term_form($form, $term, $instance, $element['#delta']);
|
||||
|
||||
// dsm($form, 'end tode_field_widget_form :: $form');
|
||||
return $element;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* _tode_add_term_form($term)
|
||||
*
|
||||
* show the complete taxonomy term form if feature is enabled
|
||||
*
|
||||
*/
|
||||
function _tode_add_term_form(&$form, $term, $instance, $delta){
|
||||
// dsm('- - - - _tode_add_term_form');
|
||||
module_load_include('inc', 'taxonomy', 'taxonomy.admin');
|
||||
|
||||
$term_form = _tode_term_form($term);
|
||||
// dsm($term_form, 'term_form');
|
||||
|
||||
if($term_form){
|
||||
|
||||
unset($term_form['actions']);
|
||||
unset($term_form['#action']);
|
||||
unset($term_form['#method']);
|
||||
|
||||
#unset vid info 'cause is in conflict with the node's vid field
|
||||
unset($term_form['vid']);
|
||||
|
||||
$term_form = _tode_clean_form($term_form);
|
||||
|
||||
$prefix = 'tode_termform_'.$instance['field_name'];
|
||||
$term_form = _tode_prefix_form($term_form, $prefix.'_');
|
||||
|
||||
$visible = $instance['widget']['settings']['show_term_form'];
|
||||
|
||||
$form[$prefix] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Term edit'),
|
||||
'#tree' => TRUE,
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => FALSE,
|
||||
'#weight'=>1,
|
||||
// '#group'=>'additional_settings',
|
||||
'#prefix' => $visible ? null : '<div style="display:none;">',
|
||||
'#suffix' => $visible ? null : '</div>',
|
||||
);
|
||||
|
||||
$form[$prefix] += $term_form;
|
||||
|
||||
|
||||
|
||||
// $form['tode_termform'] = array('#type' => 'hidden', '#value' => 'true','#delta' => $delta,);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Form element validate handler for tode parent term autocomplete element.
|
||||
*/
|
||||
function tode_parent_autocomplete_validate($element, &$form_state) {
|
||||
// dsm('- - - - tode_autocomplete_validate');
|
||||
// dsm($element, '$element');
|
||||
// dsm($form_state, '$form_state');
|
||||
|
||||
$value = array();
|
||||
if ($typed_term = $element['#value']) {
|
||||
// Translate term names into actual terms.
|
||||
// See if the term exists in the chosen vocabulary and return the tid;
|
||||
// otherwise, set error.
|
||||
if ($possibilities = taxonomy_term_load_multiple(array(), array('name' => trim($typed_term), 'vid' => $form_state['values']['tode_vid']))) {
|
||||
$term = array_pop($possibilities);
|
||||
$value = (array)$term;
|
||||
}
|
||||
else {
|
||||
form_error($element, t('Parent term can only be an existing term.'));
|
||||
}
|
||||
}
|
||||
//
|
||||
// dsm('form_set_value');
|
||||
form_set_value($element, $value, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation function for the tode element
|
||||
*
|
||||
* parses input and sets the values as needed (tid) for storing the data
|
||||
*/
|
||||
function tode_validate($element, &$form_state){
|
||||
// dsm('- - - - tode_validate');
|
||||
// dsm($form_state, 'form_state');
|
||||
// dsm($element, 'element');
|
||||
|
||||
$node = $form_state['node'];
|
||||
|
||||
/*
|
||||
TODO term translation (entity translate + node title question)
|
||||
*/
|
||||
|
||||
$value = array();
|
||||
if ($typed_term = $element['#value']) {
|
||||
$field = field_widget_field($element, $form_state);
|
||||
// dsm($field, 'field');
|
||||
|
||||
$vocabularies = array();
|
||||
foreach ($field['settings']['allowed_values'] as $tree) {
|
||||
if ($vocabulary = taxonomy_vocabulary_machine_name_load($tree['vocabulary'])) {
|
||||
$vocabularies[$vocabulary->vid] = $vocabulary;
|
||||
}
|
||||
}
|
||||
|
||||
// get the parent term tid or 0 (no parents)
|
||||
$parent_tid = isset($form_state['values']['tode_parent_term']['tid']) ? $form_state['values']['tode_parent_term']['tid'] : 0;
|
||||
|
||||
// See if the term already exists and load the term
|
||||
// otherwise, create a new 'autocreate' term for insert.
|
||||
if($tid = $form_state['values']['tode_tid']){
|
||||
$term = taxonomy_term_load($tid);
|
||||
|
||||
$term->name = $typed_term;
|
||||
$term->parent = $parent_tid;
|
||||
|
||||
}else{
|
||||
$vocabulary = reset($vocabularies);
|
||||
$term = (object)array(
|
||||
// 'tid' => 'autocreate', // autocreate not nbeeded with direct taxonomy_term_save
|
||||
'vid' => $vocabulary->vid,
|
||||
'name' => $typed_term,
|
||||
'vocabulary_machine_name' => $vocabulary->machine_name,
|
||||
'parent' => $parent_tid,
|
||||
);
|
||||
taxonomy_term_save($term); // save here the new term to directly get the tid on hook_node_validate
|
||||
}
|
||||
|
||||
// dsm($term, '$term');
|
||||
$value = (array)$term;
|
||||
}
|
||||
|
||||
// dsm($value, '$value');
|
||||
form_set_value($element, $value, $form_state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_field_widget_error().
|
||||
*/
|
||||
function tode_field_widget_error($element, $error, $form, &$form_state) {
|
||||
# use this to set errors
|
||||
form_error($element['value'], $error['message']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_node_validate().
|
||||
*
|
||||
* use to save the all term form (steel have to be debuged)
|
||||
*
|
||||
*/
|
||||
function tode_node_validate($node, $form, &$form_state){
|
||||
// dsm('- - - tode_node_validate');
|
||||
// dsm($node, '$node');
|
||||
// dsm($form, '$form');
|
||||
// dsm($form_state, '$form_state');
|
||||
|
||||
module_load_include('inc', 'taxonomy', 'taxonomy.admin');
|
||||
// module_load_include('inc', 'i18n_string', 'i18n_string.pages');
|
||||
//
|
||||
$tode_fields = _tode_get_tode_fields_def($node);
|
||||
// dsm($tode_fields, '$tode_fields');
|
||||
|
||||
|
||||
if(!count($tode_fields))
|
||||
return;
|
||||
|
||||
$language = $node->language;
|
||||
|
||||
$default_language = language_default('language');
|
||||
// dsm($default_language, '$default_language');
|
||||
|
||||
foreach ($tode_fields as $field_name => $field) {
|
||||
|
||||
// retreive the prefixed termfom values (hidden or visible)
|
||||
$prefix = 'tode_termform_'.$field_name;
|
||||
|
||||
// if we do not have the term form (node creation)
|
||||
if( !isset($form_state['values'][$prefix]) ){
|
||||
$tode_field_term_value = $form_state['values'][$field_name]['und'][0]; // on node creation field language is always to und (sure ?)
|
||||
|
||||
// test the language, if not default language create the term name translation
|
||||
if( $form_state['values']['language'] != 'und' || $form_state['values']['language'] != $default_language){
|
||||
$context= array('term',$tode_field_term_value['tid'],'name');
|
||||
i18n_string_textgroup('taxonomy')->update_translation($context, $language, $tode_field_term_value['name']);
|
||||
}
|
||||
|
||||
continue;
|
||||
}else{
|
||||
// retreive the initial tode_field language
|
||||
$init_language = $form[$field_name]['#language'];
|
||||
|
||||
// retreive the value of term field, to get the typed term name
|
||||
$tode_field_term_value = $form_state['values'][$field_name][$init_language][0];
|
||||
// dsm($tode_field_term_value, '$tode_field_term_value');
|
||||
|
||||
$values = _tode_prefix_form($form_state['values'][$prefix], $prefix.'_', FALSE);
|
||||
// dsm($values, 'values');
|
||||
|
||||
if($language == 'und' || $language == $default_language || !module_exists('i18n_taxonomy')){
|
||||
|
||||
// define the form_state for term_form submit
|
||||
$new_term_form_state = array(
|
||||
'build_info'=>array(
|
||||
'args'=>array(0=>(object)$tode_field_term_value),
|
||||
),
|
||||
"values"=>array(
|
||||
'name'=> $tode_field_term_value['name'], // replace the original (hidden) term name value by the typed in the the entity field
|
||||
'op'=> t('Save'),
|
||||
)
|
||||
);
|
||||
// add new values to form_state
|
||||
$new_term_form_state['values'] += $values;
|
||||
|
||||
// dsm($new_term_form_state, 'form_state');
|
||||
drupal_form_submit('taxonomy_form_term', $new_term_form_state);
|
||||
}else{
|
||||
|
||||
$context= array('term',$values['tid'],'name');
|
||||
|
||||
i18n_string_textgroup('taxonomy')->update_translation($context, $language, $tode_field_term_value['name']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* theme_tode
|
||||
*
|
||||
*/
|
||||
// function theme_tode($element) {1
|
||||
// dsm('theme_tode');
|
||||
// dsm($element, '$element');
|
||||
// return $element['#children'];
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of hook_form_alter().
|
||||
*
|
||||
* node deletion to delete also the tode term
|
||||
*
|
||||
*/
|
||||
function tode_form_alter(&$form, $form_state, $form_id){
|
||||
|
||||
/*
|
||||
TODO block the deletion if tode term has children !! cause will delete them to …
|
||||
*/
|
||||
|
||||
if (stripos($form_id, 'node_delete_confirm') !== false){
|
||||
// dsm($form_id, 'tode form_alter form_id');
|
||||
_tode_node_delete_form_alter($form, $form_state);
|
||||
// dsm($form);
|
||||
}else if(stripos($form_id, 'node_admin_content') !== false){
|
||||
if(isset($form['operation']) && $form['operation']['#value'] == 'delete'){
|
||||
// dsm($form, 'node_admin_content form');
|
||||
// dsm($form_state, 'form_state');
|
||||
_tode_nodes_delete_form_alter($form, $form_state);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function _tode_node_delete_form_alter(&$form, $form_state){
|
||||
// dsm($form, '_tode_node_delete_form_alter : form');
|
||||
// get the node
|
||||
$node = $form['#node'];
|
||||
// dsm($node, '$node');
|
||||
|
||||
#get the fields defenition of node type
|
||||
$tode_fields = _tode_get_tode_fields_def($node);
|
||||
// dsm($tode_fields);
|
||||
|
||||
if(count($tode_fields) == 0)
|
||||
return;
|
||||
|
||||
#get the terms value
|
||||
$terms = array('names'=>array(), 'tids'=>array());
|
||||
foreach ($tode_fields as $field_name => $field)
|
||||
_tode_populate_terms_node_delete($terms, $node->$field_name);
|
||||
|
||||
_tode_node_delete_prepare_form($form, $terms);
|
||||
}
|
||||
|
||||
function _tode_nodes_delete_form_alter(&$form, $form_state){
|
||||
// dsm($form, '_tode_nodes_delete_form_alter : form');
|
||||
$nodes = array();
|
||||
foreach ($form_state['values']['nodes'] as $nid => $actif)
|
||||
if($actif)
|
||||
$nodes[] = node_load($nid);
|
||||
|
||||
#get the terms value
|
||||
$terms = array('names'=>array(), 'tids'=>array());
|
||||
foreach ($nodes as $node) {
|
||||
#get the fields definition of node type
|
||||
$tode_fields = _tode_get_tode_fields_def($node);
|
||||
//dsm($tode_fields);
|
||||
|
||||
if(count($tode_fields) == 0)
|
||||
continue;
|
||||
|
||||
foreach ($tode_fields as $field_name => $field)
|
||||
_tode_populate_terms_node_delete($terms, $node->$field_name);
|
||||
|
||||
}
|
||||
|
||||
_tode_node_delete_prepare_form($form, $terms);
|
||||
}
|
||||
|
||||
function _tode_populate_terms_node_delete(&$terms, $tode_field){
|
||||
foreach ($tode_field as $language) {
|
||||
foreach ($language as $term) {
|
||||
$term = taxonomy_term_load($term['tid']);
|
||||
if(!in_array($term->tid, $terms['tids'])){
|
||||
$terms['names'][] = $term->name;
|
||||
$terms['tids'][] = $term->tid;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _tode_node_delete_prepare_form(&$form, $terms){
|
||||
if(count($terms)){
|
||||
/*
|
||||
TODO add here a checkbox to select terms to delete
|
||||
*/
|
||||
#add some warning in form description
|
||||
$form['description']['#markup'] .= '<br />'.t('this will also delete taxonomy terms : %terms', array('%terms'=>implode(', ', $terms['names'])));
|
||||
|
||||
$form['tode_delete'] = array( '#type' => 'hidden', '#value' => serialize($terms['tids']),);
|
||||
|
||||
$form['tode_terms'] = array('#type' => 'hidden', '#value' => serialize($terms['names']),);
|
||||
|
||||
$form['#submit'][] = 'tode_delete_submit';
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function tode_delete_submit($form, &$form_state){
|
||||
$tids = unserialize($form['tode_delete']['#value']);
|
||||
foreach ($tids as $tid)
|
||||
taxonomy_term_delete($tid);
|
||||
|
||||
$terms = unserialize($form['tode_terms']['#value']);
|
||||
drupal_set_message(t('Following Taxonomy terms have been deleted : %terms', array('%terms' => implode(', ', $terms) )), 'status');
|
||||
}
|
||||
|
||||
/**
|
||||
* HELPERS
|
||||
*/
|
||||
//
|
||||
// function _tode_prefix_keys($k){
|
||||
// if(strpos('#', $kk) == false)
|
||||
// return $prefix.$k;
|
||||
// }
|
||||
|
||||
function _tode_clean_form($form, $level = 0){
|
||||
foreach ($form as $key => $value) {
|
||||
if(strpos($key,'#') !== false || $key == 'form_build_id' || $key == 'form_id' || $key == 'form_token'){
|
||||
if( $level == 0 || $key == "#element_validate")
|
||||
unset($form[$key]);
|
||||
}elseif(is_array($value)){
|
||||
$form[$key] = _tode_clean_form($value, $level+1);
|
||||
}
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
function _tode_prefix_form($form, $prefix = '', $add = TRUE){
|
||||
|
||||
foreach ($form as $key => $value) {
|
||||
if(strpos($key,'#') === false){
|
||||
|
||||
if((isset($value['#type']) && $value['#type'] == 'fieldset') || (!$add && is_array($value)))
|
||||
$value = _tode_prefix_form($value, $prefix, $add);
|
||||
|
||||
if($add){
|
||||
$form[$prefix.$key] = $value;
|
||||
unset($form[$key]);
|
||||
}elseif(strpos($key, $prefix) !== false ){
|
||||
$form[str_replace($prefix, '', $key)] = $value;
|
||||
unset($form[$key]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* _tode_term_form($tid)
|
||||
*
|
||||
*/
|
||||
function _tode_term_form($term){
|
||||
// dsm('_tode_term_form');
|
||||
if ($term) {
|
||||
|
||||
$form_state = array(
|
||||
'build_info'=>array(
|
||||
'args'=>array(0=>$term)
|
||||
),
|
||||
'method'=>'post',
|
||||
);
|
||||
|
||||
// function taxonomy_form_term($form, &$form_state, $edit = array(), $vocabulary = NULL) {
|
||||
$term_form = drupal_retrieve_form('taxonomy_form_term', $form_state);
|
||||
drupal_prepare_form('taxonomy_form_term', $term_form, $form_state);
|
||||
|
||||
return $term_form;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* _tode_trim_options(&$form, $element)
|
||||
*
|
||||
*/
|
||||
function _tode_trim_options(&$form, $item){
|
||||
foreach ($form[$item] as $field_name => $field) {
|
||||
if(((is_array($field)) && $field['#type'] == 'select') && $field['#multiple']){
|
||||
$options = $field['#options'];
|
||||
for ($i=0; $i < count($options); $i++) {
|
||||
if(!isset($options[$i]->option))
|
||||
continue;
|
||||
|
||||
$op = array();
|
||||
foreach ($options[$i]->option as $key => $value)
|
||||
$op[$key] = strlen($value) > 25 ? substr_replace ($value, ' [...] ', 15, -10) : $value; // affiche 'abc...xyz'
|
||||
|
||||
$options[$i]->option = $op;
|
||||
}
|
||||
$field['#options'] = $options;
|
||||
$form[$item][$field_name] = $field;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* OK OK OK
|
||||
*/
|
||||
function _tode_get_tode_fields_def($node){
|
||||
// dsm($node, '_tode_get_fields_def');
|
||||
|
||||
#get the fields defenition of node type
|
||||
$type_fields = field_info_instances('node');
|
||||
// dsm($type_fields, 'type_fields definition');
|
||||
|
||||
#get the tode node fields
|
||||
$tode_fields = array();
|
||||
foreach ($type_fields[$node->type] as $field_name => $field) {
|
||||
if($field['widget']['type'] == 'tode')
|
||||
$tode_fields[$field_name] = $field;
|
||||
}
|
||||
|
||||
|
||||
return $tode_fields;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Theme implementation to display a single Wysiwyg (plugin) dialog page.
|
||||
*/
|
||||
?>
|
||||
|
||||
<div id="page">
|
||||
|
||||
<?php print $messages; ?>
|
||||
|
||||
<div id="main-wrapper"><div id="main" class="clearfix">
|
||||
|
||||
<div id="content" class="column"><div class="section">
|
||||
<a id="main-content"></a>
|
||||
<?php print render($title_prefix); ?>
|
||||
<?php if ($title): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?>
|
||||
<?php print render($title_suffix); ?>
|
||||
<?php if ($tabs): ?><div class="tabs"><?php print render($tabs); ?></div><?php endif; ?>
|
||||
<?php print render($page['help']); ?>
|
||||
<?php if ($action_links): ?><ul class="action-links"><?php print render($action_links); ?></ul><?php endif; ?>
|
||||
<?php print render($page['content']); ?>
|
||||
</div></div> <!-- /.section, /#content -->
|
||||
|
||||
</div></div> <!-- /#main, /#main-wrapper -->
|
||||
|
||||
</div> <!-- /#page -->
|
||||
@@ -1,594 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Integrate Wysiwyg editors into Drupal.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Form builder for Wysiwyg profile form.
|
||||
*/
|
||||
function wysiwyg_profile_form($form, &$form_state, $profile) {
|
||||
// Merge in defaults.
|
||||
$profile = (array) $profile;
|
||||
$profile += array(
|
||||
'format' => '',
|
||||
'editor' => '',
|
||||
);
|
||||
if (empty($profile['settings'])) {
|
||||
$profile['settings'] = array();
|
||||
}
|
||||
$profile['settings'] += array(
|
||||
'default' => TRUE,
|
||||
'user_choose' => FALSE,
|
||||
'show_toggle' => TRUE,
|
||||
'theme' => 'advanced',
|
||||
'language' => 'en',
|
||||
'access' => 1,
|
||||
'access_pages' => "node/*\nuser/*\ncomment/*",
|
||||
'buttons' => array(),
|
||||
'toolbar_loc' => 'top',
|
||||
'toolbar_align' => 'left',
|
||||
'path_loc' => 'bottom',
|
||||
'resizing' => TRUE,
|
||||
// Also available, but buggy in TinyMCE 2.x: blockquote,code,dt,dd,samp.
|
||||
'block_formats' => 'p,address,pre,h2,h3,h4,h5,h6,div',
|
||||
'verify_html' => TRUE,
|
||||
'preformatted' => FALSE,
|
||||
'convert_fonts_to_spans' => TRUE,
|
||||
'remove_linebreaks' => TRUE,
|
||||
'apply_source_formatting' => FALSE,
|
||||
'paste_auto_cleanup_on_paste' => FALSE,
|
||||
'css_setting' => 'theme',
|
||||
'css_path' => NULL,
|
||||
'css_classes' => NULL,
|
||||
);
|
||||
$profile = (object) $profile;
|
||||
|
||||
$formats = filter_formats();
|
||||
$editor = wysiwyg_get_editor($profile->editor);
|
||||
drupal_set_title(t('%editor profile for %format', array('%editor' => $editor['title'], '%format' => $formats[$profile->format]->name)), PASS_THROUGH);
|
||||
|
||||
$form['format'] = array('#type' => 'value', '#value' => $profile->format);
|
||||
$form['input_format'] = array('#type' => 'value', '#value' => $formats[$profile->format]->name);
|
||||
$form['editor'] = array('#type' => 'value', '#value' => $profile->editor);
|
||||
|
||||
$form['basic'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Basic setup'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
|
||||
$form['basic']['default'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Enabled by default'),
|
||||
'#default_value' => $profile->settings['default'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('The default editor state for users having access to this profile. Users are able to override this state if the next option is enabled.'),
|
||||
);
|
||||
|
||||
$form['basic']['user_choose'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Allow users to choose default'),
|
||||
'#default_value' => $profile->settings['user_choose'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If allowed, users will be able to choose their own editor default state in their user account settings.'),
|
||||
);
|
||||
|
||||
$form['basic']['show_toggle'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Show <em>enable/disable rich text</em> toggle link'),
|
||||
'#default_value' => $profile->settings['show_toggle'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('Whether or not to show the <em>enable/disable rich text</em> toggle link below a textarea. If disabled, the user setting or global default is used (see above).'),
|
||||
);
|
||||
|
||||
$form['basic']['theme'] = array(
|
||||
'#type' => 'hidden',
|
||||
'#value' => $profile->settings['theme'],
|
||||
);
|
||||
|
||||
$form['basic']['language'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Interface language'),
|
||||
'#default_value' => $profile->settings['language'],
|
||||
);
|
||||
// @see _locale_prepare_predefined_list()
|
||||
require_once DRUPAL_ROOT . '/includes/iso.inc';
|
||||
$predefined = _locale_get_predefined_list();
|
||||
foreach ($predefined as $key => $value) {
|
||||
// Include native name in output, if possible
|
||||
if (count($value) > 1) {
|
||||
$tname = t($value[0]);
|
||||
$predefined[$key] = ($tname == $value[1]) ? $tname : "$tname ($value[1])";
|
||||
}
|
||||
else {
|
||||
$predefined[$key] = t($value[0]);
|
||||
}
|
||||
}
|
||||
asort($predefined);
|
||||
$form['basic']['language']['#options'] = $predefined;
|
||||
|
||||
$form['buttons'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Buttons and plugins'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
'#tree' => TRUE,
|
||||
'#theme' => 'wysiwyg_admin_button_table',
|
||||
);
|
||||
|
||||
$plugins = wysiwyg_get_plugins($profile->editor);
|
||||
// Generate the button list.
|
||||
foreach ($plugins as $name => $meta) {
|
||||
if (isset($meta['buttons']) && is_array($meta['buttons'])) {
|
||||
foreach ($meta['buttons'] as $button => $title) {
|
||||
$icon = '';
|
||||
if (!empty($meta['path'])) {
|
||||
// @todo Button icon locations are different in editors, editor versions,
|
||||
// and contrib/custom plugins (like Image Assist, f.e.).
|
||||
$img_src = $meta['path'] . "/images/$name.gif";
|
||||
// Handle plugins that have more than one button.
|
||||
if (!file_exists($img_src)) {
|
||||
$img_src = $meta['path'] . "/images/$button.gif";
|
||||
}
|
||||
$icon = file_exists($img_src) ? '<img src="' . base_path() . $img_src . '" title="' . $button . '" style="border: 1px solid grey; vertical-align: middle;" />' : '';
|
||||
}
|
||||
$title = (!empty($icon) ? $icon . ' ' . check_plain($title) : check_plain($title));
|
||||
$form['buttons'][$name][$button] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => $title,
|
||||
'#default_value' => !empty($profile->settings['buttons'][$name][$button]) ? $profile->settings['buttons'][$name][$button] : FALSE,
|
||||
'#description' => isset($meta['url']) ? l($meta['url'], $meta['url']) : NULL,
|
||||
);
|
||||
}
|
||||
}
|
||||
elseif (isset($meta['extensions']) && is_array($meta['extensions'])) {
|
||||
foreach ($meta['extensions'] as $extension => $title) {
|
||||
$form['buttons'][$name][$extension] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => check_plain($title),
|
||||
'#default_value' => !empty($profile->settings['buttons'][$name][$extension]) ? $profile->settings['buttons'][$name][$extension] : FALSE,
|
||||
'#description' => isset($meta['url']) ? l($meta['url'], $meta['url']) : NULL,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$form['appearance'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Editor appearance'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
|
||||
$form['appearance']['toolbar_loc'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Toolbar location'),
|
||||
'#default_value' => $profile->settings['toolbar_loc'],
|
||||
'#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.'),
|
||||
);
|
||||
|
||||
$form['appearance']['toolbar_align'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Button alignment'),
|
||||
'#default_value' => $profile->settings['toolbar_align'],
|
||||
'#options' => array('center' => t('Center'), 'left' => t('Left'), 'right' => t('Right')),
|
||||
'#description' => t('This option controls the alignment of icons in the editor toolbar.'),
|
||||
);
|
||||
|
||||
$form['appearance']['path_loc'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Path location'),
|
||||
'#default_value' => $profile->settings['path_loc'],
|
||||
'#options' => array('none' => t('Hide'), 'top' => t('Top'), 'bottom' => t('Bottom')),
|
||||
'#description' => t('Where to display the path to HTML elements (i.e. <code>body > table > tr > td</code>).'),
|
||||
);
|
||||
|
||||
$form['appearance']['resizing'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Enable resizing button'),
|
||||
'#default_value' => $profile->settings['resizing'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('This option gives you the ability to enable/disable the resizing button. If enabled, the Path location toolbar must be set to "Top" or "Bottom" in order to display the resize icon.'),
|
||||
);
|
||||
|
||||
$form['output'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Cleanup and output'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
|
||||
$form['output']['verify_html'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Verify HTML'),
|
||||
'#default_value' => $profile->settings['verify_html'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, potentially malicious code like <code><HEAD></code> tags will be removed from HTML contents.'),
|
||||
);
|
||||
|
||||
$form['output']['preformatted'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Preformatted'),
|
||||
'#default_value' => $profile->settings['preformatted'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, the editor will insert TAB characters on tab and preserve other whitespace characters just like a PRE element in HTML does.'),
|
||||
);
|
||||
|
||||
$form['output']['convert_fonts_to_spans'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Convert <font> tags to styles'),
|
||||
'#default_value' => $profile->settings['convert_fonts_to_spans'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, HTML tags declaring the font size, font family, font color and font background color will be replaced by inline CSS styles.'),
|
||||
);
|
||||
|
||||
$form['output']['remove_linebreaks'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Remove linebreaks'),
|
||||
'#default_value' => $profile->settings['remove_linebreaks'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, the editor will remove most linebreaks from contents. Disabling this option could avoid conflicts with other input filters.'),
|
||||
);
|
||||
|
||||
$form['output']['apply_source_formatting'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Apply source formatting'),
|
||||
'#default_value' => $profile->settings['apply_source_formatting'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, the editor will re-format the HTML source code. Disabling this option could avoid conflicts with other input filters.'),
|
||||
);
|
||||
|
||||
$form['output']['paste_auto_cleanup_on_paste'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Force cleanup on standard paste'),
|
||||
'#default_value' => $profile->settings['paste_auto_cleanup_on_paste'],
|
||||
'#return_value' => 1,
|
||||
'#description' => t('If enabled, the default paste function (CTRL-V or SHIFT-INS) behaves like the "paste from word" plugin function.'),
|
||||
);
|
||||
|
||||
$form['css'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('CSS'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => TRUE,
|
||||
);
|
||||
|
||||
$form['css']['block_formats'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Block formats'),
|
||||
'#default_value' => $profile->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')),
|
||||
);
|
||||
|
||||
$form['css']['css_setting'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Editor CSS'),
|
||||
'#default_value' => $profile->settings['css_setting'],
|
||||
'#options' => array('theme' => t('Use theme CSS'), 'self' => t('Define CSS'), 'none' => t('Editor default CSS')),
|
||||
'#description' => t('Defines the CSS to be used in the editor area.<br />Use theme CSS - loads stylesheets from current site theme.<br/>Define CSS - enter path for stylesheet files below.<br />Editor default CSS - uses default stylesheets from editor.'),
|
||||
);
|
||||
|
||||
$form['css']['css_path'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('CSS path'),
|
||||
'#default_value' => $profile->settings['css_path'],
|
||||
'#size' => 40,
|
||||
'#maxlength' => 255,
|
||||
'#description' => t('If "Define CSS" was selected above, enter path to a CSS file or a list of CSS files separated by a comma.') . '<br />' . t('Available tokens: <code>%b</code> (base path, eg: <code>/</code>), <code>%t</code> (path to theme, eg: <code>themes/garland</code>)') . '<br />' . t('Example:') . ' css/editor.css,/themes/garland/style.css,%b%t/style.css,http://example.com/external.css',
|
||||
);
|
||||
|
||||
$form['css']['css_classes'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('CSS classes'),
|
||||
'#default_value' => $profile->settings['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 all loaded stylesheet(s).', array('!format' => '<code>[title]=[class]</code>', '!example' => 'My heading=header1')),
|
||||
);
|
||||
|
||||
$form['submit'] = array(
|
||||
'#type' => 'submit',
|
||||
'#value' => t('Save'),
|
||||
'#weight' => 100,
|
||||
);
|
||||
$form['cancel'] = array(
|
||||
'#value' => l(t('Cancel'), 'admin/config/content/wysiwyg'),
|
||||
'#weight' => 110,
|
||||
);
|
||||
|
||||
// Supply contextual information for other callbacks and handlers.
|
||||
// @todo Modernize this form for D7+ and declare these earlier.
|
||||
// $profile is the primary object of this form, and as an entity, usually
|
||||
// expected to live in $form_state[$entity_type].
|
||||
$form_state['wysiwyg_profile'] = $profile;
|
||||
$form_state['wysiwyg']['editor'] = $editor;
|
||||
$form_state['wysiwyg']['plugins'] = $plugins;
|
||||
|
||||
// Allow editor library specific changes to be made to the form.
|
||||
if (isset($editor['settings form callback'])) {
|
||||
$editor['settings form callback']($form, $form_state);
|
||||
}
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit callback for Wysiwyg profile form.
|
||||
*
|
||||
* @see wysiwyg_profile_form()
|
||||
*/
|
||||
function wysiwyg_profile_form_submit($form, &$form_state) {
|
||||
$values = $form_state['values'];
|
||||
if (isset($values['buttons'])) {
|
||||
// Store only enabled buttons for each plugin.
|
||||
foreach ($values['buttons'] as $plugin => $buttons) {
|
||||
$values['buttons'][$plugin] = array_filter($values['buttons'][$plugin]);
|
||||
}
|
||||
// Store only enabled plugins.
|
||||
$values['buttons'] = array_filter($values['buttons']);
|
||||
}
|
||||
// Remove any white-space from 'block_formats' setting, since editor
|
||||
// implementations rely on a comma-separated list to explode().
|
||||
$values['block_formats'] = preg_replace('@\s+@', '', $values['block_formats']);
|
||||
|
||||
// Remove input format name.
|
||||
$format = $values['format'];
|
||||
$input_format = $values['input_format'];
|
||||
$editor = $values['editor'];
|
||||
unset($values['format'], $values['input_format'], $values['editor']);
|
||||
|
||||
// Remove FAPI values.
|
||||
// @see system_settings_form_submit()
|
||||
unset($values['submit'], $values['form_id'], $values['op'], $values['form_token'], $values['form_build_id']);
|
||||
|
||||
// Insert new profile data.
|
||||
db_merge('wysiwyg')
|
||||
->key(array('format' => $format))
|
||||
->fields(array(
|
||||
'editor' => $editor,
|
||||
'settings' => serialize($values),
|
||||
))
|
||||
->execute();
|
||||
wysiwyg_profile_cache_clear();
|
||||
|
||||
drupal_set_message(t('Wysiwyg profile for %format has been saved.', array('%format' => $input_format)));
|
||||
|
||||
$form_state['redirect'] = 'admin/config/content/wysiwyg';
|
||||
}
|
||||
|
||||
/**
|
||||
* Layout for the buttons in the Wysiwyg Editor profile form.
|
||||
*/
|
||||
function theme_wysiwyg_admin_button_table($variables) {
|
||||
$form = $variables['form'];
|
||||
$buttons = array();
|
||||
|
||||
// Flatten forms array.
|
||||
foreach (element_children($form) as $name) {
|
||||
foreach (element_children($form[$name]) as $button) {
|
||||
$buttons[] = drupal_render($form[$name][$button]);
|
||||
}
|
||||
}
|
||||
|
||||
// Split checkboxes into rows with 3 columns.
|
||||
$total = count($buttons);
|
||||
$rows = array();
|
||||
for ($i = 0; $i < $total; $i += 3) {
|
||||
$row = array();
|
||||
$row_buttons = array_slice($buttons, $i, 3) + array_fill(0, 3, array());
|
||||
foreach ($row_buttons as $row_button) {
|
||||
$row[] = array('data' => $row_button);
|
||||
}
|
||||
$rows[] = $row;
|
||||
}
|
||||
|
||||
$output = theme('table', array('rows' => $rows, 'attributes' => array('width' => '100%')));
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display overview of setup Wysiwyg Editor profiles; menu callback.
|
||||
*/
|
||||
function wysiwyg_profile_overview($form, &$form_state) {
|
||||
include_once './includes/install.inc';
|
||||
|
||||
// Check which wysiwyg editors are installed.
|
||||
$editors = wysiwyg_get_all_editors();
|
||||
$count = count($editors);
|
||||
$status = array();
|
||||
$options = array('' => t('No editor'));
|
||||
|
||||
// D7's seven theme displays links in table headers as block elements.
|
||||
drupal_add_css('table.system-status-report th a {display: inline;}', 'inline');
|
||||
|
||||
foreach ($editors as $name => $editor) {
|
||||
$status[$name] = array(
|
||||
'severity' => (isset($editor['error']) ? REQUIREMENT_ERROR : ($editor['installed'] ? REQUIREMENT_OK : REQUIREMENT_INFO)),
|
||||
'title' => t('<a href="!vendor-url">@editor</a> (<a href="!download-url">Download</a>)', array('!vendor-url' => $editor['vendor url'], '@editor' => $editor['title'], '!download-url' => $editor['download url'])),
|
||||
'value' => (isset($editor['installed version']) ? $editor['installed version'] : t('Not installed.')),
|
||||
'description' => (isset($editor['error']) ? $editor['error'] : ''),
|
||||
);
|
||||
if ($editor['installed']) {
|
||||
$options[$name] = $editor['title'] . (isset($editor['installed version']) ? ' ' . $editor['installed version'] : '');
|
||||
}
|
||||
else {
|
||||
// Build on-site installation instructions.
|
||||
// @todo Setup $library in wysiwyg_load_editor() already.
|
||||
$library = (isset($editor['library']) ? $editor['library'] : key($editor['libraries']));
|
||||
$targs = array(
|
||||
'@editor-path' => $editor['editor path'],
|
||||
'@library-filepath' => $editor['library path'] . '/' . (isset($editor['libraries'][$library]['files'][0]) ? $editor['libraries'][$library]['files'][0] : key($editor['libraries'][$library]['files'])),
|
||||
);
|
||||
$instructions = '<p>' . t('Extract the archive and copy its contents into a new folder in the following location:<br /><code>@editor-path</code>', $targs) . '</p>';
|
||||
$instructions .= '<p>' . t('So the actual library can be found at:<br /><code>@library-filepath</code>', $targs) . '</p>';
|
||||
|
||||
// Add any install notes.
|
||||
if (!empty($editor['install note callback']) && function_exists($editor['install note callback'])) {
|
||||
$instructions .= '<div class="editor-install-note">' . $editor['install note callback']() . '</div>';
|
||||
}
|
||||
|
||||
$status[$name]['description'] .= $instructions;
|
||||
$count--;
|
||||
}
|
||||
// In case there is an error, always show installation instructions.
|
||||
if (isset($editor['error'])) {
|
||||
$show_instructions = TRUE;
|
||||
}
|
||||
}
|
||||
if (!$count) {
|
||||
$show_instructions = TRUE;
|
||||
}
|
||||
$form['status'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Installation instructions'),
|
||||
'#collapsible' => TRUE,
|
||||
'#collapsed' => !isset($show_instructions),
|
||||
'#description' => (!$count ? t('There are no editor libraries installed currently. The following list contains a list of currently supported editors:') : ''),
|
||||
'#weight' => 10,
|
||||
);
|
||||
$form['status']['report'] = array('#markup' => theme('status_report', array('requirements' => $status)));
|
||||
|
||||
if (!$count) {
|
||||
return $form;
|
||||
}
|
||||
|
||||
$formats = filter_formats();
|
||||
$profiles = wysiwyg_profile_load_all();
|
||||
$form['formats'] = array(
|
||||
'#type' => 'item',
|
||||
'#description' => t('To assign a different editor to a text format, click "delete" to remove the existing first.'),
|
||||
'#tree' => TRUE,
|
||||
);
|
||||
|
||||
$enable_save = FALSE;
|
||||
foreach ($formats as $id => $format) {
|
||||
$form['formats'][$id]['name'] = array(
|
||||
'#markup' => check_plain($format->name),
|
||||
);
|
||||
// Only display editor selection for associated input formats to avoid
|
||||
// confusion about disabled selection.
|
||||
if (isset($profiles[$id]) && !empty($profiles[$id]->editor)) {
|
||||
$editor_name = $profiles[$id]->editor;
|
||||
$installed = !empty($editors[$editor_name]['installed']);
|
||||
$form['formats'][$id]['editor'] = array(
|
||||
'#wysiwyg-editor-name' => $editor_name,
|
||||
);
|
||||
if ($installed) {
|
||||
$form['formats'][$id]['editor']['#markup'] = $options[$editor_name];
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('Missing %editor library for %format format. Re-install the %editor library or delete the editor profile.', array(
|
||||
'%editor' => $editors[$editor_name]['title'],
|
||||
'%format' => $format->name,
|
||||
)), 'warning');
|
||||
}
|
||||
}
|
||||
else {
|
||||
$form['formats'][$id]['editor'] = array(
|
||||
'#type' => 'select',
|
||||
'#default_value' => '',
|
||||
'#options' => $options,
|
||||
);
|
||||
$enable_save = TRUE;
|
||||
}
|
||||
if (isset($profiles[$id]) && !empty($profiles[$id]->editor)) {
|
||||
$form['formats'][$id]['edit'] = array(
|
||||
'#markup' => l(t('Edit'), "admin/config/content/wysiwyg/profile/$id/edit"),
|
||||
);
|
||||
$form['formats'][$id]['delete'] = array(
|
||||
'#markup' => l(t('Delete'), "admin/config/content/wysiwyg/profile/$id/delete"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Submitting the form when no editors can be selected causes errors.
|
||||
if ($enable_save) {
|
||||
$form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
|
||||
}
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return HTML for the Wysiwyg profile overview form.
|
||||
*/
|
||||
function theme_wysiwyg_profile_overview($variables) {
|
||||
$form = $variables['form'];
|
||||
if (!isset($form['formats'])) {
|
||||
return;
|
||||
}
|
||||
$editors = wysiwyg_get_all_editors();
|
||||
$output = '';
|
||||
$header = array(t('Text format'), t('Editor'), array('data' => t('Operations'), 'colspan' => 2));
|
||||
$rows = array();
|
||||
foreach (element_children($form['formats']) as $item) {
|
||||
$format = &$form['formats'][$item];
|
||||
$row = array(
|
||||
'data' => array(
|
||||
drupal_render($format['name']),
|
||||
drupal_render($format['editor']),
|
||||
isset($format['edit']) ? drupal_render($format['edit']) : '',
|
||||
isset($format['delete']) ? drupal_render($format['delete']) : '',
|
||||
),
|
||||
);
|
||||
if (empty($row['data'][1])) {
|
||||
$row['data'][1] = array(
|
||||
'data' => t('Missing library: @library', array('@library' => $editors[$format['editor']['#wysiwyg-editor-name']]['title'])),
|
||||
'class' => 'error',
|
||||
);
|
||||
$row['class'] = array('error');
|
||||
}
|
||||
$rows[] = $row;
|
||||
}
|
||||
$form['formats']['table']['#markup'] = theme('table', array('header' => $header, 'rows' => $rows));
|
||||
$output .= drupal_render_children($form);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit callback for Wysiwyg profile overview form.
|
||||
*/
|
||||
function wysiwyg_profile_overview_submit($form, &$form_state) {
|
||||
foreach ($form_state['values']['formats'] as $format => $values) {
|
||||
db_merge('wysiwyg')
|
||||
->key(array('format' => $format))
|
||||
->fields(array(
|
||||
'editor' => $values['editor'],
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
wysiwyg_profile_cache_clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete editor profile confirmation form.
|
||||
*/
|
||||
function wysiwyg_profile_delete_confirm($form, &$form_state, $profile) {
|
||||
$formats = filter_formats();
|
||||
$format = $formats[$profile->format];
|
||||
$form['format'] = array('#type' => 'value', '#value' => $format);
|
||||
return confirm_form(
|
||||
$form,
|
||||
t('Are you sure you want to remove the profile for %name?', array('%name' => $format->name)),
|
||||
'admin/config/content/wysiwyg',
|
||||
t('This action cannot be undone.'), t('Remove'), t('Cancel')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit callback for Wysiwyg profile delete form.
|
||||
*
|
||||
* @see wysiwyg_profile_delete_confirm()
|
||||
*/
|
||||
function wysiwyg_profile_delete_confirm_submit($form, &$form_state) {
|
||||
$format = $form_state['values']['format'];
|
||||
wysiwyg_profile_delete($format->format);
|
||||
wysiwyg_profile_cache_clear();
|
||||
|
||||
drupal_set_message(t('Wysiwyg profile for %name has been deleted.', array('%name' => $format->name)));
|
||||
$form_state['redirect'] = 'admin/config/content/wysiwyg';
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
|
||||
/**
|
||||
* Wysiwyg plugin button implementation for Awesome plugin.
|
||||
*/
|
||||
Drupal.wysiwyg.plugins.awesome = {
|
||||
/**
|
||||
* Return whether the passed node belongs to this plugin.
|
||||
*
|
||||
* @param node
|
||||
* The currently focused DOM element in the editor content.
|
||||
*/
|
||||
isNode: function(node) {
|
||||
return ($(node).is('img.mymodule-awesome'));
|
||||
},
|
||||
|
||||
/**
|
||||
* Execute the button.
|
||||
*
|
||||
* @param data
|
||||
* An object containing data about the current selection:
|
||||
* - format: 'html' when the passed data is HTML content, 'text' when the
|
||||
* passed data is plain-text content.
|
||||
* - node: When 'format' is 'html', the focused DOM element in the editor.
|
||||
* - content: The textual representation of the focused/selected editor
|
||||
* content.
|
||||
* @param settings
|
||||
* The plugin settings, as provided in the plugin's PHP include file.
|
||||
* @param instanceId
|
||||
* The ID of the current editor instance.
|
||||
*/
|
||||
invoke: function(data, settings, instanceId) {
|
||||
// Generate HTML markup.
|
||||
if (data.format == 'html') {
|
||||
// Prevent duplicating a teaser break.
|
||||
if ($(data.node).is('img.mymodule-awesome')) {
|
||||
return;
|
||||
}
|
||||
var content = this._getPlaceholder(settings);
|
||||
}
|
||||
// Generate plain text.
|
||||
else {
|
||||
var content = '<!--break-->';
|
||||
}
|
||||
// Insert new content into the editor.
|
||||
if (typeof content != 'undefined') {
|
||||
Drupal.wysiwyg.instances[instanceId].insert(content);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Prepare all plain-text contents of this plugin with HTML representations.
|
||||
*
|
||||
* Optional; only required for "inline macro tag-processing" plugins.
|
||||
*
|
||||
* @param content
|
||||
* The plain-text contents of a textarea.
|
||||
* @param settings
|
||||
* The plugin settings, as provided in the plugin's PHP include file.
|
||||
* @param instanceId
|
||||
* The ID of the current editor instance.
|
||||
*/
|
||||
attach: function(content, settings, instanceId) {
|
||||
content = content.replace(/<!--break-->/g, this._getPlaceholder(settings));
|
||||
return content;
|
||||
},
|
||||
|
||||
/**
|
||||
* Process all HTML placeholders of this plugin with plain-text contents.
|
||||
*
|
||||
* Optional; only required for "inline macro tag-processing" plugins.
|
||||
*
|
||||
* @param content
|
||||
* The HTML content string of the editor.
|
||||
* @param settings
|
||||
* The plugin settings, as provided in the plugin's PHP include file.
|
||||
* @param instanceId
|
||||
* The ID of the current editor instance.
|
||||
*/
|
||||
detach: function(content, settings, instanceId) {
|
||||
var $content = $('<div>' + content + '</div>');
|
||||
$.each($('img.mymodule-awesome', $content), function (i, elem) {
|
||||
//...
|
||||
});
|
||||
return $content.html();
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper function to return a HTML placeholder.
|
||||
*
|
||||
* The 'drupal-content' CSS class is required for HTML elements in the editor
|
||||
* content that shall not trigger any editor's native buttons (such as the
|
||||
* image button for this example placeholder markup).
|
||||
*/
|
||||
_getPlaceholder: function (settings) {
|
||||
return '<img src="' + settings.path + '/images/spacer.gif" alt="<--break->" title="<--break-->" class="wysiwyg-break drupal-content" />';
|
||||
}
|
||||
};
|
||||
-283
@@ -1,283 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* API documentation for Wysiwyg module.
|
||||
*
|
||||
* To implement a "Drupal plugin" button, you need to write a Wysiwyg plugin:
|
||||
* - Implement hook_wysiwyg_include_directory() to register the directory
|
||||
* containing plugin definitions.
|
||||
* - In each plugin definition file, implement hook_INCLUDE_plugin().
|
||||
* - For each plugin button, implement a JavaScript integration and an icon for
|
||||
* the button.
|
||||
*
|
||||
* @todo Icon: Recommended size and type of image.
|
||||
*
|
||||
* For example implementations you may want to look at
|
||||
* - Image Assist (img_assist)
|
||||
* - Teaser break plugin (plugins/break; part of WYSIWYG)
|
||||
* - IMCE (imce_wysiwyg)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return an array of native editor plugins.
|
||||
*
|
||||
* Only to be used for native (internal) editor plugins.
|
||||
*
|
||||
* @see hook_wysiwyg_include_directory()
|
||||
*
|
||||
* @param $editor
|
||||
* The internal name of the currently processed editor.
|
||||
* @param $version
|
||||
* The version of the currently processed editor.
|
||||
*
|
||||
* @return
|
||||
* An associative array having internal plugin names as keys and an array of
|
||||
* plugin meta-information as values.
|
||||
*/
|
||||
function hook_wysiwyg_plugin($editor, $version) {
|
||||
switch ($editor) {
|
||||
case 'tinymce':
|
||||
if ($version > 3) {
|
||||
return array(
|
||||
'myplugin' => array(
|
||||
// A URL to the plugin's homepage.
|
||||
'url' => 'http://drupal.org/project/img_assist',
|
||||
// The full path to the native editor plugin, no trailing slash.
|
||||
// Ignored when 'internal' is set to TRUE below.
|
||||
'path' => drupal_get_path('module', 'img_assist') . '/drupalimage',
|
||||
// The name of the plugin's main JavaScript file.
|
||||
// Ignored when 'internal' is set to TRUE below.
|
||||
// Default value depends on which editor the plugin is for.
|
||||
'filename' => 'editor_plugin.js',
|
||||
// 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.
|
||||
'buttons' => array(
|
||||
'img_assist' => t('Image Assist'),
|
||||
),
|
||||
// A list of editor extensions provided by this native plugin.
|
||||
// Extensions are not displayed as buttons and touch the editor's
|
||||
// internals, so you should know what you are doing.
|
||||
'extensions' => array(
|
||||
'imce' => t('IMCE'),
|
||||
),
|
||||
// A list of global, native editor configuration settings to
|
||||
// override. To be used rarely and only when required.
|
||||
'options' => array(
|
||||
'file_browser_callback' => 'imceImageBrowser',
|
||||
'inline_styles' => TRUE,
|
||||
),
|
||||
// Boolean whether the editor needs to load this plugin. When TRUE,
|
||||
// the editor will automatically load the plugin based on the 'path'
|
||||
// variable provided. If FALSE, the plugin either does not need to
|
||||
// be loaded or is already loaded by something else on the page.
|
||||
// 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
|
||||
// other modules. TRUE means 'path' and 'filename' above are ignored
|
||||
// and the plugin is instead loaded from the editor's plugin folder.
|
||||
'internal' => TRUE,
|
||||
// TinyMCE-specific: Additional HTML elements to allow in the markup.
|
||||
'extended_valid_elements' => array(
|
||||
'img[class|src|border=0|alt|title|width|height|align|name|style]',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a directory containing Wysiwyg plugins.
|
||||
*
|
||||
* @param $type
|
||||
* The type of objects being collected: either 'plugins' or 'editors'.
|
||||
* @return
|
||||
* A sub-directory of the implementing module that contains the corresponding
|
||||
* plugin files. This directory must only contain integration files for
|
||||
* Wysiwyg module.
|
||||
*/
|
||||
function hook_wysiwyg_include_directory($type) {
|
||||
switch ($type) {
|
||||
case 'plugins':
|
||||
// You can just return $type, if you place your Wysiwyg plugins into a
|
||||
// sub-directory named 'plugins'.
|
||||
return $type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a Wysiwyg plugin.
|
||||
*
|
||||
* Supposed to be used for "Drupal plugins" (cross-editor plugins) only.
|
||||
*
|
||||
* @see hook_wysiwyg_plugin()
|
||||
*
|
||||
* Each plugin file in the specified plugin directory of a module needs to
|
||||
* define meta information about the particular plugin provided.
|
||||
* The plugin's hook implementation function name is built out of the following:
|
||||
* - 'hook': The name of the module providing the plugin.
|
||||
* - 'INCLUDE': The basename of the file containing the plugin definition.
|
||||
* - 'plugin': Static.
|
||||
*
|
||||
* For example, if your module's name is 'mymodule' and
|
||||
* mymodule_wysiwyg_include_directory() returned 'plugins' as plugin directory,
|
||||
* and this directory contains an "awesome" plugin file named 'awesome.inc', i.e.
|
||||
* sites/all/modules/mymodule/plugins/awesome.inc
|
||||
* then the corresponding plugin hook function name is:
|
||||
* mymodule_awesome_plugin()
|
||||
*
|
||||
* @see hook_wysiwyg_include_directory()
|
||||
*
|
||||
* @return
|
||||
* Meta information about the buttons provided by this plugin.
|
||||
*/
|
||||
function hook_INCLUDE_plugin() {
|
||||
$plugins['awesome'] = array(
|
||||
// The plugin's title; defaulting to its internal name ('awesome').
|
||||
'title' => t('Awesome plugin'),
|
||||
// The (vendor) homepage of this plugin; defaults to ''.
|
||||
'vendor url' => 'http://drupal.org/project/wysiwyg',
|
||||
// The path to the button's icon; defaults to
|
||||
// '/[path-to-module]/[plugins-directory]/[plugin-name]/images'.
|
||||
'icon path' => 'path to icon',
|
||||
// The button image filename; defaults to '[plugin-name].png'.
|
||||
'icon file' => 'name of the icon file with extension',
|
||||
// The button title to display on hover.
|
||||
'icon title' => t('Do something'),
|
||||
// An alternative path to the integration JavaScript; defaults to
|
||||
// '[path-to-module]/[plugins-directory]/[plugin-name]'.
|
||||
'js path' => drupal_get_path('module', 'mymodule') . '/awesomeness',
|
||||
// An alternative filename of the integration JavaScript; defaults to
|
||||
// '[plugin-name].js'.
|
||||
'js file' => 'awesome.js',
|
||||
// An alternative path to the integration stylesheet; defaults to
|
||||
// '[path-to-module]/[plugins-directory]/[plugin-name]'.
|
||||
'css path' => drupal_get_path('module', 'mymodule') . '/awesomeness',
|
||||
// An alternative filename of the integration stylesheet; defaults to
|
||||
// '[plugin-name].css'.
|
||||
'css file' => 'awesome.css',
|
||||
// An array of settings for this button. Required, but API is still in flux.
|
||||
'settings' => array(
|
||||
),
|
||||
// TinyMCE-specific: Additional HTML elements to allow in the markup.
|
||||
'extended_valid_elements' => array(
|
||||
'tag1[attribute1|attribute2]',
|
||||
'tag2[attribute3|attribute4]',
|
||||
),
|
||||
);
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a Wysiwyg editor library.
|
||||
*
|
||||
* @todo Complete this documentation.
|
||||
*/
|
||||
function hook_INCLUDE_editor() {
|
||||
$editor['ckeditor'] = array(
|
||||
// The official, human-readable label of the editor library.
|
||||
'title' => 'CKEditor',
|
||||
// The URL to the library's homepage.
|
||||
'vendor url' => 'http://ckeditor.com',
|
||||
// The URL to the library's download page.
|
||||
'download url' => 'http://ckeditor.com/download',
|
||||
// A definition of available variants for the editor library.
|
||||
// The first defined is used by default.
|
||||
'libraries' => array(
|
||||
'' => array(
|
||||
'title' => 'Default',
|
||||
'files' => array(
|
||||
'ckeditor.js' => array('preprocess' => FALSE),
|
||||
),
|
||||
),
|
||||
'src' => array(
|
||||
'title' => 'Source',
|
||||
'files' => array(
|
||||
'ckeditor_source.js' => array('preprocess' => FALSE),
|
||||
),
|
||||
),
|
||||
),
|
||||
// (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',
|
||||
// A callback to determine the library's version.
|
||||
'version callback' => 'wysiwyg_ckeditor_version',
|
||||
// A callback to return available themes/skins for the editor library.
|
||||
'themes callback' => 'wysiwyg_ckeditor_themes',
|
||||
// (optional) A callback to perform editor-specific adjustments or
|
||||
// enhancements for the administrative editor profile settings form.
|
||||
'settings form callback' => 'wysiwyg_ckeditor_settings_form',
|
||||
// (optional) A callback to return an initialization JavaScript snippet for
|
||||
// this editor library, loaded before the actual library files. The returned
|
||||
// JavaScript is executed as inline script in a primitive environment,
|
||||
// before the DOM is loaded; typically used to prime a base path and other
|
||||
// global window variables for the editor library before it is loaded.
|
||||
// All implementations should verbosely document what they are doing and
|
||||
// why that is required.
|
||||
'init callback' => 'wysiwyg_ckeditor_init',
|
||||
// A callback to convert administrative profile/editor settings into
|
||||
// JavaScript settings.
|
||||
'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.
|
||||
'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.
|
||||
'proxy plugin' => array(
|
||||
'drupal' => array(
|
||||
'load' => TRUE,
|
||||
'proxy' => TRUE,
|
||||
),
|
||||
),
|
||||
// (optional) A callback to convert proxy plugin settings into JavaScript
|
||||
// settings.
|
||||
'proxy plugin settings callback' => 'wysiwyg_ckeditor_proxy_plugin_settings',
|
||||
// Defines the list of supported (minimum) versions of the editor library,
|
||||
// and the respective Drupal integration files to load.
|
||||
'versions' => array(
|
||||
'3.0.0.3665' => array(
|
||||
'js files' => array('ckeditor-3.0.js'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $editor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Act on editor profile settings.
|
||||
*
|
||||
* This hook is invoked from wysiwyg_get_editor_config() after the JavaScript
|
||||
* settings have been generated for an editor profile and before the settings
|
||||
* are added to the page. The settings may be customized or enhanced; typically
|
||||
* with options that cannot be controlled through Wysiwyg module's
|
||||
* administrative UI currently.
|
||||
*
|
||||
* Modules implementing this hook to enforce settings that can also be
|
||||
* controlled through the UI should also implement
|
||||
* hook_form_wysiwyg_profile_form_alter() to adjust or at least indicate on the
|
||||
* editor profile configuration form that certain/affected settings cannot be
|
||||
* changed.
|
||||
*
|
||||
* @param $settings
|
||||
* An associative array of JavaScript settings to pass to the editor.
|
||||
* @param $context
|
||||
* An associative array containing additional context information:
|
||||
* - editor: The plugin definition array of the editor.
|
||||
* - profile: The editor profile object, as loaded from the database.
|
||||
* - theme: The name of the editor theme/skin.
|
||||
*/
|
||||
function hook_wysiwyg_editor_settings_alter(&$settings, $context) {
|
||||
// Each editor has its own collection of native settings that may be extended
|
||||
// or overridden. Please consult the respective official vendor documentation
|
||||
// for details.
|
||||
if ($context['profile']->editor == 'tinymce') {
|
||||
// Supported values to JSON data types.
|
||||
$settings['cleanup_on_startup'] = TRUE;
|
||||
}
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Wysiwyg dialog page handling functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Page callback; Outputs a dialog page for a wysiwyg plugin.
|
||||
*
|
||||
* A Wysiwyg dialog is a bare minimum, simple HTML page; presented in a
|
||||
* modal/popup window, triggered via JavaScript.
|
||||
*
|
||||
* However, Drupal core does not support such a concept, at all.
|
||||
* Insanity happens on two separate layers:
|
||||
* - All HTML pages go through the default delivery callback of
|
||||
* drupal_deliver_html_page(), which calls into drupal_render_page(), which
|
||||
* in turn *unconditionally* invokes hook_page_build() implementations. Thus,
|
||||
* block_page_build() and similar implementations add the entirety of their
|
||||
* page regions and blocks to our simple dialog page.
|
||||
* Obviously, we don't want that.
|
||||
* - There is a nice default 'page' theme template implementation, which
|
||||
* performs all the heavy-lifting that is required for outputting a sane HTML
|
||||
* page through preprocess and process functions. The theme system does not
|
||||
* support to "inherit" preprocess and process hooks to alternative
|
||||
* implementations. Even a very basic HTML page requires almost all of that.
|
||||
* However, the default page template (normally overridden by a theme)
|
||||
* contains too many regions and usually also huge a header and footer.
|
||||
* Obviously, we don't want that.
|
||||
*
|
||||
* The poor workaround would be to follow the Overlay module's implementation in
|
||||
* core: override the theme, build everything, and after doing all of that,
|
||||
* strip away what isn't needed. Obviously, we don't want that.
|
||||
*
|
||||
* Instead, we bend Drupal to sane rules:
|
||||
* - This page callback returns the actual main content.
|
||||
* - wysiwyg_menu() defines a custom delivery callback that replaces
|
||||
* drupal_deliver_html_page(), just because we need to replace
|
||||
* drupal_render_page().
|
||||
* - Our replacement for drupal_render_page() builds a $page that does not use
|
||||
* #type 'page' but #type 'wysiwyg_dialog_page' instead.
|
||||
* - #type 'wysiwyg_dialog_page' is defined like #type 'page' in
|
||||
* system_element_info(), but is required, because there's no way to inherit
|
||||
* a theme definition but override the page template file to be used.
|
||||
* - As a consequence, #type 'wysiwyg_dialog_page' uses
|
||||
* #theme 'wysiwyg_dialog_page', for which we have to implement stub
|
||||
* preprocess and process callbacks in order to call into the ones for
|
||||
* #theme 'page'.
|
||||
*
|
||||
* As a result we get:
|
||||
* - A HTML response.
|
||||
* - A HTML page wrapped into html.tpl.php.
|
||||
* - A page title, title prefix/suffix, messages, help, etc.pp.
|
||||
* - A simple page without regions and blocks (neither built nor rendered).
|
||||
*
|
||||
* @see wysiwyg_menu()
|
||||
* @see wysiwyg_deliver_dialog_page
|
||||
* @see wysiwyg_render_dialog_page()
|
||||
* @see wysiwyg_element_info()
|
||||
* @see wysiwyg_theme()
|
||||
* @see template_preprocess_wysiwyg_dialog_page()
|
||||
* @see template_process_wysiwyg_dialog_page()
|
||||
*
|
||||
* @see drupal_deliver_page()
|
||||
* @see drupal_deliver_html_page()
|
||||
* @see drupal_render_page()
|
||||
* @see system_element_info()
|
||||
* @see drupal_common_theme()
|
||||
* @see template_preprocess_page()
|
||||
* @see template_process_page()
|
||||
*/
|
||||
function wysiwyg_dialog($plugin, $instance) {
|
||||
$plugins = wysiwyg_get_all_plugins();
|
||||
if (!isset($plugins[$plugin])) {
|
||||
return drupal_access_denied();
|
||||
}
|
||||
$callback = $plugin . '_wysiwyg_dialog';
|
||||
if (!function_exists($callback)) {
|
||||
return drupal_not_found();
|
||||
}
|
||||
|
||||
// Suppress admin menu.
|
||||
module_invoke('admin_menu', 'suppress');
|
||||
// Add editor instance id to Drupal.settings.
|
||||
$settings = array(
|
||||
'plugin' => $plugin,
|
||||
'instance' => $instance,
|
||||
);
|
||||
drupal_add_js(array('wysiwyg' => $settings), 'setting');
|
||||
|
||||
$build = $callback($instance);
|
||||
if (!is_array($build)) {
|
||||
$build = array('#markup' => $build);
|
||||
}
|
||||
$build += array(
|
||||
'#instance' => $instance,
|
||||
'#plugin' => $plugin,
|
||||
);
|
||||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see drupal_deliver_html_page()
|
||||
*/
|
||||
function wysiwyg_deliver_dialog_page($page_callback_result) {
|
||||
// Menu status constants are integers; page content is a string or array.
|
||||
if (is_int($page_callback_result)) {
|
||||
return drupal_deliver_html_page($page_callback_result);
|
||||
}
|
||||
|
||||
// Emit the correct charset HTTP header, but not if the page callback
|
||||
// result is NULL, since that likely indicates that it printed something
|
||||
// in which case, no further headers may be sent, and not if code running
|
||||
// for this page request has already set the content type header.
|
||||
if (isset($page_callback_result) && is_null(drupal_get_http_header('Content-Type'))) {
|
||||
drupal_add_http_header('Content-Type', 'text/html; charset=utf-8');
|
||||
}
|
||||
|
||||
// Send appropriate HTTP-Header for browsers and search engines.
|
||||
global $language;
|
||||
drupal_add_http_header('Content-Language', $language->language);
|
||||
|
||||
if (isset($page_callback_result)) {
|
||||
// Print anything besides a menu constant, assuming it's not NULL or
|
||||
// undefined.
|
||||
print wysiwyg_render_dialog_page($page_callback_result);
|
||||
}
|
||||
|
||||
// Perform end-of-request tasks.
|
||||
drupal_page_footer();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see drupal_render_page()
|
||||
*/
|
||||
function wysiwyg_render_dialog_page($page) {
|
||||
$main_content_display = &drupal_static('system_main_content_added', FALSE);
|
||||
|
||||
// Allow menu callbacks to return strings or arbitrary arrays to render.
|
||||
// If the array returned is not of #type page directly, we need to fill
|
||||
// in the page with defaults.
|
||||
if (is_string($page) || (is_array($page) && (!isset($page['#type']) || ($page['#type'] != 'page')))) {
|
||||
drupal_set_page_content($page);
|
||||
$page = element_info('wysiwyg_dialog_page');
|
||||
}
|
||||
|
||||
// Modules alter the $page as needed. Blocks are populated into regions like
|
||||
// 'sidebar_first', 'footer', etc.
|
||||
drupal_alter(array('wysiwyg_dialog_page', 'page'), $page);
|
||||
|
||||
// If no module has taken care of the main content, add it to the page now.
|
||||
// This allows the site to still be usable even if no modules that
|
||||
// control page regions (for example, the Block module) are enabled.
|
||||
if (!$main_content_display) {
|
||||
$page['content']['system_main'] = drupal_set_page_content();
|
||||
}
|
||||
|
||||
return drupal_render($page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Template preprocess function for theme_wysiwyg_dialog_page().
|
||||
*
|
||||
* @see wysiwyg_dialog()
|
||||
* @see wysiwyg-dialog-page.tpl.php
|
||||
* @see template_preprocess_page()
|
||||
*/
|
||||
function template_preprocess_wysiwyg_dialog_page(&$variables) {
|
||||
template_preprocess_page($variables);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Template process function for theme_wysiwyg_dialog_page().
|
||||
*
|
||||
* @see wysiwyg_dialog()
|
||||
* @see wysiwyg-dialog-page.tpl.php
|
||||
* @see template_process_page()
|
||||
*/
|
||||
function template_process_wysiwyg_dialog_page(&$variables) {
|
||||
template_process_page($variables);
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_options().
|
||||
*/
|
||||
function wysiwyg_features_export_options() {
|
||||
$profiles = array();
|
||||
|
||||
// Get human-readable name from filter module.
|
||||
$formats = filter_formats();
|
||||
|
||||
foreach (array_keys(wysiwyg_profile_load_all()) as $format) {
|
||||
// Text format may vanish without deleting the wysiwyg profile.
|
||||
if (isset($formats[$format])) {
|
||||
$profiles[$format] = $formats[$format]->name;
|
||||
}
|
||||
}
|
||||
return $profiles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export().
|
||||
*/
|
||||
function wysiwyg_features_export($data, &$export, $module_name = '') {
|
||||
$pipe = array();
|
||||
|
||||
// The wysiwyg_default_formats() hook integration is provided by the
|
||||
// features module so we need to add it as a dependency.
|
||||
$export['dependencies']['features'] = 'features';
|
||||
$export['dependencies']['wysiwyg'] = 'wysiwyg';
|
||||
|
||||
foreach ($data as $name) {
|
||||
if ($profile = wysiwyg_get_profile($name)) {
|
||||
// Add profile to exports.
|
||||
$export['features']['wysiwyg'][$profile->format] = $profile->format;
|
||||
|
||||
// Chain filter format for export.
|
||||
$pipe['filter'][] = $profile->format;
|
||||
}
|
||||
}
|
||||
|
||||
return $pipe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_export_render().
|
||||
*/
|
||||
function wysiwyg_features_export_render($module, $data, $export = NULL) {
|
||||
$code = array();
|
||||
$code[] = ' $profiles = array();';
|
||||
$code[] = '';
|
||||
|
||||
foreach ($data as $name) {
|
||||
if ($profile = wysiwyg_get_profile($name)) {
|
||||
$profile_export = features_var_export($profile, ' ');
|
||||
$profile_identifier = features_var_export($profile->format);
|
||||
$code[] = " // Exported profile: {$profile->format}";
|
||||
$code[] = " \$profiles[{$profile_identifier}] = {$profile_export};";
|
||||
$code[] = "";
|
||||
}
|
||||
}
|
||||
|
||||
$code[] = ' return $profiles;';
|
||||
$code = implode("\n", $code);
|
||||
return array('wysiwyg_default_profiles' => $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_revert().
|
||||
*/
|
||||
function wysiwyg_features_revert($module) {
|
||||
return wysiwyg_features_rebuild($module);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_features_rebuild().
|
||||
*/
|
||||
function wysiwyg_features_rebuild($module) {
|
||||
if ($defaults = features_get_default('wysiwyg', $module)) {
|
||||
foreach ($defaults as $profile) {
|
||||
db_merge('wysiwyg')
|
||||
->key(array('format' => $profile['format']))
|
||||
->fields(array(
|
||||
'editor' => $profile['editor'],
|
||||
'settings' => serialize($profile['settings']),
|
||||
))
|
||||
->execute();
|
||||
}
|
||||
wysiwyg_profile_cache_clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
name = Wysiwyg
|
||||
description = Allows to edit content with client-side editors.
|
||||
package = User interface
|
||||
;dependencies[] = libraries
|
||||
;dependencies[] = ctools
|
||||
;dependencies[] = debug
|
||||
core = 7.x
|
||||
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"
|
||||
core = "7.x"
|
||||
project = "wysiwyg"
|
||||
datestamp = "1349213776"
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
|
||||
Drupal.wysiwyg = Drupal.wysiwyg || { 'instances': {} };
|
||||
|
||||
Drupal.wysiwyg.editor = Drupal.wysiwyg.editor || { 'init': {}, 'attach': {}, 'detach': {}, 'instance': {} };
|
||||
|
||||
Drupal.wysiwyg.plugins = Drupal.wysiwyg.plugins || {};
|
||||
|
||||
(function ($) {
|
||||
// Determine support for queryCommandEnabled().
|
||||
// An exception should be thrown for non-existing commands.
|
||||
// Safari and Chrome (WebKit based) return -1 instead.
|
||||
try {
|
||||
document.queryCommandEnabled('__wysiwygTestCommand');
|
||||
$.support.queryCommandEnabled = false;
|
||||
}
|
||||
catch (error) {
|
||||
$.support.queryCommandEnabled = true;
|
||||
}
|
||||
})(jQuery);
|
||||
-313
@@ -1,313 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Installation functions for Wysiwyg module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of hook_schema().
|
||||
*/
|
||||
function wysiwyg_schema() {
|
||||
$schema['wysiwyg'] = array(
|
||||
'description' => 'Stores Wysiwyg profiles.',
|
||||
'fields' => array(
|
||||
'format' => array(
|
||||
'description' => 'The {filter_format}.format of the text format.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
// Primary keys are implicitly not null.
|
||||
'not null' => TRUE,
|
||||
),
|
||||
'editor' => array(
|
||||
'description' => 'Internal name of the editor attached to the text format.',
|
||||
'type' => 'varchar',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
'default' => '',
|
||||
),
|
||||
'settings' => array(
|
||||
'description' => 'Configuration settings for the editor.',
|
||||
'type' => 'text',
|
||||
'size' => 'normal',
|
||||
'serialize' => TRUE,
|
||||
),
|
||||
),
|
||||
'primary key' => array('format'),
|
||||
'foreign keys' => array(
|
||||
'format' => array(
|
||||
'table' => 'filter_format',
|
||||
'columns' => array('format' => 'format'),
|
||||
),
|
||||
),
|
||||
);
|
||||
$schema['wysiwyg_user'] = array(
|
||||
'description' => 'Stores user preferences for wysiwyg profiles.',
|
||||
'fields' => array(
|
||||
'uid' => array(
|
||||
'description' => 'The {users}.uid of the user.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'format' => array(
|
||||
'description' => 'The {filter_format}.format of the text format.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'status' => array(
|
||||
'description' => 'Boolean indicating whether the format is enabled by default.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'size' => 'tiny',
|
||||
),
|
||||
),
|
||||
'indexes' => array(
|
||||
'uid' => array('uid'),
|
||||
'format' => array('format'),
|
||||
),
|
||||
'foreign keys' => array(
|
||||
'uid' => array(
|
||||
'table' => 'users',
|
||||
'columns' => array('uid' => 'uid'),
|
||||
),
|
||||
'format' => array(
|
||||
'table' => 'filter_format',
|
||||
'columns' => array('format' => 'format'),
|
||||
),
|
||||
),
|
||||
);
|
||||
return $schema;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_enable().
|
||||
*/
|
||||
function wysiwyg_enable() {
|
||||
// Disable conflicting, obsolete editor integration modules whenever this
|
||||
// module is enabled. This is crude, but the only way to ensure no conflicts.
|
||||
module_disable(array(
|
||||
'ckeditor',
|
||||
'editarea',
|
||||
'editonpro',
|
||||
'editor',
|
||||
'fckeditor',
|
||||
'freerte',
|
||||
'htmlarea',
|
||||
'htmlbox',
|
||||
'jwysiwyg',
|
||||
'markitup',
|
||||
'nicedit',
|
||||
'openwysiwyg',
|
||||
'pegoeditor',
|
||||
'quicktext',
|
||||
'tinymce',
|
||||
'tinymce_autoconf',
|
||||
'tinytinymce',
|
||||
'whizzywig',
|
||||
'widgeditor',
|
||||
'wymeditor',
|
||||
'xstandard',
|
||||
'yui_editor',
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_update_dependencies().
|
||||
*/
|
||||
function wysiwyg_update_dependencies() {
|
||||
// Ensure that format columns are only changed after Filter module has changed
|
||||
// the primary records.
|
||||
$dependencies['wysiwyg'][7000] = array(
|
||||
'filter' => 7010,
|
||||
);
|
||||
|
||||
return $dependencies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a list of input formats to associate profiles to.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change {wysiwyg}.format into a string.
|
||||
*/
|
||||
function wysiwyg_update_7000() {
|
||||
db_drop_primary_key('wysiwyg');
|
||||
db_change_field('wysiwyg', 'format', 'format', array(
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => TRUE,
|
||||
));
|
||||
db_add_primary_key('wysiwyg', array('format'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the {wysiwyg_user} table.
|
||||
*/
|
||||
function wysiwyg_update_7200() {
|
||||
if (!db_table_exists('wysiwyg_user')) {
|
||||
db_create_table('wysiwyg_user', array(
|
||||
'description' => 'Stores user preferences for wysiwyg profiles.',
|
||||
'fields' => array(
|
||||
'uid' => array(
|
||||
'description' => 'The {users}.uid of the user.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
),
|
||||
'format' => array(
|
||||
'description' => 'The {filter_format}.format of the text format.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
),
|
||||
'status' => array(
|
||||
'description' => 'Boolean indicating whether the format is enabled by default.',
|
||||
'type' => 'int',
|
||||
'unsigned' => TRUE,
|
||||
'not null' => TRUE,
|
||||
'default' => 0,
|
||||
'size' => 'tiny',
|
||||
),
|
||||
),
|
||||
'indexes' => array(
|
||||
'uid' => array('uid'),
|
||||
'format' => array('format'),
|
||||
),
|
||||
'foreign keys' => array(
|
||||
'uid' => array(
|
||||
'table' => 'users',
|
||||
'columns' => array('uid' => 'uid'),
|
||||
),
|
||||
'format' => array(
|
||||
'table' => 'filter_format',
|
||||
'columns' => array('format' => 'format'),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
else {
|
||||
db_change_field('wysiwyg_user', 'format', 'format', array(
|
||||
'description' => 'The {filter_format}.format of the text format.',
|
||||
'type' => 'varchar',
|
||||
'length' => 255,
|
||||
'not null' => FALSE,
|
||||
));
|
||||
}
|
||||
}
|
||||
-269
@@ -1,269 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Initialize editor libraries.
|
||||
*
|
||||
* Some editors need to be initialized before the DOM is fully loaded. The
|
||||
* init hook gives them a chance to do so.
|
||||
*/
|
||||
Drupal.wysiwygInit = function() {
|
||||
// This breaks in Konqueror. Prevent it from running.
|
||||
if (/KDE/.test(navigator.vendor)) {
|
||||
return;
|
||||
}
|
||||
jQuery.each(Drupal.wysiwyg.editor.init, function(editor) {
|
||||
// Clone, so original settings are not overwritten.
|
||||
this(jQuery.extend(true, {}, Drupal.settings.wysiwyg.configs[editor]));
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach editors to input formats and target elements (f.e. textareas).
|
||||
*
|
||||
* This behavior searches for input format selectors and formatting guidelines
|
||||
* that have been preprocessed by Wysiwyg API. All CSS classes of those elements
|
||||
* with the prefix 'wysiwyg-' are parsed into input format parameters, defining
|
||||
* the input format, configured editor, target element id, and variable other
|
||||
* properties, which are passed to the attach/detach hooks of the corresponding
|
||||
* editor.
|
||||
*
|
||||
* Furthermore, an "enable/disable rich-text" toggle link is added after the
|
||||
* target element to allow users to alter its contents in plain text.
|
||||
*
|
||||
* This is executed once, while editor attach/detach hooks can be invoked
|
||||
* multiple times.
|
||||
*
|
||||
* @param context
|
||||
* A DOM element, supplied by Drupal.attachBehaviors().
|
||||
*/
|
||||
Drupal.behaviors.attachWysiwyg = {
|
||||
attach: function (context, settings) {
|
||||
// This breaks in Konqueror. Prevent it from running.
|
||||
if (/KDE/.test(navigator.vendor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('.wysiwyg', context).once('wysiwyg', function () {
|
||||
if (!this.id || typeof Drupal.settings.wysiwyg.triggers[this.id] === 'undefined') {
|
||||
return;
|
||||
}
|
||||
var $this = $(this);
|
||||
var params = Drupal.settings.wysiwyg.triggers[this.id];
|
||||
for (var format in params) {
|
||||
params[format].format = format;
|
||||
params[format].trigger = this.id;
|
||||
params[format].field = params.field;
|
||||
}
|
||||
var format = 'format' + this.value;
|
||||
// Directly attach this editor, if the input format is enabled or there is
|
||||
// only one input format at all.
|
||||
if ($this.is(':input')) {
|
||||
Drupal.wysiwygAttach(context, params[format]);
|
||||
}
|
||||
// Attach onChange handlers to input format selector elements.
|
||||
if ($this.is('select')) {
|
||||
$this.change(function() {
|
||||
// If not disabled, detach the current and attach a new editor.
|
||||
Drupal.wysiwygDetach(context, params[format]);
|
||||
format = 'format' + this.value;
|
||||
Drupal.wysiwygAttach(context, params[format]);
|
||||
});
|
||||
}
|
||||
// Detach any editor when the containing form is submitted.
|
||||
$('#' + params.field).parents('form').submit(function (event) {
|
||||
// Do not detach if the event was cancelled.
|
||||
if (event.isDefaultPrevented()) {
|
||||
return;
|
||||
}
|
||||
Drupal.wysiwygDetach(context, params[format], 'serialize');
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
detach: function (context, settings, trigger) {
|
||||
var wysiwygs;
|
||||
// The 'serialize' trigger indicates that we should simply update the
|
||||
// underlying element with the new text, without destroying the editor.
|
||||
if (trigger == 'serialize') {
|
||||
// Removing the wysiwyg-processed class guarantees that the editor will
|
||||
// be reattached. Only do this if we're planning to destroy the editor.
|
||||
wysiwygs = $('.wysiwyg-processed', context);
|
||||
}
|
||||
else {
|
||||
wysiwygs = $('.wysiwyg', context).removeOnce('wysiwyg');
|
||||
}
|
||||
wysiwygs.each(function () {
|
||||
var params = Drupal.settings.wysiwyg.triggers[this.id];
|
||||
Drupal.wysiwygDetach(context, params, trigger);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Attach an editor to a target element.
|
||||
*
|
||||
* This tests whether the passed in editor implements the attach hook and
|
||||
* invokes it if available. Editor profile settings are cloned first, so they
|
||||
* cannot be overridden. After attaching the editor, the toggle link is shown
|
||||
* again, except in case we are attaching no editor.
|
||||
*
|
||||
* @param context
|
||||
* A DOM element, supplied by Drupal.attachBehaviors().
|
||||
* @param params
|
||||
* An object containing input format parameters.
|
||||
*/
|
||||
Drupal.wysiwygAttach = function(context, params) {
|
||||
if (typeof Drupal.wysiwyg.editor.attach[params.editor] == 'function') {
|
||||
// (Re-)initialize field instance.
|
||||
Drupal.wysiwyg.instances[params.field] = {};
|
||||
// Provide all input format parameters to editor instance.
|
||||
jQuery.extend(Drupal.wysiwyg.instances[params.field], params);
|
||||
// Provide editor callbacks for plugins, if available.
|
||||
if (typeof Drupal.wysiwyg.editor.instance[params.editor] == 'object') {
|
||||
jQuery.extend(Drupal.wysiwyg.instances[params.field], Drupal.wysiwyg.editor.instance[params.editor]);
|
||||
}
|
||||
// Store this field id, so (external) plugins can use it.
|
||||
// @todo Wrong point in time. Probably can only supported by editors which
|
||||
// support an onFocus() or similar event.
|
||||
Drupal.wysiwyg.activeId = params.field;
|
||||
// Attach or update toggle link, if enabled.
|
||||
if (params.toggle) {
|
||||
Drupal.wysiwygAttachToggleLink(context, params);
|
||||
}
|
||||
// Otherwise, ensure that toggle link is hidden.
|
||||
else {
|
||||
$('#wysiwyg-toggle-' + params.field).hide();
|
||||
}
|
||||
// Attach editor, if enabled by default or last state was enabled.
|
||||
if (params.status) {
|
||||
Drupal.wysiwyg.editor.attach[params.editor](context, params, (Drupal.settings.wysiwyg.configs[params.editor] ? jQuery.extend(true, {}, Drupal.settings.wysiwyg.configs[params.editor][params.format]) : {}));
|
||||
}
|
||||
// Otherwise, attach default behaviors.
|
||||
else {
|
||||
Drupal.wysiwyg.editor.attach.none(context, params);
|
||||
Drupal.wysiwyg.instances[params.field].editor = 'none';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach all editors from a target element.
|
||||
*
|
||||
* @param context
|
||||
* A DOM element, supplied by Drupal.attachBehaviors().
|
||||
* @param params
|
||||
* An object containing input format parameters.
|
||||
* @param trigger
|
||||
* A string describing what is causing the editor to be detached.
|
||||
*
|
||||
* @see Drupal.detachBehaviors
|
||||
*/
|
||||
Drupal.wysiwygDetach = function (context, params, trigger) {
|
||||
// Do not attempt to detach an unknown editor instance (Ajax).
|
||||
if (typeof Drupal.wysiwyg.instances[params.field] == 'undefined') {
|
||||
return;
|
||||
}
|
||||
trigger = trigger || 'unload';
|
||||
var editor = Drupal.wysiwyg.instances[params.field].editor;
|
||||
if (jQuery.isFunction(Drupal.wysiwyg.editor.detach[editor])) {
|
||||
Drupal.wysiwyg.editor.detach[editor](context, params, trigger);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Append or update an editor toggle link to a target element.
|
||||
*
|
||||
* @param context
|
||||
* A DOM element, supplied by Drupal.attachBehaviors().
|
||||
* @param params
|
||||
* An object containing input format parameters.
|
||||
*/
|
||||
Drupal.wysiwygAttachToggleLink = function(context, params) {
|
||||
if (!$('#wysiwyg-toggle-' + params.field).length) {
|
||||
var text = document.createTextNode(params.status ? Drupal.settings.wysiwyg.disable : Drupal.settings.wysiwyg.enable);
|
||||
var a = document.createElement('a');
|
||||
$(a).attr({ id: 'wysiwyg-toggle-' + params.field, href: 'javascript:void(0);' }).append(text);
|
||||
var div = document.createElement('div');
|
||||
$(div).addClass('wysiwyg-toggle-wrapper').append(a);
|
||||
$('#' + params.field).after(div);
|
||||
}
|
||||
$('#wysiwyg-toggle-' + params.field)
|
||||
.html(params.status ? Drupal.settings.wysiwyg.disable : Drupal.settings.wysiwyg.enable).show()
|
||||
.unbind('click.wysiwyg', Drupal.wysiwyg.toggleWysiwyg)
|
||||
.bind('click.wysiwyg', { params: params, context: context }, Drupal.wysiwyg.toggleWysiwyg);
|
||||
|
||||
// Hide toggle link in case no editor is attached.
|
||||
if (params.editor == 'none') {
|
||||
$('#wysiwyg-toggle-' + params.field).hide();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback for the Enable/Disable rich editor link.
|
||||
*/
|
||||
Drupal.wysiwyg.toggleWysiwyg = function (event) {
|
||||
var context = event.data.context;
|
||||
var params = event.data.params;
|
||||
if (params.status) {
|
||||
// Detach current editor.
|
||||
params.status = false;
|
||||
Drupal.wysiwygDetach(context, params);
|
||||
// After disabling the editor, re-attach default behaviors.
|
||||
// @todo We HAVE TO invoke Drupal.wysiwygAttach() here.
|
||||
Drupal.wysiwyg.editor.attach.none(context, params);
|
||||
Drupal.wysiwyg.instances[params.field] = Drupal.wysiwyg.editor.instance.none;
|
||||
Drupal.wysiwyg.instances[params.field].editor = 'none';
|
||||
Drupal.wysiwyg.instances[params.field].field = params.field;
|
||||
$(this).html(Drupal.settings.wysiwyg.enable).blur();
|
||||
}
|
||||
else {
|
||||
// Before enabling the editor, detach default behaviors.
|
||||
Drupal.wysiwyg.editor.detach.none(context, params);
|
||||
// Attach new editor using parameters of the currently selected input format.
|
||||
params = Drupal.settings.wysiwyg.triggers[params.trigger]['format' + $('#' + params.trigger).val()];
|
||||
params.status = true;
|
||||
Drupal.wysiwygAttach(context, params);
|
||||
$(this).html(Drupal.settings.wysiwyg.disable).blur();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the CSS classes of an input format DOM element into parameters.
|
||||
*
|
||||
* Syntax for CSS classes is "wysiwyg-name-value".
|
||||
*
|
||||
* @param element
|
||||
* An input format DOM element containing CSS classes to parse.
|
||||
* @param params
|
||||
* (optional) An object containing input format parameters to update.
|
||||
*/
|
||||
Drupal.wysiwyg.getParams = function(element, params) {
|
||||
var classes = element.className.split(' ');
|
||||
var params = params || {};
|
||||
for (var i = 0; i < classes.length; i++) {
|
||||
if (classes[i].substr(0, 8) == 'wysiwyg-') {
|
||||
var parts = classes[i].split('-');
|
||||
var value = parts.slice(2).join('-');
|
||||
params[parts[1]] = value;
|
||||
}
|
||||
}
|
||||
// Convert format id into string.
|
||||
params.format = 'format' + params.format;
|
||||
// Convert numeric values.
|
||||
params.status = parseInt(params.status, 10);
|
||||
params.toggle = parseInt(params.toggle, 10);
|
||||
params.resizable = parseInt(params.resizable, 10);
|
||||
return params;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allow certain editor libraries to initialize before the DOM is loaded.
|
||||
*/
|
||||
Drupal.wysiwygInit();
|
||||
|
||||
// Respond to CTools detach behaviors event.
|
||||
$(document).bind('CToolsDetachBehaviors', function(event, context) {
|
||||
Drupal.behaviors.attachWysiwyg.detach(context, {}, 'unload');
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
-1135
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user