update 2.2 + precedent custom commits
Signed-off-by: bachy <git@g-u-i.net>
This commit is contained in:
parent
aff5ecb650
commit
7884444ec6
@ -1,6 +1,25 @@
|
||||
|
||||
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
|
||||
|
521
LICENSE.txt
521
LICENSE.txt
@ -1,274 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Version 2, June 1991
|
||||
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.
|
||||
|
||||
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.
|
||||
Preamble
|
||||
|
||||
Preamble
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
The precise terms and conditions for copying, distribution and modification
|
||||
follow.
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND
|
||||
MODIFICATION
|
||||
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".
|
||||
|
||||
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".
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
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.
|
||||
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:
|
||||
|
||||
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:
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
a) You must cause the modified files to carry prominent notices stating that
|
||||
you changed the files and the date of any change.
|
||||
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.
|
||||
|
||||
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.
|
||||
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.)
|
||||
|
||||
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.)
|
||||
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.
|
||||
|
||||
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.
|
||||
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
|
||||
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.
|
||||
|
@ -18,7 +18,8 @@ To submit bug reports and feature suggestions, or to track changes:
|
||||
|
||||
-- INSTALLATION --
|
||||
|
||||
* Install as usual, see http://drupal.org/node/70151 for further information.
|
||||
* 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
|
||||
|
@ -27,8 +27,11 @@ function wysiwyg_ckeditor_editor() {
|
||||
),
|
||||
),
|
||||
),
|
||||
'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',
|
||||
@ -48,6 +51,13 @@ function wysiwyg_ckeditor_editor() {
|
||||
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.
|
||||
*
|
||||
@ -111,6 +121,69 @@ function wysiwyg_ckeditor_themes($editor, $profile) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhances the editor profile settings form for CKEditor.
|
||||
*
|
||||
* Adds support for CKEditor's advanced stylesSets, which are a more advanced
|
||||
* implementation and combination of block formats and font styles that allow
|
||||
* to adjust the HTML element, attributes, and CSS styles at once.
|
||||
*
|
||||
* @see http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Styles
|
||||
* @see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#.stylesSet
|
||||
*/
|
||||
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.
|
||||
*
|
||||
@ -127,8 +200,7 @@ function wysiwyg_ckeditor_themes($editor, $profile) {
|
||||
*/
|
||||
function wysiwyg_ckeditor_settings($editor, $config, $theme) {
|
||||
$settings = array(
|
||||
'baseHref' => $GLOBALS['base_url'] . '/',
|
||||
'width' => '100%',
|
||||
'width' => 'auto',
|
||||
// For better compatibility with smaller textareas.
|
||||
'resize_minWidth' => 450,
|
||||
'height' => 420,
|
||||
@ -167,7 +239,7 @@ function wysiwyg_ckeditor_settings($editor, $config, $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' => path_to_theme()));
|
||||
$settings['contentsCss'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -175,16 +247,25 @@ function wysiwyg_ckeditor_settings($editor, $config, $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' => path_to_theme())));
|
||||
$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 tests "!== false", so ensure it is a Boolean.
|
||||
// CKEditor performs a type-agnostic comparison on this particular setting.
|
||||
$settings['resize_enabled'] = (bool) $config['resizing'];
|
||||
}
|
||||
if (isset($config['toolbar_loc'])) {
|
||||
@ -240,6 +321,51 @@ function wysiwyg_ckeditor_settings($editor, $config, $theme) {
|
||||
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.
|
||||
*/
|
||||
@ -294,6 +420,7 @@ function wysiwyg_ckeditor_plugins($editor) {
|
||||
'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'),
|
||||
@ -325,6 +452,10 @@ function wysiwyg_ckeditor_plugins($editor) {
|
||||
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']);
|
||||
}
|
||||
|
102
editors/epiceditor.inc
Normal file
102
editors/epiceditor.inc
Normal file
@ -0,0 +1,102 @@
|
||||
<?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;
|
||||
}
|
||||
|
@ -131,8 +131,8 @@ function wysiwyg_fckeditor_settings($editor, $config, $theme) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['EditorAreaCSS'] = implode(',', wysiwyg_get_css());
|
||||
}
|
||||
else if ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['EditorAreaCSS'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => path_to_theme()));
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['EditorAreaCSS'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,10 @@ Drupal.wysiwyg.editor.init.ckeditor = function(settings) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -34,6 +38,8 @@ 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;
|
||||
@ -125,6 +131,19 @@ Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -139,16 +158,19 @@ Drupal.wysiwyg.editor.attach.ckeditor = function(context, params, settings) {
|
||||
* 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) {
|
||||
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.destroy();
|
||||
instance[method]();
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (var instanceName in CKEDITOR.instances) {
|
||||
CKEDITOR.instances[instanceName].destroy();
|
||||
if (CKEDITOR.instances.hasOwnProperty(instanceName)) {
|
||||
CKEDITOR.instances[instanceName][method]();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -208,9 +230,18 @@ Drupal.wysiwyg.editor.instance.ckeditor = {
|
||||
// @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();
|
||||
}
|
||||
};
|
||||
|
||||
|
38
editors/js/epiceditor.js
Normal file
38
editors/js/epiceditor.js
Normal file
@ -0,0 +1,38 @@
|
||||
(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);
|
@ -21,7 +21,7 @@ Drupal.wysiwyg.editor.attach.fckeditor = function(context, params, settings) {
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.fckeditor = function(context, params) {
|
||||
Drupal.wysiwyg.editor.detach.fckeditor = function (context, params, trigger) {
|
||||
var instances = [];
|
||||
if (typeof params != 'undefined' && typeof FCKeditorAPI != 'undefined') {
|
||||
var instance = FCKeditorAPI.GetInstance(params.field);
|
||||
@ -36,6 +36,11 @@ Drupal.wysiwyg.editor.detach.fckeditor = function(context, params) {
|
||||
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
|
||||
@ -175,6 +180,16 @@ Drupal.wysiwyg.editor.instance.fckeditor = {
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -40,6 +40,19 @@ for (var setting in wysiwygSettings) {
|
||||
}
|
||||
}
|
||||
|
||||
// Fix Drupal toolbar obscuring editor toolbar in fullscreen mode.
|
||||
var oldFitWindowExecute = FCKFitWindow.prototype.Execute;
|
||||
var $drupalToolbar = window.parent.jQuery('#toolbar', Drupal.overlayChild ? window.parent.window.parent.document : window.parent.document);
|
||||
FCKFitWindow.prototype.Execute = function() {
|
||||
oldFitWindowExecute.apply(this, arguments);
|
||||
if (this.IsMaximized) {
|
||||
$drupalToolbar.hide();
|
||||
}
|
||||
else {
|
||||
$drupalToolbar.show();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize this editor instance.
|
||||
*/
|
||||
|
@ -11,15 +11,33 @@ Drupal.wysiwyg.editor.attach.jwysiwyg = function(context, params, settings) {
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.jwysiwyg = function(context, params) {
|
||||
Drupal.wysiwyg.editor.detach.jwysiwyg = function (context, params, trigger) {
|
||||
var $field = $('#' + params.field);
|
||||
var editor = $field.data('wysiwyg');
|
||||
if (typeof editor != 'undefined') {
|
||||
editor.saveContent();
|
||||
editor.element.remove();
|
||||
if (trigger != 'serialize') {
|
||||
editor.element.remove();
|
||||
}
|
||||
}
|
||||
$field.removeData('wysiwyg');
|
||||
$field.show();
|
||||
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);
|
||||
|
@ -17,7 +17,10 @@ Drupal.wysiwyg.editor.attach.markitup = function(context, params, settings) {
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.markitup = function(context, params) {
|
||||
Drupal.wysiwyg.editor.detach.markitup = function (context, params, trigger) {
|
||||
if (trigger == 'serialize') {
|
||||
return;
|
||||
}
|
||||
if (typeof params != 'undefined') {
|
||||
$('#' + params.field, context).markItUpRemove();
|
||||
}
|
||||
@ -26,4 +29,18 @@ Drupal.wysiwyg.editor.detach.markitup = function(context, params) {
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
|
@ -30,12 +30,17 @@ Drupal.wysiwyg.editor.attach.nicedit = function(context, params, settings) {
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.detach.none() for a full description of this hook.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.nicedit = function(context, params) {
|
||||
Drupal.wysiwyg.editor.detach.nicedit = function (context, params, trigger) {
|
||||
if (typeof params != 'undefined') {
|
||||
var instance = nicEditors.findEditor(params.field);
|
||||
if (instance) {
|
||||
instance.ne.removeInstance(params.field);
|
||||
instance.ne.removePanel();
|
||||
if (trigger == 'serialize') {
|
||||
instance.saveContent();
|
||||
}
|
||||
else {
|
||||
instance.ne.removeInstance(params.field);
|
||||
instance.ne.removePanel();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -43,10 +48,17 @@ Drupal.wysiwyg.editor.detach.nicedit = function(context, params) {
|
||||
// Save contents of all editors back into textareas.
|
||||
var instances = nicEditors.editors[e].nicInstances;
|
||||
for (var i = 0; i < instances.length; i++) {
|
||||
instances[i].remove();
|
||||
if (trigger == 'serialize') {
|
||||
instances[i].saveContent();
|
||||
}
|
||||
else {
|
||||
instances[i].remove();
|
||||
}
|
||||
}
|
||||
// Remove all editor instances.
|
||||
nicEditors.editors[e].nicInstances = [];
|
||||
if (trigger != 'serialize') {
|
||||
nicEditors.editors[e].nicInstances = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -62,7 +74,7 @@ Drupal.wysiwyg.editor.instance.nicedit = {
|
||||
// IE.
|
||||
if (document.selection) {
|
||||
editingArea.focus();
|
||||
sel.createRange().text = content;
|
||||
sel.createRange().pasteHTML(content);
|
||||
}
|
||||
else {
|
||||
// Convert selection to a range.
|
||||
@ -89,6 +101,14 @@ Drupal.wysiwyg.editor.instance.nicedit = {
|
||||
// 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();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -17,7 +17,7 @@ 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.attach) {
|
||||
if (Drupal.behaviors.textarea) {
|
||||
Drupal.behaviors.textarea.attach();
|
||||
}
|
||||
}
|
||||
@ -26,6 +26,9 @@ Drupal.wysiwyg.editor.attach.none = function(context, params, settings) {
|
||||
/**
|
||||
* 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
|
||||
@ -33,9 +36,18 @@ Drupal.wysiwyg.editor.attach.none = function(context, params, settings) {
|
||||
* 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) {
|
||||
if (typeof params != 'undefined') {
|
||||
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();
|
||||
@ -65,6 +77,14 @@ Drupal.wysiwyg.editor.instance.none = {
|
||||
else {
|
||||
editor.value += content;
|
||||
}
|
||||
},
|
||||
|
||||
setContent: function (content) {
|
||||
$('#' + this.field).val(content);
|
||||
},
|
||||
|
||||
getContent: function () {
|
||||
return $('#' + this.field).val();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -23,6 +23,19 @@ WYSIWYG.getEditor = function (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.
|
||||
*/
|
||||
@ -45,24 +58,84 @@ Drupal.wysiwyg.editor.attach.openwysiwyg = function(context, params, settings) {
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.openwysiwyg = function(context, params) {
|
||||
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);
|
||||
jQuery('#wysiwyg_div_' + params.field).remove();
|
||||
delete instance;
|
||||
if (trigger != 'serialize') {
|
||||
jQuery('#wysiwyg_div_' + params.field).remove();
|
||||
delete instance;
|
||||
}
|
||||
}
|
||||
if (trigger != 'serialize') {
|
||||
jQuery('#' + params.field).show();
|
||||
}
|
||||
jQuery('#' + params.field).show();
|
||||
}
|
||||
else {
|
||||
jQuery.each(WYSIWYG.config, function(field) {
|
||||
WYSIWYG.updateTextArea(field);
|
||||
jQuery('#wysiwyg_div_' + field).remove();
|
||||
delete this;
|
||||
jQuery('#' + field).show();
|
||||
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);
|
||||
|
@ -10,18 +10,8 @@
|
||||
* An object containing editor settings for each input format.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.init.tinymce = function(settings) {
|
||||
// If JS compression is enabled, TinyMCE is unable to autodetect its global
|
||||
// settinge, hence we need to define them manually.
|
||||
// @todo Move global library settings somewhere else.
|
||||
tinyMCE.baseURL = settings.global.editorBasePath;
|
||||
tinyMCE.srcMode = (settings.global.execMode == 'src' ? '_src' : '');
|
||||
tinyMCE.gzipMode = (settings.global.execMode == 'gzip');
|
||||
|
||||
// Initialize editor configurations.
|
||||
for (var format in settings) {
|
||||
if (format == 'global') {
|
||||
continue;
|
||||
}
|
||||
tinyMCE.init(settings[format]);
|
||||
if (Drupal.settings.wysiwyg.plugins[format]) {
|
||||
// Load native external plugins.
|
||||
@ -67,7 +57,7 @@ Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) {
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.tinymce = function(context, params) {
|
||||
Drupal.wysiwyg.editor.detach.tinymce = function (context, params, trigger) {
|
||||
if (typeof params != 'undefined') {
|
||||
tinyMCE.removeMCEControl(tinyMCE.getEditorId(params.field));
|
||||
$('#' + params.field).removeAttr('style');
|
||||
|
@ -11,19 +11,21 @@
|
||||
* An object containing editor settings for each input format.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.init.tinymce = function(settings) {
|
||||
// If JS compression is enabled, TinyMCE is unable to autodetect its global
|
||||
// settinge, hence we need to define them manually.
|
||||
// @todo Move global library settings somewhere else.
|
||||
tinyMCE.baseURL = settings.global.editorBasePath;
|
||||
tinyMCE.srcMode = (settings.global.execMode == 'src' ? '_src' : '');
|
||||
tinyMCE.gzipMode = (settings.global.execMode == 'gzip');
|
||||
// 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 (format == 'global') {
|
||||
continue;
|
||||
};
|
||||
tinyMCE.init(settings[format]);
|
||||
if (Drupal.settings.wysiwyg.plugins[format]) {
|
||||
// Load native external plugins.
|
||||
// Array syntax required; 'native' is a predefined token in JavaScript.
|
||||
@ -50,6 +52,8 @@ Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) {
|
||||
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>');
|
||||
@ -79,20 +83,24 @@ Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) {
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.tinymce = function(context, params) {
|
||||
Drupal.wysiwyg.editor.detach.tinymce = function (context, params, trigger) {
|
||||
if (typeof params != 'undefined') {
|
||||
var instance = tinyMCE.get(params.field);
|
||||
if (instance) {
|
||||
instance.save();
|
||||
instance.remove();
|
||||
if (trigger != 'serialize') {
|
||||
instance.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Save contents of all editors back into textareas.
|
||||
tinyMCE.triggerSave();
|
||||
// Remove all editor instances.
|
||||
for (var instance in tinyMCE.editors) {
|
||||
tinyMCE.editors[instance].remove();
|
||||
if (trigger != 'serialize') {
|
||||
// Remove all editor instances.
|
||||
for (var instance in tinyMCE.editors) {
|
||||
tinyMCE.editors[instance].remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -138,16 +146,18 @@ Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
|
||||
// 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, ed.id);
|
||||
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, ed.id);
|
||||
data.content = Drupal.wysiwyg.plugins[plugin].detach(data.content, pluginSettings, editorId);
|
||||
}
|
||||
});
|
||||
|
||||
@ -175,7 +185,7 @@ Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
},
|
||||
|
||||
openDialog: function(dialog, params) {
|
||||
var instanceId = this.isFullscreen() ? 'mce_fullscreen' : this.field;
|
||||
var instanceId = this.getInstanceId();
|
||||
var editor = tinyMCE.get(instanceId);
|
||||
editor.windowManager.open({
|
||||
file: dialog.url + '/' + instanceId,
|
||||
@ -186,8 +196,7 @@ Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
},
|
||||
|
||||
closeDialog: function(dialog) {
|
||||
var instanceId = this.isFullscreen() ? 'mce_fullscreen' : this.field;
|
||||
var editor = tinyMCE.get(instanceId);
|
||||
var editor = tinyMCE.get(this.getInstanceId());
|
||||
editor.windowManager.close(dialog);
|
||||
},
|
||||
|
||||
@ -222,13 +231,25 @@ Drupal.wysiwyg.editor.instance.tinymce = {
|
||||
|
||||
insert: function(content) {
|
||||
content = this.prepareContent(content);
|
||||
var instanceId = this.isFullscreen() ? 'mce_fullscreen' : this.field;
|
||||
tinyMCE.execInstanceCommand(instanceId, 'mceInsertContent', false, 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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -80,39 +80,28 @@ Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
// Attach editor.
|
||||
makeWhizzyWig(params.field, (settings.buttons ? settings.buttons : 'all'));
|
||||
// Whizzywig fails to detect and set initial textarea contents.
|
||||
var instance = $('#whizzy' + params.field).get(0);
|
||||
if (instance) {
|
||||
instance.contentWindow.document.body.innerHTML = tidyD($field.val());
|
||||
}
|
||||
$('#whizzy' + params.field).contents().find('body').html(tidyD($field.val()));
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.whizzywig = function(context, params) {
|
||||
Drupal.wysiwyg.editor.detach.whizzywig = function (context, params, trigger) {
|
||||
var detach = function (index) {
|
||||
var id = whizzies[index];
|
||||
var instance = $('#whizzy' + id).get(0);
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
var editingArea = instance.contentWindow.document;
|
||||
var $field = $('#' + id);
|
||||
// Whizzywig shows the original textarea in source mode.
|
||||
if ($field.css('display') == 'block') {
|
||||
editingArea.body.innerHTML = $field.val();
|
||||
}
|
||||
var id = whizzies[index], $field = $('#' + id), instance = Drupal.wysiwyg.instances[id];
|
||||
|
||||
// Save contents of editor back into textarea.
|
||||
$field.val(tidyH(editingArea));
|
||||
$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.
|
||||
var originalValues = Drupal.wysiwyg.instances[id];
|
||||
$field.removeAttr('style');
|
||||
$field.attr('style', originalValues.originalStyle);
|
||||
$field.removeAttr('style').attr('style', instance.originalStyle);
|
||||
};
|
||||
|
||||
if (typeof params != 'undefined') {
|
||||
@ -130,4 +119,37 @@ Drupal.wysiwyg.editor.detach.whizzywig = function(context, params) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
@ -29,42 +29,31 @@ Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
// Attach editor.
|
||||
makeWhizzyWig(params.field, (settings.buttons ? settings.buttons : 'all'));
|
||||
// Whizzywig fails to detect and set initial textarea contents.
|
||||
var instance = $('#whizzy' + params.field).get(0);
|
||||
if (instance) {
|
||||
instance.contentWindow.document.body.innerHTML = tidyD($field.val());
|
||||
}
|
||||
$('#whizzy' + params.field).contents().find('body').html(tidyD($field.val()));
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.whizzywig = function(context, params) {
|
||||
Drupal.wysiwyg.editor.detach.whizzywig = function (context, params, trigger) {
|
||||
var detach = function (index) {
|
||||
var id = whizzies[index];
|
||||
var instance = $('#whizzy' + id).get(0);
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
var editingArea = instance.contentWindow.document;
|
||||
var $field = $('#' + id);
|
||||
// Whizzywig shows the original textarea in source mode.
|
||||
if ($field.css('display') == 'block') {
|
||||
editingArea.body.innerHTML = $field.val();
|
||||
}
|
||||
var id = whizzies[index], $field = $('#' + id), instance = Drupal.wysiwyg.instances[id];
|
||||
|
||||
// Save contents of editor back into textarea.
|
||||
$field.val(tidyH(editingArea));
|
||||
$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.
|
||||
$container = $('#CONTAINER' + id);
|
||||
var $container = $('#CONTAINER' + id);
|
||||
$field.insertBefore($container);
|
||||
// Remove editor instance.
|
||||
$container.remove();
|
||||
whizzies.splice(index, 1);
|
||||
|
||||
// Restore original textarea styling.
|
||||
var originalValues = Drupal.wysiwyg.instances[id];
|
||||
$field.removeAttr('style');
|
||||
$field.attr('style', originalValues.originalStyle);
|
||||
$field.removeAttr('style').attr('style', instance.originalStyle);
|
||||
}
|
||||
|
||||
if (typeof params != 'undefined') {
|
||||
@ -82,4 +71,37 @@ Drupal.wysiwyg.editor.detach.whizzywig = function(context, params) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
@ -71,41 +71,28 @@ Drupal.wysiwyg.editor.attach.whizzywig = function(context, params, settings) {
|
||||
// Attach editor.
|
||||
makeWhizzyWig(params.field, (settings.buttons ? settings.buttons : 'all'));
|
||||
// Whizzywig fails to detect and set initial textarea contents.
|
||||
var instance = $('#whizzy' + params.field).get(0);
|
||||
if (instance) {
|
||||
instance.contentWindow.document.body.innerHTML = tidyD($field.val());
|
||||
}
|
||||
$('#whizzy' + params.field).contents().find('body').html(tidyD($field.val()));
|
||||
};
|
||||
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.whizzywig = function(context, params) {
|
||||
Drupal.wysiwyg.editor.detach.whizzywig = function (context, params, trigger) {
|
||||
var detach = function (index) {
|
||||
var id = whizzies[index];
|
||||
var instance = $('#whizzy' + id).get(0);
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
var body = instance.contentWindow.document.body;
|
||||
var $field = $('#' + id);
|
||||
// Whizzywig shows the original textarea in source mode.
|
||||
if ($field.css('display') == 'block') {
|
||||
body.innerHTML = $field.val();
|
||||
}
|
||||
body.innerHTML = tidyH(body.innerHTML);
|
||||
var id = whizzies[index], $field = $('#' + id), instance = Drupal.wysiwyg.instances[id];
|
||||
|
||||
// Save contents of editor back into textarea.
|
||||
$field.val(window.get_xhtml ? get_xhtml(body) : body.innerHTML);
|
||||
$field.val($field.val().replace(location.href + '#', '#'));
|
||||
$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.
|
||||
var originalValues = Drupal.wysiwyg.instances[id];
|
||||
$field.removeAttr('style');
|
||||
$field.attr('style', originalValues.originalStyle);
|
||||
$field.removeAttr('style').attr('style', instance.originalStyle);
|
||||
};
|
||||
|
||||
if (typeof params != 'undefined') {
|
||||
@ -123,4 +110,45 @@ Drupal.wysiwyg.editor.detach.whizzywig = function(context, params) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
@ -19,37 +19,55 @@ Drupal.wysiwyg.editor.attach.wymeditor = function (context, params, settings) {
|
||||
/**
|
||||
* Detach a single or all editors.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.wymeditor = function (context, params) {
|
||||
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();
|
||||
$(instance._box).remove();
|
||||
$(instance._element).show();
|
||||
delete instance;
|
||||
if (trigger != 'serialize') {
|
||||
$(instance._box).remove();
|
||||
$(instance._element).show();
|
||||
delete instance;
|
||||
}
|
||||
}
|
||||
if (trigger != 'serialize') {
|
||||
$field.show();
|
||||
}
|
||||
$field.show();
|
||||
}
|
||||
else {
|
||||
jQuery.each(WYMeditor.INSTANCES, function () {
|
||||
this.update();
|
||||
$(this._box).remove();
|
||||
$(this._element).show();
|
||||
delete this;
|
||||
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') {
|
||||
var instance = WYMeditor.INSTANCES[index];
|
||||
instance.insert(content);
|
||||
return WYMeditor.INSTANCES[index];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
118
editors/js/yui.js
vendored
118
editors/js/yui.js
vendored
@ -2,12 +2,70 @@
|
||||
|
||||
/**
|
||||
* 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();
|
||||
};
|
||||
|
||||
@ -16,20 +74,72 @@ Drupal.wysiwyg.editor.attach.yui = function(context, params, settings) {
|
||||
*
|
||||
* See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
|
||||
*/
|
||||
Drupal.wysiwyg.editor.detach.yui = function(context, params) {
|
||||
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.getEditorById(params.field);
|
||||
var instance = YAHOO.widget.EditorInfo._instances[params.field];
|
||||
if (instance) {
|
||||
instance.destroy();
|
||||
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.destroy();
|
||||
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);
|
||||
|
@ -77,13 +77,13 @@ function wysiwyg_nicedit_settings($editor, $config, $theme) {
|
||||
// Add editor content stylesheet.
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$css = path_to_theme() . '/style.css';
|
||||
$css = drupal_get_path('theme', variable_get('theme_default', NULL)) . '/style.css';
|
||||
if (file_exists($css)) {
|
||||
$settings['externalCSS'] = base_path() . $css;
|
||||
}
|
||||
}
|
||||
else if ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['externalCSS'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => path_to_theme()));
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['externalCSS'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,8 +102,8 @@ function wysiwyg_openwysiwyg_settings($editor, $config, $theme) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['CSSFile'] = reset(wysiwyg_get_css());
|
||||
}
|
||||
else if ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['CSSFile'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => path_to_theme()));
|
||||
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))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ function wysiwyg_tinymce_editor() {
|
||||
),
|
||||
'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',
|
||||
@ -125,6 +126,40 @@ function wysiwyg_tinymce_themes($editor, $profile) {
|
||||
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.
|
||||
*
|
||||
@ -181,6 +216,7 @@ function wysiwyg_tinymce_settings($editor, $config, $theme) {
|
||||
$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'];
|
||||
}
|
||||
|
||||
@ -192,8 +228,8 @@ function wysiwyg_tinymce_settings($editor, $config, $theme) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['content_css'] = implode(',', wysiwyg_get_css());
|
||||
}
|
||||
else if ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['content_css'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => path_to_theme()));
|
||||
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))));
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,15 +268,15 @@ function wysiwyg_tinymce_settings($editor, $config, $theme) {
|
||||
$settings['extensions'][_wysiwyg_tinymce_plugin_name('add', $button)] = 1;
|
||||
}
|
||||
// Add external plugins to the list of extensions.
|
||||
else if ($type == 'buttons' && empty($plugins[$plugin]['internal'])) {
|
||||
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.
|
||||
else if ($type == 'buttons' && !empty($plugins[$plugin]['load'])) {
|
||||
elseif ($type == 'buttons' && !empty($plugins[$plugin]['load'])) {
|
||||
$settings['extensions'][$plugin] = 1;
|
||||
}
|
||||
// Add plain extensions.
|
||||
else if ($type == 'extensions' && !empty($plugins[$plugin]['load'])) {
|
||||
elseif ($type == 'extensions' && !empty($plugins[$plugin]['load'])) {
|
||||
$settings['extensions'][$plugin] = 1;
|
||||
}
|
||||
// Allow plugins to add valid HTML elements.
|
||||
@ -268,7 +304,7 @@ function wysiwyg_tinymce_settings($editor, $config, $theme) {
|
||||
$settings += array(
|
||||
'theme_advanced_resize_horizontal' => FALSE,
|
||||
'theme_advanced_resizing_use_cookie' => FALSE,
|
||||
'theme_advanced_path_location' => isset($config['path_loc']) ? $config['path_loc'] : 'bottom',
|
||||
'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',
|
||||
@ -361,7 +397,7 @@ function _wysiwyg_tinymce_plugin_name($op, $name) {
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
else if ($op == 'remove') {
|
||||
elseif ($op == 'remove') {
|
||||
if (strpos($name, '-') === 0) {
|
||||
return substr($name, 1);
|
||||
}
|
||||
@ -386,6 +422,8 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
'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'),
|
||||
@ -402,15 +440,15 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
'path' => $editor['library path'] . '/plugins/advhr',
|
||||
'buttons' => array('advhr' => t('Advanced horizontal rule')),
|
||||
'extended_valid_elements' => array('hr[class|width|size|noshade]'),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advhr',
|
||||
'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]'),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advimage',
|
||||
'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,
|
||||
),
|
||||
@ -418,49 +456,42 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
'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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advlink',
|
||||
'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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave',
|
||||
'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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/contextmenu',
|
||||
'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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality',
|
||||
'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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/emotions',
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:emotions',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
'font' => array(
|
||||
'path' => $editor['library path'] . '/plugins/font',
|
||||
'buttons' => array('formatselect' => t('HTML block format'), 'fontselect' => t('Font'), 'fontsizeselect' => t('Font size'), 'styleselect' => t('Font style')),
|
||||
'extended_valid_elements' => array('font[face|size|color|style],span[class|align|style]'),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/font',
|
||||
'internal' => TRUE,
|
||||
),
|
||||
'fullscreen' => array(
|
||||
'path' => $editor['library path'] . '/plugins/fullscreen',
|
||||
'buttons' => array('fullscreen' => t('Fullscreen')),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen',
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:fullscreen',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
@ -470,7 +501,7 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
'options' => array(
|
||||
'dialog_type' => array('modal'),
|
||||
),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/inlinepopups',
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:inlinepopups',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
@ -481,56 +512,56 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
'plugin_insertdate_dateFormat' => '%Y-%m-%d',
|
||||
'plugin_insertdate_timeFormat' => '%H:%M:%S',
|
||||
),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/insertdatetime',
|
||||
'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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/layer',
|
||||
'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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste',
|
||||
'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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/searchreplace',
|
||||
'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('Style properties')),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE: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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/table',
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:table',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
),
|
||||
@ -540,7 +571,6 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
'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]'),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/flash',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
@ -549,14 +579,14 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
$plugins['media'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/media',
|
||||
'buttons' => array('media' => t('Media')),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/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://wiki.moxiecode.com/index.php/TinyMCE:Plugins/xhtmlxtras',
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:xhtmlxtras',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
@ -565,7 +595,7 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
$plugins['bbcode'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/bbcode',
|
||||
'extensions' => array('bbcode' => t('BBCode')),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/bbcode',
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:bbcode',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
@ -573,7 +603,6 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
$plugins['safari'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/safari',
|
||||
'extensions' => array('safari' => t('Safari compatibility')),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/safari',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
@ -583,7 +612,7 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
$plugins['autoresize'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/autoresize',
|
||||
'extensions' => array('autoresize' => t('Auto resize')),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autoresize',
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:autoresize',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
@ -592,7 +621,7 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
$plugins['advlist'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/advlist',
|
||||
'extensions' => array('advlist' => t('Advanced list')),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/advlist',
|
||||
'url' => 'http://www.tinymce.com/wiki.php/Plugin:advlist',
|
||||
'internal' => TRUE,
|
||||
'load' => TRUE,
|
||||
);
|
||||
@ -601,11 +630,24 @@ function wysiwyg_tinymce_plugins($editor) {
|
||||
$plugins['wordcount'] = array(
|
||||
'path' => $editor['library path'] . '/plugins/wordcount',
|
||||
'extensions' => array('wordcount' => t('Word count')),
|
||||
'url' => 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/wordcount',
|
||||
'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;
|
||||
}
|
||||
|
||||
|
@ -104,13 +104,13 @@ function wysiwyg_whizzywig_settings($editor, $config, $theme) {
|
||||
// Add editor content stylesheet.
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$css = path_to_theme() . '/style.css';
|
||||
$css = drupal_get_path('theme', variable_get('theme_default', NULL)) . '/style.css';
|
||||
if (file_exists($css)) {
|
||||
$settings['externalCSS'] = base_path() . $css;
|
||||
}
|
||||
}
|
||||
else if ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['externalCSS'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => path_to_theme()));
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['externalCSS'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,10 +172,11 @@ function wysiwyg_wymeditor_settings($editor, $config, $theme) {
|
||||
if (isset($config['css_setting'])) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
// WYMeditor only supports one CSS file currently.
|
||||
$settings['stylesheet'] = reset(wysiwyg_get_css());
|
||||
$css = wysiwyg_get_css();
|
||||
$settings['stylesheet'] = reset($css);
|
||||
}
|
||||
else if ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['stylesheet'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => path_to_theme()));
|
||||
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))));
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,7 +191,7 @@ function wysiwyg_wymeditor_plugins($editor) {
|
||||
'default' => array(
|
||||
'buttons' => array(
|
||||
'Bold' => t('Bold'), 'Italic' => t('Italic'),
|
||||
'InsertOrderedList' => t('Bullet list'), 'InsertUnorderedList' => t('Numbered list'),
|
||||
'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'),
|
||||
@ -212,22 +213,22 @@ function wysiwyg_wymeditor_plugins($editor) {
|
||||
*/
|
||||
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'),
|
||||
'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'),
|
||||
);
|
||||
}
|
||||
|
@ -45,6 +45,14 @@ function wysiwyg_yui_editor() {
|
||||
'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'),
|
||||
@ -177,7 +185,7 @@ function wysiwyg_yui_settings($editor, $config, $theme) {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ($button == 'fontname') {
|
||||
elseif ($button == 'fontname') {
|
||||
$extra = array('menu' => array(
|
||||
array('text' => 'Arial', 'checked' => TRUE),
|
||||
array('text' => 'Arial Black'),
|
||||
@ -202,8 +210,8 @@ function wysiwyg_yui_settings($editor, $config, $theme) {
|
||||
if ($config['css_setting'] == 'theme') {
|
||||
$settings['extracss'] = wysiwyg_get_css();
|
||||
}
|
||||
else if ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['extracss'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => path_to_theme()));
|
||||
elseif ($config['css_setting'] == 'self' && isset($config['css_path'])) {
|
||||
$settings['extracss'] = strtr($config['css_path'], array('%b' => base_path(), '%t' => drupal_get_path('theme', variable_get('theme_default', NULL))));
|
||||
$settings['extracss'] = explode(',', $settings['extracss']);
|
||||
}
|
||||
// YUI only supports inline CSS, so we need to use @import directives.
|
||||
@ -233,8 +241,7 @@ function wysiwyg_yui_button_setting($editor, $plugin, $button, $extra = array())
|
||||
static $plugins;
|
||||
|
||||
if (!isset($plugins)) {
|
||||
// @todo Invoke all enabled plugins, not just internals.
|
||||
$plugins = wysiwyg_yui_plugins($editor);
|
||||
$plugins = wysiwyg_get_plugins($editor['name']);
|
||||
}
|
||||
|
||||
// Return a simple separator.
|
||||
@ -269,6 +276,41 @@ function wysiwyg_yui_button_setting($editor, $plugin, $button, $extra = array())
|
||||
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().
|
||||
*/
|
||||
|
@ -6,9 +6,9 @@ hidden = TRUE
|
||||
dependencies[] = wysiwyg
|
||||
files[] = wysiwyg_test.module
|
||||
|
||||
; Information added by drupal.org packaging script on 2011-06-19
|
||||
version = "7.x-2.1"
|
||||
; Information added by drupal.org packaging script on 2012-10-02
|
||||
version = "7.x-2.2"
|
||||
core = "7.x"
|
||||
project = "wysiwyg"
|
||||
datestamp = "1308450722"
|
||||
datestamp = "1349213776"
|
||||
|
||||
|
@ -5,3 +5,46 @@
|
||||
* 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'];
|
||||
}
|
||||
|
@ -2,83 +2,27 @@
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Theme template to display a single Wysiwyg (plugin) dialog page.
|
||||
*
|
||||
* Available variables:
|
||||
*
|
||||
* General utility variables:
|
||||
* - $base_path: The base URL path of the Drupal installation. At the very
|
||||
* least, this will always default to /.
|
||||
* - $css: An array of CSS files for the current page.
|
||||
* - $directory: The directory the theme is located in, e.g. themes/garland or
|
||||
* themes/garland/minelli.
|
||||
* - $logged_in: TRUE if the user is registered and signed in.
|
||||
* - $is_admin: TRUE if the user has permission to access administration pages.
|
||||
*
|
||||
* Page metadata:
|
||||
* - $language: (object) The language the site is being displayed in.
|
||||
* $language->language contains its textual representation.
|
||||
* $language->dir contains the language direction. It will either be 'ltr' or 'rtl'.
|
||||
* - $head_title: A modified version of the page title, for use in the TITLE tag.
|
||||
* - $head: Markup for the HEAD section (including meta tags, keyword tags, and
|
||||
* so on).
|
||||
* - $styles: Style tags necessary to import all CSS files for the page.
|
||||
* - $scripts: Script tags necessary to load the JavaScript files and settings
|
||||
* for the page.
|
||||
*
|
||||
* Site identity:
|
||||
* - $site_name: The name of the site, empty when display has been disabled
|
||||
* in theme settings.
|
||||
*
|
||||
* Page content (in order of occurrance in the default page.tpl.php):
|
||||
* - $breadcrumb: The breadcrumb trail for the current page.
|
||||
* - $title: The page title, for use in the actual HTML content.
|
||||
* - $help: Dynamic help text, mostly for admin pages.
|
||||
* - $messages: HTML for status and error messages. Should be displayed prominently.
|
||||
* - $tabs: Tabs linking to any sub-pages beneath the current page (e.g., the view
|
||||
* and edit tabs when displaying a node).
|
||||
*
|
||||
* - $content: The main content of the current Drupal page.
|
||||
*
|
||||
* Footer/closing data:
|
||||
* - $footer : The footer region.
|
||||
* - $closure: Final closing markup from any modules that have altered the page.
|
||||
* This variable should always be output last, after all other dynamic content.
|
||||
*
|
||||
* @see template_preprocess()
|
||||
* @see template_preprocess_wysiwyg_dialog_page()
|
||||
* Theme implementation to display a single Wysiwyg (plugin) dialog page.
|
||||
*/
|
||||
?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language ?>" lang="<?php print $language->language ?>" dir="<?php print $language->dir ?>">
|
||||
|
||||
<head>
|
||||
<title><?php print $head_title; ?></title>
|
||||
<?php print $head; ?>
|
||||
<?php print $styles; ?>
|
||||
<?php print $scripts; ?>
|
||||
<script type="text/javascript"><?php /* Needed to avoid Flash of Unstyled Content in IE */ ?> </script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="page">
|
||||
<div id="container" class="clear-block">
|
||||
<div id="main" class="column">
|
||||
<?php if (!empty($breadcrumb)): ?><div id="breadcrumb"><?php print $breadcrumb; ?></div><?php endif; ?>
|
||||
|
||||
<div id="content">
|
||||
<?php if (!empty($title)): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?>
|
||||
<?php if (!empty($tabs)): ?><div class="tabs"><?php print $tabs; ?></div><?php endif; ?>
|
||||
<?php if (!empty($messages)): print $messages; endif; ?>
|
||||
<?php if (!empty($help)): print $help; endif; ?>
|
||||
<div id="content-content" class="clear-block">
|
||||
<?php print $content; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php print $messages; ?>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php print $closure; ?>
|
||||
</body>
|
||||
</html>
|
||||
<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 -->
|
||||
|
@ -135,21 +135,22 @@ function wysiwyg_profile_form($form, &$form_state, $profile) {
|
||||
}
|
||||
$icon = file_exists($img_src) ? '<img src="' . base_path() . $img_src . '" title="' . $button . '" style="border: 1px solid grey; vertical-align: middle;" />' : '';
|
||||
}
|
||||
$title = (isset($meta['url']) ? l($title, $meta['url'], array('target' => '_blank')) : $title);
|
||||
$title = (!empty($icon) ? $icon . ' ' . $title : $title);
|
||||
$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,
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (isset($meta['extensions']) && is_array($meta['extensions'])) {
|
||||
elseif (isset($meta['extensions']) && is_array($meta['extensions'])) {
|
||||
foreach ($meta['extensions'] as $extension => $title) {
|
||||
$form['buttons'][$name][$extension] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => isset($meta['url']) ? l($title, $meta['url'], array('target' => '_blank')) : $title,
|
||||
'#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,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -299,6 +300,19 @@ function wysiwyg_profile_form($form, &$form_state, $profile) {
|
||||
'#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;
|
||||
}
|
||||
|
||||
@ -363,14 +377,11 @@ function theme_wysiwyg_admin_button_table($variables) {
|
||||
// Split checkboxes into rows with 3 columns.
|
||||
$total = count($buttons);
|
||||
$rows = array();
|
||||
for ($i = 0; $i < $total; $i++) {
|
||||
for ($i = 0; $i < $total; $i += 3) {
|
||||
$row = array();
|
||||
$row[] = array('data' => $buttons[$i]);
|
||||
if (isset($buttons[++$i])) {
|
||||
$row[] = array('data' => $buttons[$i]);
|
||||
}
|
||||
if (isset($buttons[++$i])) {
|
||||
$row[] = array('data' => $buttons[$i]);
|
||||
$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;
|
||||
}
|
||||
@ -416,6 +427,11 @@ function wysiwyg_profile_overview($form, &$form_state) {
|
||||
$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--;
|
||||
}
|
||||
@ -457,9 +473,20 @@ function wysiwyg_profile_overview($form, &$form_state) {
|
||||
// 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(
|
||||
'#markup' => $options[$profiles[$id]->editor],
|
||||
'#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(
|
||||
@ -494,17 +521,28 @@ function theme_wysiwyg_profile_overview($variables) {
|
||||
if (!isset($form['formats'])) {
|
||||
return;
|
||||
}
|
||||
$editors = wysiwyg_get_all_editors();
|
||||
$output = '';
|
||||
$header = array(t('Input format'), t('Editor'), array('data' => t('Operations'), 'colspan' => 2));
|
||||
$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];
|
||||
$rows[] = array(
|
||||
drupal_render($format['name']),
|
||||
drupal_render($format['editor']),
|
||||
isset($format['edit']) ? drupal_render($format['edit']) : '',
|
||||
isset($format['delete']) ? drupal_render($format['delete']) : '',
|
||||
$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);
|
||||
@ -554,4 +592,3 @@ function wysiwyg_profile_delete_confirm_submit($form, &$form_state) {
|
||||
drupal_set_message(t('Wysiwyg profile for %name has been deleted.', array('%name' => $format->name)));
|
||||
$form_state['redirect'] = 'admin/config/content/wysiwyg';
|
||||
}
|
||||
|
||||
|
@ -172,6 +172,83 @@ function hook_INCLUDE_plugin() {
|
||||
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.
|
||||
*
|
||||
|
@ -6,7 +6,68 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Menu callback; Output a wysiwyg plugin dialog page.
|
||||
* 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();
|
||||
@ -27,7 +88,74 @@ function wysiwyg_dialog($plugin, $instance) {
|
||||
);
|
||||
drupal_add_js(array('wysiwyg' => $settings), 'setting');
|
||||
|
||||
echo theme('wysiwyg_dialog_page', $callback($instance));
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -35,29 +163,21 @@ function wysiwyg_dialog($plugin, $instance) {
|
||||
*
|
||||
* @see wysiwyg_dialog()
|
||||
* @see wysiwyg-dialog-page.tpl.php
|
||||
* @see template_preprocess()
|
||||
* @see template_preprocess_page()
|
||||
*/
|
||||
function template_preprocess_wysiwyg_dialog_page(&$variables) {
|
||||
// Construct page title
|
||||
$head_title = array(strip_tags(drupal_get_title()), variable_get('site_name', 'Drupal'));
|
||||
|
||||
$variables['head_title'] = implode(' | ', $head_title);
|
||||
$variables['base_path'] = base_path();
|
||||
$variables['front_page'] = url();
|
||||
// @todo Would a breadcrumb make sense / possible at all?
|
||||
// $variables['breadcrumb'] = theme('breadcrumb', drupal_get_breadcrumb());
|
||||
$variables['head'] = drupal_get_html_head();
|
||||
$variables['help'] = theme('help');
|
||||
$variables['language'] = $GLOBALS['language'];
|
||||
$variables['language']->dir = $GLOBALS['language']->direction ? 'rtl' : 'ltr';
|
||||
$variables['messages'] = $variables['show_messages'] ? theme('status_messages') : '';
|
||||
$variables['site_name'] = (theme_get_setting('toggle_name') ? variable_get('site_name', 'Drupal') : '');
|
||||
$variables['css'] = drupal_add_css();
|
||||
$variables['styles'] = drupal_get_css();
|
||||
$variables['scripts'] = drupal_get_js();
|
||||
$variables['tabs'] = theme('menu_local_tasks');
|
||||
$variables['title'] = drupal_get_title();
|
||||
// Closure should be filled last.
|
||||
$variables['closure'] = theme('closure');
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,9 @@ configure = admin/config/content/wysiwyg
|
||||
files[] = wysiwyg.module
|
||||
files[] = tests/wysiwyg.test
|
||||
|
||||
; Information added by drupal.org packaging script on 2011-06-19
|
||||
version = "7.x-2.1"
|
||||
; Information added by drupal.org packaging script on 2012-10-02
|
||||
version = "7.x-2.2"
|
||||
core = "7.x"
|
||||
project = "wysiwyg"
|
||||
datestamp = "1308450722"
|
||||
datestamp = "1349213776"
|
||||
|
||||
|
@ -30,6 +30,7 @@ function wysiwyg_schema() {
|
||||
'description' => 'Configuration settings for the editor.',
|
||||
'type' => 'text',
|
||||
'size' => 'normal',
|
||||
'serialize' => TRUE,
|
||||
),
|
||||
),
|
||||
'primary key' => array('format'),
|
||||
|
44
wysiwyg.js
44
wysiwyg.js
@ -11,7 +11,6 @@ Drupal.wysiwygInit = function() {
|
||||
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]));
|
||||
@ -38,13 +37,13 @@ Drupal.wysiwygInit = function() {
|
||||
* A DOM element, supplied by Drupal.attachBehaviors().
|
||||
*/
|
||||
Drupal.behaviors.attachWysiwyg = {
|
||||
attach: function(context, settings) {
|
||||
attach: function (context, settings) {
|
||||
// This breaks in Konqueror. Prevent it from running.
|
||||
if (/KDE/.test(navigator.vendor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('.wysiwyg', context).once('wysiwyg', function() {
|
||||
$('.wysiwyg', context).once('wysiwyg', function () {
|
||||
if (!this.id || typeof Drupal.settings.wysiwyg.triggers[this.id] === 'undefined') {
|
||||
return;
|
||||
}
|
||||
@ -76,9 +75,27 @@ Drupal.behaviors.attachWysiwyg = {
|
||||
if (event.isDefaultPrevented()) {
|
||||
return;
|
||||
}
|
||||
Drupal.wysiwygDetach(context, params[format]);
|
||||
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);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -136,11 +153,20 @@ Drupal.wysiwygAttach = function(context, params) {
|
||||
* 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) {
|
||||
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);
|
||||
Drupal.wysiwyg.editor.detach[editor](context, params, trigger);
|
||||
}
|
||||
};
|
||||
|
||||
@ -187,6 +213,7 @@ Drupal.wysiwyg.toggleWysiwyg = function (event) {
|
||||
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 {
|
||||
@ -234,4 +261,9 @@ Drupal.wysiwyg.getParams = function(element, params) {
|
||||
*/
|
||||
Drupal.wysiwygInit();
|
||||
|
||||
// Respond to CTools detach behaviors event.
|
||||
$(document).bind('CToolsDetachBehaviors', function(event, context) {
|
||||
Drupal.behaviors.attachWysiwyg.detach(context, {}, 'unload');
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
|
@ -79,9 +79,11 @@ function wysiwyg_menu() {
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'weight' => 10,
|
||||
);
|
||||
// @see wysiwyg_dialog()
|
||||
$items['wysiwyg/%'] = array(
|
||||
'page callback' => 'wysiwyg_dialog',
|
||||
'page arguments' => array(1),
|
||||
'delivery callback' => 'wysiwyg_deliver_dialog_page',
|
||||
'access arguments' => array('access content'),
|
||||
'type' => MENU_CALLBACK,
|
||||
'file' => 'wysiwyg.dialog.inc',
|
||||
@ -89,6 +91,19 @@ function wysiwyg_menu() {
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_element_info().
|
||||
*/
|
||||
function wysiwyg_element_info() {
|
||||
// @see wysiwyg_dialog()
|
||||
$types['wysiwyg_dialog_page'] = array(
|
||||
'#theme' => 'wysiwyg_dialog_page',
|
||||
'#theme_wrappers' => array('html'),
|
||||
'#show_messages' => TRUE,
|
||||
);
|
||||
return $types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_theme().
|
||||
*
|
||||
@ -103,8 +118,9 @@ function wysiwyg_theme() {
|
||||
'wysiwyg_admin_button_table' => array(
|
||||
'render element' => 'form',
|
||||
),
|
||||
// @see wysiwyg_dialog()
|
||||
'wysiwyg_dialog_page' => array(
|
||||
'variables' => array('content' => NULL, 'show_messages' => TRUE),
|
||||
'render element' => 'page',
|
||||
'file' => 'wysiwyg.dialog.inc',
|
||||
'template' => 'wysiwyg-dialog-page',
|
||||
),
|
||||
@ -117,7 +133,7 @@ function wysiwyg_theme() {
|
||||
function wysiwyg_help($path, $arg) {
|
||||
switch ($path) {
|
||||
case 'admin/config/content/wysiwyg':
|
||||
$output = '<p>' . t('A Wysiwyg profile is associated with an input format. A Wysiwyg profile defines which client-side editor is loaded with a particular input format, what buttons or themes are enabled for the editor, how the editor is displayed, and a few other editor-specific functions.') . '</p>';
|
||||
$output = '<p>' . t('A Wysiwyg profile is associated with a text format. A Wysiwyg profile defines which client-side editor is loaded with a particular text format, what buttons or themes are enabled for the editor, how the editor is displayed, and a few other editor-specific functions.') . '</p>';
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
@ -286,6 +302,7 @@ function wysiwyg_get_profile($format) {
|
||||
function wysiwyg_load_editor($profile) {
|
||||
static $settings_added;
|
||||
static $loaded = array();
|
||||
$path = drupal_get_path('module', 'wysiwyg');
|
||||
|
||||
$name = $profile->editor;
|
||||
// Library files must be loaded only once.
|
||||
@ -293,6 +310,13 @@ function wysiwyg_load_editor($profile) {
|
||||
// Load editor.
|
||||
$editor = wysiwyg_get_editor($name);
|
||||
if ($editor) {
|
||||
$default_library_options = array(
|
||||
'type' => 'file',
|
||||
'scope' => 'header',
|
||||
'defer' => FALSE,
|
||||
'cache' => TRUE,
|
||||
'preprocess' => TRUE,
|
||||
);
|
||||
// Determine library files to load.
|
||||
// @todo Allow to configure the library/execMode to use.
|
||||
if (isset($profile->settings['library']) && isset($editor['libraries'][$profile->settings['library']])) {
|
||||
@ -305,9 +329,33 @@ function wysiwyg_load_editor($profile) {
|
||||
$files = array_shift($editor['libraries']);
|
||||
$files = $files['files'];
|
||||
}
|
||||
|
||||
// Check whether the editor requires an initialization script.
|
||||
if (!empty($editor['init callback'])) {
|
||||
$init = $editor['init callback']($editor, $library, $profile);
|
||||
if (!empty($init)) {
|
||||
// Build a file for each of the editors to hold the init scripts.
|
||||
// @todo Aggregate all initialization scripts into one file.
|
||||
$uri = 'public://js/wysiwyg/wysiwyg_' . $name . '_' . drupal_hash_base64($init) . '.js';
|
||||
$init_exists = file_exists($uri);
|
||||
if (!$init_exists) {
|
||||
$js_path = dirname($uri);
|
||||
file_prepare_directory($js_path, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS);
|
||||
}
|
||||
// Attempt to create the file, or fall back to an inline script (which
|
||||
// will not work in Ajax calls).
|
||||
if (!$init_exists && !file_unmanaged_save_data($init, $uri, FILE_EXISTS_REPLACE)) {
|
||||
drupal_add_js($init, array('type' => 'inline') + $default_library_options);
|
||||
}
|
||||
else {
|
||||
drupal_add_js(file_create_url($uri), $default_library_options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($files as $file => $options) {
|
||||
if (is_array($options)) {
|
||||
$options += array('type' => 'file', 'scope' => 'header', 'defer' => FALSE, 'cache' => TRUE, 'preprocess' => TRUE);
|
||||
$options += $default_library_options;
|
||||
drupal_add_js($editor['library path'] . '/' . $file, $options);
|
||||
}
|
||||
else {
|
||||
@ -335,17 +383,6 @@ function wysiwyg_load_editor($profile) {
|
||||
foreach ($files as $file) {
|
||||
drupal_add_css($editor['css path'] . '/' . $file);
|
||||
}
|
||||
|
||||
drupal_add_js(array('wysiwyg' => array(
|
||||
'configs' => array($editor['name'] => array('global' => array(
|
||||
// @todo Move into (global) editor settings.
|
||||
// If JS compression is enabled, at least TinyMCE is unable to determine
|
||||
// its own base path and exec mode since it can't find the script name.
|
||||
'editorBasePath' => base_path() . $editor['library path'],
|
||||
'execMode' => $library,
|
||||
))),
|
||||
)), 'setting');
|
||||
|
||||
$loaded[$name] = TRUE;
|
||||
}
|
||||
else {
|
||||
@ -362,7 +399,6 @@ function wysiwyg_load_editor($profile) {
|
||||
'enable' => t('Enable rich-text'),
|
||||
)), 'setting');
|
||||
|
||||
$path = drupal_get_path('module', 'wysiwyg');
|
||||
// Initialize our namespaces in the *header* to do not force editor
|
||||
// integration scripts to check and define Drupal.wysiwyg on its own.
|
||||
drupal_add_js($path . '/wysiwyg.init.js', array('group' => JS_LIBRARY));
|
||||
@ -619,7 +655,10 @@ function wysiwyg_get_css() {
|
||||
$files = array();
|
||||
foreach (drupal_add_css() as $filepath => $info) {
|
||||
if ($info['group'] >= CSS_THEME && $info['media'] != 'print') {
|
||||
if (file_exists($filepath)) {
|
||||
if ($info['type'] == 'external') {
|
||||
$files[] = $filepath;
|
||||
}
|
||||
elseif (file_exists($filepath)) {
|
||||
$files[] = base_path() . $filepath;
|
||||
}
|
||||
}
|
||||
@ -809,6 +848,7 @@ function wysiwyg_get_all_editors() {
|
||||
'libraries' => array(),
|
||||
'version callback' => NULL,
|
||||
'themes callback' => NULL,
|
||||
'settings form callback' => NULL,
|
||||
'settings callback' => NULL,
|
||||
'plugin callback' => NULL,
|
||||
'plugin settings callback' => NULL,
|
||||
@ -1077,3 +1117,19 @@ function _wysiwyg_process_include($module, $identifier, $path, $hook) {
|
||||
/**
|
||||
* @} End of "defgroup wysiwyg_api".
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_features_api().
|
||||
*/
|
||||
function wysiwyg_features_api() {
|
||||
return array(
|
||||
'wysiwyg' => array(
|
||||
'name' => t('Wysiwyg profiles'),
|
||||
'default_hook' => 'wysiwyg_default_profiles',
|
||||
'default_file' => FEATURES_DEFAULTS_INCLUDED,
|
||||
'feature_source' => TRUE,
|
||||
'file' => drupal_get_path('module', 'wysiwyg') . '/wysiwyg.features.inc',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user