ckbuilder-2.3.2/ 0000775 0000000 0000000 00000000000 13230353051 0013455 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/LICENSE.md 0000664 0000000 0000000 00000005743 13230353051 0015072 0 ustar 00root root 0000000 0000000 Software License Agreement
==========================
CKBuilder - release builder for CKEditor.
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
Licensed under the terms of the [MIT License](http://en.wikipedia.org/wiki/MIT_License) (see Appendix A).
Sources of Intellectual Property Included in CKBuilder
-----------------------------------------------------
Where not otherwise indicated, all CKBuilder content is authored by
CKSource engineers and consists of CKSource-owned intellectual
property. In some specific instances, CKBuilder will incorporate work
done by developers outside of CKSource with their express permission.
### Commons CLI ###
The Apache Commons CLI library provides an API for parsing command line options passed to programs.
Location: `lib/apache`
License: Apache License, Version 2.0
### Google Closure Compiler ###
The Closure Compiler performs checking, instrumentation, and optimizations on JavaScript code.
Location: `lib/closure`
License: Apache License, Version 2.0
### JSON ###
Location: `lib/json`
License: Public Domain
### Rhino ###
Rhino is an open source JavaScript engine.
Location: `lib/rhino`
License: MPL 2.0
### JTar ###
JTar is a simple Java Tar library, that provides an easy way to create and read tar files using IO streams.
Location: `lib/javatar`
License: Public Domain
### Java Tar Package (TarTool) ###
Location: `lib/tartool`
License: Public Domain
### cssmin.js / YUI Compressor ###
A JavaScript port of the CSS minification tool.
Location: `src/lib/cssmin.js`
License: YUI Compressor Copyright License Agreement (revised BSD License)
Trademarks
----------
CKBuilder and CKEditor are trademarks of CKSource - Frederico Knabben. All other
brand and product names are trademarks, registered trademarks or service
marks of their respective holders.
---
Appendix A: The MIT License
---------------------------
The MIT License (MIT)
Copyright (c) 2012-2018, CKSource - Frederico Knabben
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
ckbuilder-2.3.2/README.md 0000664 0000000 0000000 00000006165 13230353051 0014744 0 ustar 00root root 0000000 0000000 CKBuilder
=========
This repository contains the source files of CKBuilder, **a command line builder** for [CKEditor](https://github.com/ckeditor/ckeditor-dev).
CKBuilder generates release packages of CKEditor out of its source code.
### Compiling CKBuilder
You can compile CKBuilder into a single .jar file by running `build_jar.sh` located in the `dev\build` folder. The compiled file will be generated in the `bin` folder.
[Apache Ant](http://ant.apache.org) is required to run it.
### Using CKBuilder source files
You can generate a CKEditor release version using CKBuilder source files by running `build.sh` available in the `dev\scripts` folder. The release version of CKEditor will be generated in the `release` folder.
Make sure to download the CKEditor submodule first:
> git submodule update --init
### Using the default ckbuilder.jar
If you did not compile your own version of `ckbuilder.jar` and all you want to do is to build CKEditor, then there is a simpler way to do this:
1. Clone the [CKEditor](https://github.com/ckeditor/ckeditor-dev) repository.
2. Inside ckeditor-dev run:
```
> ./dev/builder/build.sh
```
3. That's it - CKBuilder will be downloaded automatically and a "release" version of CKEditor will be built in the new `dev/builder/release/` folder.
**Note:** CKBuilder which is run by calling ```build.sh``` script will use default ```build-config.js``` which define skin, files to be ignored and plugins. For more information about build-config run builder with ```--build-help``` command.
**Note2:** The shell script is designed to run on Mac/Linux. If you are a Windows user, install [Git for Windows](http://msysgit.github.io/), make sure "Git Bash" is checked during the installation process and then run this script using "Git Bash".
### Using a custom ckbuilder.jar
To get the list of all available commands and options, run:
> java -jar ckbuilder.jar --help
#### Available commands
This is just an overview of available commands. For more details, check the built-in help options.
**--help | --build-help | --full-help**
Display various help information.
**--build**
Build CKEditor, definitely the most frequently used command.
**--build-skin**
Creates a release version of a skin (icons are merged into a single strip image, CSS files are merged and minified, JavaScript files are minified).
Note: if you want to share your skin with others, do **not** upload the release version of a skin to the [CKEditor addons repository](http://ckeditor.com/addons/skins/all), upload the source version instead.
**--verify-plugin | --verify-skin**
Used by the online builder to verify if a plugin or skin is valid. If you have problems with uploading a skin or a plugin, it might be because this command returned errors.
**--preprocess-core | --preprocess-plugin | --preprocess-skin**
Used by the [online builder](http://ckeditor.com/builder), unless you intend to do a similar service, you don't need it.
**--generate-build-config**
Creates a fresh `build-config.js`.
### Build config
### License
Licensed under the terms of the MIT License. For full details about license, please check LICENSE.md file.
ckbuilder-2.3.2/dev/ 0000775 0000000 0000000 00000000000 13230353051 0014233 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/dev/build/ 0000775 0000000 0000000 00000000000 13230353051 0015332 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/dev/build/build.xml 0000664 0000000 0000000 00000010717 13230353051 0017161 0 ustar 00root root 0000000 0000000
ckbuilder-2.3.2/dev/build/build_jar.sh 0000775 0000000 0000000 00000000303 13230353051 0017620 0 ustar 00root root 0000000 0000000 #!/bin/sh
# Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
# For licensing, see LICENSE.md
# Creates CKBuilder jar file (in the "bin" directory).
ant jar
ant clean ckbuilder-2.3.2/dev/jshint/ 0000775 0000000 0000000 00000000000 13230353051 0015532 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/dev/jshint/.jshintrc 0000664 0000000 0000000 00000002625 13230353051 0017364 0 ustar 00root root 0000000 0000000 {
"bitwise" : false,
// "forin" : true,
"immed" : true,
"latedef" : true,
"nonew" : true,
"smarttabs" : true,
"trailing" : true,
"undef" : true,
"unused": true,
"rhino" : true,
// "curly": true,
"eqnull": true,
"eqeqeq": true,
"noarg": true,
// "onevar": true,,
"globals": {
"CKBuilder": false,
"CKBuilderTest": false,
"Integer": false,
"ImageIO": false,
"System": false,
"print": false,
"YAHOO": false,
"javax": false,
"com": false,
"org": false,
"BufferedImage": false,
"BufferedInputStream": false,
"BufferedOutputStream": false,
"BufferedReader": false,
"BufferedWriter": false,
"File": false,
"FileInputStream": false,
"FileOutputStream": false,
"InputStreamReader": false,
"OutputStreamWriter": false,
"Packages": false,
"Pattern": false,
"StringBuffer": false,
"ZipEntry": false,
"ZipFile": false,
"ZipOutputStream": false,
// Rhino
"importClass": false,
"importPackage": false,
"Context": false,
"CompilerEnvirons": false,
// Closure Compiler
"Compiler": false,
"CompilerOptions": false,
"CompilationLevel": false,
"SourceFile": false,
// Apache Commons CLI
"HelpFormatter": false,
"Options": false,
"OptionBuilder": false,
// com.ice.tar
"TarEntry": false,
"TarGzOutputStream": false,
// Apache Commons CLI
"PosixParser": false
}
}
ckbuilder-2.3.2/dev/jshint/jshint.sh 0000775 0000000 0000000 00000000337 13230353051 0017373 0 ustar 00root root 0000000 0000000 #!/bin/sh
# Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
# For licensing, see LICENSE.md
# Runs jshint on source files.
jshint -c .jshintrc --show-non-errors ../../src/*.js ../../src/*/*.js ckbuilder-2.3.2/dev/scripts/ 0000775 0000000 0000000 00000000000 13230353051 0015722 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/dev/scripts/build.sh 0000775 0000000 0000000 00000001515 13230353051 0017362 0 ustar 00root root 0000000 0000000 #!/bin/sh
# Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
# For licensing, see LICENSE.md
# Builds CKEditor release using the source version of CKBuilder (useful for debugging issues in CKBuilder).
echo ""
echo "Starting CKBuilder..."
SCRIPTDIR=$(dirname $0)
# Move to the script directory.
cd $SCRIPTDIR/ckeditor
rev=`git rev-parse --verify --short HEAD`
# Move to the CKBuilder root folder.
cd ../../..
java -cp lib/apache/commons-cli.jar:lib/rhino/js.jar:lib/javatar/tar.jar:lib/closure/compiler.jar \
org.mozilla.javascript.tools.shell.Main -opt -1 src/ckbuilder.js \
--build dev/scripts/ckeditor dev/scripts/release --build-config dev/scripts/ckeditor/dev/builder/build-config.js --overwrite --version=DEV --revision=$rev $@
cd $SCRIPTDIR
echo ""
echo "Release created in the \"release\" directory."
ckbuilder-2.3.2/dev/scripts/ckeditor/ 0000775 0000000 0000000 00000000000 13230353051 0017526 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/docs/ 0000775 0000000 0000000 00000000000 13230353051 0014405 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/docs/build.sh 0000775 0000000 0000000 00000000245 13230353051 0016044 0 ustar 00root root 0000000 0000000 #!/bin/sh
# Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
# For licensing, see LICENSE.md
# Create internal API documentation
jsduck ckbuilder-2.3.2/docs/jsduck.json 0000664 0000000 0000000 00000000550 13230353051 0016563 0 ustar 00root root 0000000 0000000 {
"--title": "CKBuilder Source Code Documentation",
"--footer": "Copyright © 2012-2014, CKSource - Frederico Knabben. All rights reserved. | Generated with JSDuck.",
"--warnings": "-nodoc",
"--output": "./output",
"--": [
"../src"
]
} ckbuilder-2.3.2/lib/ 0000775 0000000 0000000 00000000000 13230353051 0014223 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/lib/apache/ 0000775 0000000 0000000 00000000000 13230353051 0015444 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/lib/apache/LICENSE.txt 0000664 0000000 0000000 00000026136 13230353051 0017277 0 ustar 00root root 0000000 0000000 Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ckbuilder-2.3.2/lib/closure/ 0000775 0000000 0000000 00000000000 13230353051 0015677 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/lib/closure/COPYING 0000664 0000000 0000000 00000026136 13230353051 0016742 0 ustar 00root root 0000000 0000000
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
ckbuilder-2.3.2/lib/closure/README.md 0000664 0000000 0000000 00000031714 13230353051 0017164 0 ustar 00root root 0000000 0000000 # [Google Closure Compiler](https://developers.google.com/closure/compiler/)
[](https://travis-ci.org/google/closure-compiler)
The [Closure Compiler](https://developers.google.com/closure/compiler/) is a tool for making JavaScript download and run faster. It is a true compiler for JavaScript. Instead of compiling from a source language to machine code, it compiles from JavaScript to better JavaScript. It parses your JavaScript, analyzes it, removes dead code and rewrites and minimizes what's left. It also checks syntax, variable references, and types, and warns about common JavaScript pitfalls.
## Getting Started
* [Download the latest version](http://dl.google.com/closure-compiler/compiler-latest.zip) ([Release details here](https://github.com/google/closure-compiler/wiki/Releases))
* [Download a specific version](https://github.com/google/closure-compiler/wiki/Binary-Downloads). Also available via:
- [Maven](https://github.com/google/closure-compiler/wiki/Maven)
- [NPM](https://www.npmjs.com/package/google-closure-compiler)
* See the [Google Developers Site](https://developers.google.com/closure/compiler/docs/gettingstarted_app) for documentation including instructions for running the compiler from the command line.
## Options for Getting Help
1. Post in the [Closure Compiler Discuss Group](https://groups.google.com/forum/#!forum/closure-compiler-discuss)
2. Ask a question on [Stack Overflow](http://stackoverflow.com/questions/tagged/google-closure-compiler)
3. Consult the [FAQ](https://github.com/google/closure-compiler/wiki/FAQ)
## Building it Yourself
Note: The Closure Compiler requires [Java 7 or higher](http://www.java.com/).
### Using [Ant](http://ant.apache.org/)
1. Download the [Ant build tool](http://ant.apache.org/bindownload.cgi).
2. At the root of the source tree, there is an Ant file named ```build.xml```.
To use it, navigate to the same directory and type the command
```
ant jar
```
This will produce a jar file called ```build/compiler.jar```.
### Using [Eclipse](http://www.eclipse.org/)
1. Download and open the [Eclipse IDE](http://www.eclipse.org/).
2. Navigate to ```File > New > Project ...``` and create a Java Project. Give
the project a name.
3. Select ```Create project from existing source``` and choose the root of the
checked-out source tree as the existing directory.
3. Navigate to the ```build.xml``` file. You will see all the build rules in
the Outline pane. Run the ```jar``` rule to build the compiler in
```build/compiler.jar```.
## Running
On the command line, at the root of this project, type
```
java -jar build/compiler.jar
```
This starts the compiler in interactive mode. Type
```javascript
var x = 17 + 25;
```
then hit "Enter", then hit "Ctrl-Z" (on Windows) or "Ctrl-D" (on Mac or Linux)
and "Enter" again. The Compiler will respond:
```javascript
var x=42;
```
The Closure Compiler has many options for reading input from a file, writing
output to a file, checking your code, and running optimizations. To learn more,
type
```
java -jar compiler.jar --help
```
More detailed information about running the Closure Compiler is available in the
[documentation](http://code.google.com/closure/compiler/docs/gettingstarted_app.html).
## Compiling Multiple Scripts
If you have multiple scripts, you should compile them all together with one
compile command.
```bash
java -jar compiler.jar --js_output_file=out.js in1.js in2.js in3.js ...
```
You can also use minimatch-style globs.
```bash
# Recursively include all js files in subdirs
java -jar compiler.jar --js_output_file=out.js 'src/**.js'
# Recursively include all js files in subdirs, exclusing test files.
# Use single-quotes, so that bash doesn't try to expand the '!'
java -jar compiler.jar --js_output_file=out.js 'src/**.js' '!**_test.js'
```
The Closure Compiler will concatenate the files in the order they're passed at
the command line.
If you're using globs or many files, you may start to run into
problems with managing dependencies between scripts. In this case, you should
use the [Closure Library](https://developers.google.com/closure/library/). It
contains functions for enforcing dependencies between scripts, and Closure Compiler
will re-order the inputs automatically.
## How to Contribute
### Reporting a bug
1. First make sure that it is really a bug and not simply the way that Closure Compiler works (especially true for ADVANCED_OPTIMIZATIONS).
* Check the [official documentation](https://developers.google.com/closure/compiler/)
* Consult the [FAQ](https://github.com/google/closure-compiler/wiki/FAQ)
* Search on [Stack Overflow](http://stackoverflow.com/questions/tagged/google-closure-compiler) and in the [Closure Compiler Discuss Group](https://groups.google.com/forum/#!forum/closure-compiler-discuss)
2. If you still think you have found a bug, make sure someone hasn't already reported it. See the list of [known issues](https://github.com/google/closure-compiler/issues).
3. If it hasn't been reported yet, post a new issue. Make sure to add enough detail so that the bug can be recreated. The smaller the reproduction code, the better.
### Suggesting a Feature
1. Consult the [FAQ](https://github.com/google/closure-compiler/wiki/FAQ) to make sure that the behaviour you would like isn't specifically excluded (such as string inlining).
2. Make sure someone hasn't requested the same thing. See the list of [known issues](https://github.com/google/closure-compiler/issues).
3. Read up on [what type of feature requests are accepted](https://github.com/google/closure-compiler/wiki/FAQ#how-do-i-submit-a-feature-request-for-a-new-type-of-optimization).
4. Submit your reqest as an issue.
### Submitting patches
1. All contributors must sign a contributor license agreement (CLA).
A CLA basically says that you own the rights to any code you contribute,
and that you give us permission to use that code in Closure Compiler.
You maintain the copyright on that code.
If you own all the rights to your code, you can fill out an
[individual CLA](http://code.google.com/legal/individual-cla-v1.0.html).
If your employer has any rights to your code, then they also need to fill out
a [corporate CLA](http://code.google.com/legal/corporate-cla-v1.0.html).
If you don't know if your employer has any rights to your code, you should
ask before signing anything.
By default, anyone with an @google.com email address already has a CLA
signed for them.
2. To make sure your changes are of the type that will be accepted, ask about your patch on the [Closure Compiler Discuss Group](https://groups.google.com/forum/#!forum/closure-compiler-discuss)
3. Fork the repository.
4. Make your changes.
5. Submit a pull request for your changes. A project developer will review your work and then merge your request into the project.
## Closure Compiler License
Copyright 2009 The Closure Compiler Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
## Dependency Licenses
### Rhino
Code Path |
src/com/google/javascript/rhino , test/com/google/javascript/rhino
|
URL |
http://www.mozilla.org/rhino |
Version |
1.5R3, with heavy modifications |
License |
Netscape Public License and MPL / GPL dual license |
Description |
A partial copy of Mozilla Rhino. Mozilla Rhino is an
implementation of JavaScript for the JVM. The JavaScript
parse tree data structures were extracted and modified
significantly for use by Google's JavaScript compiler. |
Local Modifications |
The packages have been renamespaced. All code not
relevant to the parse tree has been removed. A JsDoc parser and static typing
system have been added. |
### Args4j
Code Path |
lib/args4j.jar |
URL |
https://args4j.dev.java.net/ |
Version |
2.0.26 |
License |
MIT |
Description |
args4j is a small Java class library that makes it easy to parse command line
options/arguments in your CUI application. |
Local Modifications |
None |
### Guava Libraries
Code Path |
lib/guava.jar |
URL |
https://github.com/google/guava |
Version |
18.0 |
License |
Apache License 2.0 |
Description |
Google's core Java libraries. |
Local Modifications |
None |
### JSR 305
Code Path |
lib/jsr305.jar |
URL |
http://code.google.com/p/jsr-305/ |
Version |
svn revision 47 |
License |
BSD License |
Description |
Annotations for software defect detection. |
Local Modifications |
None |
### JUnit
Code Path |
lib/junit.jar |
URL |
http://sourceforge.net/projects/junit/ |
Version |
4.11 |
License |
Common Public License 1.0 |
Description |
A framework for writing and running automated tests in Java. |
Local Modifications |
None |
### Protocol Buffers
Code Path |
lib/protobuf-java.jar |
URL |
http://code.google.com/p/protobuf/ |
Version |
2.5.0 |
License |
New BSD License |
Description |
Supporting libraries for protocol buffers,
an encoding of structured data. |
Local Modifications |
None |
### Truth
Code Path |
lib/truth.jar |
URL |
https://github.com/google/truth |
Version |
0.24 |
License |
Apache License 2.0 |
Description |
Assertion/Proposition framework for Java unit tests |
Local Modifications |
None |
### Ant
Code Path |
lib/ant.jar , lib/ant-launcher.jar
|
URL |
http://ant.apache.org/bindownload.cgi |
Version |
1.8.1 |
License |
Apache License 2.0 |
Description |
Ant is a Java based build tool. In theory it is kind of like "make"
without make's wrinkles and with the full portability of pure java code. |
Local Modifications |
None |
### GSON
Code Path |
lib/gson.jar |
URL |
https://code.google.com/p/google-gson/ |
Version |
2.2.4 |
License |
Apache license 2.0 |
Description |
A Java library to convert JSON to Java objects and vice-versa |
Local Modifications |
None |
### Node.js Closure Compiler Externs
Code Path |
contrib/nodejs |
URL |
https://github.com/dcodeIO/node.js-closure-compiler-externs |
Version |
e891b4fbcf5f466cc4307b0fa842a7d8163a073a |
License |
Apache 2.0 license |
Description |
Type contracts for NodeJS APIs |
Local Modifications |
Substantial changes to make them compatible with NpmCommandLineRunner. |
ckbuilder-2.3.2/lib/javatar/ 0000775 0000000 0000000 00000000000 13230353051 0015653 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/lib/javatar/LICENSE.txt 0000664 0000000 0000000 00000000612 13230353051 0017475 0 ustar 00root root 0000000 0000000
---- Public Domain ----
This work was autored by Timothy Gerard Endres, time@gjt.org.
This work has been placed into the public domain.
You are free to use this work in any way you wish.
DISCLAIMER
THIS SOFTWARE IS PROVIDED AS-IS, WITH ABSOLUTELY NO WARRANTY.
YOU ASSUME ALL RESPONSIBILITY FOR ANY AND ALL CONSEQUENCES
THAT MAY RESULT FROM THE USE OF THIS SOFTWARE!
ckbuilder-2.3.2/lib/json/ 0000775 0000000 0000000 00000000000 13230353051 0015174 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/lib/rhino/ 0000775 0000000 0000000 00000000000 13230353051 0015342 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/lib/rhino/LICENSE.txt 0000664 0000000 0000000 00000040614 13230353051 0017172 0 ustar 00root root 0000000 0000000 The majority of Rhino is licensed under the MPL 2.0:
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.
ckbuilder-2.3.2/lib/tartool/ 0000775 0000000 0000000 00000000000 13230353051 0015707 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/src/ 0000775 0000000 0000000 00000000000 13230353051 0014244 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/src/assets/ 0000775 0000000 0000000 00000000000 13230353051 0015546 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/src/assets/help-build.txt 0000664 0000000 0000000 00000003371 13230353051 0020340 0 ustar 00root root 0000000 0000000 The build configuration is a critical file required to build the release.
A sample build configuration (build-config.js) looks as follows:
var CKBUILDER_CONFIG = {
skin : 'kama',
ignore : [
'_dev',
'.gitignore',
'.gitattributes'
],
plugins :
{
a11yhelp : 1,
about : 1,
// more plugins
},
js : [
'/path/to/file1.js,start'
'/path/to/file2.js,aftercore',
'/path/to/file3.js,end',
'/path/to/file4.js',
]
}
[PROPERTIES]
skin The name of the default skin.
ignore The set of files/folders to ignore.
plugins The list of plugins to include in the release.
js An optional array of javascript files to append at the end
of ckeditor.js.
It is possible to specify precisely, where the file should
be added to ckeditor.js. Add a colon and one of the
properties: start, aftercore, end.
start prepend javascript files at the beginning of
ckeditor.js
aftercore add javascript files in the middle of
ckeditor.js, before plugin files
end add javascript files at the end (default).
In oder to generate the base build configuration file (build-config.js), run the
following command:
java -jar ckbuilder.jar --generate-build-config ckeditor-dev
("ckeditor-dev" is the name of a folder with source files).
After commenting out plugins that are not needed, to build the release run:
java -jar ckbuilder.jar --build ckeditor-dev release --version 4.0
Need more help? Run:
java -jar ckbuilder.jar --help
ckbuilder-2.3.2/src/assets/help-extra.txt 0000664 0000000 0000000 00000005632 13230353051 0020366 0 ustar 00root root 0000000 0000000 ** ADVANCED COMMANDS **
If you're unsure what these commands are for, just ignore them.
[TASK: preprocess core files]
SYNOPSIS:
--preprocess-core SRC DST (options...)
[OPTIONS]
SRC source folder
DST destination folder
[OPTIONS]
--build-config path to the file
--version version number
--revision revision number
--leave-js-unminified leave javascript files as is:
merge, but do not minify.
--no-ie-checks turn off warnings about syntax errors on
Internet Explorer, like trailing commas
DESCRIPTION:
Preprocess core files. Creates ckeditor.js with no plugins enabled.
Converts language files into "intermediate" format.
EXAMPLE:
java -jar ckbuilder.jar --preprocess-core ckeditor-dev output
[TASK: preprocess plugin]
SYNOPSIS:
--preprocess-plugin SRC DST (options...)
[OPTIONS]
SRC source folder
DST destination folder
[OPTIONS]
--build-config path to the file
--leave-js-unminified leave javascript files as is
--no-ie-checks turn off warnings about syntax errors on
Internet Explorer, like trailing commas
DESCRIPTION:
Preprocess plugin folder. Minifies JavaScript files.
Fixes missing entries and converts language files into "intermediate" format.
EXAMPLE:
java -jar ckbuilder.jar --preprocess-plugin devtools output
[TASK: preprocess skin]
SYNOPSIS:
--preprocess-skin SRC DST (options...)
[OPTIONS]
SRC source folder
DST destination folder
[OPTIONS]
--build-config path to the file
--leave-js-unminified leave javascript files as is
--no-ie-checks turn off warnings about syntax errors on
Internet Explorer, like trailing commas
DESCRIPTION:
Preprocess skin folder. Minifies JavaScript files.
Merges CSS files.
EXAMPLE:
java -jar ckbuilder.jar --preprocess-skin kama output
[TASK: verify plugin]
SYNOPSIS:
--verify-plugin SRC
[OPTIONS]
SRC source folder (or zip file)
[OPTIONS]
--name the name of the plugin to be found in plugin.js
DESCRIPTION:
Verifies the plugin folder / zip file with a plugin.
Checks for plugin.js and tries to parse JS files looking for syntax errors.
EXAMPLE:
java -jar ckbuilder.jar --verify-plugin devtools
[TASK: verify skin]
SYNOPSIS:
--verify-skin SRC
[OPTIONS]
SRC source folder (or zip file)
[OPTIONS]
--name the name of the skin to be found in skin.js
DESCRIPTION:
Verifies the skin folder / zip file with a skin.
Checks for skin.js and tries to parse JS files looking for syntax errors.
EXAMPLE:
java -jar ckbuilder.jar --verify-skin kama
ckbuilder-2.3.2/src/assets/help.txt 0000664 0000000 0000000 00000005553 13230353051 0017247 0 ustar 00root root 0000000 0000000 CKBuilder 2.3.2
USAGE: java -jar ckbuilder.jar
[TASK: build release]
SYNOPSIS:
--build SRC DST (options...)
SRC source folder
DST destination folder
[OPTIONS]
--build-config path to the file
--version version number
--revision revision number
--overwrite overwrite target folder if exists
-s,--skip-omitted-in-build-config
exclude from release all plugins/skins
that are not specified in build-config
--leave-js-unminified leave javascript files as is:
merge, but do not minify.
--leave-css-unminified leave CSS files as is:
merge, but do not minify.
--no-ie-checks turn off warnings about syntax errors on
Internet Explorer, like trailing commas
--core create only the core file (ckeditor.js)
--no-zip do not create zip file
--no-tar do not create tar.gz file
--commercial builds a package with commercial license
DESCRIPTION:
Creates CKEditor build in DST folder using source files from SRC folder.
The build configuration file (build-config.js), which is required in order to
create the build package, contains the list of plugins to include.
EXAMPLE:
java -jar ckbuilder.jar --build ckeditor-dev release --version 4.0
[TASK: build skin]
SYNOPSIS:
--build-skin SRC DST (options...)
SRC source folder
DST destination folder
[OPTIONS]
--overwrite overwrite target folder if exists
--leave-js-unminified leave javascript files as is:
merge, but do not minify.
--leave-css-unminified leave CSS files as is:
merge, but do not minify.
--no-ie-checks turn off warnings about syntax errors on
Internet Explorer, like trailing commas
DESCRIPTION:
Creates a release version of a skin.
EXAMPLE:
java -jar ckbuilder.jar --build-skin skins/myskin target_dir
[TASK: create build configuration file]
SYNOPSIS:
--generate-build-config SRC (options...)
SRC source folder
[OPTIONS]
--build-config path to the new file
DESCRIPTION:
Creates build configuration file (default: build-config.js).
EXAMPLE:
java -jar ckbuilder.jar --generate-build-config ckeditor-dev
[OTHER OPTIONS]
-d,--debug-level debug level (0, 1, 2).
--help prints help information
--build-help prints help information about build configuration
--full-help prints help information about all advanced commands
ckbuilder-2.3.2/src/ckbuilder.js 0000664 0000000 0000000 00000005545 13230353051 0016557 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
importPackage( org.mozilla.javascript );
importClass( java.lang.System );
importClass( java.lang.Integer );
/**
* @class java.io.File
*
* Check out [official java.io.File documentation][1] for more.
*
* [1]: http://docs.oracle.com/javase/7/docs/api/java/io/File.html
*/
/**
* @class java.io.OutputStream
*
* Check out [official java.io.File documentation][1] for more.
*
* [1]: http://docs.oracle.com/javase/7/docs/api/java/io/OutputStream.html
*/
/**
* @class
*
* Main file which is run from Rhino. Responsible for load scripts and run controller.
*/
this.CKBuilder = ( function() {
var isMinified = true;
try {
java.lang.Class.forName( "ckbuilder.ckbuilder" );
} catch ( e ) {
isMinified = false;
}
var now = new Date();
var timestamp = Integer.toString( now.getUTCFullYear() % 1000, 36 ) + Integer.toString( now.getUTCMonth(), 36 ) + Integer.toString( now.getUTCDate(), 36 ) + Integer.toString( now.getUTCHours(), 36 );
timestamp = timestamp.toUpperCase();
return {
isMinified : isMinified,
options : {
debug : 0,
all : true,
overwrite : false,
version : 'DEV',
revision : 0,
timestamp : timestamp
},
error : function( msg ) {
print( 'ERROR:' );
print( msg );
print( '' );
// quit() does not work when compiled.
System.exit( 1000 );
},
load : function( className ) {
if ( isMinified )
loadClass( className );
else
{
var path = className;
if ( path.indexOf( "ckbuilder." ) === 0 )
path = path.replace( /^ckbuilder\./, "src/" );
else
path = path.replace( /^tools\./, 'lib/' );
path = path.replace( /\./g, '/' ) + '.js';
load( path );
}
}
};
} )();
/* jshint ignore:start */
function print( arg ) {
if ( arg === undefined )
arg = 'undefined';
if ( arg === null)
arg = 'null';
System.out.println( arg );
}
/* jshint ignore:end */
CKBuilder.DEFAULT_SKIN = 'moono';
CKBuilder.DEFAULT_LANGUAGE = 'en';
CKBuilder.load( 'tools.json.json2' );
CKBuilder.load( 'ckbuilder.lib.controller' );
CKBuilder.load( 'ckbuilder.lib.io' );
CKBuilder.load( 'ckbuilder.lib.css' );
CKBuilder.load( 'ckbuilder.lib.cssmin' );
CKBuilder.load( 'ckbuilder.lib.image' );
CKBuilder.load( 'ckbuilder.lib.lang' );
CKBuilder.load( 'ckbuilder.lib.javascript' );
CKBuilder.load( 'ckbuilder.lib.config' );
CKBuilder.load( 'ckbuilder.lib.samples' );
CKBuilder.load( 'ckbuilder.lib.plugin' );
CKBuilder.load( 'ckbuilder.lib.skin' );
CKBuilder.load( 'ckbuilder.lib.utils' );
CKBuilder.load( 'ckbuilder.lib.tools' );
CKBuilder.load( 'ckbuilder.lib.builder' );
if ( typeof CKBuilderTest === 'undefined' ) {
var controller = new CKBuilder.Controller();
controller.run( arguments );
}
ckbuilder-2.3.2/src/lib/ 0000775 0000000 0000000 00000000000 13230353051 0015012 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/src/lib/builder.js 0000664 0000000 0000000 00000061322 13230353051 0017002 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
/**
* Responsible for preprocess core, generate build and generate core.
*
* @class
* @param {String} srcDir
* @param {String} dstDir
*/
CKBuilder.builder = function( srcDir, dstDir ) {
/**
* Build configuration.
*
* @property {Object} config
*/
var config = {};
/**
* The main target skin file.
*
* @type {java.io.File}
*/
var targetSkinFile;
/**
* The main source skin file.
*
* @type {java.io.File}
*/
var sourceSkinFile;
/**
* The main language file.
*
* @type {java.io.File}
*/
var languageFile;
/**
* The list of "core" scripts.
* "Helper" variable used to mark script as loaded in "coreScriptsSorted".
*
* @type {Object}
*/
var coreScripts = {};
/**
* The list of "core" scripts, sorted by the loading order.
*
* @type {Array}
*/
var coreScriptsSorted = [];
/**
* The hash map with the list of plugins to include in ckeditor.js.
* The key is the name of the plugin.
* The value indicates whether the plugin is included in ckeditor.js (true).
*
* @type {Object}
*/
var pluginNames = {};
/**
* The list of plugin files to include in ckeditor.js, sorted by the loading order.
*
* @type {Object}
*/
var sourcePluginFilesSorted = [];
/**
* The list of plugin files to include in ckeditor.js, sorted by the loading order.
*
* @type {Object}
*/
var targetPluginFilesSorted = [];
/**
* Paths to extra files to be included in ckeditor.js, defined by the "js" property.
*
* @type {Object}
*/
var extraCoreJavaScriptFiles = null;
/**
* The extra code to be included in ckeditor.js, defined by the "js" property,
*
* @type {Object}
*/
var extraCoreJavaScriptCode = {};
/**
* The list of plugin names to include in ckeditor.js, sorted by the loading order.
*
* @type {Array}
*/
var pluginNamesSorted = [];
/**
* The "scripts" definition in the loader file.
*
* @type {Array}
*/
var loaderScripts;
/**
* Source location with CKEditor source files.
*
* @type {java.io.File}
*/
var sourceLocation = new File( srcDir );
/**
* Target location where the release will be built.
*
* @type {java.io.File}
*/
var targetLocation = new File( dstDir, 'ckeditor' );
/**
* Checks for some required files/folders and throws an error in case of missing items.
*/
function validateSourceFolder() {
if ( !sourceLocation.exists() )
CKBuilder.error( 'Source folder does not exist: ' + srcDir );
if ( !sourceLocation.isDirectory() )
CKBuilder.error( 'Source folder is not a directory: ' + srcDir );
var requiredFiles = [
'lang/' + ( config.language || CKBuilder.DEFAULT_LANGUAGE ) + '.js',
'core/loader.js',
'ckeditor.js',
'lang',
'plugins'
];
if ( config.skin )
requiredFiles.push( 'skins/' + config.skin + '/skin.js' );
for ( var i = 0; i < requiredFiles.length; i++ ) {
var file = new File( sourceLocation, requiredFiles[ i ] );
if ( !file.exists() )
throw( 'The source directory is not invalid. The following file is missing: ' + file.getAbsolutePath() );
}
}
/**
* Initializes all variables required during the build process.
*/
function init() {
if ( config.skin ) {
sourceSkinFile = new File( sourceLocation, 'skins/' + ( config.skin ) + '/skin.js' );
targetSkinFile = new File( targetLocation, 'skins/' + ( config.skin ) + '/skin.js' );
}
languageFile = new File( targetLocation, 'lang/' + ( config.language || CKBuilder.DEFAULT_LANGUAGE ) + '.js' );
var loaderFile = new File( sourceLocation, 'core/loader.js' );
/*
* Execute script loader.js in core directory and read
* CKEDITOR.loader.scripts property
*/
loaderScripts = ( function() {
var code = 'var CKEDITOR = { basePath : \'/ckeditor/\' }; ' + CKBuilder.io.readFile( loaderFile ),
cx = Context.enter(),
scope = cx.initStandardObjects();
try {
cx.evaluateString( scope, code, loaderFile.getName(), 1, null );
return scope.CKEDITOR.loader.scripts;
} catch ( e ) {
throw( 'Invalid JavaScript file: ' + loaderFile.getAbsolutePath() + '.\nError: ' + e.message );
}
}() );
if ( !loaderScripts )
throw( 'Unable to get required scripts from loader: ' + loaderFile.getAbsolutePath() );
if ( CKBuilder.options.debug )
print( 'Reading core files from loader' );
getCoreScripts( 'ckeditor' );
getCoreScripts( '_bootstrap' );
if ( CKBuilder.options.debug )
print( 'Checking plugins dependency' );
findAllRequiredPlugins( getPluginsFromBuildConfig() );
}
/**
* Generates arrays with the list of core files to include.
*
* @param {String} scriptName
*/
function getCoreScripts( scriptName ) {
// Check if the script has already been loaded.
if ( scriptName === 'ckeditor_base' || scriptName in coreScripts )
return;
// Get the script dependencies list.
var dependencies = loaderScripts[ scriptName ];
if ( !dependencies )
throw( 'The script name"' + scriptName + '" is not defined.' );
// Mark as loaded
coreScripts[ scriptName ] = true;
// Load all dependencies first.
for ( var i = 0; i < dependencies.length; i++ )
getCoreScripts( dependencies[ i ] );
if ( CKBuilder.options.debug > 1 )
print( 'Found core script to load: core/' + scriptName + '.js' );
var file = new File( sourceLocation, 'core/' + scriptName + '.js' );
coreScriptsSorted.push( file );
}
/**
* Returns an array with plugins enabled in the builder configuration file.
*
* @returns {Array}
*/
function getPluginsFromBuildConfig() {
var plugins = [];
for ( var plugin in config.plugins ) {
if ( config.plugins[ plugin ] )
plugins.push( plugin );
}
return plugins;
}
/**
* Generates arrays with the list of all plugins to include.
*
* @param {Array} plugins
*/
function findAllRequiredPlugins( plugins ) {
var pluginFile;
for ( var i = 0; i < plugins.length; i++ ) {
if ( plugins[ i ] in pluginNames )
continue;
pluginFile = new File( sourceLocation, 'plugins/' + plugins[ i ] + '/plugin.js' );
if ( !pluginFile.exists() )
throw( 'Plugin does not exist: ' + plugins[ i ] + '. Unable to open: ' + pluginFile.getPath() );
else {
var required = CKBuilder.plugin.getRequiredPlugins( pluginFile );
if ( required.length ) {
pluginNames[ plugins[ i ] ] = false;
findAllRequiredPlugins( required );
}
// Previous call to findAllRequiredPlugins() could have added our plugin to the array.
if ( !( plugins[ i ] in pluginNames ) || !pluginNames[ plugins[ i ] ] ) {
pluginNames[ plugins[ i ] ] = true;
sourcePluginFilesSorted.push( File( sourceLocation, 'plugins/' + plugins[ i ] + '/plugin.js' ) );
targetPluginFilesSorted.push( File( targetLocation, 'plugins/' + plugins[ i ] + '/plugin.js' ) );
pluginNamesSorted.push( plugins[ i ] );
}
}
}
}
/**
* Delete unused files in the destination folder.
*/
function deleteUnusedFiles() {
CKBuilder.io.deleteDirectory( new File( targetLocation, 'core' ) );
for ( var i = 0; i < targetPluginFilesSorted.length; i++ ) {
var empty = true,
parentDir = targetPluginFilesSorted[ i ].getParentFile(),
dirList = parentDir.list();
for ( var j = 0; j < dirList.length; j++ ) {
if ( String( dirList[ j ] ) === 'icons' )
CKBuilder.io.deleteDirectory( new File( parentDir, dirList[ j ] ) ); else if ( String( dirList[ j ] ) === 'lang' )
CKBuilder.io.deleteDirectory( new File( parentDir, dirList[ j ] ) ); else if ( String( dirList[ j ] ) === 'plugin.js' )
CKBuilder.io.deleteFile( new File( parentDir, dirList[ j ] ) ); else
empty = false;
}
if ( empty )
CKBuilder.io.deleteDirectory( parentDir );
}
}
/**
* Remove unused plugins (not included in the build configuration file) from the plugins folder.
* Executed only when skip-omitted-in-build-config is enabled.
*/
function filterPluginFolders() {
var pluginsFolder = new File( targetLocation, 'plugins' );
if ( !pluginsFolder.exists() )
return;
var dirList = pluginsFolder.list();
for ( var i = 0; i < dirList.length; i++ ) {
if ( !pluginNames[ dirList[ i ] ] ) {
if ( CKBuilder.options.debug > 1 )
print( 'Removing unused plugin: ' + dirList[ i ] );
CKBuilder.io.deleteDirectory( File( pluginsFolder, dirList[ i ] ) );
}
}
}
/**
* Remove unused skins (not included in the build configuation file) from the skins folder.
* Executed only when skip-omitted-in-build-config is enabled.
* @param {String} selectedSkin
*/
function filterSkinsFolders( selectedSkin ) {
var skinsFolder = new File( targetLocation, 'skins' );
if ( !skinsFolder.exists() )
return;
var dirList = skinsFolder.list();
for ( var i = 0; i < dirList.length; i++ ) {
if ( String( dirList[ i ] ) !== selectedSkin ) {
if ( CKBuilder.options.debug > 1 )
print( 'Removing unused skin: ' + dirList[ i ] );
CKBuilder.io.deleteDirectory( File( skinsFolder, dirList[ i ] ) );
}
}
}
/**
* Build skins in the skins folder.
* @private
*/
function buildSkins() {
var skinsLocation = new File( targetLocation, 'skins' ),
pluginsLocation = new File( sourceLocation, 'plugins' );
if ( !skinsLocation.exists() )
return;
var dirList = skinsLocation.list();
for ( var i = 0; i < dirList.length; i++ ) {
var skinLocation = new File( skinsLocation, dirList[ i ] );
if ( skinLocation.isDirectory() ) {
if ( CKBuilder.options.debug > 1 )
print( 'Building skin: ' + dirList[ i ] );
var outputFile = new File( skinLocation, 'icons.png' ),
outputCssFile = new File( skinLocation, 'editor.css' );
CKBuilder.image.createFullSprite( pluginsLocation, skinLocation, outputFile, outputCssFile, pluginNamesSorted );
outputFile = new File( skinLocation, 'icons_hidpi.png' );
CKBuilder.image.createFullSprite( pluginsLocation, skinLocation, outputFile, outputCssFile, pluginNamesSorted, true );
CKBuilder.css.mergeCssFiles( skinLocation );
var iconsDir = new File( skinLocation, 'icons' );
if ( iconsDir.exists )
CKBuilder.io.deleteDirectory( File( skinLocation, 'icons' ) );
}
}
}
/**
* Copies files form source to the target location.
* The following actions are additionally executed:
* - line endings are fixed
* - directives are processed
* - JS files are minified
*
* @private
*/
function copyFiles( context ) {
var flags = {},
coreLocation = new File( sourceLocation, 'core' );
CKBuilder.io.copy( sourceLocation, targetLocation, function( sourceLocation, targetLocation ) {
if ( CKBuilder.config.isIgnoredPath( sourceLocation, config.ignore ) )
return -1;
if ( extraCoreJavaScriptFiles && extraCoreJavaScriptFiles[ sourceLocation.getAbsolutePath() ] )
return -1;
if ( sourceLocation.isFile() ) {
if ( context === 'build' && 'languages' in config ) {
try {
// Find the "lang" folder inside plugins' folders and ignore language files that are not selected
if ( String( sourceLocation.getParentFile().getName() ) === 'lang' && String( sourceLocation.getParentFile().getParentFile().getParentFile().getName() ) === 'plugins' && File( sourceLocation.getParentFile().getParentFile(), 'plugin.js' ).exists() ) {
var fileName = String( sourceLocation.getName() ),
langFile = fileName.match( /^([a-z]{2}(?:-[a-z]+)?)\.js$/ );
if ( langFile ) {
var langCode = langFile[ 1 ];
if ( !config.languages[ langCode ] )
return -1;
}
}
} catch ( e ) {
}
}
var copied = CKBuilder.tools.fixLineEndings( sourceLocation, targetLocation );
if ( copied ) {
if ( CKBuilder.options.commercial )
CKBuilder.tools.updateCopyrights( targetLocation );
var flag = CKBuilder.tools.processDirectives( targetLocation );
if ( flag.LEAVE_UNMINIFIED )
flags[ targetLocation.getAbsolutePath() ] = flag;
return 1;
}
} else {
if ( coreLocation.getAbsolutePath().equals( sourceLocation.getAbsolutePath() ) )
return -1;
// No plugins specified, special case to be able to build core only
if ( !pluginNamesSorted.length && String( sourceLocation.getName() ) === "plugins" )
return -1;
// No skins specified, special case to be able to build core only
if ( typeof config.skin !== 'undefined' && !config.skin && String( sourceLocation.getName() ) === "skins" )
return -1;
}
return 0;
}, function( targetLocation ) {
if ( CKBuilder.options.leaveJsUnminified )
return;
if ( CKBuilder.io.getExtension( targetLocation.getName() ) === 'js' ) {
var targetPath = targetLocation.getAbsolutePath();
if ( flags[ targetPath ] && flags[ targetPath ].LEAVE_UNMINIFIED ) {
if ( CKBuilder.options.debug > 1 )
print( "Leaving unminified: " + targetLocation.getPath() );
CKBuilder.io.saveFile( targetLocation, CKBuilder.tools.removeLicenseInstruction( CKBuilder.io.readFile( targetLocation ) ), true );
return;
}
if ( context === 'build' && 'languages' in config && String( targetLocation.getName() ) === 'plugin.js' ) {
try {
if ( String( targetLocation.getParentFile().getParentFile().getName() ) === 'plugins' && File( targetLocation.getParentFile(), "lang" ).exists() ) {
var result = CKBuilder.plugin.updateLangProperty( targetLocation, config.languages );
// Something went wrong...
if ( result === false )
print( "WARNING: it was impossible to update the lang property in " + targetLocation.getAbsolutePath() );
}
} catch ( e ) {
}
}
if ( CKBuilder.options.debug )
print( "Minifying: " + targetLocation.getPath() );
CKBuilder.javascript.minify( targetLocation );
}
} );
}
/**
* Creates sprite image from icons provided by plugins.
*
* @returns {String} Returns JavaScript code that registers created icons.
* @private
*/
function createPluginsSpriteImage() {
var iconsCode = "";
if ( !pluginNamesSorted.length )
return "";
print( "Generating plugins sprite image" );
var sourcePluginsLocation = new File( sourceLocation, "plugins" ),
targetPluginsLocation = new File( targetLocation, "plugins" );
if ( !targetPluginsLocation.exists() )
targetPluginsLocation.mkdirs();
var outputFile = new File( targetPluginsLocation, "icons.png" ),
outputFileHidpi = new File( targetPluginsLocation, "icons_hidpi.png" ),
iconsOffset = CKBuilder.image.createFullSprite( sourcePluginsLocation, null, outputFile, null, pluginNamesSorted ),
iconsOffsetHidpi = CKBuilder.image.createFullSprite( sourcePluginsLocation, null, outputFileHidpi, null, pluginNamesSorted, true );
if ( iconsOffset )
iconsCode = "(function() {" + "var setIcons = function(icons, strip) {" + "var path = CKEDITOR.getUrl( 'plugins/' + strip );" + "icons = icons.split( ',' );" + "for ( var i = 0; i < icons.length; i++ )" + "CKEDITOR.skin.icons[ icons[ i ] ] = { path: path, offset: -icons[ ++i ], bgsize : icons[ ++i ] };" + "};" + "if (CKEDITOR.env.hidpi) " + "setIcons('" + iconsOffsetHidpi + "','icons_hidpi.png');" + "else " + "setIcons('" + iconsOffset + "','icons.png');" + "})();";
return iconsCode;
}
/**
* Creates ckeditor.js.
*
* @param {Object} config
* @param {String} extraCode JavaScript code to include in ckeditor.js
* @param {Boolean} apply7588 Whether to include patch for #7588
* @param {String} context (build|preprocess) In build,
* @private
*/
function createCore( config, extraCode, apply7588, context ) {
var ckeditorjs = "",
patch7588 = 'if(window.CKEDITOR&&window.CKEDITOR.dom)return;';
if ( extraCoreJavaScriptCode && extraCoreJavaScriptCode.start )
ckeditorjs += extraCoreJavaScriptCode.start.join( "\n" );
ckeditorjs += CKBuilder.io.readFile( File( sourceLocation, "core/ckeditor_base.js" ) ) + "\n";
ckeditorjs += CKBuilder.io.readFiles( coreScriptsSorted, "\n" );
if ( extraCoreJavaScriptCode && extraCoreJavaScriptCode.aftercore )
ckeditorjs += extraCoreJavaScriptCode.aftercore.join( "\n" );
if ( sourceSkinFile )
ckeditorjs += CKBuilder.io.readFile( sourceSkinFile ) + "\n";
if ( pluginNamesSorted.length > 0 ) {
var configEntry = "CKEDITOR.config.plugins='" + pluginNamesSorted.join( "," ) + "';";
ckeditorjs += CKBuilder.io.readFiles( sourcePluginFilesSorted, "\n" ) + "\n" + configEntry;
}
// When the core is created for the preprocessed version of CKEditor, then it makes no sense to
// specify an empty "config.plugins", because config.plugins will be later set by the online builder.
else if ( 'build' === context )
ckeditorjs += "CKEDITOR.config.plugins='';";
if ( config.language )
ckeditorjs += CKBuilder.io.readFile( languageFile ) + "\n" ;
ckeditorjs = CKBuilder.tools.processDirectivesInString( ckeditorjs );
ckeditorjs = CKBuilder.tools.processCoreDirectivesInString( ckeditorjs );
ckeditorjs = CKBuilder.tools.removeLicenseInstruction( ckeditorjs );
if ( extraCode )
ckeditorjs += extraCode + "\n";
if ( 'build' === context && config.languages ) {
var langs = [];
for ( var lang in config.languages ) {
if ( config.languages[ lang ] )
langs.push( '"' + lang + '":1' );
}
if ( langs.length )
ckeditorjs += "CKEDITOR.lang.languages={" + langs.join( ',' ) + "};";
}
// http://dev.ckeditor.com/ticket/7588
if ( apply7588 )
ckeditorjs = CKBuilder.utils.wrapInFunction( patch7588 + ckeditorjs );
if ( extraCoreJavaScriptCode && extraCoreJavaScriptCode.end )
ckeditorjs += extraCoreJavaScriptCode.end.join( "" );
var targetFile = File( targetLocation, "ckeditor.js" );
CKBuilder.io.saveFile( targetFile, ckeditorjs, true );
if ( !CKBuilder.options.leaveJsUnminified ) {
print( "Minifying ckeditor.js" );
CKBuilder.javascript.minify( targetFile );
}
CKBuilder.io.saveFile( targetFile, CKBuilder.utils.copyright( CKBuilder.options.leaveJsUnminified ? "\r\n" : "\n" ) + CKBuilder.io.readFile( targetFile ), true );
print( "Created ckeditor.js (" + parseInt( targetFile.length() / 1024, 10 ) + "KB)" );
}
/**
* Reads configuration file and returns configuration object.
*
* @returns {Object}
* @private
*/
function readConfig() {
var configPath = CKBuilder.options.buildConfig || 'build-config.js',
configFile = new File( configPath );
if ( !configFile.exists() )
CKBuilder.error( 'The build configuration file was not found: ' + configPath + "\nRun:\n java -jar ckbuilder.jar SRC --generate-build-config" );
config = CKBuilder.config.read( configFile );
if ( config.js ) {
extraCoreJavaScriptFiles = {};
extraCoreJavaScriptCode = { start: [], aftercore: [], end: [] };
var instruction,
regexInstruction = Pattern.compile( '^(.*),(aftercore|end|start)$', Pattern.DOTALL );
for ( var i = 0; i < config.js.length; i++ ) {
var matcher = regexInstruction.matcher( config.js[ i ] ),
file,
filePath;
if ( matcher.find() ) {
filePath = matcher.group( 1 );
instruction = matcher.group( 2 );
} else {
filePath = config.js[ i ];
instruction = 'end';
}
file = new File( filePath );
if ( !file.exists() )
CKBuilder.error( "File not found: " + file.getAbsolutePath() + "\nCheck the build configuration file." );
extraCoreJavaScriptFiles[ file.getAbsolutePath() ] = true;
if ( CKBuilder.options.debug )
print( 'Adding extra file [' + instruction + ']: ' + filePath );
extraCoreJavaScriptCode[ instruction ].push( CKBuilder.io.readFile( file ) );
}
}
return config;
}
return {
/**
* Preprocess CKEditor core.
*
* @static
*/
preprocess: function() {
var time = new Date(),
config = readConfig();
config.plugins = {};
config.skin = '';
config.language = false;
validateSourceFolder();
CKBuilder.tools.prepareTargetFolder( File( dstDir ) );
init();
print( "Copying files (relax, this may take a while)" );
copyFiles( 'preprocess' );
time = CKBuilder.utils.printUsedTime( time );
print( "Merging language files" );
var langFolder = new File( targetLocation, 'lang' );
CKBuilder.lang.mergeAll( sourceLocation, langFolder, {}, config.languages );
time = CKBuilder.utils.printUsedTime( time );
print( "Processing lang folder" );
var children = langFolder.list();
for ( var i = 0; i < children.length; i++ ) {
if ( children[ i ].match( /^([a-z]{2}(?:-[a-z]+)?)\.js$/ ) ) {
var langFile = new File( langFolder, children[ i ] ),
translation = CKBuilder.lang.loadLanguageFile( langFile ).translation,
pseudoObject = JSON.stringify( translation ).replace( /^\{(.*)\}$/, '$1' );
CKBuilder.io.saveFile( langFile, pseudoObject, true );
}
}
print( "Building ckeditor.js" );
createCore( config, "", false, 'preprocess' );
print( "Cleaning up target folder" );
deleteUnusedFiles();
CKBuilder.utils.printUsedTime( time );
},
/**
* Creates ckeditor.js and icons.png in the target folder.
*
* @static
*/
generateCore: function() {
var time = new Date(),
config = readConfig();
validateSourceFolder();
init();
config.language = false;
var iconsCode = createPluginsSpriteImage();
print( "Building ckeditor.js" );
var extraCode = '';
if ( config.skin )
extraCode = "CKEDITOR.config.skin='" + config.skin + "';";
createCore( config, extraCode + iconsCode, true, 'build' );
CKBuilder.utils.printUsedTime( time );
},
/**
* Creates CKEditor build in the specified folder.
*
* @static
*/
generateBuild: function() {
var time = new Date(),
startTime = time,
config = readConfig();
validateSourceFolder();
CKBuilder.tools.prepareTargetFolder( File( dstDir ) );
init();
print( "Copying files (relax, this may take a while)" );
copyFiles( 'build' );
if ( !CKBuilder.options.all ) {
filterPluginFolders();
if ( config.skin )
filterSkinsFolders( config.skin );
}
time = CKBuilder.utils.printUsedTime( time );
print( "Merging language files" );
CKBuilder.lang.mergeAll( sourceLocation, File( targetLocation, 'lang' ), pluginNames, config.languages );
time = CKBuilder.utils.printUsedTime( time );
var iconsCode = createPluginsSpriteImage();
print( "Building ckeditor.js" );
var extraCode = '';
if ( config.skin )
extraCode = "CKEDITOR.config.skin='" + config.skin + "';";
createCore( config, extraCode + iconsCode, true, 'build' );
time = CKBuilder.utils.printUsedTime( time );
print( "Building skins" );
buildSkins();
if ( targetSkinFile )
CKBuilder.io.deleteFile( targetSkinFile );
time = CKBuilder.utils.printUsedTime( time );
CKBuilder.samples.mergeSamples( targetLocation );
print( "Cleaning up target folder" );
deleteUnusedFiles();
time = CKBuilder.utils.printUsedTime( time );
// get information about release directory
var info = CKBuilder.io.getDirectoryInfo( targetLocation );
if ( !CKBuilder.options.noZip || !CKBuilder.options.noTar )
print( "\nCreating compressed files...\n" );
var normalize = function( version ) {
return String( version ).toLowerCase().replace( / /g, "_" ).replace( /\(\)/g, "" );
};
if ( !CKBuilder.options.noZip ) {
var zipFile = new File( targetLocation.getParentFile(), "ckeditor_" + normalize( CKBuilder.options.version ) + ".zip" );
CKBuilder.io.zipDirectory( targetLocation, targetLocation, zipFile, "ckeditor" );
print( " Created " + zipFile.getName() + "...: " + zipFile.length() + " bytes (" + Math.round( zipFile.length() / info.size * 100 ) + "% of original)" );
}
if ( !CKBuilder.options.noTar ) {
var tarFile = new File( targetLocation.getParentFile(), "ckeditor_" + normalize( CKBuilder.options.version ) + ".tar.gz" );
CKBuilder.io.targzDirectory( targetLocation, targetLocation, tarFile, "ckeditor" );
print( " Created " + tarFile.getName() + ": " + tarFile.length() + " bytes (" + Math.round( tarFile.length() / info.size * 100 ) + "% of original)" );
}
CKBuilder.utils.printUsedTime( time );
print( "\n==========================" );
print( "Release process completed:\n" );
print( " Number of files: " + info.files );
print( " Total size.....: " + info.size + " bytes" );
CKBuilder.utils.printUsedTime( startTime );
print( "" );
}
};
};
ckbuilder-2.3.2/src/lib/config.js 0000664 0000000 0000000 00000006735 13230353051 0016630 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
importClass( java.io.BufferedWriter );
importClass( java.io.FileWriter );
importClass( java.io.FileOutputStream );
importClass( java.io.FileInputStream );
( function() {
/**
* Looking through directory and search subdirectories.
* When second parameter provided also filter subdirectories which contains file provided in parameter.
*
* @param {java.io.File} rootDir
* @param {String=} requiredFile If parameter provided also check whether directory contains file
* @returns {Object} Hash map of 1
* @member CKBuilder.config
*/
function getSubfolders( rootDir, requiredFile ) {
if ( !rootDir.exists() || !rootDir.isDirectory() )
return {};
var children = rootDir.list(), // get directory children
result = {};
children.sort();
for ( var i = 0; i < children.length; i++ ) {
var childDir = new File( rootDir, children[ i ] );
if ( !requiredFile || File( childDir, requiredFile ).exists() )
result[ children[ i ] ] = 1;
}
return result;
}
/**
* Responsible for creating CKBuilder config based on source directory
*
* @class
*/
CKBuilder.config = {
/**
* Creates a configuration file (build-config.js) with all plugins and skins listed.
* Config file structure is based on `plugins` and `skins` catalogue content.
*
* @param {String} sourceDir Path to the folder with source files
* @static
*/
create: function( sourceDir ) {
var sourceLocation = new File( sourceDir );
if ( !sourceLocation.exists() )
CKBuilder.error( "Source folder does not exist: " + sourceDir );
if ( !sourceLocation.isDirectory() )
CKBuilder.error( "Source folder is not a directory: " + sourceDir );
var plugins = getSubfolders( File( sourceLocation, "plugins" ), "plugin.js" ),
skins = getSubfolders( File( sourceLocation, "skins" ), "skin.js" ),
config = {
skins: skins,
plugins: plugins
};
CKBuilder.io.saveFile( CKBuilder.options.buildConfig || 'build-config.js', "var CKBUILDER_CONFIG = {\n" + CKBuilder.utils.prettyPrintObject( config, " " ) + "\n};" );
},
/**
* Reads a configuration file and returns the configuration object.
*
* @param {java.io.File} configFile Path to the configuration file
* @static
*/
read: function( configFile ) {
var file = new File( configFile ),
code = CKBuilder.io.readFile( file ),
cx = Context.enter(),
scope = cx.initStandardObjects();
try {
cx.evaluateString( scope, code, file.getName(), 1, null );
return scope.CKBUILDER_CONFIG;
} catch ( e ) {
throw( "Configuration file is invalid: " + file.getAbsolutePath() + ".\nError: " + e.message );
}
},
/**
* Returns true if the file/folder is set to be ignored.
*
* @param {java.io.File} sourceLocation
* @param {Array} ignoredPaths An array with ignored paths
* @returns {Boolean}
* @static
*/
isIgnoredPath: function( sourceLocation, ignoredPaths ) {
if ( !ignoredPaths )
return false;
for ( var i = 0; i < ignoredPaths.length; i++ ) {
var rule = ignoredPaths[ i ];
if ( rule.indexOf( '/' ) === -1 ) {
if ( String( sourceLocation.getName() ) === rule )
return true;
} else if ( sourceLocation.getAbsolutePath().replace( "\\", "/" ).endsWith( rule ) )
return true;
}
return false;
}
};
}() );
ckbuilder-2.3.2/src/lib/controller.js 0000664 0000000 0000000 00000020053 13230353051 0017533 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
importPackage( org.apache.commons.cli );
importClass( java.lang.System );
/**
* The main controller, parses the command line options and calls the right methods.
*
* @class
* @constructor
*/
CKBuilder.Controller = function() {
/**
* Command definitions along with descriptions.
*
* @type {Array}
* @private
*/
var options = [
// Commands
[ null, "build", false, "build release" ],
[ null, "generate-build-config", false, "generate build configuration file" ],
[ null, "help", false, "print help" ],
[ null, "full-help", false, "print help for all advanced commands" ],
[ null, "build-help", false, "print help about build configuration" ],
[ null, "preprocess-core", false, "preprocess CKEditor core" ],
[ null, "preprocess-plugin", false, "preprocess plugin" ],
[ null, "preprocess-skin", false, "preprocess skin" ],
[ null, "build-skin", false, "build skin" ],
[ null, "verify-plugin", false, "verify plugin" ],
[ null, "verify-skin", false, "verify skin" ],
// Options
[ null, "build-config", [ "FILE", "path to the file" ], "path to the build configuration" ],
[ null, "leave-js-unminified", false, "leave javascript files as is, do not minify them" ],
[ null, "leave-css-unminified", false, "leave CSS files as is, do not minify them" ],
[ "s", "skip-omitted-in-build-config", false, "exclude from release all plugins/skins that are not specified in build-config" ],
[ null, "revision", [ "NUMBER", "revision number" ], "revision number" ],
[ null, "version", [ "NUMBER", "version number" ], "version number" ],
[ null, "overwrite", false, "overwrite target folder if exists" ],
[ null, "no-ie-checks", false, "turn off warnings about syntax errors on Internet Explorer, like trailing commas" ],
[ null, "no-zip", false, "do not create zip file" ],
[ null, "no-tar", false, "do not create tar.gz file" ],
[ null, "core", false, "build only the core file (ckeditor.js)" ],
[ null, "commercial", false, "builds a package with commercial license" ],
[ null, "name", [ "NAME", "expected name" ], "the expected name of the skin/plugin, used for verification" ],
[ "d", "debug-level", [ "LEVEL", "debug level (0, 1, 2)." ], "sets the debug level" ]
];
/**
* Object with functions which are called for appropriate commands.
* Key is command name and value is function which is called with `CKBuilder.Controller` context
* and two arguments:
* first - Array of strings which are command line arguments
* second - Command line instance {org.apache.commons.cli.CommandLine}
*
* @type {Object}
*/
this.commandsHandlers = {
'help': function() {
this.printHelp( [ 'help.txt' ] );
},
'full-help': function() {
this.printHelp( [ 'help.txt', 'help-extra.txt' ] );
},
'build-help': function() {
this.printHelp( [ 'help-build.txt' ] );
},
'build': function( args ) {
if ( args.length < 2 )
CKBuilder.error( "The build command requires two arguments." );
var builder = CKBuilder.builder( args[ 0 ], args[ 1 ] );
if ( CKBuilder.options.core )
builder.generateCore();
else
builder.generateBuild();
},
'generate-build-config': function( args ) {
if ( args.length < 1 )
CKBuilder.error( "The generate-build-config command requires an argument." );
CKBuilder.config.create( args[ 0 ] );
},
'preprocess-core': function( args ) {
if ( args.length < 2 )
CKBuilder.error( "The preprocess-core command requires two arguments." );
var builder = CKBuilder.builder( args[ 0 ], args[ 1 ] );
builder.preprocess();
},
'preprocess-plugin': function( args ) {
if ( args.length < 2 )
CKBuilder.error( "The preprocess-plugin command requires two arguments." );
CKBuilder.plugin.preprocess( args[ 0 ], args[ 1 ] );
print( "Plugin preprocessed successfully" );
},
'preprocess-skin': function( args ) {
if ( args.length < 2 )
CKBuilder.error( "The preprocess-skin command requires two arguments." );
CKBuilder.skin.preprocess( args[ 0 ], args[ 1 ] );
print( "Skin preprocessed successfully" );
},
'build-skin': function( args ) {
if ( args.length < 2 )
CKBuilder.error( "The build-skin command requires two arguments." );
CKBuilder.skin.build( args[ 0 ], args[ 1 ] );
},
'verify-plugin': function( args, line ) {
var options = {};
if ( line.hasOption( "name" ) )
options.pluginName = String( line.getOptionValue( "name" ) );
if ( args.length < 1 )
CKBuilder.error( "The verify-plugin command requires an argument." );
print( CKBuilder.plugin.verify( args[ 0 ], options ) );
},
'verify-skin': function( args, line ) {
var options = {};
if ( line.hasOption( "name" ) )
options.skinName = String( line.getOptionValue( "name" ) );
if ( args.length < 1 )
CKBuilder.error( "The verify-skin command requires an argument." );
print( CKBuilder.skin.verify( args[ 0 ], options ) );
}
};
/**
* @type {org.apache.commons.cli.PosixParser}
*/
this.parser = new PosixParser();
/**
* @type {org.apache.commons.cli.Options}
*/
this.options = new Options();
for ( var i = 0; i < options.length; i++ ) {
if ( !options[ i ][ 2 ] )
this.options.addOption.apply( this.options, options[ i ] );
else {
var option = OptionBuilder.withLongOpt( options[ i ][ 1 ] ).withDescription( options[ i ][ 2 ][ 1 ] ).hasArg().withArgName( options[ i ][ 2 ][ 0 ] );
this.options.addOption( option.create( options[ i ][ 0 ] || null ) );
}
}
};
CKBuilder.Controller.prototype = {
/**
* Prints all available options.
*
* @param {Array} types
*/
printHelp: function( types ) {
var i, date = new Date();
if ( CKBuilder.isMinified ) {
for ( i = 0; i < types.length; i++ )
print( "\n" + CKBuilder.io.readFileFromJar( types[ i ] ) );
} else {
for ( i = 0; i < types.length; i++ )
print( "\n" + CKBuilder.io.readFile( new File( "src/assets/" + types[ i ] ) ) );
}
print( "Copyright (c) 2003-" + date.getFullYear() + ", CKSource - Frederico Knabben" );
},
/**
* Executes commands based on passed arguments.
*
* @param {Array} _arguments An array containing the strings of all the arguments given at the command line when the shell was invoked
*/
run: function( _arguments ) {
// parse the command line arguments
var line = this.parser.parse( this.options, _arguments );
// Options
if ( line.hasOption( "debug-level" ) )
CKBuilder.options.debug = line.getOptionValue( "debug-level" );
if ( line.hasOption( "overwrite" ) )
CKBuilder.options.overwrite = true;
if ( line.hasOption( "build-config" ) )
CKBuilder.options.buildConfig = line.getOptionValue( "build-config" );
if ( line.hasOption( "skip-omitted-in-build-config" ) )
CKBuilder.options.all = false;
if ( line.hasOption( "version" ) )
CKBuilder.options.version = line.getOptionValue( "version" );
if ( line.hasOption( "core" ) )
CKBuilder.options.core = true;
if ( line.hasOption( "commercial" ) )
CKBuilder.options.commercial = true;
if ( line.hasOption( "revision" ) )
CKBuilder.options.revision = line.getOptionValue( "revision" );
if ( line.hasOption( "leave-js-unminified" ) )
CKBuilder.options.leaveJsUnminified = true;
if ( line.hasOption( "leave-css-unminified" ) )
CKBuilder.options.leaveCssUnminified = true;
if ( line.hasOption( "no-zip" ) )
CKBuilder.options.noZip = true;
if ( line.hasOption( "no-ie-checks" ) )
CKBuilder.options.noIeChecks = true;
if ( line.hasOption( "no-tar" ) )
CKBuilder.options.noTar = true;
var foundCommandName = null;
for ( var commandName in this.commandsHandlers ) {
if ( line.hasOption( commandName ) ) {
foundCommandName = commandName;
break;
}
}
foundCommandName = foundCommandName || 'help';
this.commandsHandlers[ foundCommandName ].call(this, line.getArgs(), line );
System.exit( 0 );
}
}; ckbuilder-2.3.2/src/lib/css.js 0000664 0000000 0000000 00000016211 13230353051 0016141 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
importClass( java.io.BufferedWriter );
importClass( java.io.FileWriter );
importClass( java.io.FileOutputStream );
importClass( java.io.FileInputStream );
importPackage( com.yahoo.platform.yui.compressor );
( function() {
var importedFiles = {};
/**
* Removes comments from specified text.
*
* @param {String} text
* @returns {String}
* @member CKBuilder.css
* @private
*/
function removeComments( text ) {
var endIndex,
startIndex = 0,
/**
* Indicating comment to hide rules from IE Mac.
*
* @property {Boolean} iemac
* @private
* @member CKBuilder.css
*/
iemac = false,
preserve = false,
sb = new StringBuffer( text );
while ( ( startIndex = sb.indexOf( "/*", startIndex ) ) >= 0 ) {
preserve = sb.length() > startIndex + 2 && sb.charAt( startIndex + 2 ) === '!';
endIndex = sb.indexOf( "*/", startIndex + 2 );
if ( endIndex < 0 ) {
if ( !preserve )
sb[ "delete" ]( startIndex, sb.length() );
} else if ( endIndex >= startIndex + 2 ) {
if ( sb.charAt( endIndex - 1 ) === '\\' ) {
/*
* Looks like a comment to hide rules from IE Mac.
* Leave this comment, and the following one, alone...
*/
startIndex = endIndex + 2;
iemac = true;
} else if ( iemac ) {
startIndex = endIndex + 2;
iemac = false;
} else if ( !preserve ) {
try {
/* Remove new line character if there is nothing else after a comment */
if ( sb.charAt( endIndex + 2 ) === 13 && sb.charAt( endIndex + 3 ) === 10 )
endIndex += 2;
else if ( sb.charAt( endIndex + 2 ) === 10 && sb.charAt( endIndex + 3 ) === 13 )
endIndex += 2;
else if ( sb.charAt( endIndex + 2 ) === 13 && sb.charAt( endIndex + 3 ) === 13 )
endIndex += 1;
else if ( sb.charAt( endIndex + 2 ) === 10 && sb.charAt( endIndex + 3 ) === 10 )
endIndex += 1;
} catch ( e ) {
/* catch StringIndexOutOfBoundsException if comment is at the end of file */
}
sb[ "delete" ]( startIndex, endIndex + 2 );
} else
startIndex = endIndex + 2;
}
}
return sb.toString();
}
/**
* Returns content of source file and all CSS files included in import statements.
*
* @param {java.io.File} sourceLocation The location of CSS file
* @param {java.io.File=} parentLocation The location of parent CSS file, if source file was imported
* @returns {String}
* @member CKBuilder.css
* @private
*/
function processCssFile( sourceLocation, parentLocation ) {
var out = [],
isImported = false,
parentPath,
path = sourceLocation.getCanonicalPath(),
lines = CKBuilder.io.readFile( new File( path ) ).split( /\r\n|\n|\r/ );
if ( !parentLocation ) {
parentLocation = sourceLocation;
parentPath = sourceLocation.getCanonicalPath();
} else {
isImported = true;
parentPath = parentLocation.getCanonicalPath();
if ( path === parentPath )
throw( "Invalid @import statements, file including itself: " + path );
if ( importedFiles[ parentPath ][ path ] )
throw( "Invalid @import statement in " + parentPath + ", file " + path + " was already imported." );
importedFiles[ parentPath ][ path ] = true;
}
for ( var i = 0, length = lines.length; i < length; i++ ) {
if ( lines[ i ].indexOf( "@import" ) === -1 )
out.push( lines[ i ] );
else {
var matches = lines[ i ].match( /^\s*@import\s+url\(["'](.*?)["']\)/ );
if ( matches[ 1 ] ) {
var file = new File( sourceLocation.getParent(), matches[ 1 ] );
if ( !file.exists() )
throw( "Importing of CSS file failed, file does not exist (" + file.getPath() + ")" );
else {
if ( !importedFiles[ parentPath ] )
importedFiles[ parentPath ] = {};
out.push( processCssFile( file, parentLocation ) );
}
} else
out.push( lines[ i ] );
}
}
if ( isImported )
return removeComments( out.join( "\r\n" ) );
else
return out.join( "\r\n" ).replace( /(\r\n){2,}/g, "\r\n" );
}
/**
* Copies files from source to the target folder and calls the CSS processor on each css file.
*
* @param {java.io.File} targetLocation Target folder
* @member CKBuilder.css
* @private
*/
function processCssFiles( targetLocation ) {
var children = targetLocation.list();
for ( var i = 0; i < children.length; i++ ) {
var f = new File( targetLocation, children[ i ] );
if ( f.isDirectory() )
processCssFiles( f );
else if ( f.getName().toLowerCase().endsWith( ".css" ) ) {
CKBuilder.io.saveFile( f, processCssFile( f ) );
if ( CKBuilder.options.debug )
print( " Saved CSS file: " + f.getAbsolutePath() );
}
}
}
/**
* Compress all CSS files in given directory.
*
* @param {java.io.File} targetLocation
* @member CKBuilder.css
* @private
*/
function compressCssFiles( targetLocation ) {
var children = targetLocation.list();
for ( var i = 0; i < children.length; i++ ) {
var f = new File( targetLocation, children[ i ] );
if ( f.isDirectory() )
compressCssFiles( f );
else if ( f.getName().toLowerCase().endsWith( ".css" ) ) {
if ( CKBuilder.options.debug )
print( "Compressing " + f.getAbsolutePath() );
var cssContent = CKBuilder.io.readFile( f ),
copyright = CKBuilder.tools.getCopyrightFromText( cssContent );
cssContent = YAHOO.compressor.cssmin( cssContent, -1 );
CKBuilder.io.saveFile( f, copyright + cssContent );
}
}
}
/**
* Removes imported CSS files.
*
* @param {Object} importedFiles
* @member CKBuilder.css
* @private
*/
function deleteImportedFiles( importedFiles ) {
for ( var parentPath in importedFiles ) {
for ( var path in importedFiles[ parentPath ] ) {
if ( !importedFiles[ path ] ) {
var file = new File( path ),
fileName = String( file.getName() );
if ( fileName === "dialog.css" || fileName === "editor.css" )
continue;
if ( CKBuilder.options.debug > 1 )
print( " CSS file was imported, removing: " + path );
CKBuilder.io.deleteFile( path );
} else {
if ( CKBuilder.options.debug > 1 )
print( " CSS file was imported, but is also a root CSS file for another file: " + path );
}
}
}
}
/**
* Handle css files - merge then, and determine dependencies.
*
* @class
*/
CKBuilder.css = {
/**
* Performs optimization of CSS files in given location.
* Join @import files into root CSS file.
*
* @param {java.io.File} targetLocation The folder where to optimize CSS files.
* @static
*/
mergeCssFiles: function( targetLocation ) {
if ( !targetLocation.isDirectory() )
throw( "CSS compression failed. The target location is not a directory: " + targetLocation.getAbsolutePath() );
importedFiles = {};
processCssFiles( targetLocation );
deleteImportedFiles( importedFiles );
if ( !CKBuilder.options.leaveCssUnminified )
compressCssFiles( targetLocation );
}
};
}() );
ckbuilder-2.3.2/src/lib/cssmin.js 0000664 0000000 0000000 00000030036 13230353051 0016646 0 ustar 00root root 0000000 0000000 /*
* cssmin.js
* Author: Stoyan Stefanov - http://phpied.com/
* This is a JavaScript port of the CSS minification tool
* distributed with YUICompressor, itself a port
* of the cssmin utility by Isaac Schlueter - http://foohack.com/
* Permission is hereby granted to use the JavaScript version under the same
* conditions as the YUICompressor (original YUICompressor note below).
*/
/* jshint eqeqeq: false */
/**
* YUI Compressor
* http://developer.yahoo.com/yui/compressor/
* Author: Julien Lecomte - http://www.julienlecomte.net/
* Copyright (c) 2011 Yahoo! Inc. All rights reserved.
* The copyrights embodied in the content of this file are licensed
* by Yahoo! Inc. under the BSD (revised) open source license.
*
* @class YAHOO.compressor
*/
this.YAHOO = this.YAHOO || {};
YAHOO.compressor = YAHOO.compressor || {};
/**
* Utility method to replace all data urls with tokens before we start
* compressing, to avoid performance issues running some of the subsequent
* regexes against large strings chunks.
*
* @private
* @method _extractDataUrls
* @param {String} css The input css
* @param {Array} preservedTokens The global array of tokens to preserve
* @returns String The processed css
*/
YAHOO.compressor._extractDataUrls = function( css, preservedTokens ) {
// Leave data urls alone to increase parse performance.
var maxIndex = css.length - 1, appendIndex = 0, startIndex, endIndex, terminator, foundTerminator, sb = [], m, preserver, token, pattern = /url\(\s*(["']?)data\:/g;
// Since we need to account for non-base64 data urls, we need to handle
// ' and ) being part of the data string. Hence switching to indexOf,
// to determine whether or not we have matching string terminators and
// handling sb appends directly, instead of using matcher.append* methods.
while ( ( m = pattern.exec( css ) ) !== null ) {
startIndex = m.index + 4; // "url(".length()
terminator = m[ 1 ]; // ', " or empty (not quoted)
if ( terminator.length === 0 )
terminator = ")";
foundTerminator = false;
endIndex = pattern.lastIndex - 1;
while ( foundTerminator === false && endIndex + 1 <= maxIndex ) {
endIndex = css.indexOf( terminator, endIndex + 1 );
// endIndex == 0 doesn't really apply here
if ( ( endIndex > 0 ) && ( css.charAt( endIndex - 1 ) !== '\\') ) {
foundTerminator = true;
if ( ")" != terminator )
endIndex = css.indexOf( ")", endIndex );
}
}
// Enough searching, start moving stuff over to the buffer
sb.push( css.substring( appendIndex, m.index ) );
if ( foundTerminator ) {
token = css.substring( startIndex, endIndex );
token = token.replace( /\s+/g, "" );
preservedTokens.push( token );
preserver = "url(___YUICSSMIN_PRESERVED_TOKEN_" + ( preservedTokens.length - 1 ) + "___)";
sb.push( preserver );
appendIndex = endIndex + 1;
} else {
// No end terminator found, re-add the whole match. Should we throw/warn here?
sb.push( css.substring( m.index, pattern.lastIndex ) );
appendIndex = pattern.lastIndex;
}
}
sb.push( css.substring( appendIndex ) );
return sb.join( "" );
};
/**
* Utility method to compress hex color values of the form #AABBCC to #ABC.
*
* DOES NOT compress CSS ID selectors which match the above pattern (which would break things).
* e.g. #AddressForm { ... }
*
* DOES NOT compress IE filters, which have hex color values (which would break things).
* e.g. filter: chroma(color="#FFFFFF");
*
* DOES NOT compress invalid hex values.
* e.g. background-color: #aabbccdd
*
* @private
* @method _compressHexColors
* @param {String} css The input css
* @returns String The processed css
*/
YAHOO.compressor._compressHexColors = function( css ) {
// Look for hex colors inside { ... } (to avoid IDs) and which don't have a =, or a " in front of them (to avoid filters)
var pattern = /(\=\s*?["']?)?#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])(\}|[^0-9a-f{][^{]*?\})/gi, m, index = 0, isFilter, sb = [];
while ( ( m = pattern.exec( css ) ) !== null ) {
sb.push( css.substring( index, m.index ) );
isFilter = m[ 1 ];
if ( isFilter ) {
// Restore, maintain case, otherwise filter will break
sb.push( m[ 1 ] + "#" + ( m[ 2 ] + m[ 3 ] + m[ 4 ] + m[ 5 ] + m[ 6 ] + m[ 7 ] ) );
} else {
if ( m[ 2 ].toLowerCase() == m[ 3 ].toLowerCase() && m[ 4 ].toLowerCase() == m[ 5 ].toLowerCase() && m[ 6 ].toLowerCase() == m[ 7 ].toLowerCase() ) {
// Compress.
sb.push( "#" + ( m[ 3 ] + m[ 5 ] + m[ 7 ] ).toLowerCase() );
} else {
// Non compressible color, restore but lower case.
sb.push( "#" + ( m[ 2 ] + m[ 3 ] + m[ 4 ] + m[ 5 ] + m[ 6 ] + m[ 7 ] ).toLowerCase() );
}
}
index = pattern.lastIndex = pattern.lastIndex - m[ 8 ].length;
}
sb.push( css.substring( index ) );
return sb.join( "" );
};
YAHOO.compressor.cssmin = function( css, linebreakpos ) {
var startIndex = 0, endIndex = 0, i = 0, max = 0, preservedTokens = [], comments = [], token = '', totallen = css.length, placeholder = '';
css = this._extractDataUrls( css, preservedTokens );
// collect all comment blocks...
while ( ( startIndex = css.indexOf( "/*", startIndex ) ) >= 0 ) {
endIndex = css.indexOf( "*/", startIndex + 2 );
if ( endIndex < 0 )
endIndex = totallen;
token = css.slice( startIndex + 2, endIndex );
comments.push( token );
css = css.slice( 0, startIndex + 2 ) + "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + ( comments.length - 1 ) + "___" + css.slice( endIndex );
startIndex += 2;
}
// preserve strings so their content doesn't get accidentally minified
css = css.replace( /("([^\\"]|\\.|\\)*")|('([^\\']|\\.|\\)*')/g, function( match ) {
var i, max, quote = match.substring( 0, 1 );
match = match.slice( 1, -1 );
// maybe the string contains a comment-like substring?
// one, maybe more? put'em back then
if ( match.indexOf( "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" ) >= 0 ) {
for ( i = 0, max = comments.length; i < max; i = i + 1 ) {
match = match.replace( "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", comments[ i ] );
}
}
// minify alpha opacity in filter strings
match = match.replace( /progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/gi, "alpha(opacity=" );
preservedTokens.push( match );
return quote + "___YUICSSMIN_PRESERVED_TOKEN_" + ( preservedTokens.length - 1 ) + "___" + quote;
} );
// strings are safe, now wrestle the comments
for ( i = 0, max = comments.length; i < max; i = i + 1 ) {
token = comments[ i ];
placeholder = "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___";
// ! in the first position of the comment means preserve
// so push to the preserved tokens keeping the !
if ( token.charAt( 0 ) === "!" ) {
preservedTokens.push( token );
css = css.replace( placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + ( preservedTokens.length - 1 ) + "___" );
continue;
}
// \ in the last position looks like hack for Mac/IE5
// shorten that to /*\*/ and the next one to /**/
if ( token.charAt( token.length - 1 ) === "\\" ) {
preservedTokens.push( "\\" );
css = css.replace( placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + ( preservedTokens.length - 1 ) + "___" );
i = i + 1; // attn: advancing the loop
preservedTokens.push( "" );
css = css.replace( "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", "___YUICSSMIN_PRESERVED_TOKEN_" + ( preservedTokens.length - 1 ) + "___" );
continue;
}
// keep empty comments after child selectors (IE7 hack)
// e.g. html >/**/ body
if ( token.length === 0 ) {
startIndex = css.indexOf( placeholder );
if ( startIndex > 2 ) {
if ( css.charAt( startIndex - 3 ) === '>' ) {
preservedTokens.push( "" );
css = css.replace( placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + ( preservedTokens.length - 1 ) + "___" );
}
}
}
// in all other cases kill the comment
css = css.replace( "/*" + placeholder + "*/", "" );
}
// Normalize all whitespace strings to single spaces. Easier to work with that way.
css = css.replace( /\s+/g, " " );
// Remove the spaces before the things that should not have spaces before them.
// But, be careful not to turn "p :link {...}" into "p:link{...}"
// Swap out any pseudo-class colons with the token, and then swap back.
css = css.replace( /(^|\})(([^\{:])+:)+([^\{]*\{)/g, function( m ) {
return m.replace( ":", "___YUICSSMIN_PSEUDOCLASSCOLON___" );
} );
css = css.replace( /\s+([!{};:>+\(\)\],])/g, '$1' );
css = css.replace( /___YUICSSMIN_PSEUDOCLASSCOLON___/g, ":" );
// retain space for special IE6 cases
css = css.replace( /:first-(line|letter)(\{|,)/g, ":first-$1 $2" );
// no space after the end of a preserved comment
css = css.replace( /\*\/ /g, '*/' );
// If there is a @charset, then only allow one, and push to the top of the file.
css = css.replace( /^(.*)(@charset "[^"]*";)/gi, '$2$1' );
css = css.replace( /^(\s*@charset [^;]+;\s*)+/gi, '$1' );
// Put the space back in some cases, to support stuff like
// @media screen and (-webkit-min-device-pixel-ratio:0){
css = css.replace( /\band\(/gi, "and (" );
// Remove the spaces after the things that should not have spaces after them.
css = css.replace( /([!{}:;>+\(\[,])\s+/g, '$1' );
// remove unnecessary semicolons
css = css.replace( /;+\}/g, "}" );
// Replace 0(px,em,%) with 0.
css = css.replace( /([\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)/gi, "$1$2" );
// Replace 0 0 0 0; with 0.
css = css.replace( /:0 0 0 0(;|\})/g, ":0$1" );
css = css.replace( /:0 0 0(;|\})/g, ":0$1" );
css = css.replace( /:0 0(;|\})/g, ":0$1" );
// Replace background-position:0; with background-position:0 0;
// same for transform-origin
css = css.replace( /(background-position|transform-origin|webkit-transform-origin|moz-transform-origin|o-transform-origin|ms-transform-origin):0(;|\})/gi, function( all, prop, tail ) {
return prop.toLowerCase() + ":0 0" + tail;
} );
// Replace 0.6 to .6, but only when preceded by : or a white-space
css = css.replace( /(:|\s)0+\.(\d+)/g, "$1.$2" );
// Shorten colors from rgb(51,102,153) to #336699
// This makes it more likely that it'll get further compressed in the next step.
css = css.replace( /rgb\s*\(\s*([0-9,\s]+)\s*\)/gi, function() {
var i, rgbcolors = arguments[ 1 ].split( ',' );
for ( i = 0; i < rgbcolors.length; i = i + 1 ) {
rgbcolors[ i ] = parseInt( rgbcolors[ i ], 10 ).toString( 16 );
if ( rgbcolors[ i ].length === 1 )
rgbcolors[ i ] = '0' + rgbcolors[ i ];
}
return '#' + rgbcolors.join( '' );
} );
// Shorten colors from #AABBCC to #ABC.
css = this._compressHexColors( css );
// border: none -> border:0
css = css.replace( /(border|border-top|border-right|border-bottom|border-right|outline|background):none(;|\})/gi, function( all, prop, tail ) {
return prop.toLowerCase() + ":0" + tail;
} );
// shorter opacity IE filter
css = css.replace( /progid:DXImageTransform\.Microsoft\.Alpha\(Opacity=/gi, "alpha(opacity=" );
// Remove empty rules.
css = css.replace( /[^\};\{\/]+\{\}/g, "" );
if ( linebreakpos >= 0 ) {
// Some source control tools don't like it when files containing lines longer
// than, say 8000 characters, are checked in. The linebreak option is used in
// that case to split long lines after a specific column.
startIndex = 0;
i = 0;
while ( i < css.length ) {
i = i + 1;
if ( css[ i - 1 ] === '}' && i - startIndex > linebreakpos ) {
css = css.slice( 0, i ) + '\n' + css.slice( i );
startIndex = i;
}
}
}
// Replace multiple semi-colons in a row by a single one
// See SF bug #1980989
css = css.replace( /;;+/g, ";" );
// restore preserved comments and strings
for ( i = 0, max = preservedTokens.length; i < max; i = i + 1 ) {
css = css.replace( "___YUICSSMIN_PRESERVED_TOKEN_" + i + "___", preservedTokens[ i ] );
}
// Trim the final string (for any leading or trailing white spaces)
css = css.replace( /^\s+|\s+$/g, "" );
return css;
}; ckbuilder-2.3.2/src/lib/image.js 0000664 0000000 0000000 00000024327 13230353051 0016442 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
importClass( java.io.File );
importClass( javax.imageio.ImageIO );
importClass( java.awt.image.BufferedImage );
( function() {
/**
* Iterating through files in directory and when file has one of the following
* png, jpg, gif extension then file absolute path is set as a value and
* file name is set as a key
*
* @param {java.io.File} directory
* @param {Object=} paths
* @private
* @returns {Object}
* @member CKBuilder.image
*/
function getAbsolutePathForImageFiles( directory, paths ) {
paths = paths || {};
var files = directory.list().sort();
for ( var i = 0; i < files.length; i++ ) {
var f = new File( directory, files[ i ] );
if ( f.isFile() ) {
var extension = CKBuilder.io.getExtension( files[ i ] );
if ( extension === "png" || extension === "jpg" || extension === "gif" ) {
var fileName = files[ i ].slice( 0, files[ i ].indexOf( "." ) );
paths[ String( fileName ) ] = String( f.getAbsolutePath() );
}
}
}
return paths;
}
/**
* Responsible for generating sprite with icons.
*
* @class
*/
CKBuilder.image = {
/**
* @param {java.io.File} sourceLocation
* @param {Boolean} hidpi
* @static
*/
findIcons: function( sourceLocation, hidpi ) {
if ( !sourceLocation || !sourceLocation.exists() )
return {};
var result = {},
children = sourceLocation.list().sort();
for ( var i = 0; i < children.length; i++ ) {
var child = new File( sourceLocation, children[ i ] );
// Handle only directories
if ( !child.isDirectory() )
continue;
if ( String( children[ i ] ) === "icons" ) {
getAbsolutePathForImageFiles( child, result );
// When the "hidpi" flag is set, overwrite 16px icons with hidpi versions.
// Searching above for 16px icons still makes sense, because a plugin may not
// provide hidpi icons at all.
if ( hidpi ) {
var hidpiFolder = new File( child, 'hidpi' );
if ( !hidpiFolder.isDirectory() )
continue;
getAbsolutePathForImageFiles( hidpiFolder, result );
}
// When directory name is not "icons", going deeper.
} else {
var icons = CKBuilder.image.findIcons( child, hidpi );
result = CKBuilder.utils.merge( result, icons );
}
}
return result;
},
/**
* Creates a complete sprite, based on passed plugins and skin location.
*
* @param {java.io.File} pluginsLocation
* @param {java.io.File} skinLocation
* @param {java.io.File} outputFile
* @param {java.io.File} outputCssFile
* @param {String[]} pluginNamesSorted
* @param {Boolean} [hidpi=false]
* @returns {*}
* @static
*/
createFullSprite: function( pluginsLocation, skinLocation, outputFile, outputCssFile, pluginNamesSorted, hidpi ) {
var pluginIcons = {};
// Include all available icons
if ( CKBuilder.options.all )
pluginIcons = CKBuilder.image.findIcons( pluginsLocation, hidpi );
// Include in strip image only icons provided by plugins included in core
else {
for ( var i = 0; i < pluginNamesSorted.length; i++ ) {
var pluginName = pluginNamesSorted[ i ],
pluginFolder = new File( pluginsLocation, pluginName );
if ( pluginFolder.exists() && pluginFolder.isDirectory() ) {
var result = CKBuilder.image.findIcons( pluginFolder, hidpi );
pluginIcons = CKBuilder.utils.merge( result, pluginIcons, true );
}
}
}
var skinIcons = CKBuilder.image.findIcons( skinLocation, hidpi ),
icons = CKBuilder.utils.merge( pluginIcons, skinIcons, false );
if ( CKBuilder.options.debug > 1 ) {
print( "Generating sprite image" );
print( "\n== Plugin names ==\n" );
print( pluginNamesSorted.join( "," ) );
print( "\n== Plugin icons ==\n" );
print( CKBuilder.utils.prettyPrintObject( pluginIcons ) );
print( "\n== Skin icons ==\n" );
print( CKBuilder.utils.prettyPrintObject( skinIcons ) );
print( "\n== Used icons ==\n" );
print( CKBuilder.utils.prettyPrintObject( icons ) );
}
var files = Object.keys( pluginIcons )// Map to paths array.
.map( function( buttonName ) {
return icons[ buttonName ];
} )// Sort in paths order, so icon-rtl.png will be before icon.png.
.sort()// Map to files array.
.map( function( iconPath ) {
return new File( iconPath );
} );
return this.createSprite( files, outputFile, outputCssFile, hidpi );
},
/**
* Generate sprite file from given images.
*
* @param {Array} files An array with image files ({java.io.File})
* @param {Boolean} outputFile Where to save sprite image
* @param {java.io.File} outputCssFile Where to save CSS information about buttons
* @param {Boolean} hidpi Whether to create hidpi strip image
* @static
*/
createSprite: function( files, outputFile, outputCssFile, hidpi ) {
if ( !files.length ) {
if ( CKBuilder.options.debug )
print( "No images given, sprite file will not be created." );
return '';
}
var totalHeight = 0,
iconsOffset = [],
iconsHasRtl = {},
minimumIconSpace = hidpi ? 16 : 8,
cssRules = [];
if ( outputCssFile && outputCssFile.exists() )
cssRules.push( CKBuilder.io.readFile( outputCssFile ) || "" );
// Read images
var i,
// each image is an object with keys:
// {Boolean} isHidpi
// {java.awt.image.BufferedImage} bufferedImage
// {String} fileName
images = [],
// while iterating through images there is determined highest icon width and height
maxIconWidth = 0,
maxIconHeight = 0;
for ( i = 0; i < files.length; i++ ) {
images[ i ] = {
isHidpi: String( files[ i ].getAbsolutePath() ).replace( /\\/g, '/' ).indexOf( "/icons/hidpi/" ) !== -1,
bufferedImage: ImageIO.read( files[ i ] ),
fileName: files[ i ].getName()
};
images[ i ].width = images[ i ].bufferedImage.getWidth();
images[ i ].height = images[ i ].bufferedImage.getHeight();
// Humm huge images? That's probably not an icon, ignore that file.
if ( images[ i ].height > 100 || images[ i ].width > 100 ) {
print( "WARNING: cowardly refused to add an image to a sprite because it's too big: " + files[ i ].getAbsolutePath() );
images[ i ] = null;
continue;
}
maxIconHeight = Math.max( images[ i ].height, maxIconHeight );
maxIconWidth = Math.max( images[ i ].width, maxIconWidth );
}
// Get rid of images that turned out to be too big
images = images.filter( function( image ) {
return !!image;
} );
if ( maxIconWidth <= 0 )
throw( 'Error while generating sprite image: invalid width (' + maxIconWidth + ')' );
var cssHidpiPrefix = hidpi ? ".cke_hidpi" : "",
iconsStrip = ( hidpi ? "icons_hidpi.png" : "icons.png" ) + "?t=" + CKBuilder.options.timestamp;
for ( i = 0; i < images.length; i++ ) {
var buttonName = images[ i ].fileName.match( /.*?(?=\.|-rtl)/ ),
buttonSelector = ".cke_button__" + buttonName + '_icon',
ypos,
backgroundSize,
cssBackgroundSize;
if ( hidpi ) {
if ( images[ i ].isHidpi ) {
backgroundSize = Math.round( maxIconWidth / 2 ) + "px";
cssBackgroundSize = "background-size: " + backgroundSize + " !important;";
// This is the default value in CKEditor, so it does not make sense to specify it again
if ( backgroundSize === '16px' )
backgroundSize = "";
ypos = totalHeight / 2;
} else {
backgroundSize = "auto";
cssBackgroundSize = "";
ypos = totalHeight;
}
} else {
// The icons folder in 3rd party plugins may contain surprises
// As a result, the strip image may have unpredictable width
// https://github.com/WebSpellChecker/ckeditor-plugin-wsc/issues/6
// Here, with wsc plugin, the strip image had 108px width, so default background-size:16px was invalid
// We need to always reset it to auto
backgroundSize = "auto";
cssBackgroundSize = "";
ypos = totalHeight;
}
if ( images[ i ].fileName.indexOf( "-rtl" ) !== -1 ) {
iconsHasRtl[ buttonName ] = 1;
cssRules.push( ".cke_rtl" + cssHidpiPrefix + " " + buttonSelector + "," + // The "cke_mixed_dir_content" env class is to increase the specificity,
// with RTL button in LTR editor.
( cssHidpiPrefix ? " " : "" ) + cssHidpiPrefix + " .cke_mixed_dir_content .cke_rtl " + buttonSelector + " {background: url(" + iconsStrip + ") no-repeat 0 -" + ypos + "px !important;" + cssBackgroundSize + "}" );
iconsOffset.push( buttonName + '-rtl' );
iconsOffset.push( ypos );
iconsOffset.push( backgroundSize );
} else {
var envSelector = ( buttonName in iconsHasRtl ? ".cke_ltr" : "" ) + cssHidpiPrefix;
if ( envSelector )
envSelector = envSelector + " ";
if ( hidpi && buttonName in iconsHasRtl )
cssRules.push( ".cke_hidpi .cke_ltr " + buttonSelector + "," );
cssRules.push( envSelector + buttonSelector + " {background: url(" + iconsStrip + ") no-repeat 0 -" + ypos + "px !important;" + cssBackgroundSize + "}" );
iconsOffset.push( buttonName );
iconsOffset.push( ypos );
iconsOffset.push( backgroundSize );
}
totalHeight = totalHeight + maxIconHeight + minimumIconSpace;
}
if ( totalHeight <= 0 )
throw( 'Error while generating sprite image: invalid height (' + totalHeight + ')' );
if ( CKBuilder.options.debug )
System.out.format( "Sprites generator: %s images. Total height: %spx, width: %spx%n", images.length, totalHeight, maxIconWidth );
// Create the actual sprite
var sprite = new BufferedImage( maxIconWidth, totalHeight, BufferedImage.TYPE_INT_ARGB ),
currentY = 0,
g = sprite.getGraphics();
for ( i = 0; i < images.length; i++ ) {
// image = BufferedImage object
g.drawImage( images[ i ].bufferedImage, 0, currentY, null );
currentY = currentY + maxIconHeight + minimumIconSpace;
}
if ( CKBuilder.options.debug )
print( "Saving sprite: ", outputFile.getAbsolutePath() );
ImageIO.write( sprite, "png", outputFile );
if ( outputCssFile ) {
if ( CKBuilder.options.debug )
print( "Saving CSS rules to " + outputCssFile.getAbsolutePath() );
CKBuilder.io.saveFile( outputCssFile, cssRules.join( CKBuilder.options.leaveCssUnminified ? "\r\n" : "" ) );
}
return iconsOffset.join( ',' );
}
};
}() );
ckbuilder-2.3.2/src/lib/io.js 0000664 0000000 0000000 00000043537 13230353051 0015773 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
importPackage( com.ice.tar );
importPackage( java.util.zip );
importClass( java.io.BufferedReader );
importClass( java.io.BufferedWriter );
importClass( java.io.File );
importClass( java.io.FileWriter );
importClass( java.io.FileOutputStream );
importClass( java.io.FileInputStream );
importClass( java.io.BufferedInputStream );
importClass( java.io.BufferedOutputStream );
importClass( java.lang.StringBuffer );
importClass( java.io.InputStreamReader );
importClass( java.io.FileOutputStream );
importClass( java.io.OutputStreamWriter );
importClass( java.util.zip.ZipOutputStream );
importClass( java.util.zip.ZipEntry );
importClass( java.util.zip.GZIPInputStream );
( function() {
/**
* Creates an archive from specified path.
*
* @param {String} sourceLocation Path Source path
* @param {String} startLocation Path Source path
* @param {java.io.OutputStream} outStream Output stream to which the archive is created
* @param {String} compressMethod The type of the archive (tar.gz|zip)
* @param {String} rootDir The root folder of the archive.
* @member CKBuilder.io
*/
function compressDirectory( sourceLocation, startLocation, outStream, compressMethod, rootDir ) {
if ( CKBuilder.options.debug )
print( " " + compressMethod + ": " + sourceLocation.getAbsolutePath() );
if ( !rootDir )
rootDir = "";
try {
var dirList = sourceLocation.list(),
readBuffer = new Packages.java.lang.reflect.Array.newInstance( java.lang.Byte.TYPE, 2056 ),
bytesIn = 0,
anEntry,
fis;
for ( var i = 0; i < dirList.length; i++ ) {
var f = new File( sourceLocation, dirList[ i ] );
if ( f.isDirectory() ) {
compressDirectory( f, startLocation, outStream, compressMethod, rootDir );
continue;
}
fis = new FileInputStream( f );
switch ( compressMethod ) {
case 'tar.gz' :
anEntry = new TarEntry( f.getCanonicalPath().replace( startLocation.getCanonicalPath(), rootDir ).replace( "\\", "/" ) );
break;
case 'zip' :
anEntry = new ZipEntry( f.getCanonicalPath().replace( startLocation.getCanonicalPath(), rootDir ).replace( "\\", "/" ) );
break;
default:
throw "Unknown compression method: " + compressMethod;
}
outStream.putNextEntry( anEntry );
while ( ( bytesIn = fis.read( readBuffer ) ) !== -1 ) {
outStream.write( readBuffer, 0, bytesIn );
}
outStream.closeEntry();
fis.close();
}
} catch ( e ) {
throw "An error occurred during (" + compressMethod + ") compression of " + sourceLocation.getAbsolutePath() + ": " + e;
}
}
/**
* Copy file from source to target location.
*
* @param {String} sourceLocation Source folder
* @param {String} targetLocation Target folder
* @member CKBuilder.io
*/
function copyFile( sourceLocation, targetLocation ) {
try {
var inStream = new FileInputStream( sourceLocation ),
outStream = new FileOutputStream( targetLocation );
if ( CKBuilder.options.debug > 1 )
print( "Copying file: " + sourceLocation.getCanonicalPath() );
var len,
buf = new Packages.java.lang.reflect.Array.newInstance( java.lang.Byte.TYPE, 1024 );
while ( ( len = inStream.read( buf ) ) !== -1 )
outStream.write( buf, 0, len );
inStream.close();
outStream.close();
if ( CKBuilder.options.debug > 1 )
print( "File copied: " + targetLocation.getCanonicalPath() );
} catch ( e ) {
throw "Cannot copy file:\n Source: " + sourceLocation.getCanonicalPath() + "\n Destination : " + targetLocation.getCanonicalPath() + "\n" + e.message;
}
}
/**
* Input output actions. Copy, delete files and directories. Save them, show directory info.
*
* @class
*/
CKBuilder.io = {
/**
* This method is preventable depending on callback value.
* When callback returns false value then nothing changes.
*
* @static
* @param {java.io.File} sourceLocation
* @param {java.io.File} targetLocation
* @param {function(java.io.File, java.io.File):Boolean} callback
*/
copyFile: function( sourceLocation, targetLocation, callback ) {
if ( callback ) {
if ( !callback.call( this, sourceLocation, targetLocation ) )
return;
}
copyFile( sourceLocation, targetLocation );
},
/**
* Unzips a file recursively.
*
* @param {String} zipFile Path to the source file
* @param {String|java.io.File} newPath Path to the destination folder
* @static
*/
unzipFile: function( zipFile, newPath ) {
try {
var BUFFER = 2048,
file = new File( zipFile ),
zip = new ZipFile( file );
newPath = newPath || zipFile.substring( 0, zipFile.length() - 4 );
new File( newPath ).mkdir();
var zipFileEntries = zip.entries();
// Process each entry
while ( zipFileEntries.hasMoreElements() ) {
// grab a zip file entry
var entry = zipFileEntries.nextElement(),
currentEntry = entry.getName(),
destFile = new File( newPath, currentEntry ),
destinationParent = destFile.getParentFile();
// create the parent directory structure if needed
destinationParent.mkdirs();
if ( !entry.isDirectory() ) {
var is = new BufferedInputStream( zip.getInputStream( entry ) ),
// establish buffer for writing file
data = new Packages.java.lang.reflect.Array.newInstance( java.lang.Byte.TYPE, BUFFER ),
// write the current file to disk
fos = new FileOutputStream( destFile ),
dest = new BufferedOutputStream( fos, BUFFER );
// read and write until last byte is encountered
var currentByte;
while ( ( currentByte = is.read( data, 0, BUFFER ) ) !== -1 ) {
dest.write( data, 0, currentByte );
}
dest.flush();
dest.close();
is.close();
}
if ( currentEntry.endsWith( ".zip" ) ) {
// found a zip file, try to open
CKBuilder.io.unzipFile( destFile.getAbsolutePath() );
}
}
} catch ( e ) {
throw "Unable to extract archive file:\n Source: " + zipFile + "\n" + e.message;
}
},
/**
* Deletes a directory.
*
* @param {java.io.File} path Directory to delete
* @static
*/
deleteDirectory: function( path ) {
var dir = new File( path );
if ( !dir.exists() )
return true;
if ( dir.isDirectory() ) {
var children = dir.list();
for ( var i = 0; i < children.length; i++ ) {
if ( !this.deleteDirectory( new File( dir, children[ i ] ) ) )
return false;
}
}
return dir['delete']();
},
/**
* Deletes a file.
*
* @param {java.io.File} path File to delete
* @static
*/
deleteFile: function( path ) {
var f = new File( path );
if ( !f.exists() )
return true;
if ( !f.canWrite() )
throw "Cannot delete file: " + f.getAbsolutePath();
return f[ "delete" ]();
},
/**
* Saves a file.
*
* @param {java.io.File} file Path to the file
* @param {String} text Content of a file
* @param {Boolean} [includeBom=false] includeBom Whether to include BOM character
* @static
*/
saveFile: function( file, text, includeBom ) {
includeBom = ( includeBom === true );
try {
var stream = new BufferedWriter( new OutputStreamWriter( new FileOutputStream( file ), "UTF-8" ) );
if ( includeBom )
stream.write( 65279 );
stream.write( text );
stream.flush();
stream.close();
} catch ( e ) {
throw "Cannot save file:\n Path: " + file.getCanonicalPath() + "\n Exception details: " + e.message;
}
},
/**
* Copies file/folder, with the possibility of ignoring specific paths.
*
* @param {java.io.File} sourceLocation Source location
* @param {java.io.File} targetLocation Target location
* @param {function(java.io.File, java.io.File): number} callbackBefore (Optional)
* The possible returned values are:
*
* -1 Do not copy file, do not call callbackAfter.
*
* 0 Copy file, call callbackAfter.
*
* 1 File was already copied, call callbackAfter.
* @param {Function} callbackAfter (Optional) Callback function executed after the file is copied.
* @static
*/
copy: function( sourceLocation, targetLocation, callbackBefore, callbackAfter ) {
if ( callbackBefore ) {
var code = callbackBefore.call( this, sourceLocation, targetLocation );
if ( code === -1 )
return;
if ( callbackAfter )
callbackAfter.call( this, targetLocation );
if ( code === 1 )
return;
}
if ( sourceLocation.isDirectory() ) {
if ( !targetLocation.exists() )
targetLocation.mkdir();
var children = sourceLocation.list();
for ( var i = 0; i < children.length; i++ ) {
if ( String( children[ i ] ) === ".svn" || String( children[ i ] ) === "CVS" || String( children[ i ] ) === ".git" )
continue;
this.copy( new File( sourceLocation, children[ i ] ), new File( targetLocation, children[ i ] ), callbackBefore, callbackAfter );
}
if ( !targetLocation.list().length )
targetLocation[ 'delete' ]();
} else {
copyFile( sourceLocation, targetLocation );
if ( callbackAfter )
callbackAfter.call( this, targetLocation );
}
},
/**
* Creates a zip archive from specified location.
*
* @param {java.io.File} sourceLocation The location of the folder to compress.
* @param {java.io.File} startLocation Starting from this location the folder structure will be replicated.
* The startLocation should be a subfolder of sourceLocation.
* @param {java.io.File} targetFile The location of the target zip file.
* @param {String} rootDir The name of root folder in which the rest of files will be placed
* @static
*/
zipDirectory: function( sourceLocation, startLocation, targetFile, rootDir ) {
var outStream = new ZipOutputStream( new FileOutputStream( targetFile ) );
compressDirectory( sourceLocation, startLocation, outStream, 'zip', rootDir );
outStream.close();
},
/**
* Creates a tar.gz archive from specified location.
*
* @param {java.io.File} sourceLocation The location of the folder to compress.
* @param {java.io.File} startLocation Starting from this location the folder structure will be replicated.
* The startLocation should be a subfolder of sourceLocation.
* @param {java.io.File} targetFile The location of the target tar.gz file.
* @param {String} rootDir The name of root folder in which the rest of files will be placed
* @static
*/
targzDirectory: function( sourceLocation, startLocation, targetFile, rootDir ) {
var outStream = new TarGzOutputStream( new FileOutputStream( targetFile ) );
compressDirectory( sourceLocation, startLocation, outStream, 'tar.gz', rootDir );
outStream.close();
},
/**
* Sets or removes the BOM character at the beginning of the file.
*
* @param {String} file Path to the file
* @param {Boolean} includeUtf8Bom Boolean value indicating whether the BOM character should exist
* @static
*/
setByteOrderMark: function( file, includeUtf8Bom ) {
var buffer = new StringBuffer(),
chars = new Packages.java.lang.reflect.Array.newInstance( java.lang.Character.TYPE, 32 ),
inStream;
try {
inStream = new InputStreamReader( new FileInputStream( file ), 'UTF-8' );
} catch ( e ) {
throw 'An I/O error occurred while opening the ' + file + ' file.';
}
try {
var count = inStream.read( chars, 0, 32 );
if ( count <= 0 )
return;
buffer.append( chars, 0, count );
/* BOM is at the beginning of file */
if ( buffer.length() && buffer.charAt( 0 ) === 65279 ) {
if ( !includeUtf8Bom ) {
if ( CKBuilder.options.debug )
print( 'Removing BOM from ' + file.getCanonicalPath() );
this.saveFile( file, this.readFile( file ) );
}
} else {
if ( includeUtf8Bom ) {
if ( CKBuilder.options.debug )
print( 'Adding BOM to ' + file.getCanonicalPath() );
this.saveFile( file, this.readFile( file ), true );
}
}
} catch ( e ) {
throw 'An I/O error occurred while reading the ' + file.getCanonicalPath() + ' file.';
} finally {
inStream.close();
}
},
/**
* Reads files from given array and returns joined file contents.
*
* @param {java.io.File[]} files The list of files to read.
* @returns {String}
* @static
*/
readFiles: function( files, separator ) {
var i,
out = [];
for ( i = 0; i < files.length; i++ ) {
out.push( this.readFile( files[ i ] ) );
}
return out.join( separator ? separator : "" );
},
/**
* Reads file and returns file contents without initial UTF-8 Byte Order.
*
* Mark
* @param {java.io.File} file
* @returns {String}
* @static
*/
readFile: function( file ) {
var buffer = new StringBuffer(),
chars = new Packages.java.lang.reflect.Array.newInstance( java.lang.Character.TYPE, 8192 ),
count,
fis,
inStream;
if ( !file.exists() )
throw 'File ' + file + ' does not exist.';
try {
fis = new FileInputStream( file );
inStream = new InputStreamReader( fis, 'UTF-8' );
} catch ( e ) {
throw 'An I/O error occurred while opening the ' + file + ' file.';
}
try {
while ( ( count = inStream.read( chars, 0, 8192 ) ) !== -1 ) {
if ( count > 0 )
buffer.append( chars, 0, count );
}
} catch ( e ) {
throw 'An I/O error occurred while reading the ' + file.getCanonicalPath() + ' file.';
} finally {
fis.close();
inStream.close();
}
/* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 */
if ( buffer.length() && buffer.charAt( 0 ) === 65279 )
buffer.deleteCharAt( 0 );
return String( buffer.toString() );
},
/**
* Reads file from within .jar file and returns file contents without initial UTF-8 Byte Order Mark.
*
* @param {String} path Path to the file
* @returns {String}
* @static
*/
readFileFromJar: function( path ) {
var buffer = new StringBuffer(),
chars = new Packages.java.lang.reflect.Array.newInstance( java.lang.Character.TYPE, 8192 ),
fis,
inStream;
try {
fis = java.lang.Class.forName( "ckbuilder.ckbuilder" ).getClassLoader().getResourceAsStream( path );
inStream = new InputStreamReader( fis, "UTF-8" );
} catch ( e ) {
throw 'An I/O error occurred while opening the ' + path + ' file.';
}
try {
var count;
while ( ( count = inStream.read( chars, 0, 8192 ) ) !== -1 ) {
if ( count > 0 )
buffer.append( chars, 0, count );
}
} catch ( e ) {
throw 'An I/O error occurred while reading the ' + path + ' file.';
} finally {
fis.close();
inStream.close();
}
/* http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058 */
if ( buffer.length() && buffer.charAt( 0 ) === 65279 )
buffer.deleteCharAt( 0 );
return String( buffer.toString() );
},
/**
* Returns size and number of files in the specified directory.
*
* @param {String} path Path to the folder
* @returns {{files: Number, size: Number}}
* @static
*/
getDirectoryInfo: function( path ) {
var result = {
files: 0,
size: 0
};
if ( !path.exists() )
return result;
var files = path.listFiles();
if ( !files )
return result;
var path_iterator = ( java.util.Arrays.asList( files ) ).iterator();
while ( path_iterator.hasNext() ) {
var current_file = path_iterator.next();
if ( current_file.isFile() ) {
result.size += current_file.length();
result.files++;
} else {
var info = this.getDirectoryInfo( current_file );
result.size += info.size;
result.files += info.files;
}
}
return result;
},
/**
* Returns the (lower-cased) extension of the file from the specified path (e.g. "txt").
*
* @param {String} fileName The file name
* @returns {String}
* @static
*/
getExtension: function( fileName ) {
var pos = fileName.lastIndexOf( "." );
if ( pos === -1 )
return "";
else
return String( fileName.substring( pos + 1 ).toLowerCase() );
},
/**
* Check element wether its a zip file. If yes, then extract it into temporary directory.
*
* @param {java.io.File|String} element Directory or zip file.
* @returns {java.io.File} Directory on which work will be done.
*/
prepareWorkingDirectoryIfNeeded: function( element ) {
var elementLocation = new File( element ),
tmpDir,
workingDir,
isTemporary = false;
if ( !elementLocation.isDirectory() ) { //is not a directory
if ( CKBuilder.io.getExtension( element ) !== "zip" ) // is not a zip
throw( "The element file is not a zip file: " + elementLocation.getCanonicalPath() );
// temporary directory
tmpDir = new File( System.getProperty( "java.io.tmpdir" ), ".tmp" + Math.floor( ( Math.random() * 1000000 ) + 1 ) );
// cleaning up dir
if ( tmpDir.exists() && !CKBuilder.io.deleteDirectory( tmpDir ) )
throw( "Unable to delete tmp dir: " + tmpDir.getCanonicalPath() );
try {
tmpDir.mkdirs(); // creating temporary directory
} catch ( e ) {
throw( "Unable to create temp directory: " + tmpDir.getAbsolutePath() + "\nError: " + e.getMessage() );
}
// unzip into temp directory
CKBuilder.io.unzipFile( element, tmpDir );
isTemporary = true;
workingDir = tmpDir;
} else
workingDir = elementLocation;
return {
directory: workingDir,
cleanUp: function () {
if ( isTemporary && workingDir.exists() )
CKBuilder.io.deleteDirectory( workingDir );
}
};
}
};
}() );
ckbuilder-2.3.2/src/lib/javascript.js 0000664 0000000 0000000 00000014422 13230353051 0017521 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
importClass( java.io.File );
importClass( java.lang.System );
importPackage( java.util.regex );
importClass( java.util.regex.Pattern );
importClass( java.util.regex.Matcher );
importClass( com.google.javascript.jscomp.CompilationLevel );
importClass( com.google.javascript.jscomp.Compiler );
importClass( com.google.javascript.jscomp.CompilerOptions );
importClass( com.google.javascript.jscomp.SourceFile );
( function() {
/**
* Compile JavaScript file.
*
* @param {java.io.File} file
* http://closure-compiler.googlecode.com/svn/trunk/javadoc/index.html
* @member CKBuilder.javascript
* @private
* @returns {String}
*/
function compileFile( file ) {
var compiler = new Compiler();
compiler.setLoggingLevel( java.util.logging.Level.WARNING );
// http://closure-compiler.googlecode.com/svn/trunk/javadoc/index.html
// http://closure-compiler.googlecode.com/svn/trunk/javadoc/com/google/javascript/jscomp/CompilerOptions.html
var options = new CompilerOptions();
// Otherwise strings in language files are escaped as \u1234 making them larger
options.outputCharset = 'UTF-8';
CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel( options );
// This is required in order to compile JS files with JSC_TRAILING_COMMA errors
options.setWarningLevel( com.google.javascript.jscomp.DiagnosticGroups.INTERNET_EXPLORER_CHECKS, CKBuilder.options.noIeChecks ? com.google.javascript.jscomp.CheckLevel.OFF : com.google.javascript.jscomp.CheckLevel.WARNING );
options.setWarningLevel(
com.google.javascript.jscomp.DiagnosticGroups.NON_STANDARD_JSDOC,
com.google.javascript.jscomp.CheckLevel.OFF
);
options.setWarningLevel(
com.google.javascript.jscomp.DiagnosticGroups.MISPLACED_TYPE_ANNOTATION,
com.google.javascript.jscomp.CheckLevel.OFF
);
// To get the complete set of externs, the logic in
// CompilerRunner.getDefaultExterns() should be used here.
var extern = SourceFile.fromCode( "externs.js", "function PACKAGER_RENAME() {}" ),
// The dummy input name "input.js" is used here so that any warnings or
// errors will cite line numbers in terms of input.js.
input = SourceFile.fromCode( file.getName(), CKBuilder.io.readFile( file ) ),
// compile() returns a Result, but it is not needed here.
result = compiler.compile( extern, input, options );
if ( result.success )
return compiler.toSource();
else
throw( "Unable to compile file: " + file.getAbsolutePath() );
}
/**
* Handle javascript files. Minify them, remove white spaces and find errors.
*
* @class
*/
CKBuilder.javascript = {
/**
* Finds errors in given code.
*
* @param {String} code JavaScript code
* @param fileName The name of the file from which the code has been taken (used only to build error messages).
* @returns {Array|null}
* @static
*/
findErrors: function( code, fileName ) {
var compiler = new Compiler();
compiler.setLoggingLevel( java.util.logging.Level.OFF );
var options = new CompilerOptions();
options.outputCharset = 'UTF-8';
CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel( options );
// To get the complete set of externs, the logic in
// CompilerRunner.getDefaultExterns() should be used here.
var extern = SourceFile.fromCode( "externs.js", "function PACKAGER_RENAME() {}" ),
// The dummy input name "input.js" is used here so that any warnings or
// errors will cite line numbers in terms of input.js.
input = SourceFile.fromCode( fileName || "input.js", code );
// compile() returns a Result, but it is not needed here.
compiler.compile( extern, input, options );
var arr = [],
errors = compiler.getErrors();
for ( var i = 0; i < errors.length; i++ ) {
// There are simply too many errors of this kind in various libraries :(
/* jshint eqeqeq: false */
if ( 'JSC_TRAILING_COMMA' != errors[ i ].getType().key )
arr.push( errors[ i ].toString() );
/* jshint eqeqeq: true */
}
return arr.length ? arr : null;
},
/**
* Removes white space characters from given code (removes comments and extra whitespace in the input JS).
*
* @param {String} code JavaScript code
* @param {String} fileName The name of the file from which the code has been taken (used only to build error messages).
* @returns {String}
* @static
*/
removeWhiteSpace: function( code, fileName ) {
var compiler = new Compiler();
//compiler.setLoggingLevel(java.util.logging.Level.OFF);
compiler.setLoggingLevel( java.util.logging.Level.SEVERE );
// compiler.setLoggingLevel( java.util.logging.Level.WARNING );
var options = new CompilerOptions();
// This is required in order to compile JS files with JSC_TRAILING_COMMA errors
options.setWarningLevel(
com.google.javascript.jscomp.DiagnosticGroups.INTERNET_EXPLORER_CHECKS,
CKBuilder.options.noIeChecks ? com.google.javascript.jscomp.CheckLevel.OFF : com.google.javascript.jscomp.CheckLevel.WARNING
);
// Otherwise strings in language files are escaped as \u1234 making them larger
options.outputCharset = 'UTF-8';
CompilationLevel.WHITESPACE_ONLY.setOptionsForCompilationLevel( options );
// To get the complete set of externs, the logic in
// CompilerRunner.getDefaultExterns() should be used here.
var extern = SourceFile.fromCode( "externs.js", "function PACKAGER_RENAME() {}" ),
// The dummy input name "input.js" is used here so that any warnings or
// errors will cite line numbers in terms of input.js.
input = SourceFile.fromCode( fileName || "input.js", code ),
result = compiler.compile( extern, input, options );
if ( result.success )
return compiler.toSource(); else
throw( "Unable to compile file: " + fileName );
},
/**
* Minify and save specified file.
*
* @param {java.io.File} file
* @static
*/
minify: function( file ) {
if ( CKBuilder.io.getExtension( file.getName() ) !== "js" )
throw( "Not a JavaScript file: " + file.getAbsolutePath() );
CKBuilder.io.saveFile( file, compileFile( file ), true );
}
};
}() );
ckbuilder-2.3.2/src/lib/lang.js 0000664 0000000 0000000 00000012073 13230353051 0016274 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
importClass( java.io.BufferedWriter );
importClass( java.io.FileWriter );
importClass( java.io.FileOutputStream );
importClass( java.io.FileInputStream );
( function() {
var translations = {};
/**
* This method modifies translations property.
*
* @param {java.io.File} sourceLocation Source folder. Directory which represents plugin, so is located in `plugins` directory.
* @member CKBuilder.lang
*/
function loadPluginLanguageFiles( sourceLocation ) {
var folder = new File( sourceLocation, 'lang' );
if ( !folder.exists() )
return;
var englishFile = new File( folder, 'en.js' ),
englishObj = CKBuilder.lang.loadLanguageFile( englishFile ).translation;
for ( var langCode in translations ) {
var langFile = new File( folder, langCode + '.js' ),
langObj;
if ( langFile.exists() )
langObj = CKBuilder.utils.merge( englishObj, CKBuilder.lang.loadLanguageFile( langFile ).translation );
else
langObj = englishObj;
translations[ langCode ] = CKBuilder.utils.merge( translations[ langCode ], langObj );
}
}
/**
* @param {java.io.File} folder
* @member CKBuilder.lang
*/
function loadCoreLanguageFiles( folder ) {
translations.en = CKBuilder.lang.loadLanguageFile( new File( folder, "en.js" ) ).translation;
var children = folder.list();
for ( var i = 0; i < children.length; i++ ) {
var langFile = children[ i ].match( /^([a-z]{2}(?:-[a-z]+)?)\.js$/ );
if ( langFile ) {
var langCode = langFile[ 1 ];
translations[ langCode ] = CKBuilder.utils.merge( translations.en, CKBuilder.lang.loadLanguageFile( new File( folder, children[ i ] ) ).translation );
}
}
}
/**
* @param langCode
* @returns {string}
* @member CKBuilder.lang
*/
function printTranslation( langCode ) {
if ( CKBuilder.options.leaveJsUnminified )
return CKBuilder.utils.copyright( "\r\n" ) + "CKEDITOR.lang['" + langCode + "'] = {\n" + CKBuilder.utils.prettyPrintObject( translations[ langCode ], ' ' ) + " }; ";
else
return CKBuilder.utils.copyright( "\n" ) + "CKEDITOR.lang['" + langCode + "']=" + JSON.stringify( translations[ langCode ] ) + ";";
}
/**
* Gather translations from CKEditor, merge them and sace into single file.
*
* @class
*/
CKBuilder.lang = {
/**
* @param {String} sourceLocation Path to the folder with source files
* @param {String} targetLocation The target folder where to save the resulting files
* @param {Object} pluginNames Object with a set of plugins included in build
* @param {Object} languages (Optional) Object with languages included in build (if empty, all languages are used)
* @static
*/
mergeAll: function( sourceLocation, targetLocation, pluginNames, languages ) {
var langLocation = new File( sourceLocation, "lang" );
if ( !langLocation.exists() )
throw( "Language folder is missing: " + langLocation.getAbsolutePath() );
var pluginsLocation = new File( sourceLocation, "plugins" );
if ( !pluginsLocation.exists() )
throw( "Plugins folder is missing: " + pluginsLocation.getAbsolutePath() );
loadCoreLanguageFiles( langLocation );
// Load plugins language files
var children = pluginsLocation.list();
children.sort();
for ( var i = 0; i < children.length; i++ ) {
var folderName = String( children[ i ] );
if ( folderName === ".svn" || folderName === "CVS" || folderName === ".git" )
continue;
// Do not load language files from plugins that are not enabled.
if ( pluginNames[ folderName ] )
loadPluginLanguageFiles( new File( pluginsLocation, children[ i ] ) );
}
for ( var langCode in translations ) {
if ( !languages || languages[ langCode ] )
CKBuilder.io.saveFile( File( targetLocation, langCode + ".js" ), printTranslation( langCode ), true );
else
CKBuilder.io.deleteFile( File( targetLocation, langCode + ".js" ) );
}
},
/**
* Load language file and return an object with the whole translation.
*
* @param {java.io.File} file Language file to load.
* @returns {{languageCode: String, translation: Object }}
* @static
*/
loadLanguageFile: function( file ) {
var translationCode = 'var CKEDITOR = { lang : {}, plugins : { setLang : function(plugin, langCode, obj) { if(!CKEDITOR.lang[langCode]) CKEDITOR.lang[langCode] = {};CKEDITOR.lang[langCode][plugin] = obj; } } }; ' + CKBuilder.io.readFile( file ),
cx = Context.enter(),
scope = cx.initStandardObjects();
try {
cx.evaluateString( scope, translationCode, file.getName(), 1, null );
/*
* Return the first entry from scope.CKEDITOR.lang object
*/
for ( var languageCode in scope.CKEDITOR.lang ) {
return {
languageCode: languageCode,
translation: scope.CKEDITOR.lang[ languageCode ]
};
}
} catch ( e ) {
throw( "Language file is invalid: " + file.getAbsolutePath() + ".\nError: " + e.message );
}
}
};
}() );
ckbuilder-2.3.2/src/lib/plugin.js 0000664 0000000 0000000 00000034363 13230353051 0016657 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
( function() {
var regexLib = {
// requires : [ 'dialogui' ]
requiresArray: Pattern.compile( '^\\s*requires\\s*:\\s*\\[\\s*(.*?)\\s*\\]' ),
requiresString: Pattern.compile( '^\\s*requires\\s*:\\s*([\'"])\\s*((?:[a-z0-9-_]+|\\s*,\\s*)+?)\\1\\s*' ),
// lang : 'af,ar,bg'
langString: Pattern.compile( '^(\\s*lang\\s*:\\s*)([\'"])(\\s*(?:[a-z-_]+|\\s*,\\s*)+?)(\\2\\s*.*$)' ),
// matches both CKEDITOR.plugins.add( pluginName AND CKEDITOR.plugins.add( 'pluginName'
// can be used to detect where "CKEDITOR.plugins.add" is located in code
pluginsAdd: Pattern.compile( 'CKEDITOR.plugins.add\\s*\\(\\s*([\'"]?)([a-zA-Z0-9-_]+)\\1', Pattern.DOTALL ),
// matches CKEDITOR.plugins.liststyle =
pluginsDef: Pattern.compile( 'CKEDITOR.plugins.[a-z-_0-9]+\\s*=\\s*', Pattern.DOTALL ),
// matches only CKEDITOR.plugins.add( 'pluginName'
// can be used to find the real plugin name, because the name is not stored in a variable but in a string
pluginsAddWithStringName: Pattern.compile( 'CKEDITOR.plugins.add\\s*\\(\\s*([\'"])([a-zA-Z0-9-_]+)\\1', Pattern.DOTALL ),
pluginName: Pattern.compile( 'var\\s+pluginName\\s*=\\s*([\'"])([a-zA-Z0-9-_]+)\\1', Pattern.DOTALL ),
validPluginProps: Pattern.compile( '(^\\s*icons\\s*:\\s*|^\\s*requires\\s*:\\s*|^\\s*lang\\s*:\\s*|^\\s*$|^\\s*//)', Pattern.DOTALL ),
blockComments: Pattern.compile( "/\\*[^\\r\\n]*[\\r\\n]+(.*?)[\\r\\n]+[^\\r\\n]*\\*+/", Pattern.DOTALL )
};
/**
* Finds the plugin name in given file (plugin.js).
*
* @param {java.io.File} file
* @returns {String|null}
* @member CKBuilder.plugin
* @private
*/
function findPluginNameInPluginDefinition( file ) {
var pluginName = null,
code = CKBuilder.io.readFile( file );
code = CKBuilder.javascript.removeWhiteSpace( code, file.getParentFile().getName() + "/plugin.js" );
var matcher = regexLib.pluginsAddWithStringName.matcher( code );
if ( matcher.find() )
pluginName = matcher.group( 2 );
else {
matcher = regexLib.pluginName.matcher( code );
if ( matcher.find() )
pluginName = matcher.group( 2 );
}
return ( pluginName === null ? pluginName : String( pluginName ) );
}
/**
* Finds the correct plugin.js in given directory.
*
* @param {java.io.File} dir
* @returns {Boolean|String} Path to the right plugin.js file or false.
* @member CKBuilder.plugin
*/
function findCorrectPluginFile( dir ) {
var pluginFiles = CKBuilder.utils.findFilesInDirectory( 'plugin.js', dir ),
result = false;
if ( pluginFiles.length === 1 )
result = pluginFiles[ 0 ];
// let's exclude plugin.js located in the _source or dev folders
else if ( pluginFiles.length > 1 ) {
var tmpArray = [];
for ( var i = 0; i < pluginFiles.length; i++ ) {
if ( !pluginFiles[ i ].match( /(\/|\\)(?:_source|dev)\1/i ) )
tmpArray.push( pluginFiles[ i ] );
}
if ( tmpArray.length === 1 )
result = tmpArray[ 0 ];
}
return result;
}
/**
* Handle plugins. Validate them and preprocess.
*
* @class
*/
CKBuilder.plugin = {
/**
* Returns an array with plugins required by this plugin.
*
* @param {java.io.File} file Plugin file
* @returns {Array}
* @static
*/
getRequiredPlugins: function( file ) {
if ( CKBuilder.options.debug > 1 )
print( "Getting required plugins from " + file.getPath() );
var text = String( CKBuilder.io.readFile( file ) ),
// Remove comments
matcher = regexLib.blockComments.matcher( text );
if ( matcher.find() )
text = matcher.replaceAll( '' );
var lines = text.split( "\n" ),
pluginsAddFound = false,
checkValidPluginProps = false,
invalidLinesCounter = 0;
for ( var i = 0; i < lines.length; i++ ) {
if ( !pluginsAddFound ) {
matcher = regexLib.pluginsAdd.matcher( lines[ i ] );
if ( matcher.find() )
pluginsAddFound = true;
else {
matcher = regexLib.pluginsDef.matcher( lines[ i ] );
if ( matcher.find() )
pluginsAddFound = true;
}
if ( pluginsAddFound )
invalidLinesCounter = 0;
}
var requires;
if ( pluginsAddFound ) {
matcher = regexLib.requiresArray.matcher( lines[ i ] );
if ( matcher.find() ) {
requires = String( matcher.group( 1 ) );
if ( CKBuilder.options.debug > 1 )
print( "Found: " + matcher.group( 1 ) );
return requires.replace( /['" ]/g, '' ).split( "," );
}
matcher = regexLib.requiresString.matcher( lines[ i ] );
if ( matcher.find() ) {
requires = String( matcher.group( 2 ) );
if ( CKBuilder.options.debug > 1 )
print( "Found: " + matcher.group( 2 ) );
return requires.replace( /['" ]/g, '' ).split( "," );
}
if ( checkValidPluginProps ) {
matcher = regexLib.validPluginProps.matcher( lines[ i ] );
if ( !matcher.find() )
invalidLinesCounter++;
if ( invalidLinesCounter > 5 ) {
pluginsAddFound = false;
checkValidPluginProps = false;
}
}
// we're in the same line where plugin definition has started, start checking from another line
else
checkValidPluginProps = true;
}
}
return [];
},
/**
* Updates lang property in file.
*
* @param {java.io.File} sourceLocation
* @param {Object} languages
* @returns {Array|Boolean}
* @static
*/
updateLangProperty: function( sourceLocation, languages ) {
var text = String( CKBuilder.io.readFile( sourceLocation ) ),
lines = text.split( "\n" ),
pluginsAddFound = false,
checkValidPluginProps = false,
langPropertyChanged = false,
invalidLinesCounter = 0,
validLanguages;
for ( var i = 0; i < lines.length; i++ ) {
var matcher;
if ( !pluginsAddFound ) {
matcher = regexLib.pluginsAdd.matcher( lines[ i ] );
if ( matcher.find() )
pluginsAddFound = true;
else {
matcher = regexLib.pluginsDef.matcher( lines[ i ] );
if ( matcher.find() )
pluginsAddFound = true;
}
if ( pluginsAddFound )
invalidLinesCounter = 0;
}
if ( pluginsAddFound ) {
matcher = regexLib.langString.matcher( lines[ i ] );
if ( matcher.find() ) {
var pluginLanguages = String( matcher.group( 3 ) ).replace( /['" ]/g, '' ).split( "," );
validLanguages = [];
for ( var langCode in languages ) {
if ( languages[ langCode ] && pluginLanguages.indexOf( langCode ) !== -1 )
validLanguages.push( langCode );
}
// better to change the lang property only if we're able to find some matching language files...
if ( validLanguages.length ) {
if ( validLanguages.length !== pluginLanguages.length ) {
lines[ i ] = matcher.group( 1 ) + matcher.group( 2 ) + validLanguages.join( ',' ) + matcher.group( 4 );
langPropertyChanged = true;
} else
return true;
}
}
if ( checkValidPluginProps ) {
matcher = regexLib.validPluginProps.matcher( lines[ i ] );
if ( !matcher.find() )
invalidLinesCounter++;
if ( invalidLinesCounter > 5 ) {
pluginsAddFound = false;
checkValidPluginProps = false;
}
}
// We're in the same line where plugin definition has started, start checking from another line.
else
checkValidPluginProps = true;
}
}
if ( langPropertyChanged ) {
if ( CKBuilder.options.debug > 1 )
print( "Updated lang property in " + sourceLocation.getPath() );
CKBuilder.io.saveFile( sourceLocation, lines.join( "\r\n" ), true );
return validLanguages;
}
return false;
},
/**
* Checks specified plugin for errors.
*
* @param {java.io.File|String} plugin Path to the plugin (or the java.io.File object pointing to a plugin file).
* @param {Object=} options
* @param {Boolean=} options.exitOnError
* @param {String=} options.pluginName
* @returns {String}
* @static
*/
verify: function( plugin, options ) {
var errors = "",
workingDirObj = CKBuilder.io.prepareWorkingDirectoryIfNeeded( plugin ),
workingDir = workingDirObj.directory;
if ( CKBuilder.options.debug > 1 )
print( "Validating JS files" );
errors += CKBuilder.tools.validateJavaScriptFiles( workingDir );
errors += CKBuilder.tools.validateJavaScriptFilesUsingCC( workingDir );
if ( !errors ) {
var pluginPath = findCorrectPluginFile( workingDir );
if ( !pluginPath ) {
// check why findCorrectPluginFile() returned false
var pluginPaths = CKBuilder.utils.findFilesInDirectory( 'plugin.js', workingDir );
if ( pluginPaths.length > 1 ) {
var tmpArray = [],
workingDirPath = workingDir.getAbsolutePath();
for ( var i = 0; i < pluginPaths.length; i++ ) {
pluginPaths[ i ] = String( pluginPaths[ i ].replace( workingDirPath, '' ) ).replace( /\\/g, '/' );
if ( !pluginPaths[ i ].match( /(\/|\\)(?:_source|dev)\1/i ) )
tmpArray.push( pluginPaths[ i ] );
}
if ( !tmpArray.length )
errors += "Could not find plugin.js:\n" + pluginPaths.join( "\n" ) + "\n";
else if ( tmpArray.length > 1 )
errors += "Found more than one plugin.js:\n" + pluginPaths.join( "\n" ) + "\n";
} else
errors += "Unable to locate plugin.js" + "\n";
} else {
if ( options && options.pluginName ) {
var pluginName = findPluginNameInPluginDefinition( new File( pluginPath ) );
if ( pluginName && pluginName !== options.pluginName )
errors += "The plugin name defined inside plugin.js (" + pluginName + ") does not match the expected plugin name (" + options.pluginName + ")" + "\n";
}
}
}
workingDirObj.cleanUp();
if ( errors && options && options.exitOnError )
System.exit( 500 );
return errors ? errors : "OK";
},
/**
* Preprocesses the specified plugin and saves in an optimized form in the target folder.
*
* @param {String} plugin Path to the plugin
* @param {String} dstDir Path to the destination folder
* @static
*/
preprocess: function( plugin, dstDir ) {
var workingDirObj = CKBuilder.io.prepareWorkingDirectoryIfNeeded( plugin ),
workingDir = workingDirObj.directory;
if ( this.verify( workingDir, { exitOnError: false } ) !== "OK" ) {
workingDirObj.cleanUp();
throw( "The plugin is invalid" );
}
var pluginPath = findCorrectPluginFile( workingDir );
if ( !pluginPath ) {
workingDirObj.cleanUp();
throw( "The plugin file (plugin.js) was not found in " + workingDir.getCanonicalPath() );
}
var pluginFile = new File( pluginPath ),
targetFolder = new File( dstDir );
try {
targetFolder.mkdirs();
} catch ( e ) {
workingDirObj.cleanUp();
throw( "Unable to create target directory: " + targetFolder.getAbsolutePath() + "\nError: " + e.getMessage() );
}
var flags = {},
rootFolder = pluginFile.getParentFile();
CKBuilder.io.copy( rootFolder, targetFolder, function( sourceLocation, targetLocation ) {
if ( sourceLocation.isFile() ) {
// Manifest file is converted later to a "php.ini" format and saved as manifest.mf
if ( String( sourceLocation.getAbsolutePath() ) === String( File( rootFolder, "manifest.js" ).getAbsolutePath() ) )
return -1;
var copied = CKBuilder.tools.fixLineEndings( sourceLocation, targetLocation );
if ( copied ) {
// Do not process any directives
if ( CKBuilder.options.leaveJsUnminified )
return 1;
var flag = CKBuilder.tools.processDirectives( targetLocation, null, true );
if ( flag.LEAVE_UNMINIFIED )
flags[ targetLocation.getAbsolutePath() ] = flag;
return 1;
}
} else {
if ( !CKBuilder.options.leaveJsUnminified && String( sourceLocation.getAbsolutePath() ) === String( File( rootFolder, "lang" ).getAbsolutePath() ) )
return -1;
}
return 0;
}, function( targetLocation ) {
if ( CKBuilder.options.leaveJsUnminified )
return;
if ( CKBuilder.io.getExtension( targetLocation.getName() ) === 'js' ) {
var targetPath = targetLocation.getAbsolutePath();
if ( flags[ targetPath ] && flags[ targetPath ].LEAVE_UNMINIFIED ) {
if ( CKBuilder.options.debug > 1 )
print( "Leaving unminified: " + targetLocation.getPath() );
CKBuilder.io.saveFile( targetLocation, CKBuilder.tools.removeLicenseInstruction( CKBuilder.io.readFile( targetLocation ) ), true );
return;
}
// remove @license information from files that will go into ckeditor.js (plugin.js)
if ( String( targetPath ) === String( File( targetFolder, "plugin.js" ).getAbsolutePath() ) ) {
if ( CKBuilder.options.debug > 2 )
print( "Removing license information from " + targetPath );
CKBuilder.io.saveFile( targetLocation, CKBuilder.tools.removeLicenseInstruction( CKBuilder.io.readFile( targetLocation ) ), true );
}
if ( CKBuilder.options.debug )
print( "Minifying: " + targetLocation.getPath() );
CKBuilder.javascript.minify( targetLocation );
}
} );
var langFolder = new File( rootFolder, "lang" ),
targetLangFolder = new File( targetFolder, "lang" );
if ( !CKBuilder.options.leaveJsUnminified && langFolder.exists() ) {
targetLangFolder.mkdir();
var translations = {};
print( "Processing lang folder" );
translations.en = CKBuilder.lang.loadLanguageFile( new File( langFolder, "en.js" ) ).translation;
var children = langFolder.list();
for ( var i = 0; i < children.length; i++ ) {
var langFile = children[ i ].match( /^([a-z]{2}(?:-[a-z]+)?)\.js$/ );
if ( langFile ) {
var langCode = langFile[ 1 ];
translations[ langCode ] = CKBuilder.utils.merge( translations.en, CKBuilder.lang.loadLanguageFile( new File( langFolder, children[ i ] ) ).translation );
var pseudoObject = JSON.stringify( translations[ langCode ] ).replace( /^\{(.*)\}$/, '$1' );
CKBuilder.io.saveFile( File( targetLangFolder, children[ i ] ), pseudoObject, true );
}
}
}
workingDirObj.cleanUp();
}
};
}() );
ckbuilder-2.3.2/src/lib/samples.js 0000664 0000000 0000000 00000017760 13230353051 0017027 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
( function() {
var regexLib = {
PluginsSamples: Pattern.compile( '', Pattern.DOTALL ),
AdvancedSamples: Pattern.compile( '', Pattern.DOTALL ),
InlineEditingSamples: Pattern.compile( '', Pattern.DOTALL ),
metaTag: Pattern.compile( '', Pattern.DOTALL ),
metaName: Pattern.compile( 'name="(.*?)"', Pattern.DOTALL ),
metaContent: Pattern.compile( 'content="(.*?)"', Pattern.DOTALL )
};
/**
* Holds URLs, names and descriptions of samples found in meta tags.
*
* @property {Object} samplesMetaInformation
* @member CKBuilder.samples
*/
var samplesMetaInformation = {
'beta': {},
'new': {},
'normal': {}
};
/**
* Returns an information gathered from the tag in HTML.
*
* @param {String} text
* @returns {Object}
* @private
* @member CKBuilder.samples
*/
function getMetaInformation( text ) {
var matcher = regexLib.metaTag.matcher( text ),
metaInformation = {};
while ( matcher.find() ) {
var metaText = matcher.group( 1 ),
metaNameMatcher = regexLib.metaName.matcher( metaText ),
metaContentMatcher = regexLib.metaContent.matcher( metaText );
if ( metaContentMatcher.find() && metaNameMatcher.find() )
metaInformation[ String( metaNameMatcher.group( 1 ) ).replace( /^ckeditor-sample-/, '' ) ] = String( metaContentMatcher.group( 1 ) );
}
if ( !metaInformation.group || ( metaInformation.group !== 'Inline Editing' && metaInformation.group !== 'Advanced Samples' ) )
metaInformation.group = 'Plugins';
return metaInformation;
}
/**
* Checks every plugin folder for the "samples" directory, moves the samples into the root "samples directory.
*
* @param {java.io.File} sourceLocation
* @private
* @member CKBuilder.samples
*/
function mergePluginSamples( sourceLocation ) {
var pluginsLocation = new File( sourceLocation, "plugins" );
if ( !pluginsLocation.exists() )
return;
var children = pluginsLocation.list();
children.sort();
for ( var i = 0; i < children.length; i++ ) {
if ( String( children[ i ] ) === ".svn" || String( children[ i ] ) === "CVS" || String( children[ i ] ) === ".git" )
continue;
// Find the "samples" folder
var pluginSamplesLocation = new File( pluginsLocation, children[ i ] + '/samples' );
if ( pluginSamplesLocation.exists() && pluginSamplesLocation.isDirectory() ) {
mergeSamples( pluginSamplesLocation, new File( sourceLocation, 'samples/old/' + children[ i ] ), children[ i ] );
CKBuilder.io.deleteDirectory( pluginSamplesLocation.getAbsolutePath() );
}
}
}
/**
* Moves samples from source to the target location, gathers information stored in meta tags.
*
* @param {java.io.File} sourceLocation
* @param {java.io.File} targetLocation
* @param {String} path URL to a sample, relative to the location of index.html with link to old samples
* @private
* @member CKBuilder.samples
*/
function mergeSamples( sourceLocation, targetLocation, path ) {
if ( sourceLocation.isDirectory() ) {
if ( !targetLocation.exists() )
targetLocation.mkdirs();
var children = sourceLocation.list();
for ( var i = 0; i < children.length; i++ ) {
if ( String( children[ i ] ) === ".svn" || String( children[ i ] ) === "CVS" || String( children[ i ] ) === ".git" )
continue;
mergeSamples( new File( sourceLocation, children[ i ] ), new File( targetLocation, children[ i ] ), path + '/' + children[ i ] );
}
if ( !targetLocation.list().length )
targetLocation[ 'delete' ]();
} else {
CKBuilder.io.copyFile( sourceLocation, targetLocation );
if ( CKBuilder.io.getExtension( sourceLocation.getName() ) !== 'html' )
return;
var text = CKBuilder.io.readFile( sourceLocation );
// check if required meta information is available
if ( text.indexOf( "ckeditor-sample-name" ) === -1 )
return;
var meta = getMetaInformation( text );
if ( meta.isbeta )
samplesMetaInformation['beta'][ path ] = meta; // jshint ignore:line
else if ( meta.isnew )
samplesMetaInformation['new'][ path ] = meta;
else
samplesMetaInformation['normal'][ path ] = meta; // jshint ignore:line
}
}
/**
* Returns a single definition list that represents one sample.
*
* @param {String} url URL to a sample
* @param {Object} info An object with information like name and description
* @returns {String}
* @private
* @member CKBuilder.samples
*/
function linkToSample( url, info ) {
if ( !info.name )
return '';
// Support , and tags
var description = info.description.replace( /<(\/?(?:code|strong|em))>/g, '<$1>' );
// Basic usage of the API
// Using the CKEditor JavaScript API to interact with the editor at runtime.
var out = [];
out.push( "\n", '', info.name, '' );
if ( info.isnew )
out.push( ' New!' );
if ( info.isbeta )
out.push( ' Beta' );
out.push( '', "\n" );
out.push( '', description, '', "\n" );
return out.join( '' );
}
/**
* Returns HTML structure for the "Plugins" section.
*
* @param {String} html HTML code with definition lists containing links to samples
* @returns {String}
* @member CKBuilder.samples
*/
function pluginsSection( html ) {
if ( !html )
return '';
return 'Plugins
' + "\n" + '' + html + '
';
}
/**
* Prepare samples.
*
* @class
*/
CKBuilder.samples = {
/**
* Merges samples from plugins folders into the root "samples/old" folder.
*
* @param {java.io.File} sourceLocation Path to CKEditor, where the "samples" and "plugins" folders are available.
* @static
*/
mergeSamples: function( sourceLocation ) {
var samplesFolder = 'samples/old';
var samplesLocation = new File( sourceLocation, samplesFolder );
if ( !samplesLocation.exists() ) {
if ( CKBuilder.options.debug )
print( "INFO: " + samplesFolder + " dir not found in " + sourceLocation.getAbsolutePath() );
return;
}
var indexFile = new File( samplesLocation, 'index.html' );
if ( !indexFile.exists() ) {
if ( CKBuilder.options.debug )
print( "index.html not found in the " + samplesFolder + " directory: " + samplesLocation.getAbsolutePath() );
return;
}
var indexHtml = CKBuilder.io.readFile( indexFile );
indexHtml = CKBuilder.tools.processDirectivesInString( indexHtml );
// Nothing to do
if ( indexHtml.indexOf( "PLUGINS_SAMPLES" ) === -1 && indexHtml.indexOf( "ADVANCED_SAMPLES" ) === -1 && indexHtml.indexOf( "INLINE_EDITING_SAMPLES" ) === -1 ) {
if ( CKBuilder.options.debug )
print( samplesFolder + '/index.html does not contain any placeholders to replace' );
CKBuilder.io.saveFile( indexFile, indexHtml, true );
return;
}
mergePluginSamples( sourceLocation );
var html = {
'Inline Editing': '',
'Advanced Samples': '',
'Plugins': ''
};
for ( var type in samplesMetaInformation ) {
for ( var url in samplesMetaInformation[ type ] ) {
html[ samplesMetaInformation[ type ][ url ].group ] += linkToSample( url, samplesMetaInformation[ type ][ url ] );
}
}
/* jshint sub: true */
indexHtml = regexLib.PluginsSamples.matcher( indexHtml ).replaceFirst( pluginsSection( html[ 'Plugins' ] ) );
indexHtml = regexLib.InlineEditingSamples.matcher( indexHtml ).replaceFirst( html[ 'Inline Editing' ] );
indexHtml = regexLib.AdvancedSamples.matcher( indexHtml ).replaceFirst( html[ 'Advanced Samples' ] );
/* jshint sub: false */
CKBuilder.io.saveFile( indexFile, indexHtml, true );
}
};
}() );
ckbuilder-2.3.2/src/lib/skin.js 0000664 0000000 0000000 00000021024 13230353051 0016313 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
( function() {
var regexLib = {
skinName: Pattern.compile( 'CKEDITOR.skin.name\\s*\\=\\s*([\'"])([a-zA-Z0-9-_]+)\\1', Pattern.DOTALL )
};
/**
* Finds the skin name in give file (skin.js).
*
* @param {java.io.File} file
* @returns {String|null}
* @private
* @member CKBuilder.skin
*/
function findSkinNameInSkinDefinition( file ) {
var code = CKBuilder.io.readFile( file );
code = CKBuilder.javascript.removeWhiteSpace( code, file.getParentFile().getName() + "/skin.js" );
var matcher = regexLib.skinName.matcher( code ),
skinName;
if ( matcher.find() )
skinName = matcher.group( 2 );
return skinName === null ? null : String( skinName );
}
/**
* Finds the correct skin.js in given directory.
*
* @param {java.io.File} dir
* @returns {Boolean|String} Path to the right skin.js file or false.
* @member CKBuilder.skin
*/
function findCorrectSkinFile( dir ) {
var skinFiles = CKBuilder.utils.findFilesInDirectory( 'skin.js', dir );
if ( !skinFiles.length )
return false;
if ( skinFiles.length === 1 )
return skinFiles[ 0 ];
// let's exclude skin.js located in the _source folder
if ( skinFiles.length > 1 ) {
var tmpArray = [];
for ( var i = 0; i < skinFiles.length; i++ ) {
if ( !skinFiles[ i ].match( /(\/|\\)_source\1/ ) )
tmpArray.push( skinFiles[ i ] );
}
if ( !tmpArray.length )
return false;
else if ( tmpArray.length > 1 )
return false;
else
return tmpArray[ 0 ];
}
}
/**
* Handle skins. Validate them and preprocess.
*
* @class
*/
CKBuilder.skin = {
/**
* Checks specified skin for errors.
*
* @param {String} skin
* @param {Object} options
* @param {String=} options.skinName
* @param {Boolean=} options.exitOnError
* @static
*/
verify: function( skin, options ) {
var skinPath,
errors = '',
workingDirObj = CKBuilder.io.prepareWorkingDirectoryIfNeeded( skin ),
workingDir = workingDirObj.directory;
if ( CKBuilder.options.debug > 1 )
print( "Validating JS files" );
errors += CKBuilder.tools.validateJavaScriptFiles( workingDir );
errors += CKBuilder.tools.validateJavaScriptFilesUsingCC( workingDir );
if ( !errors ) {
skinPath = findCorrectSkinFile( workingDir );
if ( !skinPath ) {
// check why findCorrectSkinFile() returned false
var skinPaths = CKBuilder.utils.findFilesInDirectory( 'skin.js', workingDir );
if ( skinPaths.length > 1 ) {
var tmpArray = [],
workingDirPath = workingDir.getAbsolutePath();
for ( var i = 0; i < skinPaths.length; i++ ) {
skinPaths[ i ] = String( skinPaths[ i ].replace( workingDirPath, '' ) ).replace( /\\/g, '/' );
if ( !skinPaths[ i ].match( /(\/|\\)_source\1/ ) )
tmpArray.push( skinPaths[ i ] );
}
if ( !tmpArray.length )
errors += "Found more than one skin.js:\n" + skinPaths.join( "\n" ) + "\n";
else if ( tmpArray.length > 1 )
errors += "Found more than one skin.js:\n" + skinPaths.join( "\n" ) + "\n";
} else
errors += "Unable to locate skin.js";
} else {
if ( options && options.skinName ) {
var skinName = findSkinNameInSkinDefinition( new File( skinPath ) );
if ( skinName && skinName !== options.skinName )
errors += "The skin name defined inside skin.js (" + skinName + ") does not match the expected skin name (" + options.skinName + ")" + "\n";
}
}
}
if ( skinPath ) {
var skinFile = new File( skinPath ),
iconsFolder = new File( skinFile.getParentFile(), 'icons' );
// Skin is not obliged to provide icons
if ( iconsFolder.exists() && !iconsFolder.isDirectory() )
errors += "There is an \"icons\" file, but a folder with this name is expected." + "\n";
}
workingDirObj.cleanUp();
if ( errors && options && options.exitOnError )
System.exit( 500 );
return errors ? errors : "OK";
},
/**
* Builds the specified skin and saves in an optimized form in the target folder.
*
* @param {String} skin Path to the skin
* @param {String} dstDir Path to the destination folder
* @static
*/
build: function( skin, dstDir ) {
var time = new Date(),
startTime = time,
skinLocation = new File( dstDir );
CKBuilder.tools.prepareTargetFolder( skinLocation );
print( "Building skin: " + skin );
this.preprocess( skin, dstDir, true );
var iconsDir = new File( skinLocation, "icons" );
if ( iconsDir.exists )
CKBuilder.io.deleteDirectory( File( skinLocation, "icons" ) );
CKBuilder.utils.printUsedTime( startTime );
},
/**
* Preprocesses the specified skin and saves in an optimized form in the target folder.
*
* @param {String} skin Path to the skin
* @param {String} dstDir Path to the destination folder
* @param {Boolean=} generateSprite Whether to generate strip image from available icons
* @static
*/
preprocess: function( skin, dstDir, generateSprite ) {
var workingDirObj = CKBuilder.io.prepareWorkingDirectoryIfNeeded( skin ),
workingDir = workingDirObj.directory;
if ( !this.verify( workingDir, { exitOnError: false } ) ) {
workingDirObj.cleanUp();
throw( "The skin is invalid" );
}
var skinPath = findCorrectSkinFile( workingDir );
if ( !skinPath ) {
workingDirObj.cleanUp();
throw( "The skin file (skin.js) was not found in " + workingDir.getCanonicalPath() );
}
var skinFile = new File( skinPath ),
name = findSkinNameInSkinDefinition( skinFile );
if ( !name ) {
workingDirObj.cleanUp();
throw( "Unable to find skin name" );
}
var targetFolder = new File( dstDir );
try {
targetFolder.mkdirs();
} catch ( e ) {
throw( "Unable to create target directory: " + targetFolder.getAbsolutePath() + "\nError: " + e.getMessage() );
}
var flags = {},
rootFolder = skinFile.getParentFile();
CKBuilder.io.copy( rootFolder, targetFolder, function( sourceLocation, targetLocation ) {
if ( sourceLocation.isFile() ) {
var copied = CKBuilder.tools.fixLineEndings( sourceLocation, targetLocation );
if ( copied ) {
// Do not process any directives
if ( CKBuilder.options.leaveJsUnminified )
return 1;
var flag = CKBuilder.tools.processDirectives( targetLocation, null, true );
if ( flag.LEAVE_UNMINIFIED )
flags[ targetLocation.getAbsolutePath() ] = flag;
return 1;
}
}
return 0;
}, function( targetLocation ) {
if ( CKBuilder.options.leaveJsUnminified )
return;
if ( CKBuilder.io.getExtension( targetLocation.getName() ) === 'js' ) {
var targetPath = targetLocation.getAbsolutePath();
if ( flags[ targetPath ] && flags[ targetPath ].LEAVE_UNMINIFIED ) {
if ( CKBuilder.options.debug > 1 )
print( "Leaving unminified: " + targetLocation.getPath() );
CKBuilder.io.saveFile( targetLocation, CKBuilder.tools.removeLicenseInstruction( CKBuilder.io.readFile( targetLocation ) ), true );
return;
}
if ( CKBuilder.options.debug )
print( "Minifying: " + targetLocation.getPath() );
CKBuilder.javascript.minify( targetLocation );
}
} );
if ( generateSprite ) {
var skinIcons = CKBuilder.image.findIcons( targetFolder ),
files = [],
outputFile = new File( targetFolder, "icons.png" ),
outputCssFile = new File( targetFolder, "editor.css" ),
noIcons = true,
buttonName;
// Sorted by plugin name
for ( buttonName in skinIcons ) {
files.push( new File( skinIcons[ buttonName ] ) );
noIcons = false;
}
if ( !noIcons )
CKBuilder.image.createSprite( files, outputFile, outputCssFile );
// HiDPI support, set some variables again
skinIcons = CKBuilder.image.findIcons( targetFolder, true );
files = [];
outputFile = new File( targetFolder, "icons_hidpi.png" );
noIcons = true;
// Sorted by plugin name
for ( buttonName in skinIcons ) {
files.push( new File( skinIcons[ buttonName ] ) );
noIcons = false;
}
if ( !noIcons )
CKBuilder.image.createSprite( files, outputFile, outputCssFile, true );
}
if ( !CKBuilder.options.leaveCssUnminified )
CKBuilder.css.mergeCssFiles( targetFolder );
workingDirObj.cleanUp();
}
};
}() );
ckbuilder-2.3.2/src/lib/tools.js 0000664 0000000 0000000 00000034064 13230353051 0016517 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
( function() {
var regexLib = {
eol: Pattern.compile( '(?:\\x09|\\x20)+$' ),
eof: Pattern.compile( '(?:\\x09|\\x20|\\r|\\n)+$' ),
Remove: Pattern.compile( '(?m-s:^.*?%REMOVE_START%).*?(?m-s:%REMOVE_END%.*?$)', Pattern.DOTALL ),
RemoveCore: Pattern.compile( '(?m-s:^.*?%REMOVE_START_CORE%).*?(?m-s:%REMOVE_END_CORE%.*?$)', Pattern.DOTALL ),
RemoveLine: Pattern.compile( '.*%REMOVE_LINE%.*(?:\\r\\n|\\r|\\n)?' ),
RemoveLineCore: Pattern.compile( '.*%REMOVE_LINE_CORE%.*(?:\\r\\n|\\r|\\n)?' ),
Timestamp: Pattern.compile( '%TIMESTAMP%' ),
CopyrightComment: Pattern.compile( '/\\*[\\s\\*]*Copyright[\\s\\S]+?\\*/(?:\\r\\n|\\r|\\n)', Pattern.DOTALL | Pattern.CASE_INSENSITIVE ),
LicenseComment: Pattern.compile( '/\\*[\\s\\*]*\\@license[\\s\\S]+?\\*/(?:\\r\\n|\\r|\\n)', Pattern.DOTALL ),
Rev: Pattern.compile( '%REV%' ),
Version: Pattern.compile( '%VERSION%' ),
license: Pattern.compile( '\\@license( )?', Pattern.DOTALL )
};
var lineEndings = {
"cgi": "\n",
"pl": "\n",
"sh": "\n",
"readme": "\r\n",
"afp": "\r\n",
"afpa": "\r\n",
"ascx": "\r\n",
"asp": "\r\n",
"aspx": "\r\n",
"bat": "\r\n",
"cfc": "\r\n",
"cfm": "\r\n",
"code": "\r\n",
"command": "\r\n",
"conf": "\r\n",
"css": "\r\n",
"dtd": "\r\n",
"htaccess": "\r\n",
"htc": "\r\n",
"htm": "\r\n",
"html": "\r\n",
"js": "\r\n",
"jsp": "\r\n",
"lasso": "\r\n",
"md": "\r\n",
"php": "\r\n",
"py": "\r\n",
"sample": "\r\n",
"txt": "\r\n",
"xml": "\r\n"
};
/**
* @class
*/
CKBuilder.tools = {
/**
* Fix line endings in given file. Only selected text files are processed.
*
* @param {java.io.File} sourceFile
* @param {java.io.File} targetFile
* @static
*/
fixLineEndings: function( sourceFile, targetFile ) {
var extension = CKBuilder.io.getExtension( sourceFile.getName() ),
bomExtensions = { asp: 1, js: 1 };
if ( !lineEndings[ extension ] )
return false;
if ( CKBuilder.options.debug > 1 )
print( "Fixing line endings in: " + targetFile.getAbsolutePath() );
var buffer = new StringBuffer(),
inStream = new BufferedReader( new InputStreamReader( new FileInputStream( sourceFile ), "UTF-8" ) ),
line;
var firstLine = true;
while ( ( line = inStream.readLine() ) != null ) {
if ( firstLine ) {
var hasBom = line.length() && line.charAt( 0 ) === 65279;
if ( !hasBom && extension in bomExtensions )
buffer.append( String.fromCharCode( 65279 ) );
else if ( hasBom && !( extension in bomExtensions ) )
line = line.substring( 1 );
firstLine = false;
}
// Strip whitespace characters
line = regexLib.eol.matcher( line ).replaceAll( "" );
buffer.append( line );
buffer.append( lineEndings[ extension ] );
}
CKBuilder.io.saveFile( targetFile, regexLib.eof.matcher( buffer.toString() ).replaceAll( lineEndings[ extension ] ) );
return true;
},
/**
* Updates copyright headers in text files.
*
* @param {java.io.File} targetFile
*/
updateCopyrights: function( targetFile ) {
var extension = CKBuilder.io.getExtension( targetFile.getName() ),
bomExtensions = { asp: 1, js: 1 };
if ( !lineEndings[ extension ] ) {
return false;
}
text = CKBuilder.io.readFile( targetFile );
if ( text.indexOf( "Copyright" ) === -1 || text.indexOf( "CKSource" ) === -1 ) {
return;
}
if ( text.indexOf( 'For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license' ) !== -1 ) {
text = text.replace( 'For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license', 'This software is covered by CKEditor Commercial License. Usage without proper license is prohibited.' );
CKBuilder.io.saveFile( targetFile, text, bomExtensions[ extension ] );
return;
}
if ( text.indexOf( 'For licensing, see LICENSE.md or [https://ckeditor.com/legal/ckeditor-oss-license](https://ckeditor.com/legal/ckeditor-oss-license)' ) !== -1 ) {
text = text.replace( 'For licensing, see LICENSE.md or [https://ckeditor.com/legal/ckeditor-oss-license](https://ckeditor.com/legal/ckeditor-oss-license)', 'This software is covered by CKEditor Commercial License. Usage without proper license is prohibited.' );
CKBuilder.io.saveFile( targetFile, text, bomExtensions[ extension ] );
return;
}
},
/**
* Returns the copyright statement found in the text
* The Copyright statement starts either with "@license" or with "Copyright".
*
* @param {String} text
* @returns {String}
* @static
*/
getCopyrightFromText: function( text ) {
var matcher = regexLib.CopyrightComment.matcher( text );
if ( matcher.find() )
return matcher.group( 0 );
matcher = regexLib.LicenseComment.matcher( text );
if ( matcher.find() )
return matcher.group( 0 );
return "";
},
/**
* Remove all copyright statements in given string.
*
* @param {String} text
* @returns {String}
* @static
*/
removeLicenseInstruction: function( text ) {
return String( regexLib.license.matcher( text ).replaceAll( '' ) );
},
/**
* Cleans up the target folder.
*
* @param {java.io.File} targetLocation
* @static
*/
prepareTargetFolder: function( targetLocation ) {
if ( targetLocation.exists() ) {
if ( !CKBuilder.options.overwrite )
CKBuilder.error( "Target folder already exists: " + targetLocation.getAbsolutePath() );
print( "Cleaning up target folder" );
try {
if ( !CKBuilder.io.deleteDirectory( targetLocation ) )
throw( "Unable to delete target directory: " + targetLocation.getAbsolutePath() );
} catch ( e ) {
throw( "Unable to delete target directory: " + targetLocation.getAbsolutePath() );
}
}
try {
if ( !targetLocation.mkdirs() )
throw( "Unable to create target directory: " + targetLocation.getAbsolutePath() );
} catch ( e ) {
throw( "Unable to create target directory: " + targetLocation.getAbsolutePath() + "\n" );
}
},
/**
* Validate all JS files included in given location using Rhino parser.
*
* @param {java.io.File} sourceLocation Folder to validate.
* @returns {String} An error message with errors, if found any. Empty string if no errors are found.
* @static
*/
validateJavaScriptFiles: function( sourceLocation ) {
var dirList = sourceLocation.list(),
result = "";
for ( var i = 0; i < dirList.length; i++ ) {
var f = new File( sourceLocation, dirList[ i ] ),
error;
if ( f.isDirectory() ) {
error = this.validateJavaScriptFiles( f );
if ( error )
result += error;
} else if ( CKBuilder.io.getExtension( f.getName() ) === "js" ) {
error = this.validateJavaScriptFile( f );
if ( error )
result += error + "\n";
}
}
return result;
},
/**
* Validate all JS files included in given location using Closure Compiler.
*
* @param {java.io.File} sourceLocation Folder to validate.
* @returns {String} An error message with errors, if found any. Empty string if no errors are found.
* @static
*/
validateJavaScriptFilesUsingCC: function( sourceLocation ) {
var dirList = sourceLocation.list();
var result = "";
for ( var i = 0; i < dirList.length; i++ ) {
var f = new File( sourceLocation, dirList[ i ] ),
error;
if ( f.isDirectory() ) {
error = this.validateJavaScriptFilesUsingCC( f );
if ( error )
result += error;
} else if ( CKBuilder.io.getExtension( f.getName() ) === "js" ) {
var code = CKBuilder.io.readFile( f ),
errors = CKBuilder.javascript.findErrors( code, f.getParentFile().getName() + "/" + f.getName() );
if ( errors )
result += errors.join( "\n" );
}
}
return result;
},
/**
* Validate JS file included in given location using Rhino parser.
*
* @param {java.io.File} sourceLocation Folder to validate.
* @returns {String} An error message with errors, if found any. Empty string if no errors are found.
* @static
*/
validateJavaScriptFile: function( sourceLocation ) {
// Setup the compiler environment, error reporter...
var compilerEnv = new CompilerEnvirons(),
errorReporter = compilerEnv.getErrorReporter(),
// Create an instance of the parser...
parser = new org.mozilla.javascript.Parser( compilerEnv, errorReporter );
try {
parser.parse( CKBuilder.io.readFile( sourceLocation ), null, 1 );
return "";
} catch ( e ) {
return sourceLocation.getName() + " (line " + e.lineNumber + "):\n " + e.message + "";
}
},
/**
* Replace CKBuilder directives in given file.
* %VERSION%:
* the "version" string passed to the CKReleaser execution command.
* %REV%:
* the revision number of the source directory (returned by version control system).
* %TIMESTAMP%:
* a four characters string containing the
* concatenation of the "Base 36" value of each of the following components
* of the program execution date and time: year + month + day + hour.
* %REMOVE_LINE%:
* removes the line.
* %REMOVE_START% and %REMOVE_END%:
* removes all lines starting from %REMOVE_START% to %REMOVE_END%,
* declaration line inclusive.
* %LEAVE_UNMINIFIED%
* if set, the resulting object contains LEAVE_UNMINIFIED property set to true.
*
* @param {java.io.File} file File in which replace the directives
* @param {Object} directives (optional) An object with values for placeholders.
* @param {Boolean} core Whether to process core directives
* @returns {Object} an object with optional set of flags.
* @static
* Available flags:
* LEAVE_UNMINIFIED (Boolean) Indicates whether the file should be minified.
*/
processDirectives: function( location, directives, core ) {
var flags = {},
text = CKBuilder.io.readFile( location );
if ( text.indexOf( "%LEAVE_UNMINIFIED%" ) !== -1 )
flags.LEAVE_UNMINIFIED = true;
if ( text.indexOf( "%VERSION%" ) !== -1 || text.indexOf( "%REV%" ) !== -1 || text.indexOf( "%TIMESTAMP%" ) !== -1 || text.indexOf( "%REMOVE_START" ) !== -1 || text.indexOf( "%REMOVE_END" ) !== -1 || text.indexOf( "%REMOVE_LINE" ) !== -1 ) {
var processedText = this.processDirectivesInString( text, directives );
if ( core )
processedText = this.processCoreDirectivesInString( processedText );
if ( text !== processedText ) {
if ( CKBuilder.options.debug )
print( "Replaced directives in " + location.getAbsolutePath() );
CKBuilder.io.saveFile( location, processedText );
}
}
return flags;
},
/**
* Replace CKBuilder directives in given string.
* %VERSION%:
* the "version" string passed to the CKBuilder execution command.
* %REV%:
* the revision number of the source directory (returned by version control system).
* %TIMESTAMP%:
* a four characters string containing the
* concatenation of the "Base 36" value of each of the following components
* of the program execution date and time: year + month + day + hour.
* %REMOVE_LINE%:
* removes the line.
* %REMOVE_LINE_CORE%:
* removes the line, but only if file is included in core (merged into ckeditor.js).
* %REMOVE_START% and %REMOVE_END%:
* removes all lines starting from %REMOVE_START% to %REMOVE_END%,
* declaration line inclusive.
* %REMOVE_START_CORE% and %REMOVE_END_CORE%:
* same as %REMOVE_START% and %REMOVE_END%, but works
* only if file is included in core (merged into ckeditor.js).
* @param text {String} Text in which replace the directives
* @param directives {Object} (Optional) An object with values for placeholders.
* @returns {String} Text
* @static
*/
processDirectivesInString: function( text, directives ) {
directives = directives || {};
directives.version = directives.version || CKBuilder.options.version;
directives.revision = directives.revision || CKBuilder.options.revision;
directives.timestamp = directives.timestamp || CKBuilder.options.timestamp;
if ( text.indexOf( "%VERSION%" ) !== -1 )
text = String( regexLib.Version.matcher( text ).replaceAll( directives.version ) );
if ( text.indexOf( "%REV%" ) !== -1 )
text = String( regexLib.Rev.matcher( text ).replaceAll( directives.revision ) );
if ( text.indexOf( "%TIMESTAMP%" ) !== -1 )
text = String( regexLib.Timestamp.matcher( text ).replaceAll( directives.timestamp ) );
if ( text.indexOf( "%REMOVE_START%" ) !== -1 && text.indexOf( "%REMOVE_END%" ) !== -1 ) {
text = String( regexLib.Remove.matcher( text ).replaceAll( '%REMOVE_LINE%' ) );
text = String( regexLib.RemoveLine.matcher( text ).replaceAll( '' ) );
} else if ( text.indexOf( "%REMOVE_LINE%" ) !== -1 )
text = String( regexLib.RemoveLine.matcher( text ).replaceAll( '' ) );
return text;
},
/**
* Replace CKBuilder "core" directives in given string.
* %REMOVE_LINE_CORE%:
* removes the line, but only if file is included in core (merged into ckeditor.js).
* %REMOVE_START_CORE% and %REMOVE_END_CORE%:
* same as %REMOVE_START% and %REMOVE_END%, but works
* only if file is included in core (merged into ckeditor.js).
* @param {String} text Text in which replace the directives
* @returns {String}
* @static
*/
processCoreDirectivesInString: function( text ) {
if ( text.indexOf( "%REMOVE_START_CORE%" ) !== -1 && text.indexOf( "%REMOVE_END_CORE%" ) !== -1 ) {
text = String( regexLib.RemoveCore.matcher( text ).replaceAll( '%REMOVE_LINE_CORE%' ) );
text = String( regexLib.RemoveLineCore.matcher( text ).replaceAll( '' ) );
} else if ( text.indexOf( "%REMOVE_LINE_CORE%" ) !== -1 )
text = String( regexLib.RemoveLineCore.matcher( text ).replaceAll( '' ) );
return text;
}
};
}() );
ckbuilder-2.3.2/src/lib/utils.js 0000664 0000000 0000000 00000014177 13230353051 0016522 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
( function() {
function escapeProperty( string ) {
if ( string.match( /^[a-z][a-z0-9_]+$/i ) )
return string;
return "'" + escapeString( string ) + "'";
}
function escapeString( string ) {
return string.replace( /\\/g, "\\\\" ).replace( /\r/g, "\\r" ).replace( /\n/g, "\\n" ).replace( /'/g, "\\'" ).replace( /\u200b/g, "\\u200b" );
}
/**
* Utility class.
*
* @class
*/
CKBuilder.utils = {
/**
* Returns the copyright header with selected newline characters.
*
* @param {String} eol
* @returns {String}
* @static
*/
copyright: function( eol ) {
var copyright,
date = new Date();
if ( CKBuilder.options.commercial )
copyright = "/*" + eol + "This software is covered by CKEditor Commercial License. Usage without proper license is prohibited." + eol + "Copyright (c) 2003-" + date.getFullYear() + ", CKSource - Frederico Knabben. All rights reserved." + eol + "*/" + eol;
else
copyright = "/*" + eol + "Copyright (c) 2003-" + date.getFullYear() + ", CKSource - Frederico Knabben. All rights reserved." + eol + "For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license" + eol + "*/" + eol;
return copyright;
},
/**
* Helper function that prints how many seconds an operation took.
*
* @param {Date} timeStart
* @return {Date}
* @static
*/
printUsedTime: function( timeStart ) {
var timeEnd = new Date(),
timeTaken = timeEnd - timeStart;
if ( timeTaken > 1000 )
print( " Time taken.....: " + ( timeTaken / 1000 ) + "seconds" );
return timeEnd;
},
/**
* Wrap the JavaScript code into anonymous function call.
*
* @param {String} string Source code
* @returns {String} Wrapped source code
* @static
*/
wrapInFunction: function( string ) {
return '(function(){' + string + '}());';
},
/**
* Pretty print JavaScript object.
*
* @param {Object} obj Object to print
* @param {String=} indent Current indentation
* @returns {String}
* @static
*/
prettyPrintObject: function( obj, indent ) {
var result = "";
indent = indent || "";
for ( var property in obj ) {
var value = obj[ property ];
if ( typeof value === 'string' )
value = "'" + escapeString( value ) + "'";
else if ( typeof value === 'object' ) {
if ( value instanceof Array )
value = "[ " + value + " ]";
else {
var od = CKBuilder.utils.prettyPrintObject( value, indent + " " );
value = "\n" + indent + "{\n" + od + "\n" + indent + "}";
}
}
result += indent + escapeProperty( property ) + " : " + value + ",\n";
}
return result.replace( /,\n$/, "" );
},
/**
* Print JavaScript object.
*
* @param {Object} obj Object to print
* @returns {String}
* @static
*/
printObject: function( obj ) {
var result = '';
for ( var property in obj ) {
var value = obj[ property ];
if ( typeof value === 'string' )
value = "'" + value + "'";
else if ( typeof value === 'object' ) {
if ( value instanceof Array )
value = "[" + value + "]";
else {
var od = CKBuilder.utils.printObject( value );
value = "{" + od + "}";
}
}
result += escapeString( property ) + ":" + value + ",";
}
return result;
},
/**
* Find file in the specified folder.
*
* @param {String} filename Name of the file to search for
* @param {java.io.File} dir The directory in which to search
* @returns {java.io.File|null}
* @static
*/
findFileInDirectory: function( filename, dir ) {
var dirList = dir.list();
for ( var i = 0; i < dirList.length; i++ ) {
var f = new File( dir, dirList[ i ] );
if ( !f.isDirectory() ) {
if ( String( f.getName() ) === filename )
return f;
} else {
var file = CKBuilder.utils.findFileInDirectory( filename, f );
if ( file )
return file;
}
}
return null;
},
/**
* Find files in the specified folder.
*
* @param {String} filename Name of the file to search for
* @param {java.io.File} dir The directory in which to search
* @returns {Array} An array with absolute paths to files found
* @static
*/
findFilesInDirectory: function( filename, dir ) {
var dirList = dir.list().sort(),
files = [];
for ( var i = 0; i < dirList.length; i++ ) {
var f = new File( dir, dirList[ i ] );
if ( !f.isDirectory() ) {
if ( String( f.getName() ) === filename )
files.push( f.getAbsolutePath() );
} else {
var tmp = CKBuilder.utils.findFilesInDirectory( filename, f );
if ( tmp )
files = files.concat( tmp );
}
}
return files;
},
/**
* Overwrites the properties from obj1 with values from obj2.
* Adds properties from obj2 that do not exists in obj1.
* Does not change values of obj1 or obj2.
*
* @param {Object} obj1 The base object to be extended.
* @param {Object} obj2 The object from which copy values.
* @param {Boolean} [fullMerge=true] fullMerge Whether to include in the resulting object properties from obj2 that do not exist in obj1
* @returns {Object} the extended object
* @static
*/
merge: function( obj1, obj2, fullMerge ) {
var result = {};
for ( var i in obj2 ) {
if ( fullMerge === false && typeof( obj1[ i ] ) === 'undefined' )
continue;
try {
// Property in destination object set; update its value.
if ( typeof( obj2[ i ] ) === 'object' )
result[ i ] = this.merge( obj1[ i ], obj2[ i ], fullMerge ); else
result[ i ] = obj2[ i ];
} catch ( e ) {
// Property in destination object not set; create it and set its value.
result[ i ] = obj2[ i ];
}
}
for ( var j in obj1 ) {
if ( typeof obj2[ j ] !== 'undefined' )
continue;
// Property is missing in source object.
result[ j ] = obj1[ j ];
}
return result;
}
};
}() ); ckbuilder-2.3.2/test/ 0000775 0000000 0000000 00000000000 13230353051 0014434 5 ustar 00root root 0000000 0000000 ckbuilder-2.3.2/test/test.js 0000664 0000000 0000000 00000061370 13230353051 0015760 0 ustar 00root root 0000000 0000000 /*
Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.md
*/
var CKBuilderTest = true;
load( "src/ckbuilder.js" );
CKBuilder.options.debug = 2;
( function()
{
// Run tests.
var passCount = 0, failCount = 0;
var assetsPath = 'test/_assets';
var assetsDir = new File( assetsPath );
var tempPath = 'test/tmp';
var tempDir = new File( tempPath );
var timestampStub = 'G3KH';
function isArray(o) {
return Object.prototype.toString.call(o) === '[object Array]';
}
function assertDirectoriesAreEqual( expected, actual, title )
{
var dirList = expected.list(), actualFile, expectedFile;
for ( var i = 0 ; i < dirList.length ; i++ )
{
actualFile = new File( actual, dirList[i] );
expectedFile = new File( expected, dirList[i] );
assertEquals( true, actualFile.exists(), '[' + title + '] file should exist: ' + actualFile.getPath() );
assertEquals( expectedFile.isDirectory(), actualFile.isDirectory(), '[' + title + '] files should be of the same type: ' + actualFile.getPath() );
if ( actualFile.exists() )
{
if ( actualFile.isDirectory() )
assertDirectoriesAreEqual( expectedFile, actualFile, title );
else
assertFilesAreEqual( expectedFile, actualFile, title );
}
}
dirList = actual.list();
// Check for files that should not exists
for ( var i = 0 ; i < dirList.length ; i++ )
{
actualFile = new File( actual, dirList[i] );
expectedFile = new File( expected, dirList[i] );
if ( !expectedFile.exists() )
assertEquals( false, actualFile.exists(), '[' + title + '] file should not exist: ' + actualFile.getPath() );
}
}
function assertFilesAreEqual( expected, actual, title )
{
assertEquals( String( md5( CKBuilder.io.readFile( expected ) ) ), String( md5( CKBuilder.io.readFile( actual ) ) ),
'[' + title + '] Checking MD5 of ' + actual.getPath());
}
function assertEquals( expected, actual, title )
{
if ( ( !isArray( expected ) && expected !== actual) || JSON.stringify( expected ) !== JSON.stringify( actual ) )
{
var error = {
expected : expected,
actual : actual
};
print( 'FAILED: ' + (title ? title : "") );
// if ( !error.expected )
// throw error;
print( ' Expected: ' + error.expected );
print( ' Actual : ' + error.actual );
failCount++;
}
else
passCount++;
}
function md5( s )
{
s = new java.lang.String( s );
var m = java.security.MessageDigest.getInstance( "MD5" );
m.update( s.getBytes("UTF-8"), 0, s.length() );
return new java.math.BigInteger( 1, m.digest() ).toString( 16 );
}
function error( msg )
{
print( msg );
quit();
}
function prepareTempDirs()
{
if ( tempDir.exists() && !CKBuilder.io.deleteDirectory( tempPath ) )
error( "Can't delete temp directory" );
if ( !tempDir.mkdir() )
error( "Can't create temp directory: " + tempDir );
var assetsDirList = assetsDir.list();
for ( var i = 0; i < assetsDirList.length; i++ )
{
var f = new File( tempDir, assetsDirList[i] );
if ( !f.mkdir() )
error( "Can't create temp directory: " + f );
}
}
function testLanguageFiles()
{
print( "\nTesting processing language files\n" );
var dir = new File( assetsDir, 'langfiles' );
var dirList = dir.list();
var pluginNames = { devtools : 1, placeholder : 1, uicolor : 1 };
var languages = { en : 1, he : 1, pl : 1 };
CKBuilder.lang.mergeAll( new File( assetsDir, 'langfiles' ), new File( tempDir, 'langfiles' ), pluginNames, languages );
for ( var i = 0; i < dirList.length; i++ )
{
if ( dirList[i].indexOf( ".correct" ) === -1 )
continue;
var correctFile = new File( dir, dirList[i] );
var testName = correctFile.getName().replace( ".correct", "" );
var tempFile = new File( tempDir + '/langfiles/' + testName );
assertEquals( CKBuilder.io.readFile( correctFile ), CKBuilder.io.readFile( tempFile ), 'Language file: ' + testName );
}
var french = new File( tempDir + '/langfiles/fr.js' );
assertEquals( french.exists(), false );
}
function testCssProcessor( testFolder, leaveCssUnminified )
{
print( "\nTesting CSS processor\n" );
var correctFile, dir, dirList, test, tempFile;
CKBuilder.options.leaveCssUnminified = leaveCssUnminified;
CKBuilder.io.copy( new File( assetsDir + testFolder ), new File( tempDir + testFolder ) );
CKBuilder.css.mergeCssFiles( new File( tempDir + testFolder ) );
var sourceDir = new File( assetsDir + testFolder );
var sourceDirList = sourceDir.list();
for ( var i = 0 ; i < sourceDirList.length ; i++ )
{
if ( String( sourceDirList[i] ) === ".svn" || String( sourceDirList[i] ) === ".git" )
continue;
dir = new File( tempDir + testFolder, sourceDirList[i] );
assertEquals( true, dir.exists(), dir + " exists?" );
dirList = dir.list();
assertEquals( true, dirList.length > 0, dir + " not empty?" );
var foundCorrect = 0;
var foundCss = 0;
/**
* Loop through files in the target directory and search for valid
* CSS files
*/
for ( var j = 0 ; j < dirList.length ; j++ )
{
if ( dirList[j].indexOf( ".css" ) !== -1 )
foundCss++;
if ( dirList[j].indexOf( "correct.txt" ) !== -1 )
{
foundCorrect++;
test = dirList[j].replace( ".correct.txt", "" );
correctFile = new File( dir, dirList[j] );
tempFile = new File( dir, test + '.css' );
assertEquals( true, tempFile.exists(), tempFile + " exists?" );
assertEquals( String( md5( CKBuilder.io.readFile( correctFile ) ) ), String( md5( CKBuilder.io.readFile( tempFile ) ) ),
'Checking md5 of created file [' + dir.getName() + "/" + test + '.css]' );
}
}
if ( foundCorrect )
assertEquals( foundCorrect, foundCss, 'The number of created and correct css files must be equal in skin ' + dir.getName() );
}
}
function testSprite()
{
var plugins = ['basicstyles', 'link', 'list', 'table'];
var pluginsLocation = new File( assetsDir, "/sprite/plugins" );
var skinLocation = new File( assetsDir, "/sprite/skins/v2" );
// 1. Unminified CSS, use only specified plugins
CKBuilder.options.all = false;
CKBuilder.options.leaveCssUnminified = true;
var imageFile = new File( tempPath + "/sprite/icons.png" );
var cssFile = new File( tempPath + "/sprite/icons.css" );
var originalTimestamp = CKBuilder.options.timestamp;
CKBuilder.options.timestamp = timestampStub;
try {
CKBuilder.image.createFullSprite( pluginsLocation, skinLocation, imageFile, cssFile, plugins );
} catch ( e ) {
// In any case restore timestamp.
CKBuilder.options.timestamp = originalTimestamp;
// And rethrow the exception.
throw e;
}
assertEquals( CKBuilder.io.readFile( new File( assetsDir, "/sprite/icons.correct.css" ) ), CKBuilder.io.readFile( cssFile ),
'Checking content of icons.css' );
assertEquals( imageFile.exists(), true, "Sprite image should exist." );
var image = ImageIO.read( imageFile );
// 14 icons x (21px + 8px)
// 21 pixels - biggest single icon height
// 8 pixels - a distance in a non-hidpi strip
assertEquals( 14 * (21 + 8), image.getHeight(), "Checking height of sprite image." );
assertEquals( 21, image.getWidth(), "Checking width of sprite image." );
// 2. Minified CSS, include icons for all plugins (also the maximize plugin)
CKBuilder.options.all = true;
CKBuilder.options.leaveCssUnminified = false;
imageFile = new File( tempPath + "/sprite/icons2.png" );
cssFile = new File( tempPath + "/sprite/icons2.css" );
CKBuilder.image.createFullSprite( pluginsLocation, skinLocation, imageFile, cssFile, plugins );
assertEquals( CKBuilder.io.readFile( new File( assetsDir, "/sprite/icons2.correct.css" ) ), CKBuilder.io.readFile( cssFile ),
'Checking content of icons2.css' );
assertEquals( imageFile.exists(), true, "Sprite image should exist." );
var image = ImageIO.read( imageFile );
// 15 icons x (21px + 8px)
// 21 pixels - biggest single icon height
// 8 pixels - a distance in a non-hidpi strip
assertEquals( 15 * (21 + 8), image.getHeight(), "Checking height of sprite image." );
assertEquals( 21, image.getWidth(), "Checking width of sprite image." );
// 3. Unminified CSS, use only specified plugins, hidpi
CKBuilder.options.all = false;
CKBuilder.options.leaveCssUnminified = true;
var skinLocation = new File( assetsDir, "/sprite/skins/sapphire" );
var imageFile = new File( tempPath + "/sprite/icons3.png" );
var cssFile = new File( tempPath + "/sprite/icons3.css" );
CKBuilder.options.timestamp = timestampStub;
try {
CKBuilder.image.createFullSprite( pluginsLocation, skinLocation, imageFile, cssFile, plugins, true );
} catch ( e ) {
CKBuilder.options.timestamp = originalTimestamp;
throw e;
}
assertEquals( CKBuilder.io.readFile( new File( assetsDir, "/sprite/icons3.correct.css" ) ), CKBuilder.io.readFile( cssFile ),
'Checking content of icons3.css' );
assertEquals( imageFile.exists(), true, "Sprite image should exist." );
var image = ImageIO.read( imageFile );
// 14 icons x (32px + 16px)
// 32 pixels - biggest single icon height
// 16 pixels - a distance in a hidpi strip
assertEquals( 14 * ( 32 + 16 ), image.getHeight(), "Checking height of sprite image." );
assertEquals( 32, image.getWidth(), "Checking width of sprite image." );
}
function testDirectives()
{
print( "\nTesting directives\n" );
var name = 'directives';
var testName, tempFile, correctFile, sampleFile;
var dir = new File( assetsDir, 'directives' );
var dirList = dir.list();
for ( var i = 0 ; i < dirList.length ; i++ )
{
if ( dirList[i].indexOf( ".correct." ) === -1 )
continue;
testName = dirList[i].replace( ".correct.txt", "" );
sampleFile = new File( dir, testName + '.txt' );
correctFile = new File( dir, testName + '.correct.txt' );
tempFile = new File( tempDir, name + '/' + testName + '.out.txt' );
CKBuilder.io.copy( sampleFile, tempFile );
CKBuilder.tools.processDirectives( tempFile, { version: '3.1beta', revisionNumber : '1234', timestamp : 'AB89' } );
assertEquals( CKBuilder.io.readFile( correctFile ), CKBuilder.io.readFile( tempFile ),
'releaser.directives[' + testName + ']' );
}
}
function testBom()
{
var file, extension;
var dir = new File( tempDir, 'bom' );
CKBuilder.io.copy( new File( assetsDir, 'bom' ), dir, function( sourceLocation, targetLocation ) {
if ( !sourceLocation.isDirectory() )
return CKBuilder.tools.fixLineEndings( sourceLocation, targetLocation ) ? 1 : 0;
} );
var children = dir.list();
for ( var i = 0 ; i < children.length ; i++ )
{
file = new File( dir, children[i] );
extension = CKBuilder.io.getExtension( file.getName() );
switch ( extension )
{
case "asp":
case "js":
// BOM + CRLF
assertEquals( 8, file.length(), "testing BOM: " + children[i] );
break;
case "sh":
// !BOM + LF
assertEquals( 4, file.length(), "testing BOM: " + children[i] );
break;
default:
// !BOM + CRLF
assertEquals( 5, file.length(), "testing BOM: " + children[i] );
break;
}
}
}
function testLineEndings()
{
print( "\nTesting line endings\n" );
var testName, tempFile, correctFile, sampleFile;
var name = "lineendings";
var dir = new File( assetsDir, 'lineendings' );
var dirList = dir.list();
for ( var i = 0 ; i < dirList.length ; i++ )
{
if ( dirList[i].indexOf( ".correct." ) === -1 )
continue;
testName = dirList[i].replace( ".correct", "" );
sampleFile = new File( assetsDir, name + '/' + testName );
correctFile = new File( assetsDir, name + '/' + dirList[i] );
tempFile = new File( tempDir, name + '/' + testName );
CKBuilder.tools.fixLineEndings( sampleFile, tempFile );
assertEquals( CKBuilder.io.readFile( correctFile ), CKBuilder.io.readFile( tempFile ),
'testing line endings: [' + testName + ']' );
}
}
function flatten(arr) {
return arr.reduce(function (flat, toFlatten) {
return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);
}, []);
}
function listFiles( file )
{
var result = [];
if ( file.isDirectory() )
{
var children = file.list();
if ( !children.length )
{
result.push( file );
}
else
{
for ( var i = 0 ; i < children.length ; i++ )
{
result.push( listFiles( new File( file, children[i] ) ) );
}
}
}
else
{
result.push( file );
}
return result;
}
function testIgnoringPaths()
{
print( "\nTesting ignored paths...\n" );
var sourceLocation = new File( assetsDir, 'ignored' );
var targetLocation = new File( tempDir, 'ignored' );
var ignored = [ 'devtools', 'placeholder/lang/he.js', 'uicolor.js' ];
CKBuilder.io.copy( sourceLocation, targetLocation , function( sourceLocation, targetLocation ) {
if ( CKBuilder.config.isIgnoredPath( sourceLocation, ignored ) )
return -1;
});
var files = listFiles(targetLocation);
files.sort();
var validResult = [
'test/tmp/ignored/a11yhelp/lang/en.js',
'test/tmp/ignored/a11yhelp/lang/he.js',
'test/tmp/ignored/a11yhelp/plugin.js',
'test/tmp/ignored/placeholder/dialogs/placeholder.js',
'test/tmp/ignored/placeholder/lang/en.js',
'test/tmp/ignored/placeholder/lang/pl.js',
'test/tmp/ignored/placeholder/plugin.js',
'test/tmp/ignored/uicolor/lang/en.js',
'test/tmp/ignored/uicolor/lang/he.js',
'test/tmp/ignored/uicolor/plugin.js'];
assertEquals( files.length, 3, "Comparing plugins directories (same number of subfolders?)" );
var areEqual = flatten(files).sort().toString().replace(/\\/g, "/") === validResult.sort().toString();
assertEquals( true, areEqual, "Comparing plugins directories (are equal?)" );
}
function testLangProps()
{
print( "\nTesting language properties...\n" );
var sourceLocation = new File( assetsDir, 'langprops' );
var targetLocation = new File( tempDir, 'langprops' );
CKBuilder.io.copy( sourceLocation, targetLocation );
var plugins = {
devtools : {
test : { en : 1, pl : 1, foo : 1 },
expected : ['en', 'pl']
},
div : {
test: { foo : 1, bar : 1 },
expected: false
},
find : {
test : { en : 1, pl : 1, 'zh-cn' : 1, fr : 0 },
expected : ['en', 'pl', 'zh-cn']
},
colordialog : {
test : { en : 1, pl : 1, 'zh-cn' : 1, fr : 1 },
expected : ['en', 'pl', 'zh-cn', 'fr']
},
liststyle : {
test : { en : 1, pl : 1, 'zh-cn' : 1, he : 1 },
expected : ['en', 'pl', 'zh-cn', 'he']
},
magicline : {
test : { en : 1, pl : 1, foo : 1 },
expected : true
},
specialchar : {
test : { en : 1, pl : 1, 'zh-cn' : 1, he : 1 },
expected : ['en', 'pl', 'zh-cn', 'he']
}
};
for ( var plugin in plugins )
{
assertEquals( plugins[plugin].expected, CKBuilder.plugin.updateLangProperty( File( targetLocation, 'plugins/' + plugin + '/plugin.js'), plugins[plugin].test ), "lang property (" + plugin + ")" );
assertFilesAreEqual( File( sourceLocation, 'plugins_correct/' + plugin + '/plugin.js'), File( targetLocation, 'plugins/' + plugin + '/plugin.js') );
}
}
CKBuilder.plugin.updateLangProperty(File("test/_assets/requires/plugin_hr.js"), 'en.pl');
function testMinification()
{
print( "\nTesting minification...\n" );
var sourceLocation = new File( assetsDir, 'minification' );
var targetLocation = new File( tempDir, 'minification' );
CKBuilder.io.copy( sourceLocation, targetLocation , null, function( targetLocation ) {
if ( CKBuilder.io.getExtension( targetLocation.getName() ) === 'js' )
CKBuilder.javascript.minify( targetLocation );
} );
var testName, tempFile, correctFile;
var dir = new File( tempDir, 'minification' );
var dirList = dir.list();
for ( var i = 0 ; i < dirList.length ; i++ )
{
if ( dirList[i].indexOf( ".correct" ) === -1 )
continue;
testName = dirList[i].replace( ".correct", "" );
correctFile = new File( dir, testName + '.correct' );
tempFile = new File( dir, testName );
assertEquals( CKBuilder.io.readFile( correctFile ), CKBuilder.io.readFile( tempFile ),
'minification[' + testName + ']' );
}
}
function testRequiredPlugins()
{
print( "\nTesting required plugins...\n" );
var assetsLocation = new File( assetsDir, 'requires' );
assertEquals( ['dialog', 'fakeobjects'], CKBuilder.plugin.getRequiredPlugins(new File( assetsLocation, "plugin_flash.js" )));
assertEquals( ['richcombo'], CKBuilder.plugin.getRequiredPlugins(new File( assetsLocation, "plugin_font.js" )));
assertEquals( ['dialog', 'fakeobjects'], CKBuilder.plugin.getRequiredPlugins(new File( assetsLocation, "plugin_link.js" )));
assertEquals( ['floatpanel'], CKBuilder.plugin.getRequiredPlugins(new File( assetsLocation, "plugin_menu.js" )));
assertEquals( [], CKBuilder.plugin.getRequiredPlugins(new File( assetsLocation, "plugin_xml.js" )));
assertEquals( [], CKBuilder.plugin.getRequiredPlugins(new File( assetsLocation, "plugin_hr.js" )));
assertEquals( [], CKBuilder.plugin.getRequiredPlugins(new File( assetsLocation, "plugin_hr2.js" )));
assertEquals( ['foo'], CKBuilder.plugin.getRequiredPlugins(new File( assetsLocation, "plugin_hr3.js" )));
assertEquals( ['dialog', 'contextmenu'], CKBuilder.plugin.getRequiredPlugins(new File( assetsLocation, "plugin_liststyle.js" )));
}
function testSkinBuilder()
{
print( "\nTesting skin builder...\n" );
var originalTimestamp = CKBuilder.options.timestamp;
// Stub the timestamp.
CKBuilder.options.timestamp = timestampStub;
CKBuilder.options.leaveCssUnminified = true;
var sourceLocation = new File( assetsDir, 'skins/kama' );
var correctResultLocation = new File( assetsDir, 'skins/kama_correct' );
var targetLocation = new File( tempDir, 'skins/kama' );
try {
CKBuilder.skin.build( sourceLocation, targetLocation );
assertDirectoriesAreEqual( correctResultLocation, targetLocation, 'Checking skin builder (CSS minification disabled)' );
CKBuilder.options.leaveCssUnminified = false;
var sourceLocation = new File( assetsDir, 'skins_minified/kama' );
var correctResultLocation = new File( assetsDir, 'skins_minified/kama_correct' );
var targetLocation = new File( tempDir, 'skins_minified/kama' );
CKBuilder.skin.build( sourceLocation, targetLocation );
assertDirectoriesAreEqual( correctResultLocation, targetLocation, 'Checking skin builder (CSS minification enabled)' );
} catch ( e ) {
// In any case restore timestamp.
CKBuilder.options.timestamp = originalTimestamp;
// And rethrow the exception.
throw e;
}
}
function testVerifyPlugins()
{
print( "\nTesting plugins verification...\n" );
var pluginsLocation = new File( assetsDir, 'verify_plugins' );
var dirList = pluginsLocation.list();
var plugins = {
'_pubme_extratags_1_1.zip' : { name : '_pubme_extratags', expected : 'OK' },
'apinstein-ckeditor-autocss-2e37374.zip' : { name : 'autocss', expected : 'OK' },
'autosave_1.0.2.zip' : { name : 'autosave', expected : 'OK' },
'confighelper1.2.zip' : { name : 'confighelper', expected : 'OK' },
'fakeelements_checkbox_radio_select.zip' : { name : 'formchanges', expected : 'OK' },
'groupedcolorbutton.zip' : { name : 'groupedcolorbutton', expected : 'OK' },
'highlite_source_with_codemirror.zip' : { name : 'highlightsource', expected : "The plugin name defined inside plugin.js (sourcepopup) does not match the expected plugin name (highlightsource)\n" },
'htmlbuttons1.0.zip' : { name : 'htmlbuttons', expected : 'OK' },
'imagepaste1.0.zip' : { name : 'imagepaste', expected : 'OK' },
'insert-edit_source_code_icons.zip' : { name : 'insertedit', expected : "The plugin name defined inside plugin.js (scriptcode) does not match the expected plugin name (insertedit)\n" },
'languages.zip' : { name : 'languages', expected : 'OK' },
'lightbox_plus.zip' : { name : 'lightboxplus', expected : "The plugin name defined inside plugin.js (lightbox) does not match the expected plugin name (lightboxplus)\n" },
'links_to_own_pages.zip' : { name : 'linktoown', expected : "The plugin name defined inside plugin.js (internpage) does not match the expected plugin name (linktoown)\n" },
'loremIpsum.zip' : { name : 'loremipsum', expected : "The plugin name defined inside plugin.js (loremIpsum) does not match the expected plugin name (loremipsum)\n" },
'onchange1.5.zip' : { name : 'onchange', expected : 'OK' },
'small_google_map.zip' : { name : 'gmap', expected : 'OK' },
'smallerselection0.1.zip' : { name : 'smallerselection', expected : 'OK' },
'video1.3.zip' : { name : 'video', expected : 'OK' },
'w8tcha-CKEditor-oEmbed-Plugin-481d449.zip' : { name : 'oEmbed', expected : "Found more than one plugin.js:\n/w8tcha-CKEditor-oEmbed-Plugin-481d449/oEmbed_CKEditor3/oEmbed/plugin.js\n/w8tcha-CKEditor-oEmbed-Plugin-481d449/oEmbed_CKEditor4/oEmbed/plugin.js\n" },
'whitelist1.0.zip' : { name : 'whitelist', expected : 'OK' },
'xmltemplates1.0.zip' : { name : 'xmltemplates', expected : 'OK' },
'youtube.zip' : { name : 'youtube', expected : 'OK' },
'youtube_mp3.zip' : { name : 'youtube', expected : "Found more than one plugin.js:\n/youtube_mp3/mp3player/plugin.js\n/youtube_mp3/youtube/plugin.js\n" },
'zoom1.0.zip' : { name : 'zoom', expected : 'OK' }
};
for ( var i = 0 ; i < dirList.length ; i++ )
{
var file = new File( pluginsLocation, dirList[i] );
if ( file.isDirectory() )
{
assertEquals( "OK", CKBuilder.plugin.verify( file.getPath(), { pluginName : String( file.getName() ) } ));
}
else
{
assertEquals( plugins[file.getName()].expected, CKBuilder.plugin.verify( file.getPath(), { pluginName : plugins[file.getName()].name } ));
}
//print('Checking ' + file.getPath());
}
}
function testVerifySkins()
{
print( "\nTesting skins verification...\n" );
var skinsLocation = new File( assetsDir, 'verify_skins' );
var dirList = skinsLocation.list();
for ( var i = 0 ; i < dirList.length ; i++ )
{
var file = new File( skinsLocation, dirList[i] );
if ( file.isDirectory() )
{
if ( file.getName() == "fake" ) {
assertEquals( "The skin name defined inside skin.js (kama) does not match the expected skin name (fake)\n", CKBuilder.skin.verify( file.getPath(), { skinName : file.getName() } ));
}
else if ( file.getName() == "noicons" ) {
assertEquals( "OK", CKBuilder.skin.verify( file.getPath(), { skinName : String( file.getName() ) } ));
}
else {
assertEquals( "OK", CKBuilder.skin.verify( file.getPath(), { skinName : String( file.getName() ) } ));
}
}
}
}
function testSamples()
{
print( "\nTesting samples merging...\n" );
var samplesLocation = new File( assetsDir, 'samples/ckeditor-dev' );
var targetLocation = new File( tempDir, 'samples' );
CKBuilder.io.copy( samplesLocation, targetLocation );
CKBuilder.samples.mergeSamples( targetLocation );
var correctResultLocation = new File( assetsDir, 'samples/ckeditor-dev-correct' );
assertDirectoriesAreEqual( correctResultLocation, targetLocation, 'Checking merged samples' );
}
function testCopyrights()
{
print( "\nTesting copyrights...\n" );
CKBuilder.options.commercial = true;
CKBuilder.options.leaveJsUnminified = true;
var sourceLocation = new File( assetsDir, 'copyrights' );
var targetLocation = new File( tempDir, 'copyrights' );
CKBuilder.io.copy( sourceLocation, targetLocation );
var testName, tempFile, correctFile;
var dir = new File( tempDir, 'copyrights' );
var dirList = dir.list();
for ( var i = 0 ; i < dirList.length ; i++ )
{
if ( dirList[i].indexOf( ".correct" ) === -1 )
continue;
testName = dirList[i].replace( ".correct", "" );
correctFile = new File( dir, testName + '.correct' );
tempFile = new File( dir, testName );
CKBuilder.tools.updateCopyrights( tempFile );
assertEquals( CKBuilder.io.readFile( correctFile ), CKBuilder.io.readFile( tempFile ),
'copyrights[' + testName + ']' );
}
CKBuilder.options.commercial = false;
CKBuilder.options.leaveJsUnminified = false;
}
prepareTempDirs();
testLangProps();
testLanguageFiles();
testSprite();
testCssProcessor( "/css", true );
testCssProcessor( "/css_minified", false );
testDirectives();
testBom();
testLineEndings();
testIgnoringPaths();
testMinification();
testRequiredPlugins();
testSkinBuilder();
testVerifyPlugins();
testVerifySkins();
testSamples();
testCopyrights();
print( '' );
print( 'Finished: ' + passCount + ' passed / ' + failCount + ' failed' );
}());
ckbuilder-2.3.2/test/test.sh 0000775 0000000 0000000 00000000601 13230353051 0015747 0 ustar 00root root 0000000 0000000 #!/bin/bash
# Copyright (c) 2012-2018, CKSource - Frederico Knabben. All rights reserved.
# For licensing, see LICENSE.md
# We need to execute scripts from parent directory...
cd ..
/usr/bin/java -cp lib/rhino/js.jar:lib/apache/commons-cli.jar:lib/javatar/tar.jar:lib/tartool/tartool.jar:lib/closure/compiler.jar org.mozilla.javascript.tools.shell.Main -opt -1 test/test.js
cd test