From 9e2f9f49ec9803adfa0249161c8d2188ee0d40ca Mon Sep 17 00:00:00 2001 From: Benjamin Southall Date: Sun, 3 Sep 2017 23:15:56 +0900 Subject: [PATCH] Add sceditor WYSIWIG post editor support --- js/loadsceditor.js | 87 + js/sceditor/README.md | 103 + .../development/jquery.sceditor.bbcode.js | 10039 ++++++++++++++++ .../development/jquery.sceditor.default.css | 83 + js/sceditor/development/jquery.sceditor.js | 7230 +++++++++++ .../development/jquery.sceditor.xhtml.js | 8548 +++++++++++++ js/sceditor/development/plugins/bbcode.js | 2810 +++++ js/sceditor/development/plugins/format.js | 127 + js/sceditor/development/plugins/undo.js | 187 + js/sceditor/development/plugins/xhtml.js | 1319 ++ js/sceditor/development/themes/default.css | 500 + js/sceditor/development/themes/famfamfam.png | Bin 0 -> 11682 bytes js/sceditor/development/themes/modern.css | 578 + js/sceditor/development/themes/monocons.css | 643 + .../development/themes/monocons/monocons.eot | Bin 0 -> 8028 bytes .../development/themes/monocons/monocons.ttf | Bin 0 -> 7860 bytes .../development/themes/office-toolbar.css | 594 + js/sceditor/development/themes/office.css | 616 + js/sceditor/development/themes/square.css | 589 + js/sceditor/emoticons/alien.png | Bin 0 -> 756 bytes js/sceditor/emoticons/angel.png | Bin 0 -> 1182 bytes js/sceditor/emoticons/angry.png | Bin 0 -> 781 bytes js/sceditor/emoticons/blink.png | Bin 0 -> 972 bytes js/sceditor/emoticons/blush.png | Bin 0 -> 865 bytes js/sceditor/emoticons/cheerful.png | Bin 0 -> 753 bytes js/sceditor/emoticons/cool.png | Bin 0 -> 965 bytes js/sceditor/emoticons/credits.txt | 9 + js/sceditor/emoticons/cwy.png | Bin 0 -> 877 bytes js/sceditor/emoticons/devil.png | Bin 0 -> 1012 bytes js/sceditor/emoticons/dizzy.png | Bin 0 -> 991 bytes js/sceditor/emoticons/ermm.png | Bin 0 -> 983 bytes js/sceditor/emoticons/face.png | Bin 0 -> 793 bytes js/sceditor/emoticons/getlost.png | Bin 0 -> 792 bytes js/sceditor/emoticons/grin.png | Bin 0 -> 867 bytes js/sceditor/emoticons/happy.png | Bin 0 -> 792 bytes js/sceditor/emoticons/heart.png | Bin 0 -> 572 bytes js/sceditor/emoticons/kissing.png | Bin 0 -> 793 bytes js/sceditor/emoticons/laughing.png | Bin 0 -> 912 bytes js/sceditor/emoticons/ninja.png | Bin 0 -> 694 bytes js/sceditor/emoticons/pinch.png | Bin 0 -> 804 bytes js/sceditor/emoticons/pouty.png | Bin 0 -> 799 bytes js/sceditor/emoticons/sad.png | Bin 0 -> 789 bytes js/sceditor/emoticons/shocked.png | Bin 0 -> 780 bytes js/sceditor/emoticons/sick.png | Bin 0 -> 783 bytes js/sceditor/emoticons/sideways.png | Bin 0 -> 788 bytes js/sceditor/emoticons/silly.png | Bin 0 -> 930 bytes js/sceditor/emoticons/sleeping.png | Bin 0 -> 1039 bytes js/sceditor/emoticons/smile.png | Bin 0 -> 983 bytes js/sceditor/emoticons/tongue.png | Bin 0 -> 981 bytes js/sceditor/emoticons/unsure.png | Bin 0 -> 763 bytes js/sceditor/emoticons/w00t.png | Bin 0 -> 718 bytes js/sceditor/emoticons/wassat.png | Bin 0 -> 810 bytes js/sceditor/emoticons/whistling.png | Bin 0 -> 1072 bytes js/sceditor/emoticons/wink.png | Bin 0 -> 791 bytes js/sceditor/emoticons/wub.png | Bin 0 -> 1010 bytes js/sceditor/example.html | 117 + js/sceditor/languages/ar.js | 68 + js/sceditor/languages/ca.js | 68 + js/sceditor/languages/cn.js | 68 + js/sceditor/languages/cs.js | 71 + js/sceditor/languages/de.js | 59 + js/sceditor/languages/el.js | 68 + js/sceditor/languages/en-US.js | 7 + js/sceditor/languages/en.js | 12 + js/sceditor/languages/es.js | 68 + js/sceditor/languages/et.js | 57 + js/sceditor/languages/fa.js | 69 + js/sceditor/languages/fr.js | 70 + js/sceditor/languages/gl.js | 68 + js/sceditor/languages/hu.js | 69 + js/sceditor/languages/it.js | 72 + js/sceditor/languages/ja.js | 71 + js/sceditor/languages/lt.js | 68 + js/sceditor/languages/nb.js | 70 + js/sceditor/languages/nl.js | 57 + js/sceditor/languages/pl.js | 68 + js/sceditor/languages/pt-BR.js | 67 + js/sceditor/languages/pt.js | 69 + js/sceditor/languages/ru.js | 57 + js/sceditor/languages/sv.js | 58 + js/sceditor/languages/template.js | 74 + js/sceditor/languages/tr.js | 66 + js/sceditor/languages/tw.js | 68 + js/sceditor/languages/uk.js | 57 + js/sceditor/languages/vi.js | 68 + .../minified/jquery.sceditor.bbcode.min.js | 4 + js/sceditor/minified/jquery.sceditor.min.js | 3 + .../minified/jquery.sceditor.xhtml.min.js | 3 + js/sceditor/minified/plugins/bbcode.js | 2 + js/sceditor/minified/plugins/format.js | 2 + js/sceditor/minified/plugins/undo.js | 2 + js/sceditor/minified/plugins/xhtml.js | 2 + js/sceditor/minified/themes/default.min.css | 1 + js/sceditor/minified/themes/famfamfam.png | Bin 0 -> 11682 bytes js/sceditor/minified/themes/modern.min.css | 1 + js/sceditor/minified/themes/monocons.min.css | 1 + .../minified/themes/monocons/monocons.eot | Bin 0 -> 8028 bytes .../minified/themes/monocons/monocons.ttf | Bin 0 -> 7860 bytes .../minified/themes/office-toolbar.min.css | 1 + js/sceditor/minified/themes/office.min.css | 1 + js/sceditor/minified/themes/square.min.css | 1 + .../sceditor/jquery.sceditor.default.min.css | 1 + stylesheets/sceditor/themes/default.min.css | 1 + stylesheets/sceditor/themes/famfamfam.png | Bin 0 -> 11682 bytes stylesheets/sceditor/themes/modern.min.css | 1 + stylesheets/sceditor/themes/monocons.min.css | 1 + .../sceditor/themes/monocons/monocons.eot | Bin 0 -> 8028 bytes .../sceditor/themes/monocons/monocons.ttf | Bin 0 -> 7860 bytes .../sceditor/themes/office-toolbar.min.css | 1 + stylesheets/sceditor/themes/office.min.css | 1 + stylesheets/sceditor/themes/square.min.css | 1 + .../sceditor/themes/transparent.min.css | 3 + 112 files changed, 36025 insertions(+) create mode 100644 js/loadsceditor.js create mode 100644 js/sceditor/README.md create mode 100644 js/sceditor/development/jquery.sceditor.bbcode.js create mode 100644 js/sceditor/development/jquery.sceditor.default.css create mode 100644 js/sceditor/development/jquery.sceditor.js create mode 100644 js/sceditor/development/jquery.sceditor.xhtml.js create mode 100644 js/sceditor/development/plugins/bbcode.js create mode 100644 js/sceditor/development/plugins/format.js create mode 100644 js/sceditor/development/plugins/undo.js create mode 100644 js/sceditor/development/plugins/xhtml.js create mode 100644 js/sceditor/development/themes/default.css create mode 100644 js/sceditor/development/themes/famfamfam.png create mode 100644 js/sceditor/development/themes/modern.css create mode 100644 js/sceditor/development/themes/monocons.css create mode 100644 js/sceditor/development/themes/monocons/monocons.eot create mode 100644 js/sceditor/development/themes/monocons/monocons.ttf create mode 100644 js/sceditor/development/themes/office-toolbar.css create mode 100644 js/sceditor/development/themes/office.css create mode 100644 js/sceditor/development/themes/square.css create mode 100644 js/sceditor/emoticons/alien.png create mode 100644 js/sceditor/emoticons/angel.png create mode 100644 js/sceditor/emoticons/angry.png create mode 100644 js/sceditor/emoticons/blink.png create mode 100644 js/sceditor/emoticons/blush.png create mode 100644 js/sceditor/emoticons/cheerful.png create mode 100644 js/sceditor/emoticons/cool.png create mode 100644 js/sceditor/emoticons/credits.txt create mode 100644 js/sceditor/emoticons/cwy.png create mode 100644 js/sceditor/emoticons/devil.png create mode 100644 js/sceditor/emoticons/dizzy.png create mode 100644 js/sceditor/emoticons/ermm.png create mode 100644 js/sceditor/emoticons/face.png create mode 100644 js/sceditor/emoticons/getlost.png create mode 100644 js/sceditor/emoticons/grin.png create mode 100644 js/sceditor/emoticons/happy.png create mode 100644 js/sceditor/emoticons/heart.png create mode 100644 js/sceditor/emoticons/kissing.png create mode 100644 js/sceditor/emoticons/laughing.png create mode 100644 js/sceditor/emoticons/ninja.png create mode 100644 js/sceditor/emoticons/pinch.png create mode 100644 js/sceditor/emoticons/pouty.png create mode 100644 js/sceditor/emoticons/sad.png create mode 100644 js/sceditor/emoticons/shocked.png create mode 100644 js/sceditor/emoticons/sick.png create mode 100644 js/sceditor/emoticons/sideways.png create mode 100644 js/sceditor/emoticons/silly.png create mode 100644 js/sceditor/emoticons/sleeping.png create mode 100644 js/sceditor/emoticons/smile.png create mode 100644 js/sceditor/emoticons/tongue.png create mode 100644 js/sceditor/emoticons/unsure.png create mode 100644 js/sceditor/emoticons/w00t.png create mode 100644 js/sceditor/emoticons/wassat.png create mode 100644 js/sceditor/emoticons/whistling.png create mode 100644 js/sceditor/emoticons/wink.png create mode 100644 js/sceditor/emoticons/wub.png create mode 100644 js/sceditor/example.html create mode 100644 js/sceditor/languages/ar.js create mode 100644 js/sceditor/languages/ca.js create mode 100644 js/sceditor/languages/cn.js create mode 100644 js/sceditor/languages/cs.js create mode 100644 js/sceditor/languages/de.js create mode 100644 js/sceditor/languages/el.js create mode 100644 js/sceditor/languages/en-US.js create mode 100644 js/sceditor/languages/en.js create mode 100644 js/sceditor/languages/es.js create mode 100644 js/sceditor/languages/et.js create mode 100644 js/sceditor/languages/fa.js create mode 100644 js/sceditor/languages/fr.js create mode 100644 js/sceditor/languages/gl.js create mode 100644 js/sceditor/languages/hu.js create mode 100644 js/sceditor/languages/it.js create mode 100644 js/sceditor/languages/ja.js create mode 100644 js/sceditor/languages/lt.js create mode 100644 js/sceditor/languages/nb.js create mode 100644 js/sceditor/languages/nl.js create mode 100644 js/sceditor/languages/pl.js create mode 100644 js/sceditor/languages/pt-BR.js create mode 100644 js/sceditor/languages/pt.js create mode 100644 js/sceditor/languages/ru.js create mode 100644 js/sceditor/languages/sv.js create mode 100644 js/sceditor/languages/template.js create mode 100644 js/sceditor/languages/tr.js create mode 100644 js/sceditor/languages/tw.js create mode 100644 js/sceditor/languages/uk.js create mode 100644 js/sceditor/languages/vi.js create mode 100644 js/sceditor/minified/jquery.sceditor.bbcode.min.js create mode 100644 js/sceditor/minified/jquery.sceditor.min.js create mode 100644 js/sceditor/minified/jquery.sceditor.xhtml.min.js create mode 100644 js/sceditor/minified/plugins/bbcode.js create mode 100644 js/sceditor/minified/plugins/format.js create mode 100644 js/sceditor/minified/plugins/undo.js create mode 100644 js/sceditor/minified/plugins/xhtml.js create mode 100644 js/sceditor/minified/themes/default.min.css create mode 100644 js/sceditor/minified/themes/famfamfam.png create mode 100644 js/sceditor/minified/themes/modern.min.css create mode 100644 js/sceditor/minified/themes/monocons.min.css create mode 100644 js/sceditor/minified/themes/monocons/monocons.eot create mode 100644 js/sceditor/minified/themes/monocons/monocons.ttf create mode 100644 js/sceditor/minified/themes/office-toolbar.min.css create mode 100644 js/sceditor/minified/themes/office.min.css create mode 100644 js/sceditor/minified/themes/square.min.css create mode 100644 stylesheets/sceditor/jquery.sceditor.default.min.css create mode 100644 stylesheets/sceditor/themes/default.min.css create mode 100644 stylesheets/sceditor/themes/famfamfam.png create mode 100644 stylesheets/sceditor/themes/modern.min.css create mode 100644 stylesheets/sceditor/themes/monocons.min.css create mode 100644 stylesheets/sceditor/themes/monocons/monocons.eot create mode 100644 stylesheets/sceditor/themes/monocons/monocons.ttf create mode 100644 stylesheets/sceditor/themes/office-toolbar.min.css create mode 100644 stylesheets/sceditor/themes/office.min.css create mode 100644 stylesheets/sceditor/themes/square.min.css create mode 100644 stylesheets/sceditor/themes/transparent.min.css diff --git a/js/loadsceditor.js b/js/loadsceditor.js new file mode 100644 index 00000000..08511526 --- /dev/null +++ b/js/loadsceditor.js @@ -0,0 +1,87 @@ +if (active_page === "thread" || active_page === "index" || active_page === "ukko") { + +$(document).on("ready", function() { +if (window.Options && Options.get_tab('general')) { + Options.extend_tab("general", + "
Editor Dialog " + + ("") + + "
"); +} + +$('.sceditorc').on('change', function(){ + var setting = $(this).attr('id'); + + localStorage[setting] = $(this).children('input').is(':checked'); + location.reload(); +}); + +if (!localStorage.sceditor) { + localStorage.sceditor = 'false'; +} + +function getSetting(key) { + return (localStorage[key] == 'true'); +} + +if (getSetting('sceditor')) $('#sceditor>input').prop('checked', 'checked'); + +function initsceditor() { + if (!getSetting("sceditor")) {return;} + $('.format-text').toggle(); + + $.sceditor.plugins.bbcode.bbcode.set('spoiler', { + tags: { + 'span': { + 'class': ['spoiler'] + } + }, + format: '[spoiler]{0}[/spoiler]', + html: '{0}' + }); + $.sceditor.plugins.bbcode.bbcode.set('t', { + tags: { + 'span': { + 'class': ['heading'] + } + }, + format: '\t=={0}==\t', + html: '{0}' + }); + $.sceditor.command.set("spoiler", { + exec: function() { + this.insert("[spoiler]", "[/spoiler]"); + }, + txtExec: ["[spoiler]", "[/spoiler]"], + tooltip: "Spoiler (CTRL+S)", + }); + $.sceditor.command.set("t", { + exec: function() { + this.insert("\t==", "==\t"); + }, + txtExec: ["\t==", "==\t"], + tooltip: "Heading (CTRL+T)", + }); + $('#body').sceditor({ + plugins: 'bbcode', + style: $('#stylesheet').attr("href"), + //style: '/stylesheets/sceditor/jquery.sceditor.default.min.css', + toolbar: "bold,italic,t,spoiler,code|source", + emoticonsEnabled : false, + autoUpdate : true, + }); + var backgroundcolor = $('#body').css('background-color'); + $('.sceditor-container').css('background-color',backgroundcolor); + $('.sceditor-toolbar').css('background-color',backgroundcolor); + $('#body').sceditor('instance').css('body { background-color: ' + backgroundcolor +'; }'); + + /*$(document).on('ajax_before_post', function (e, formData) { + formData.set(body, $("#body").sceditor('instance').val()); + }); + + $(document).on('ajax_after_post', function () { + $("#body").sceditor('instance').val(""); + });*/ +} +initsceditor(); +}); +} diff --git a/js/sceditor/README.md b/js/sceditor/README.md new file mode 100644 index 00000000..381427c8 --- /dev/null +++ b/js/sceditor/README.md @@ -0,0 +1,103 @@ +# [SCEditor](http://www.sceditor.com/) v1.5.2 + +[![Build Status](http://img.shields.io/travis/samclarke/SCEditor/master.svg?style=flat-square)](https://travis-ci.org/samclarke/SCEditor) +[![Dependency Status](http://img.shields.io/gemnasium/samclarke/SCEditor.svg?style=flat-square)](https://gemnasium.com/samclarke/SCEditor) +[![SemVer](http://img.shields.io/:semver-✓-brightgreen.svg?style=flat-square)](http://semver.org) +[![License](http://img.shields.io/npm/l/sceditor.svg?style=flat-square)](https://github.com/samclarke/SCEditor/blob/master/MIT.txt) + +A lightweight WYSIWYG BBCode and XHTML editor. + +For more information visit [sceditor.com](http://www.sceditor.com/) + + +## Usage + +Include the JQuery and SCEditor JavaScript + + + + +Then to change all textareas to WYSIWYG editors, simply do: + + $(function() { + $("textarea").sceditor({ + plugins: 'xhtml', + style: 'minified/jquery.sceditor.default.min.css' + }); + }); + +or for a BBCode WYSIWYG editor do: + + $(function() { + $("textarea").sceditor({ + plugins: 'bbcode', + style: 'minified/jquery.sceditor.default.min.css' + }); + }); + + + +## Options + +For a full list of options, see the [options documentation](http://www.sceditor.com/documentation/options/). + + + +## Building and testing + +You will need [Grunt](http://gruntjs.com/) installed to run the build/tests. To install Grunt run: + + npm install -g grunt-cli + +Next, to install the SCEditor dev dependencies run: + + npm install + +That's it! You can now build and test SCEditor with the following commands: + + grunt build # Minifies the JS and converts the LESS to CSS + grunt test # Runs the linter and unit tests + grunt release # Creates the distributable ZIP file + + + +## Contribute + +Any contributions and/or pull requests would be welcome. + +Themes, translations, bug reports, bug fixes and donations are greatly appreciated. + + + +## Donate + +If you would like to make a donation you can via +[PayPal](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=AVJSF5NEETYYG) +or via [Flattr](http://flattr.com/thing/400345/SCEditor) + + + +## License + +SCEditor is licensed under the [MIT](http://www.opensource.org/licenses/mit-license.php) license: + + +Copyright (C) 2011 - 2015 Sam Clarke and contributors – sceditor.com + +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. + + + +## Credits + +**Nomicons: The Full Monty Emoticons by:** +Oscar Gruno, aka Nominell v. 2.0 -> oscargruno@mac.com +Andy Fedosjeenko, aka Nightwolf -> bobo@animevanguard.com + +**Icons by:** +Mark James (http://www.famfamfam.com/lab/icons/silk/) +Licensed under the [Creative Commons CC-BY license](http://creativecommons.org/licenses/by/3.0/). \ No newline at end of file diff --git a/js/sceditor/development/jquery.sceditor.bbcode.js b/js/sceditor/development/jquery.sceditor.bbcode.js new file mode 100644 index 00000000..010b8a5b --- /dev/null +++ b/js/sceditor/development/jquery.sceditor.bbcode.js @@ -0,0 +1,10039 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/** + * SCEditor + * http://www.sceditor.com/ + * + * Copyright (C) 2014, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * @fileoverview SCEditor - A lightweight WYSIWYG BBCode and HTML editor + * @author Sam Clarke + * @requires jQuery + */ + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var SCEditor = __webpack_require__(2); + var PluginManager = __webpack_require__(3); + var browser = __webpack_require__(6); + var escape = __webpack_require__(7); + + + // For backwards compatibility + $.sceditor = SCEditor; + + SCEditor.commands = __webpack_require__(9); + SCEditor.defaultOptions = __webpack_require__(10); + SCEditor.RangeHelper = __webpack_require__(4); + SCEditor.dom = __webpack_require__(5); + + SCEditor.ie = browser.ie; + SCEditor.ios = browser.ios; + SCEditor.isWysiwygSupported = browser.isWysiwygSupported; + + SCEditor.regexEscape = escape.regex; + SCEditor.escapeEntities = escape.entities; + SCEditor.escapeUriScheme = escape.uriScheme; + + SCEditor.PluginManager = PluginManager; + SCEditor.plugins = PluginManager.plugins; + + + /** + * Creates an instance of sceditor on all textareas + * matched by the jQuery selector. + * + * If options is set to "state" it will return bool value + * indicating if the editor has been initialised on the + * matched textarea(s). If there is only one textarea + * it will return the bool value for that textarea. + * If more than one textarea is matched it will + * return an array of bool values for each textarea. + * + * If options is set to "instance" it will return the + * current editor instance for the textarea(s). Like the + * state option, if only one textarea is matched this will + * return just the instance for that textarea. If more than + * one textarea is matched it will return an array of + * instances each textarea. + * + * @param {Object|String} options Should either be an Object of options or + * the strings "state" or "instance" + * @return {this|Array|jQuery.sceditor|Bool} + */ + $.fn.sceditor = function (options) { + var $this, instance, + ret = []; + + options = options || {}; + + if (!options.runWithoutWysiwygSupport && !browser.isWysiwygSupported) { + return; + } + + this.each(function () { + $this = this.jquery ? this : $(this); + instance = $this.data('sceditor'); + + // Don't allow the editor to be initialised + // on it's own source editor + if ($this.parents('.sceditor-container').length > 0) { + return; + } + + // Add state of instance to ret if that is what options is set to + if (options === 'state') { + ret.push(!!instance); + } else if (options === 'instance') { + ret.push(instance); + } else if (!instance) { + /*jshint -W031*/ + (new SCEditor(this, options)); + } + }); + + // If nothing in the ret array then must be init so return this + if (!ret.length) { + return this; + } + + return ret.length === 1 ? ret[0] : $(ret); + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + module.exports = jQuery; + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var PluginManager = __webpack_require__(3); + var RangeHelper = __webpack_require__(4); + var dom = __webpack_require__(5); + var escape = __webpack_require__(7); + var browser = __webpack_require__(6); + var _tmpl = __webpack_require__(8); + + var globalWin = window; + var globalDoc = document; + var $globalWin = $(globalWin); + var $globalDoc = $(globalDoc); + + var IE_VER = browser.ie; + + // In IE < 11 a BR at the end of a block level element + // causes a line break. In all other browsers it's collapsed. + var IE_BR_FIX = IE_VER && IE_VER < 11; + + + /** + * SCEditor - A lightweight WYSIWYG editor + * + * @param {Element} el The textarea to be converted + * @return {Object} options + * @class sceditor + * @name jQuery.sceditor + */ + var SCEditor = function (el, options) { + /** + * Alias of this + * + * @private + */ + var base = this; + + /** + * The textarea element being replaced + * + * @private + */ + var original = el.get ? el.get(0) : el; + var $original = $(original); + + /** + * The div which contains the editor and toolbar + * + * @private + */ + var $editorContainer; + + /** + * The editors toolbar + * + * @private + */ + var $toolbar; + + /** + * The editors iframe which should be in design mode + * + * @private + */ + var $wysiwygEditor; + var wysiwygEditor; + + /** + * The WYSIWYG editors body element + * + * @private + */ + var $wysiwygBody; + + /** + * The WYSIWYG editors document + * + * @private + */ + var $wysiwygDoc; + + /** + * The editors textarea for viewing source + * + * @private + */ + var $sourceEditor; + var sourceEditor; + + /** + * The current dropdown + * + * @private + */ + var $dropdown; + + /** + * Store the last cursor position. Needed for IE because it forgets + * + * @private + */ + var lastRange; + + /** + * The editors locale + * + * @private + */ + var locale; + + /** + * Stores a cache of preloaded images + * + * @private + * @type {Array} + */ + var preLoadCache = []; + + /** + * The editors rangeHelper instance + * + * @type {jQuery.sceditor.rangeHelper} + * @private + */ + var rangeHelper; + + /** + * Tags which require the new line fix + * + * @type {Array} + * @private + */ + var requireNewLineFix = []; + + /** + * An array of button state handlers + * + * @type {Array} + * @private + */ + var btnStateHandlers = []; + + /** + * Plugin manager instance + * + * @type {jQuery.sceditor.PluginManager} + * @private + */ + var pluginManager; + + /** + * The current node containing the selection/caret + * + * @type {Node} + * @private + */ + var currentNode; + + /** + * The first block level parent of the current node + * + * @type {node} + * @private + */ + var currentBlockNode; + + /** + * The current node selection/caret + * + * @type {Object} + * @private + */ + var currentSelection; + + /** + * Used to make sure only 1 selection changed + * check is called every 100ms. + * + * Helps improve performance as it is checked a lot. + * + * @type {Boolean} + * @private + */ + var isSelectionCheckPending; + + /** + * If content is required (equivalent to the HTML5 required attribute) + * + * @type {Boolean} + * @private + */ + var isRequired; + + /** + * The inline CSS style element. Will be undefined + * until css() is called for the first time. + * + * @type {HTMLElement} + * @private + */ + var inlineCss; + + /** + * Object containing a list of shortcut handlers + * + * @type {Object} + * @private + */ + var shortcutHandlers = {}; + + /** + * An array of all the current emoticons. + * + * Only used or populated when emoticonsCompat is enabled. + * + * @type {Array} + * @private + */ + var currentEmoticons = []; + + /** + * Cache of the current toolbar buttons + * + * @type {Object} + * @private + */ + var toolbarButtons = {}; + + /** + * If the current autoUpdate action is canceled. + * + * @type {Boolean} + * @private + */ + var autoUpdateCanceled; + + /** + * Private functions + * @private + */ + var init, + replaceEmoticons, + handleCommand, + saveRange, + initEditor, + initPlugins, + initLocale, + initToolBar, + initOptions, + initEvents, + initCommands, + initResize, + initEmoticons, + getWysiwygDoc, + handlePasteEvt, + handlePasteData, + handleKeyDown, + handleBackSpace, + handleKeyPress, + handleFormReset, + handleMouseDown, + handleEvent, + handleDocumentClick, + handleWindowResize, + updateToolBar, + updateActiveButtons, + sourceEditorSelectedText, + appendNewLine, + checkSelectionChanged, + checkNodeChanged, + autofocus, + emoticonsKeyPress, + emoticonsCheckWhitespace, + currentStyledBlockNode, + triggerValueChanged, + valueChangedBlur, + valueChangedKeyUp, + autoUpdate; + + /** + * All the commands supported by the editor + * @name commands + * @memberOf jQuery.sceditor.prototype + */ + base.commands = $.extend( + true, + {}, + (options.commands || SCEditor.commands) + ); + + /** + * Options for this editor instance + * @name opts + * @memberOf jQuery.sceditor.prototype + */ + base.opts = options = $.extend({}, SCEditor.defaultOptions, options); + + + /** + * Creates the editor iframe and textarea + * @private + */ + init = function () { + $original.data('sceditor', base); + + // Clone any objects in options + $.each(options, function (key, val) { + if ($.isPlainObject(val)) { + options[key] = $.extend(true, {}, val); + } + }); + + // Load locale + if (options.locale && options.locale !== 'en') { + initLocale(); + } + + $editorContainer = $('
') + .insertAfter($original) + .css('z-index', options.zIndex); + + // Add IE version to the container to allow IE specific CSS + // fixes without using CSS hacks or conditional comments + if (IE_VER) { + $editorContainer.addClass('ie ie' + IE_VER); + } + + isRequired = !!$original.attr('required'); + $original.removeAttr('required'); + + // create the editor + initPlugins(); + initEmoticons(); + initToolBar(); + initEditor(!!options.startInSourceMode); + initCommands(); + initOptions(); + initEvents(); + + // force into source mode if is a browser that can't handle + // full editing + if (!browser.isWysiwygSupported) { + base.toggleSourceMode(); + } + + updateActiveButtons(); + + var loaded = function () { + $globalWin.off('load', loaded); + + if (options.autofocus) { + autofocus(); + } + + if (options.autoExpand) { + base.expandToContent(); + } + + // Page width might have changed after CSS is loaded so + // call handleWindowResize to update any % based dimensions + handleWindowResize(); + + pluginManager.call('ready'); + }; + $globalWin.on('load', loaded); + if (globalDoc.readyState && globalDoc.readyState === 'complete') { + loaded(); + } + }; + + initPlugins = function () { + var plugins = options.plugins; + + plugins = plugins ? plugins.toString().split(',') : []; + pluginManager = new PluginManager(base); + + $.each(plugins, function (idx, plugin) { + pluginManager.register($.trim(plugin)); + }); + }; + + /** + * Init the locale variable with the specified locale if possible + * @private + * @return void + */ + initLocale = function () { + var lang; + + locale = SCEditor.locale[options.locale]; + + if (!locale) { + lang = options.locale.split('-'); + locale = SCEditor.locale[lang[0]]; + } + + // Locale DateTime format overrides any specified in the options + if (locale && locale.dateFormat) { + options.dateFormat = locale.dateFormat; + } + }; + + /** + * Creates the editor iframe and textarea + * @param {boolean} startInSourceMode Force loading the editor in this + * mode + * @private + */ + initEditor = function (startInSourceMode) { + var doc, tabIndex; + + $sourceEditor = $(''); + $wysiwygEditor = $( + '' + ); + + /* This needs to be done right after they are created because, + * for any reason, the user may not want the value to be tinkered + * by any filters. + */ + if (startInSourceMode) { + $editorContainer.addClass('sourceMode'); + $wysiwygEditor.hide(); + } else { + $editorContainer.addClass('wysiwygMode'); + $sourceEditor.hide(); + } + + if (!options.spellcheck) { + $sourceEditor.attr('spellcheck', 'false'); + } + + /*jshint scripturl: true*/ + if (globalWin.location.protocol === 'https:') { + $wysiwygEditor.attr('src', 'javascript:false'); + } + + // Add the editor to the container + $editorContainer.append($wysiwygEditor).append($sourceEditor); + wysiwygEditor = $wysiwygEditor[0]; + sourceEditor = $sourceEditor[0]; + + base.dimensions( + options.width || $original.width(), + options.height || $original.height() + ); + + doc = getWysiwygDoc(); + doc.open(); + doc.write(_tmpl('html', { + // Add IE version class to the HTML element so can apply + // conditional styling without CSS hacks + attrs: IE_VER ? ' class="ie ie' + IE_VER + '"' : '', + spellcheck: options.spellcheck ? '' : 'spellcheck="false"', + charset: options.charset, + style: options.style + })); + doc.close(); + + $wysiwygDoc = $(doc); + $wysiwygBody = $(doc.body); + + base.readOnly(!!options.readOnly); + + // iframe overflow fix for iOS, also fixes an IE issue with the + // editor not getting focus when clicking inside + if (browser.ios || IE_VER) { + $wysiwygBody.height('100%'); + + if (!IE_VER) { + $wysiwygBody.on('touchend', base.focus); + } + } + + tabIndex = $original.attr('tabindex'); + $sourceEditor.attr('tabindex', tabIndex); + $wysiwygEditor.attr('tabindex', tabIndex); + + rangeHelper = new RangeHelper(wysiwygEditor.contentWindow); + + // load any textarea value into the editor + base.val($original.hide().val()); + }; + + /** + * Initialises options + * @private + */ + initOptions = function () { + // auto-update original textbox on blur if option set to true + if (options.autoUpdate) { + $wysiwygBody.on('blur', autoUpdate); + $sourceEditor.on('blur', autoUpdate); + } + + if (options.rtl === null) { + options.rtl = $sourceEditor.css('direction') === 'rtl'; + } + + base.rtl(!!options.rtl); + + if (options.autoExpand) { + $wysiwygDoc.on('keyup', base.expandToContent); + } + + if (options.resizeEnabled) { + initResize(); + } + + $editorContainer.attr('id', options.id); + base.emoticons(options.emoticonsEnabled); + }; + + /** + * Initialises events + * @private + */ + initEvents = function () { + var CHECK_SELECTION_EVENTS = IE_VER ? + 'selectionchange' : + 'keyup focus blur contextmenu mouseup touchend click'; + + var EVENTS_TO_FORWARD = 'keydown keyup keypress ' + + 'focus blur contextmenu'; + + $globalDoc.click(handleDocumentClick); + + $(original.form) + .on('reset', handleFormReset) + .submit(base.updateOriginal); + + $globalWin.on('resize orientationChanged', handleWindowResize); + + $wysiwygBody + .keypress(handleKeyPress) + .keydown(handleKeyDown) + .keydown(handleBackSpace) + .keyup(appendNewLine) + .blur(valueChangedBlur) + .keyup(valueChangedKeyUp) + .on('paste', handlePasteEvt) + .on(CHECK_SELECTION_EVENTS, checkSelectionChanged) + .on(EVENTS_TO_FORWARD, handleEvent); + + if (options.emoticonsCompat && globalWin.getSelection) { + $wysiwygBody.keyup(emoticonsCheckWhitespace); + } + + $sourceEditor + .blur(valueChangedBlur) + .keyup(valueChangedKeyUp) + .keydown(handleKeyDown) + .on(EVENTS_TO_FORWARD, handleEvent); + + $wysiwygDoc + .mousedown(handleMouseDown) + .blur(valueChangedBlur) + .on(CHECK_SELECTION_EVENTS, checkSelectionChanged) + .on('beforedeactivate keyup mouseup', saveRange) + .keyup(appendNewLine) + .focus(function () { + lastRange = null; + }); + + $editorContainer + .on('selectionchanged', checkNodeChanged) + .on('selectionchanged', updateActiveButtons) + .on('selectionchanged valuechanged nodechanged', handleEvent); + }; + + /** + * Creates the toolbar and appends it to the container + * @private + */ + initToolBar = function () { + var $group, + commands = base.commands, + exclude = (options.toolbarExclude || '').split(','), + groups = options.toolbar.split('|'); + + $toolbar = $('
'); + + $.each(groups, function (idx, group) { + $group = $('
'); + + $.each(group.split(','), function (idx, commandName) { + var $button, shortcut, + command = commands[commandName]; + + // The commandName must be a valid command and not excluded + if (!command || $.inArray(commandName, exclude) > -1) { + return; + } + + shortcut = command.shortcut; + $button = _tmpl('toolbarButton', { + name: commandName, + dispName: base._(command.name || + command.tooltip || commandName) + }, true); + + $button + .data('sceditor-txtmode', !!command.txtExec) + .data('sceditor-wysiwygmode', !!command.exec) + .toggleClass('disabled', !command.exec) + .mousedown(function () { + // IE < 8 supports unselectable attribute + // so don't need this + if (!IE_VER || IE_VER < 9) { + autoUpdateCanceled = true; + } + }) + .click(function () { + var $this = $(this); + + if (!$this.hasClass('disabled')) { + handleCommand($this, command); + } + + updateActiveButtons(); + return false; + }); + + if (command.tooltip) { + $button.attr( + 'title', + base._(command.tooltip) + + (shortcut ? ' (' + shortcut + ')' : '') + ); + } + + if (shortcut) { + base.addShortcut(shortcut, commandName); + } + + if (command.state) { + btnStateHandlers.push({ + name: commandName, + state: command.state + }); + // exec string commands can be passed to queryCommandState + } else if (typeof command.exec === 'string') { + btnStateHandlers.push({ + name: commandName, + state: command.exec + }); + } + + $group.append($button); + toolbarButtons[commandName] = $button; + }); + + // Exclude empty groups + if ($group[0].firstChild) { + $toolbar.append($group); + } + }); + + // Append the toolbar to the toolbarContainer option if given + $(options.toolbarContainer || $editorContainer).append($toolbar); + }; + + /** + * Creates an array of all the key press functions + * like emoticons, ect. + * @private + */ + initCommands = function () { + $.each(base.commands, function (name, cmd) { + if (cmd.forceNewLineAfter && $.isArray(cmd.forceNewLineAfter)) { + requireNewLineFix = $.merge( + requireNewLineFix, + cmd.forceNewLineAfter + ); + } + }); + + appendNewLine(); + }; + + /** + * Creates the resizer. + * @private + */ + initResize = function () { + var minHeight, maxHeight, minWidth, maxWidth, + mouseMoveFunc, mouseUpFunc, + $grip = $('
'), + // Cover is used to cover the editor iframe so document + // still gets mouse move events + $cover = $('
'), + moveEvents = 'touchmove mousemove', + endEvents = 'touchcancel touchend mouseup', + startX = 0, + startY = 0, + newX = 0, + newY = 0, + startWidth = 0, + startHeight = 0, + origWidth = $editorContainer.width(), + origHeight = $editorContainer.height(), + isDragging = false, + rtl = base.rtl(); + + minHeight = options.resizeMinHeight || origHeight / 1.5; + maxHeight = options.resizeMaxHeight || origHeight * 2.5; + minWidth = options.resizeMinWidth || origWidth / 1.25; + maxWidth = options.resizeMaxWidth || origWidth * 1.25; + + mouseMoveFunc = function (e) { + // iOS uses window.event + if (e.type === 'touchmove') { + e = globalWin.event; + newX = e.changedTouches[0].pageX; + newY = e.changedTouches[0].pageY; + } else { + newX = e.pageX; + newY = e.pageY; + } + + var newHeight = startHeight + (newY - startY), + newWidth = rtl ? + startWidth - (newX - startX) : + startWidth + (newX - startX); + + if (maxWidth > 0 && newWidth > maxWidth) { + newWidth = maxWidth; + } + if (minWidth > 0 && newWidth < minWidth) { + newWidth = minWidth; + } + if (!options.resizeWidth) { + newWidth = false; + } + + if (maxHeight > 0 && newHeight > maxHeight) { + newHeight = maxHeight; + } + if (minHeight > 0 && newHeight < minHeight) { + newHeight = minHeight; + } + if (!options.resizeHeight) { + newHeight = false; + } + + if (newWidth || newHeight) { + base.dimensions(newWidth, newHeight); + + // The resize cover will not fill the container + // in IE6 unless a height is specified. + if (IE_VER < 7) { + $editorContainer.height(newHeight); + } + } + + e.preventDefault(); + }; + + mouseUpFunc = function (e) { + if (!isDragging) { + return; + } + + isDragging = false; + + $cover.hide(); + $editorContainer.removeClass('resizing').height('auto'); + $globalDoc.off(moveEvents, mouseMoveFunc); + $globalDoc.off(endEvents, mouseUpFunc); + + e.preventDefault(); + }; + + $editorContainer.append($grip); + $editorContainer.append($cover.hide()); + + $grip.on('touchstart mousedown', function (e) { + // iOS uses window.event + if (e.type === 'touchstart') { + e = globalWin.event; + startX = e.touches[0].pageX; + startY = e.touches[0].pageY; + } else { + startX = e.pageX; + startY = e.pageY; + } + + startWidth = $editorContainer.width(); + startHeight = $editorContainer.height(); + isDragging = true; + + $editorContainer.addClass('resizing'); + $cover.show(); + $globalDoc.on(moveEvents, mouseMoveFunc); + $globalDoc.on(endEvents, mouseUpFunc); + + // The resize cover will not fill the container in + // IE6 unless a height is specified. + if (IE_VER < 7) { + $editorContainer.height(startHeight); + } + + e.preventDefault(); + }); + }; + + /** + * Prefixes and preloads the emoticon images + * @private + */ + initEmoticons = function () { + var emoticon, + emoticons = options.emoticons, + root = options.emoticonsRoot; + + if (!$.isPlainObject(emoticons) || !options.emoticonsEnabled) { + return; + } + + $.each(emoticons, function (idx, val) { + $.each(val, function (key, url) { + // Prefix emoticon root to emoticon urls + if (root) { + url = { + url: root + (url.url || url), + tooltip: url.tooltip || key + }; + + emoticons[idx][key] = url; + } + + // Preload the emoticon + emoticon = globalDoc.createElement('img'); + emoticon.src = url.url || url; + preLoadCache.push(emoticon); + }); + }); + }; + + /** + * Autofocus the editor + * @private + */ + autofocus = function () { + var range, txtPos, + doc = $wysiwygDoc[0], + body = $wysiwygBody[0], + node = body.firstChild, + focusEnd = !!options.autofocusEnd; + + // Can't focus invisible elements + if (!$editorContainer.is(':visible')) { + return; + } + + if (base.sourceMode()) { + txtPos = focusEnd ? sourceEditor.value.length : 0; + + if (sourceEditor.setSelectionRange) { + sourceEditor.setSelectionRange(txtPos, txtPos); + } else { + range = sourceEditor.createTextRange(); + range.moveEnd('character', txtPos); + range.collapse(false); + range.select(); + } + + return; + } + + dom.removeWhiteSpace(body); + + if (focusEnd) { + if (!(node = body.lastChild)) { + node = doc.createElement('p'); + $wysiwygBody.append(node); + } + + while (node.lastChild) { + node = node.lastChild; + + // IE < 11 should place the cursor after the
as + // it will show it as a newline. IE >= 11 and all + // other browsers should place the cursor before. + if (!IE_BR_FIX && $(node).is('br') && + node.previousSibling) { + node = node.previousSibling; + } + } + } + + if (doc.createRange) { + range = doc.createRange(); + + if (!dom.canHaveChildren(node)) { + range.setStartBefore(node); + + if (focusEnd) { + range.setStartAfter(node); + } + } else { + range.selectNodeContents(node); + } + } else { + range = body.createTextRange(); + range.moveToElementText(node.nodeType !== 3 ? + node : node.parentNode); + } + + range.collapse(!focusEnd); + rangeHelper.selectRange(range); + currentSelection = range; + + if (focusEnd) { + $wysiwygDoc.scrollTop(body.scrollHeight); + $wysiwygBody.scrollTop(body.scrollHeight); + } + + base.focus(); + }; + + /** + * Gets if the editor is read only + * + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name readOnly + * @return {Boolean} + */ + /** + * Sets if the editor is read only + * + * @param {boolean} readOnly + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name readOnly^2 + * @return {this} + */ + base.readOnly = function (readOnly) { + if (typeof readOnly !== 'boolean') { + return $sourceEditor.attr('readonly') === 'readonly'; + } + + $wysiwygBody[0].contentEditable = !readOnly; + + if (!readOnly) { + $sourceEditor.removeAttr('readonly'); + } else { + $sourceEditor.attr('readonly', 'readonly'); + } + + updateToolBar(readOnly); + + return base; + }; + + /** + * Gets if the editor is in RTL mode + * + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name rtl + * @return {Boolean} + */ + /** + * Sets if the editor is in RTL mode + * + * @param {boolean} rtl + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name rtl^2 + * @return {this} + */ + base.rtl = function (rtl) { + var dir = rtl ? 'rtl' : 'ltr'; + + if (typeof rtl !== 'boolean') { + return $sourceEditor.attr('dir') === 'rtl'; + } + + $wysiwygBody.attr('dir', dir); + $sourceEditor.attr('dir', dir); + + $editorContainer + .removeClass('rtl') + .removeClass('ltr') + .addClass(dir); + + return base; + }; + + /** + * Updates the toolbar to disable/enable the appropriate buttons + * @private + */ + updateToolBar = function (disable) { + var mode = base.inSourceMode() ? 'txtmode' : 'wysiwygmode'; + + $.each(toolbarButtons, function (idx, $button) { + if (disable === true || !$button.data('sceditor-' + mode)) { + $button.addClass('disabled'); + } else { + $button.removeClass('disabled'); + } + }); + }; + + /** + * Gets the width of the editor in pixels + * + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name width + * @return {int} + */ + /** + * Sets the width of the editor + * + * @param {int} width Width in pixels + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name width^2 + * @return {this} + */ + /** + * Sets the width of the editor + * + * The saveWidth specifies if to save the width. The stored width can be + * used for things like restoring from maximized state. + * + * @param {int} width Width in pixels + * @param {boolean} [saveWidth=true] If to store the width + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name width^3 + * @return {this} + */ + base.width = function (width, saveWidth) { + if (!width && width !== 0) { + return $editorContainer.width(); + } + + base.dimensions(width, null, saveWidth); + + return base; + }; + + /** + * Returns an object with the properties width and height + * which are the width and height of the editor in px. + * + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name dimensions + * @return {object} + */ + /** + *

Sets the width and/or height of the editor.

+ * + *

If width or height is not numeric it is ignored.

+ * + * @param {int} width Width in px + * @param {int} height Height in px + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name dimensions^2 + * @return {this} + */ + /** + *

Sets the width and/or height of the editor.

+ * + *

If width or height is not numeric it is ignored.

+ * + *

The save argument specifies if to save the new sizes. + * The saved sizes can be used for things like restoring from + * maximized state. This should normally be left as true.

+ * + * @param {int} width Width in px + * @param {int} height Height in px + * @param {boolean} [save=true] If to store the new sizes + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name dimensions^3 + * @return {this} + */ + base.dimensions = function (width, height, save) { + // IE6 & IE7 add 2 pixels to the source mode textarea + // height which must be ignored. + // Doesn't seem to be any way to fix it with only CSS + var ieBorder = IE_VER < 8 || globalDoc.documentMode < 8 ? 2 : 0; + var undef; + + // set undefined width/height to boolean false + width = (!width && width !== 0) ? false : width; + height = (!height && height !== 0) ? false : height; + + if (width === false && height === false) { + return { width: base.width(), height: base.height() }; + } + + if ($wysiwygEditor.data('outerWidthOffset') === undef) { + base.updateStyleCache(); + } + + if (width !== false) { + if (save !== false) { + options.width = width; + } + // This is the problem + if (height === false) { + height = $editorContainer.height(); + save = false; + } + + $editorContainer.width(width); + if (width && width.toString().indexOf('%') > -1) { + width = $editorContainer.width(); + } + + $wysiwygEditor.width( + width - $wysiwygEditor.data('outerWidthOffset') + ); + + $sourceEditor.width( + width - $sourceEditor.data('outerWidthOffset') + ); + + // Fix overflow issue with iOS not + // breaking words unless a width is set + if (browser.ios && $wysiwygBody) { + $wysiwygBody.width( + width - $wysiwygEditor.data('outerWidthOffset') - + ($wysiwygBody.outerWidth(true) - $wysiwygBody.width()) + ); + } + } + + if (height !== false) { + if (save !== false) { + options.height = height; + } + + // Convert % based heights to px + if (height && height.toString().indexOf('%') > -1) { + height = $editorContainer.height(height).height(); + $editorContainer.height('auto'); + } + + height -= !options.toolbarContainer ? + $toolbar.outerHeight(true) : 0; + + $wysiwygEditor.height( + height - $wysiwygEditor.data('outerHeightOffset') + ); + + $sourceEditor.height( + height - ieBorder - $sourceEditor.data('outerHeightOffset') + ); + } + + return base; + }; + + /** + * Updates the CSS styles cache. + * + * This shouldn't be needed unless changing the editors theme. + *F + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name updateStyleCache + * @return {int} + */ + base.updateStyleCache = function () { + // caching these improves FF resize performance + $wysiwygEditor.data( + 'outerWidthOffset', + $wysiwygEditor.outerWidth(true) - $wysiwygEditor.width() + ); + $sourceEditor.data( + 'outerWidthOffset', + $sourceEditor.outerWidth(true) - $sourceEditor.width() + ); + + $wysiwygEditor.data( + 'outerHeightOffset', + $wysiwygEditor.outerHeight(true) - $wysiwygEditor.height() + ); + $sourceEditor.data( + 'outerHeightOffset', + $sourceEditor.outerHeight(true) - $sourceEditor.height() + ); + }; + + /** + * Gets the height of the editor in px + * + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name height + * @return {int} + */ + /** + * Sets the height of the editor + * + * @param {int} height Height in px + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name height^2 + * @return {this} + */ + /** + * Sets the height of the editor + * + * The saveHeight specifies if to save the height. + * + * The stored height can be used for things like + * restoring from maximized state. + * + * @param {int} height Height in px + * @param {boolean} [saveHeight=true] If to store the height + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name height^3 + * @return {this} + */ + base.height = function (height, saveHeight) { + if (!height && height !== 0) { + return $editorContainer.height(); + } + + base.dimensions(null, height, saveHeight); + + return base; + }; + + /** + * Gets if the editor is maximised or not + * + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name maximize + * @return {boolean} + */ + /** + * Sets if the editor is maximised or not + * + * @param {boolean} maximize If to maximise the editor + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name maximize^2 + * @return {this} + */ + base.maximize = function (maximize) { + if (typeof maximize === 'undefined') { + return $editorContainer.is('.sceditor-maximize'); + } + + maximize = !!maximize; + + // IE 6 fix + if (IE_VER < 7) { + $('html, body').toggleClass('sceditor-maximize', maximize); + } + + $editorContainer.toggleClass('sceditor-maximize', maximize); + base.width(maximize ? '100%' : options.width, false); + base.height(maximize ? '100%' : options.height, false); + + return base; + }; + + /** + * Expands the editors height to the height of it's content + * + * Unless ignoreMaxHeight is set to true it will not expand + * higher than the maxHeight option. + * + * @since 1.3.5 + * @param {Boolean} [ignoreMaxHeight=false] + * @function + * @name expandToContent + * @memberOf jQuery.sceditor.prototype + * @see #resizeToContent + */ + base.expandToContent = function (ignoreMaxHeight) { + var currentHeight = $editorContainer.height(), + padding = (currentHeight - $wysiwygEditor.height()), + height = $wysiwygBody[0].scrollHeight || + $wysiwygDoc[0].documentElement.scrollHeight, + maxHeight = options.resizeMaxHeight || + ((options.height || $original.height()) * 2); + + height += padding; + + if ((ignoreMaxHeight === true || height <= maxHeight) && + height > currentHeight) { + base.height(height); + } + }; + + /** + * Destroys the editor, removing all elements and + * event handlers. + * + * Leaves only the original textarea. + * + * @function + * @name destroy + * @memberOf jQuery.sceditor.prototype + */ + base.destroy = function () { + // Don't destroy if the editor has already been destroyed + if (!pluginManager) { + return; + } + + pluginManager.destroy(); + + rangeHelper = null; + lastRange = null; + pluginManager = null; + + if ($dropdown) { + $dropdown.off().remove(); + } + + $globalDoc.off('click', handleDocumentClick); + $globalWin.off('resize orientationChanged', handleWindowResize); + + $(original.form) + .off('reset', handleFormReset) + .off('submit', base.updateOriginal); + + $wysiwygBody.off(); + $wysiwygDoc.off().find('*').remove(); + + $sourceEditor.off().remove(); + $toolbar.remove(); + $editorContainer.off().find('*').off().remove(); + $editorContainer.remove(); + + $original + .removeData('sceditor') + .removeData('sceditorbbcode') + .show(); + + if (isRequired) { + $original.attr('required', 'required'); + } + }; + + + /** + * Creates a menu item drop down + * + * @param {HTMLElement} menuItem The button to align the dropdown with + * @param {string} name Used for styling the dropdown, will be + * a class sceditor-name + * @param {HTMLElement} content The HTML content of the dropdown + * @param {bool} ieFix If to add the unselectable attribute + * to all the contents elements. Stops + * IE from deselecting the text in the + * editor + * @function + * @name createDropDown + * @memberOf jQuery.sceditor.prototype + */ + base.createDropDown = function (menuItem, name, content, ieFix) { + // first click for create second click for close + var dropDownCss, + cssClass = 'sceditor-' + name, + onlyclose = $dropdown && $dropdown.is('.' + cssClass); + + // Will re-focus the editor. This is needed for IE + // as it has special logic to save/restore the selection + base.closeDropDown(true); + + if (onlyclose) { + return; + } + + // IE needs unselectable attr to stop it from + // unselecting the text in the editor. + // SCEditor can cope if IE does unselect the + // text it's just not nice. + if (ieFix !== false) { + $(content) + .find(':not(input,textarea)') + .filter(function () { + return this.nodeType === 1; + }) + .attr('unselectable', 'on'); + } + + dropDownCss = { + top: menuItem.offset().top, + left: menuItem.offset().left, + marginTop: menuItem.outerHeight() + }; + $.extend(dropDownCss, options.dropDownCss); + + $dropdown = $('
') + .css(dropDownCss) + .append(content) + .appendTo($('body')) + .on('click focusin', function (e) { + // stop clicks within the dropdown from being handled + e.stopPropagation(); + }); + + // If try to focus the first input immediately IE will + // place the cursor at the start of the editor instead + // of focusing on the input. + setTimeout(function () { + if ($dropdown) { + $dropdown.find('input,textarea').first().focus(); + } + }); + }; + + /** + * Handles any document click and closes the dropdown if open + * @private + */ + handleDocumentClick = function (e) { + // ignore right clicks + if (e.which !== 3 && $dropdown) { + autoUpdate(); + + base.closeDropDown(); + } + }; + + /** + * Handles the WYSIWYG editors paste event + * @private + */ + handlePasteEvt = function (e) { + var html, handlePaste, scrollTop, + elm = $wysiwygBody[0], + doc = $wysiwygDoc[0], + checkCount = 0, + pastearea = globalDoc.createElement('div'), + prePasteContent = doc.createDocumentFragment(), + clipboardData = e ? e.clipboardData : false; + + if (options.disablePasting) { + return false; + } + + if (!options.enablePasteFiltering) { + return; + } + + rangeHelper.saveRange(); + globalDoc.body.appendChild(pastearea); + + if (clipboardData && clipboardData.getData) { + if ((html = clipboardData.getData('text/html')) || + (html = clipboardData.getData('text/plain'))) { + pastearea.innerHTML = html; + handlePasteData(elm, pastearea); + + return false; + } + } + + // Save the scroll position so can be restored + // when contents is restored + scrollTop = $wysiwygBody.scrollTop() || $wysiwygDoc.scrollTop(); + + while (elm.firstChild) { + prePasteContent.appendChild(elm.firstChild); + } + + // try make pastearea contenteditable and redirect to that? Might work. + // Check the tests if still exist, if not re-0create + handlePaste = function (elm, pastearea) { + if (elm.childNodes.length > 0 || checkCount > 25) { + while (elm.firstChild) { + pastearea.appendChild(elm.firstChild); + } + + while (prePasteContent.firstChild) { + elm.appendChild(prePasteContent.firstChild); + } + + $wysiwygBody.scrollTop(scrollTop); + $wysiwygDoc.scrollTop(scrollTop); + + if (pastearea.childNodes.length > 0) { + handlePasteData(elm, pastearea); + } else { + rangeHelper.restoreRange(); + } + } else { + // Allow max 25 checks before giving up. + // Needed in case an empty string is pasted or + // something goes wrong. + checkCount++; + setTimeout(function () { + handlePaste(elm, pastearea); + }, 20); + } + }; + handlePaste(elm, pastearea); + + base.focus(); + return true; + }; + + /** + * Gets the pasted data, filters it and then inserts it. + * @param {Element} elm + * @param {Element} pastearea + * @private + */ + handlePasteData = function (elm, pastearea) { + // fix any invalid nesting + dom.fixNesting(pastearea); + // TODO: Trigger custom paste event to allow filtering + // (pre and post converstion?) + var pasteddata = pastearea.innerHTML; + + if (pluginManager.hasHandler('toSource')) { + pasteddata = pluginManager.callOnlyFirst( + 'toSource', pasteddata, $(pastearea) + ); + } + + pastearea.parentNode.removeChild(pastearea); + + if (pluginManager.hasHandler('toWysiwyg')) { + pasteddata = pluginManager.callOnlyFirst( + 'toWysiwyg', pasteddata, true + ); + } + + rangeHelper.restoreRange(); + base.wysiwygEditorInsertHtml(pasteddata, null, true); + }; + + /** + * Closes any currently open drop down + * + * @param {bool} [focus=false] If to focus the editor + * after closing the drop down + * @function + * @name closeDropDown + * @memberOf jQuery.sceditor.prototype + */ + base.closeDropDown = function (focus) { + if ($dropdown) { + $dropdown.off().remove(); + $dropdown = null; + } + + if (focus === true) { + base.focus(); + } + }; + + /** + * Gets the WYSIWYG editors document + * @private + */ + getWysiwygDoc = function () { + if (wysiwygEditor.contentDocument) { + return wysiwygEditor.contentDocument; + } + + if (wysiwygEditor.contentWindow && + wysiwygEditor.contentWindow.document) { + return wysiwygEditor.contentWindow.document; + } + + return wysiwygEditor.document; + }; + + + /** + *

Inserts HTML into WYSIWYG editor.

+ * + *

If endHtml is specified, any selected text will be placed + * between html and endHtml. If there is no selected text html + * and endHtml will just be concatenate together.

+ * + * @param {string} html + * @param {string} [endHtml=null] + * @param {boolean} [overrideCodeBlocking=false] If to insert the html + * into code tags, by + * default code tags only + * support text. + * @function + * @name wysiwygEditorInsertHtml + * @memberOf jQuery.sceditor.prototype + */ + base.wysiwygEditorInsertHtml = function ( + html, endHtml, overrideCodeBlocking + ) { + var $marker, scrollTop, scrollTo, + editorHeight = $wysiwygEditor.height(); + + base.focus(); + + // TODO: This code tag should be configurable and + // should maybe convert the HTML into text instead + // Don't apply to code elements + if (!overrideCodeBlocking && ($(currentBlockNode).is('code') || + $(currentBlockNode).parents('code').length !== 0)) { + return; + } + + // Insert the HTML and save the range so the editor can be scrolled + // to the end of the selection. Also allows emoticons to be replaced + // without affecting the cursor position + rangeHelper.insertHTML(html, endHtml); + rangeHelper.saveRange(); + replaceEmoticons($wysiwygBody[0]); + + // Scroll the editor after the end of the selection + $marker = $wysiwygBody.find('#sceditor-end-marker').show(); + scrollTop = $wysiwygBody.scrollTop() || $wysiwygDoc.scrollTop(); + scrollTo = (dom.getOffset($marker[0]).top + + ($marker.outerHeight(true) * 1.5)) - editorHeight; + $marker.hide(); + + // Only scroll if marker isn't already visible + if (scrollTo > scrollTop || scrollTo + editorHeight < scrollTop) { + $wysiwygBody.scrollTop(scrollTo); + $wysiwygDoc.scrollTop(scrollTo); + } + + triggerValueChanged(false); + rangeHelper.restoreRange(); + + // Add a new line after the last block element + // so can always add text after it + appendNewLine(); + }; + + /** + * Like wysiwygEditorInsertHtml except it will convert any HTML + * into text before inserting it. + * + * @param {String} text + * @param {String} [endText=null] + * @function + * @name wysiwygEditorInsertText + * @memberOf jQuery.sceditor.prototype + */ + base.wysiwygEditorInsertText = function (text, endText) { + base.wysiwygEditorInsertHtml( + escape.entities(text), escape.entities(endText) + ); + }; + + /** + *

Inserts text into the WYSIWYG or source editor depending on which + * mode the editor is in.

+ * + *

If endText is specified any selected text will be placed between + * text and endText. If no text is selected text and endText will + * just be concatenate together.

+ * + * @param {String} text + * @param {String} [endText=null] + * @since 1.3.5 + * @function + * @name insertText + * @memberOf jQuery.sceditor.prototype + */ + base.insertText = function (text, endText) { + if (base.inSourceMode()) { + base.sourceEditorInsertText(text, endText); + } else { + base.wysiwygEditorInsertText(text, endText); + } + + return base; + }; + + /** + *

Like wysiwygEditorInsertHtml but inserts text into the + * source mode editor instead.

+ * + *

If endText is specified any selected text will be placed between + * text and endText. If no text is selected text and endText will + * just be concatenate together.

+ * + *

The cursor will be placed after the text param. If endText is + * specified the cursor will be placed before endText, so passing:
+ * + * '[b]', '[/b]'

+ * + *

Would cause the cursor to be placed:
+ * + * [b]Selected text|[/b]

+ * + * @param {String} text + * @param {String} [endText=null] + * @since 1.4.0 + * @function + * @name sourceEditorInsertText + * @memberOf jQuery.sceditor.prototype + */ + base.sourceEditorInsertText = function (text, endText) { + var range, scrollTop, currentValue, + startPos = sourceEditor.selectionStart, + endPos = sourceEditor.selectionEnd; + + scrollTop = sourceEditor.scrollTop; + sourceEditor.focus(); + + // All browsers except IE < 9 + if (typeof startPos !== 'undefined') { + currentValue = sourceEditor.value; + + if (endText) { + text += currentValue.substring(startPos, endPos) + endText; + } + + sourceEditor.value = currentValue.substring(0, startPos) + + text + + currentValue.substring(endPos, currentValue.length); + + sourceEditor.selectionStart = (startPos + text.length) - + (endText ? endText.length : 0); + sourceEditor.selectionEnd = sourceEditor.selectionStart; + // IE < 9 + } else { + range = globalDoc.selection.createRange(); + + if (endText) { + text += range.text + endText; + } + + range.text = text; + + if (endText) { + range.moveEnd('character', 0 - endText.length); + } + + range.moveStart('character', range.End - range.Start); + range.select(); + } + + sourceEditor.scrollTop = scrollTop; + sourceEditor.focus(); + + triggerValueChanged(); + }; + + /** + * Gets the current instance of the rangeHelper class + * for the editor. + * + * @return jQuery.sceditor.rangeHelper + * @function + * @name getRangeHelper + * @memberOf jQuery.sceditor.prototype + */ + base.getRangeHelper = function () { + return rangeHelper; + }; + + /** + * Gets the source editors textarea. + * + * This shouldn't be used to insert text + * + * @return {jQuery} + * @function + * @since 1.4.5 + * @name sourceEditorCaret + * @memberOf jQuery.sceditor.prototype + */ + base.sourceEditorCaret = function (position) { + var range, + ret = {}; + + sourceEditor.focus(); + + // All browsers except IE <= 8 + if (typeof sourceEditor.selectionStart !== 'undefined') { + if (position) { + sourceEditor.selectionStart = position.start; + sourceEditor.selectionEnd = position.end; + } else { + ret.start = sourceEditor.selectionStart; + ret.end = sourceEditor.selectionEnd; + } + + // IE8 and below + } else { + range = globalDoc.selection.createRange(); + + if (position) { + range.moveEnd('character', position.end); + range.moveStart('character', position.start); + range.select(); + } else { + ret.start = range.Start; + ret.end = range.End; + } + } + + return position ? this : ret; + }; + + /** + *

Gets the value of the editor.

+ * + *

If the editor is in WYSIWYG mode it will return the filtered + * HTML from it (converted to BBCode if using the BBCode plugin). + * It it's in Source Mode it will return the unfiltered contents + * of the source editor (if using the BBCode plugin this will be + * BBCode again).

+ * + * @since 1.3.5 + * @return {string} + * @function + * @name val + * @memberOf jQuery.sceditor.prototype + */ + /** + *

Sets the value of the editor.

+ * + *

If filter set true the val will be passed through the filter + * function. If using the BBCode plugin it will pass the val to + * the BBCode filter to convert any BBCode into HTML.

+ * + * @param {String} val + * @param {Boolean} [filter=true] + * @return {this} + * @since 1.3.5 + * @function + * @name val^2 + * @memberOf jQuery.sceditor.prototype + */ + base.val = function (val, filter) { + if (typeof val !== 'string') { + return base.inSourceMode() ? + base.getSourceEditorValue(false) : + base.getWysiwygEditorValue(filter); + } + + if (!base.inSourceMode()) { + if (filter !== false && + pluginManager.hasHandler('toWysiwyg')) { + val = pluginManager.callOnlyFirst('toWysiwyg', val); + } + + base.setWysiwygEditorValue(val); + } else { + base.setSourceEditorValue(val); + } + + return base; + }; + + /** + *

Inserts HTML/BBCode into the editor

+ * + *

If end is supplied any selected text will be placed between + * start and end. If there is no selected text start and end + * will be concatenate together.

+ * + *

If the filter param is set to true, the HTML/BBCode will be + * passed through any plugin filters. If using the BBCode plugin + * this will convert any BBCode into HTML.

+ * + * @param {String} start + * @param {String} [end=null] + * @param {Boolean} [filter=true] + * @param {Boolean} [convertEmoticons=true] If to convert emoticons + * @return {this} + * @since 1.3.5 + * @function + * @name insert + * @memberOf jQuery.sceditor.prototype + */ + /** + *

Inserts HTML/BBCode into the editor

+ * + *

If end is supplied any selected text will be placed between + * start and end. If there is no selected text start and end + * will be concatenate together.

+ * + *

If the filter param is set to true, the HTML/BBCode will be + * passed through any plugin filters. If using the BBCode plugin + * this will convert any BBCode into HTML.

+ * + *

If the allowMixed param is set to true, HTML any will not be + * escaped

+ * + * @param {String} start + * @param {String} [end=null] + * @param {Boolean} [filter=true] + * @param {Boolean} [convertEmoticons=true] If to convert emoticons + * @param {Boolean} [allowMixed=false] + * @return {this} + * @since 1.4.3 + * @function + * @name insert^2 + * @memberOf jQuery.sceditor.prototype + */ + base.insert = function ( + /*jshint maxparams: false */ + start, end, filter, convertEmoticons, allowMixed + ) { + if (base.inSourceMode()) { + base.sourceEditorInsertText(start, end); + return base; + } + + // Add the selection between start and end + if (end) { + var html = rangeHelper.selectedHtml(), + $div = $('
').appendTo($('body')).hide().html(html); + + if (filter !== false && pluginManager.hasHandler('toSource')) { + html = pluginManager.callOnlyFirst('toSource', html, $div); + } + + $div.remove(); + + start += html + end; + } + // TODO: This filter should allow empty tags as it's inserting. + if (filter !== false && pluginManager.hasHandler('toWysiwyg')) { + start = pluginManager.callOnlyFirst('toWysiwyg', start, true); + } + + // Convert any escaped HTML back into HTML if mixed is allowed + if (filter !== false && allowMixed === true) { + start = start.replace(/</g, '<') + .replace(/>/g, '>') + .replace(/&/g, '&'); + } + + base.wysiwygEditorInsertHtml(start); + + return base; + }; + + /** + * Gets the WYSIWYG editors HTML value. + * + * If using a plugin that filters the Ht Ml like the BBCode plugin + * it will return the result of the filtering (BBCode) unless the + * filter param is set to false. + * + * @param {bool} [filter=true] + * @return {string} + * @function + * @name getWysiwygEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.getWysiwygEditorValue = function (filter) { + var html; + // Create a tmp node to store contents so it can be modified + // without affecting anything else. + var $tmp = $('
') + .appendTo(document.body) + .append($($wysiwygBody[0].childNodes).clone()); + + dom.fixNesting($tmp[0]); + + html = $tmp.html(); + + // filter the HTML and DOM through any plugins + if (filter !== false && pluginManager.hasHandler('toSource')) { + html = pluginManager.callOnlyFirst('toSource', html, $tmp); + } + + $tmp.remove(); + + return html; + }; + + /** + * Gets the WYSIWYG editor's iFrame Body. + * + * @return {jQuery} + * @function + * @since 1.4.3 + * @name getBody + * @memberOf jQuery.sceditor.prototype + */ + base.getBody = function () { + return $wysiwygBody; + }; + + /** + * Gets the WYSIWYG editors container area (whole iFrame). + * + * @return {Node} + * @function + * @since 1.4.3 + * @name getContentAreaContainer + * @memberOf jQuery.sceditor.prototype + */ + base.getContentAreaContainer = function () { + return $wysiwygEditor; + }; + + /** + * Gets the text editor value + * + * If using a plugin that filters the text like the BBCode plugin + * it will return the result of the filtering which is BBCode to + * HTML so it will return HTML. If filter is set to false it will + * just return the contents of the source editor (BBCode). + * + * @param {bool} [filter=true] + * @return {string} + * @function + * @since 1.4.0 + * @name getSourceEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.getSourceEditorValue = function (filter) { + var val = $sourceEditor.val(); + + if (filter !== false && pluginManager.hasHandler('toWysiwyg')) { + val = pluginManager.callOnlyFirst('toWysiwyg', val); + } + + return val; + }; + + /** + * Sets the WYSIWYG HTML editor value. Should only be the HTML + * contained within the body tags + * + * @param {string} value + * @function + * @name setWysiwygEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.setWysiwygEditorValue = function (value) { + if (!value) { + value = '

' + (IE_VER ? '' : '
') + '

'; + } + + $wysiwygBody[0].innerHTML = value; + replaceEmoticons($wysiwygBody[0]); + + appendNewLine(); + triggerValueChanged(); + }; + + /** + * Sets the text editor value + * + * @param {string} value + * @function + * @name setSourceEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.setSourceEditorValue = function (value) { + $sourceEditor.val(value); + + triggerValueChanged(); + }; + + /** + * Updates the textarea that the editor is replacing + * with the value currently inside the editor. + * + * @function + * @name updateOriginal + * @since 1.4.0 + * @memberOf jQuery.sceditor.prototype + */ + base.updateOriginal = function () { + $original.val(base.val()); + }; + + /** + * Replaces any emoticon codes in the passed HTML + * with their emoticon images + * @private + */ + replaceEmoticons = function (node) { + // TODO: Make this tag configurable. + if (!options.emoticonsEnabled || $(node).parents('code').length) { + return; + } + + var doc = node.ownerDocument, + whitespace = '\\s|\xA0|\u2002|\u2003|\u2009| ', + emoticonCodes = [], + emoticonRegex = [], + emoticons = $.extend( + {}, + options.emoticons.more, + options.emoticons.dropdown, + options.emoticons.hidden + ); + // TODO: cache the emoticonCodes and emoticonCodes objects and share them with + // the AYT converstion + $.each(emoticons, function (key) { + if (options.emoticonsCompat) { + emoticonRegex[key] = new RegExp( + '(>|^|' + whitespace + ')' + + escape.regex(key) + + '($|<|' + whitespace + ')' + ); + } + + emoticonCodes.push(key); + }); + // TODO: tidy below + var convertEmoticons = function (node) { + node = node.firstChild; + + while (node) { + var parts, key, emoticon, parsedHtml, + emoticonIdx, nextSibling, matchPos, + nodeParent = node.parentNode, + nodeValue = node.nodeValue; + + // All none textnodes + if (node.nodeType !== 3) { + // TODO: Make this tag configurable. + if (!$(node).is('code')) { + convertEmoticons(node); + } + } else if (nodeValue) { + emoticonIdx = emoticonCodes.length; + while (emoticonIdx--) { + key = emoticonCodes[emoticonIdx]; + matchPos = options.emoticonsCompat ? + nodeValue.search(emoticonRegex[key]) : + nodeValue.indexOf(key); + + if (matchPos > -1) { + nextSibling = node.nextSibling; + emoticon = emoticons[key]; + parts = nodeValue + .substr(matchPos).split(key); + nodeValue = nodeValue + .substr(0, matchPos) + parts.shift(); + node.nodeValue = nodeValue; + + parsedHtml = dom.parseHTML(_tmpl('emoticon', { + key: key, + url: emoticon.url || emoticon, + tooltip: emoticon.tooltip || key + }), doc); + + nodeParent.insertBefore( + parsedHtml[0], + nextSibling + ); + + nodeParent.insertBefore( + doc.createTextNode(parts.join(key)), + nextSibling + ); + } + } + } + + node = node.nextSibling; + } + }; + + convertEmoticons(node); + + if (options.emoticonsCompat) { + currentEmoticons = $wysiwygBody + .find('img[data-sceditor-emoticon]'); + } + }; + + /** + * If the editor is in source code mode + * + * @return {bool} + * @function + * @name inSourceMode + * @memberOf jQuery.sceditor.prototype + */ + base.inSourceMode = function () { + return $editorContainer.hasClass('sourceMode'); + }; + + /** + * Gets if the editor is in sourceMode + * + * @return boolean + * @function + * @name sourceMode + * @memberOf jQuery.sceditor.prototype + */ + /** + * Sets if the editor is in sourceMode + * + * @param {bool} enable + * @return {this} + * @function + * @name sourceMode^2 + * @memberOf jQuery.sceditor.prototype + */ + base.sourceMode = function (enable) { + var inSourceMode = base.inSourceMode(); + + if (typeof enable !== 'boolean') { + return inSourceMode; + } + + if ((inSourceMode && !enable) || (!inSourceMode && enable)) { + base.toggleSourceMode(); + } + + return base; + }; + + /** + * Switches between the WYSIWYG and source modes + * + * @function + * @name toggleSourceMode + * @since 1.4.0 + * @memberOf jQuery.sceditor.prototype + */ + base.toggleSourceMode = function () { + var sourceMode = base.inSourceMode(); + + // don't allow switching to WYSIWYG if doesn't support it + if (!browser.isWysiwygSupported && sourceMode) { + return; + } + + if (!sourceMode) { + rangeHelper.saveRange(); + rangeHelper.clear(); + } + + base.blur(); + + if (sourceMode) { + base.setWysiwygEditorValue(base.getSourceEditorValue()); + } else { + base.setSourceEditorValue(base.getWysiwygEditorValue()); + } + + lastRange = null; + $sourceEditor.toggle(); + $wysiwygEditor.toggle(); + $editorContainer + .toggleClass('wysiwygMode', sourceMode) + .toggleClass('sourceMode', !sourceMode); + + updateToolBar(); + updateActiveButtons(); + }; + + /** + * Gets the selected text of the source editor + * @return {String} + * @private + */ + sourceEditorSelectedText = function () { + sourceEditor.focus(); + + if (typeof sourceEditor.selectionStart !== 'undefined') { + return sourceEditor.value.substring( + sourceEditor.selectionStart, + sourceEditor.selectionEnd + ); + } else { + return globalDoc.selection.createRange().text; + } + }; + + /** + * Handles the passed command + * @private + */ + handleCommand = function (caller, cmd) { + // check if in text mode and handle text commands + if (base.inSourceMode()) { + if (cmd.txtExec) { + if ($.isArray(cmd.txtExec)) { + base.sourceEditorInsertText.apply(base, cmd.txtExec); + } else { + cmd.txtExec.call( + base, + caller, + sourceEditorSelectedText() + ); + } + } + } else if (cmd.exec) { + if ($.isFunction(cmd.exec)) { + cmd.exec.call(base, caller); + } else { + base.execCommand( + cmd.exec, + cmd.hasOwnProperty('execParam') ? + cmd.execParam : null + ); + } + } + + }; + + /** + * Saves the current range. Needed for IE because it forgets + * where the cursor was and what was selected + * @private + */ + saveRange = function () { + /* this is only needed for IE */ + if (IE_VER) { + lastRange = rangeHelper.selectedRange(); + } + }; + + /** + * Executes a command on the WYSIWYG editor + * + * @param {String} command + * @param {String|Boolean} [param] + * @function + * @name execCommand + * @memberOf jQuery.sceditor.prototype + */ + base.execCommand = function (command, param) { + var executed = false, + commandObj = base.commands[command], + $parentNode = $(rangeHelper.parentNode()); + + base.focus(); + + // TODO: make configurable + // don't apply any commands to code elements + if ($parentNode.is('code') || + $parentNode.parents('code').length !== 0) { + return; + } + + try { + executed = $wysiwygDoc[0].execCommand(command, false, param); + } catch (ex) {} + + // show error if execution failed and an error message exists + if (!executed && commandObj && commandObj.errorMessage) { + /*global alert:false*/ + alert(base._(commandObj.errorMessage)); + } + + updateActiveButtons(); + }; + + /** + * Checks if the current selection has changed and triggers + * the selectionchanged event if it has. + * + * In browsers other than IE, it will check at most once every 100ms. + * This is because only IE has a selection changed event. + * @private + */ + checkSelectionChanged = function () { + function check () { + // rangeHelper could be null if editor was destroyed + // before the timeout had finished + if (rangeHelper && !rangeHelper.compare(currentSelection)) { + currentSelection = rangeHelper.cloneSelected(); + $editorContainer.trigger($.Event('selectionchanged')); + } + + isSelectionCheckPending = false; + } + + if (isSelectionCheckPending) { + return; + } + + isSelectionCheckPending = true; + + // In IE, this is only called on the selectionchange event so no + // need to limit checking as it should always be valid to do. + if (IE_VER) { + check(); + } else { + setTimeout(check, 100); + } + }; + + /** + * Checks if the current node has changed and triggers + * the nodechanged event if it has + * @private + */ + checkNodeChanged = function () { + // check if node has changed + var oldNode, + node = rangeHelper.parentNode(); + + if (currentNode !== node) { + oldNode = currentNode; + currentNode = node; + currentBlockNode = rangeHelper.getFirstBlockParent(node); + + $editorContainer.trigger($.Event('nodechanged', { + oldNode: oldNode, + newNode: currentNode + })); + } + }; + + /** + *

Gets the current node that contains the selection/caret in + * WYSIWYG mode.

+ * + *

Will be null in sourceMode or if there is no selection.

+ * @return {Node} + * @function + * @name currentNode + * @memberOf jQuery.sceditor.prototype + */ + base.currentNode = function () { + return currentNode; + }; + + /** + *

Gets the first block level node that contains the + * selection/caret in WYSIWYG mode.

+ * + *

Will be null in sourceMode or if there is no selection.

+ * @return {Node} + * @function + * @name currentBlockNode + * @memberOf jQuery.sceditor.prototype + * @since 1.4.4 + */ + base.currentBlockNode = function () { + return currentBlockNode; + }; + + /** + * Updates if buttons are active or not + * @private + */ + updateActiveButtons = function (e) { + var firstBlock, parent; + var activeClass = 'active'; + var doc = $wysiwygDoc[0]; + var isSource = base.sourceMode(); + + if (base.readOnly()) { + $toolbar.find(activeClass).removeClass(activeClass); + return; + } + + if (!isSource) { + parent = e ? e.newNode : rangeHelper.parentNode(); + firstBlock = rangeHelper.getFirstBlockParent(parent); + } + + for (var i = 0; i < btnStateHandlers.length; i++) { + var state = 0; + var $btn = toolbarButtons[btnStateHandlers[i].name]; + var stateFn = btnStateHandlers[i].state; + var isDisabled = (isSource && !$btn.data('sceditor-txtmode')) || + (!isSource && !$btn.data('sceditor-wysiwygmode')); + + if (typeof stateFn === 'string') { + if (!isSource) { + try { + state = doc.queryCommandEnabled(stateFn) ? 0 : -1; + + /*jshint maxdepth: false*/ + if (state > -1) { + state = doc.queryCommandState(stateFn) ? 1 : 0; + } + } catch (ex) {} + } + } else if (!isDisabled) { + state = stateFn.call(base, parent, firstBlock); + } + + $btn + .toggleClass('disabled', isDisabled || state < 0) + .toggleClass(activeClass, state > 0); + } + }; + + /** + * Handles any key press in the WYSIWYG editor + * + * @private + */ + handleKeyPress = function (e) { + var $closestTag, br, brParent, lastChild; + + // TODO: improve this so isn't set list, probably should just use + // dom.hasStyling to all block parents and if one does insert a br + var DUPLICATED_TAGS = 'code,blockquote,pre'; + var LIST_TAGS = 'li,ul,ol'; + + // FF bug: https://bugzilla.mozilla.org/show_bug.cgi?id=501496 + if (e.originalEvent.defaultPrevented) { + return; + } + + base.closeDropDown(); + + $closestTag = $(currentBlockNode) + .closest(DUPLICATED_TAGS + ',' + LIST_TAGS) + .first(); + + // "Fix" (OK it's a cludge) for blocklevel elements being + // duplicated in some browsers when enter is pressed instead + // of inserting a newline + if (e.which === 13 && $closestTag.length && + !$closestTag.is(LIST_TAGS)) { + lastRange = null; + + br = $wysiwygDoc[0].createElement('br'); + rangeHelper.insertNode(br); + + // Last
of a block will be collapsed unless it is + // IE < 11 so need to make sure the
that was inserted + // isn't the last node of a block. + if (!IE_BR_FIX) { + brParent = br.parentNode; + lastChild = brParent.lastChild; + + // Sometimes an empty next node is created after the
+ if (lastChild && lastChild.nodeType === 3 && + lastChild.nodeValue === '') { + brParent.removeChild(lastChild); + lastChild = brParent.lastChild; + } + + // If this is the last BR of a block and the previous + // sibling is inline then will need an extra BR. This + // is needed because the last BR of a block will be + // collapsed. Fixes issue #248 + if (!dom.isInline(brParent, true) && lastChild === br && + dom.isInline(br.previousSibling)) { + rangeHelper.insertHTML('
'); + } + } + + return false; + } + }; + + /** + * Makes sure that if there is a code or quote tag at the + * end of the editor, that there is a new line after it. + * + * If there wasn't a new line at the end you wouldn't be able + * to enter any text after a code/quote tag + * @return {void} + * @private + */ + appendNewLine = function () { + var name, requiresNewLine, paragraph, + body = $wysiwygBody[0]; + + dom.rTraverse(body, function (node) { + name = node.nodeName.toLowerCase(); + // TODO: Replace requireNewLineFix with just a block level fix for any + // block that has styling and any block that isn't a plain

or

+ if ($.inArray(name, requireNewLineFix) > -1) { + requiresNewLine = true; + } + // TODO: tidy this up + // find the last non-empty text node or line break. + if ((node.nodeType === 3 && !/^\s*$/.test(node.nodeValue)) || + name === 'br' || (IE_BR_FIX && !node.firstChild && + !dom.isInline(node, false))) { + + // this is the last text or br node, if its in a code or + // quote tag then add a newline to the end of the editor + if (requiresNewLine) { + paragraph = $wysiwygDoc[0].createElement('p'); + paragraph.className = 'sceditor-nlf'; + paragraph.innerHTML = !IE_BR_FIX ? '
' : ''; + body.appendChild(paragraph); + } + + return false; + } + }); + }; + + /** + * Handles form reset event + * @private + */ + handleFormReset = function () { + base.val($original.val()); + }; + + /** + * Handles any mousedown press in the WYSIWYG editor + * @private + */ + handleMouseDown = function () { + base.closeDropDown(); + lastRange = null; + }; + + /** + * Handles the window resize event. Needed to resize then editor + * when the window size changes in fluid designs. + * @ignore + */ + handleWindowResize = function () { + var height = options.height, + width = options.width; + + if (!base.maximize()) { + if ((height && height.toString().indexOf('%') > -1) || + (width && width.toString().indexOf('%') > -1)) { + base.dimensions(width, height); + } + } else { + base.dimensions('100%', '100%', false); + } + }; + + /** + * Translates the string into the locale language. + * + * Replaces any {0}, {1}, {2}, ect. with the params provided. + * + * @param {string} str + * @param {...String} args + * @return {string} + * @function + * @name _ + * @memberOf jQuery.sceditor.prototype + */ + base._ = function () { + var undef, + args = arguments; + + if (locale && locale[args[0]]) { + args[0] = locale[args[0]]; + } + + return args[0].replace(/\{(\d+)\}/g, function (str, p1) { + return args[p1 - 0 + 1] !== undef ? + args[p1 - 0 + 1] : + '{' + p1 + '}'; + }); + }; + + /** + * Passes events on to any handlers + * @private + * @return void + */ + handleEvent = function (e) { + // Send event to all plugins + pluginManager.call(e.type + 'Event', e, base); + + // convert the event into a custom event to send + var prefix = e.target === sourceEditor ? 'scesrc' : 'scewys'; + var customEvent = $.Event(e); + customEvent.type = prefix + e.type; + + $editorContainer.trigger(customEvent, base); + }; + + /** + *

Binds a handler to the specified events

+ * + *

This function only binds to a limited list of + * supported events.
+ * The supported events are: + *

    + *
  • keyup
  • + *
  • keydown
  • + *
  • Keypress
  • + *
  • blur
  • + *
  • focus
  • + *
  • nodechanged
    + * When the current node containing the selection changes + * in WYSIWYG mode
  • + *
  • contextmenu
  • + *
  • selectionchanged
  • + *
  • valuechanged
  • + *
+ *

+ * + *

The events param should be a string containing the event(s) + * to bind this handler to. If multiple, they should be separated + * by spaces.

+ * + * @param {String} events + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name bind + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.bind = function (events, handler, excludeWysiwyg, excludeSource) { + events = events.split(' '); + + var i = events.length; + while (i--) { + if ($.isFunction(handler)) { + // Use custom events to allow passing the instance as the + // 2nd argument. + // Also allows unbinding without unbinding the editors own + // event handlers. + if (!excludeWysiwyg) { + $editorContainer.on('scewys' + events[i], handler); + } + + if (!excludeSource) { + $editorContainer.on('scesrc' + events[i], handler); + } + + // Start sending value changed events + if (events[i] === 'valuechanged') { + triggerValueChanged.hasHandler = true; + } + } + } + + return base; + }; + + /** + * Unbinds an event that was bound using bind(). + * + * @param {String} events + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude unbinding this + * handler from the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude unbinding this + * handler from the source editor + * @return {this} + * @function + * @name unbind + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + * @see bind + */ + base.unbind = function ( + events, handler, excludeWysiwyg, excludeSource + ) { + events = events.split(' '); + + var i = events.length; + while (i--) { + if ($.isFunction(handler)) { + if (!excludeWysiwyg) { + $editorContainer.off('scewys' + events[i], handler); + } + + if (!excludeSource) { + $editorContainer.off('scesrc' + events[i], handler); + } + } + } + + return base; + }; + + /** + * Blurs the editors input area + * + * @return {this} + * @function + * @name blur + * @memberOf jQuery.sceditor.prototype + * @since 1.3.6 + */ + /** + * Adds a handler to the editors blur event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name blur^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.blur = function (handler, excludeWysiwyg, excludeSource) { + if ($.isFunction(handler)) { + base.bind('blur', handler, excludeWysiwyg, excludeSource); + } else if (!base.sourceMode()) { + $wysiwygBody.blur(); + } else { + $sourceEditor.blur(); + } + + return base; + }; + + /** + * Focuses the editors input area + * + * @return {this} + * @function + * @name focus + * @memberOf jQuery.sceditor.prototype + */ + /** + * Adds an event handler to the focus event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name focus^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.focus = function (handler, excludeWysiwyg, excludeSource) { + if ($.isFunction(handler)) { + base.bind('focus', handler, excludeWysiwyg, excludeSource); + } else if (!base.inSourceMode()) { + var container, + rng = rangeHelper.selectedRange(); + + // Fix FF bug where it shows the cursor in the wrong place + // if the editor hasn't had focus before. See issue #393 + if (!currentSelection && !rangeHelper.hasSelection()) { + autofocus(); + } + + // Check if cursor is set after a BR when the BR is the only + // child of the parent. In Firefox this causes a line break + // to occur when something is typed. See issue #321 + if (!IE_BR_FIX && rng && rng.endOffset === 1 && rng.collapsed) { + container = rng.endContainer; + + if (container && container.childNodes.length === 1 && + $(container.firstChild).is('br')) { + rng.setStartBefore(container.firstChild); + rng.collapse(true); + rangeHelper.selectRange(rng); + } + } + + wysiwygEditor.contentWindow.focus(); + $wysiwygBody[0].focus(); + + // Needed for IE < 9 + if (lastRange) { + rangeHelper.selectRange(lastRange); + + // remove the stored range after being set. + // If the editor loses focus it should be + // saved again. + lastRange = null; + } + } else { + sourceEditor.focus(); + } + + updateActiveButtons(); + + return base; + }; + + /** + * Adds a handler to the key down event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name keyDown + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.keyDown = function (handler, excludeWysiwyg, excludeSource) { + return base.bind('keydown', handler, excludeWysiwyg, excludeSource); + }; + + /** + * Adds a handler to the key press event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name keyPress + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.keyPress = function (handler, excludeWysiwyg, excludeSource) { + return base + .bind('keypress', handler, excludeWysiwyg, excludeSource); + }; + + /** + * Adds a handler to the key up event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name keyUp + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.keyUp = function (handler, excludeWysiwyg, excludeSource) { + return base.bind('keyup', handler, excludeWysiwyg, excludeSource); + }; + + /** + *

Adds a handler to the node changed event.

+ * + *

Happens whenever the node containing the selection/caret + * changes in WYSIWYG mode.

+ * + * @param {Function} handler + * @return {this} + * @function + * @name nodeChanged + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.nodeChanged = function (handler) { + return base.bind('nodechanged', handler, false, true); + }; + + /** + *

Adds a handler to the selection changed event

+ * + *

Happens whenever the selection changes in WYSIWYG mode.

+ * + * @param {Function} handler + * @return {this} + * @function + * @name selectionChanged + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.selectionChanged = function (handler) { + return base.bind('selectionchanged', handler, false, true); + }; + + /** + *

Adds a handler to the value changed event

+ * + *

Happens whenever the current editor value changes.

+ * + *

Whenever anything is inserted, the value changed or + * 1.5 secs after text is typed. If a space is typed it will + * cause the event to be triggered immediately instead of + * after 1.5 seconds

+ * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name valueChanged + * @memberOf jQuery.sceditor.prototype + * @since 1.4.5 + */ + base.valueChanged = function (handler, excludeWysiwyg, excludeSource) { + return base + .bind('valuechanged', handler, excludeWysiwyg, excludeSource); + }; + + /** + * Emoticons keypress handler + * @private + */ + emoticonsKeyPress = function (e) { + var replacedEmoticon, + cachePos = 0, + emoticonsCache = base.emoticonsCache, + curChar = String.fromCharCode(e.which); + // TODO: Make configurable + if ($(currentBlockNode).is('code') || + $(currentBlockNode).parents('code').length) { + return; + } + + if (!emoticonsCache) { + emoticonsCache = []; + + $.each($.extend( + {}, + options.emoticons.more, + options.emoticons.dropdown, + options.emoticons.hidden + ), function (key, url) { + emoticonsCache[cachePos++] = [ + key, + _tmpl('emoticon', { + key: key, + url: url.url || url, + tooltip: url.tooltip || key + }) + ]; + }); + + emoticonsCache.sort(function (a, b) { + return a[0].length - b[0].length; + }); + + base.emoticonsCache = emoticonsCache; + base.longestEmoticonCode = + emoticonsCache[emoticonsCache.length - 1][0].length; + } + + replacedEmoticon = rangeHelper.replaceKeyword( + base.emoticonsCache, + true, + true, + base.longestEmoticonCode, + options.emoticonsCompat, + curChar + ); + + if (replacedEmoticon && options.emoticonsCompat) { + currentEmoticons = $wysiwygBody + .find('img[data-sceditor-emoticon]'); + + return /^\s$/.test(curChar); + } + + return !replacedEmoticon; + }; + + /** + * Makes sure emoticons are surrounded by whitespace + * @private + */ + emoticonsCheckWhitespace = function () { + if (!currentEmoticons.length) { + return; + } + + var prev, next, parent, range, previousText, rangeStartContainer, + currentBlock = base.currentBlockNode(), + rangeStart = false, + noneWsRegex = /[^\s\xA0\u2002\u2003\u2009\u00a0]+/; + + currentEmoticons = $.map(currentEmoticons, function (emoticon) { + // Ignore emoticons that have been removed from DOM + if (!emoticon || !emoticon.parentNode) { + return null; + } + + if (!$.contains(currentBlock, emoticon)) { + return emoticon; + } + + prev = emoticon.previousSibling; + next = emoticon.nextSibling; + previousText = prev.nodeValue; + + // For IE's HTMLPhraseElement + if (previousText === null) { + previousText = prev.innerText || ''; + } + + if ((!prev || !noneWsRegex.test(prev.nodeValue.slice(-1))) && + (!next || !noneWsRegex.test((next.nodeValue || '')[0]))) { + return emoticon; + } + + parent = emoticon.parentNode; + range = rangeHelper.cloneSelected(); + rangeStartContainer = range.startContainer; + previousText = previousText + + $(emoticon).data('sceditor-emoticon'); + + // Store current caret position + if (rangeStartContainer === next) { + rangeStart = previousText.length + range.startOffset; + } else if (rangeStartContainer === currentBlock && + currentBlock.childNodes[range.startOffset] === next) { + rangeStart = previousText.length; + } else if (rangeStartContainer === prev) { + rangeStart = range.startOffset; + } + + if (!next || next.nodeType !== 3) { + next = parent.insertBefore( + parent.ownerDocument.createTextNode(''), next + ); + } + + next.insertData(0, previousText); + parent.removeChild(prev); + parent.removeChild(emoticon); + + // Need to update the range starting + // position if it has been modified + if (rangeStart !== false) { + range.setStart(next, rangeStart); + range.collapse(true); + rangeHelper.selectRange(range); + } + + return null; + }); + }; + + /** + * Gets if emoticons are currently enabled + * @return {boolean} + * @function + * @name emoticons + * @memberOf jQuery.sceditor.prototype + * @since 1.4.2 + */ + /** + * Enables/disables emoticons + * + * @param {boolean} enable + * @return {this} + * @function + * @name emoticons^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.2 + */ + base.emoticons = function (enable) { + if (!enable && enable !== false) { + return options.emoticonsEnabled; + } + + options.emoticonsEnabled = enable; + + if (enable) { + $wysiwygBody.keypress(emoticonsKeyPress); + + if (!base.sourceMode()) { + rangeHelper.saveRange(); + + replaceEmoticons($wysiwygBody[0]); + currentEmoticons = $wysiwygBody + .find('img[data-sceditor-emoticon]'); + triggerValueChanged(false); + + rangeHelper.restoreRange(); + } + } else { + $wysiwygBody + .find('img[data-sceditor-emoticon]') + .replaceWith(function () { + return $(this).data('sceditor-emoticon'); + }); + + currentEmoticons = []; + $wysiwygBody.off('keypress', emoticonsKeyPress); + + triggerValueChanged(); + } + + return base; + }; + + /** + * Gets the current WYSIWYG editors inline CSS + * + * @return {string} + * @function + * @name css + * @memberOf jQuery.sceditor.prototype + * @since 1.4.3 + */ + /** + * Sets inline CSS for the WYSIWYG editor + * + * @param {string} css + * @return {this} + * @function + * @name css^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.3 + */ + base.css = function (css) { + if (!inlineCss) { + inlineCss = $('' + + '' + + '' + + '' + + '

' + + '', + + toolbarButton: '' + + '
{dispName}
', + + emoticon: '', + + fontOpt: '{font}', + + sizeOpt: '{size}', + + pastetext: + '
' + + '
' + + '
' + + '
', + + table: + '
' + + '
' + + '
', + + image: + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
', + + email: + '
' + + '
' + + '
' + + '
' + + '
' + + '
', + + link: + '
' + + '
' + + '
' + + '
' + + '
', + + youtubeMenu: + '
' + + '
' + + '
' + + '
', + + youtube: + '' + }; + + /** + *

Replaces any params in a template with the passed params.

+ * + *

If createHtml is passed it will use jQuery to create the HTML. The + * same as doing: $(editor.tmpl("html", {params...}));

+ * + * @param {string} name + * @param {Object} params + * @param {Boolean} createHtml + * @private + */ + return function (name, params, createHtml) { + var template = _templates[name]; + + $.each(params, function (name, val) { + template = template.replace( + new RegExp('\\{' + name + '\\}', 'g'), val + ); + }); + + if (createHtml) { + template = $(template); + } + + return template; + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var IE_VER = __webpack_require__(6).ie; + var _tmpl = __webpack_require__(8); + + // In IE < 11 a BR at the end of a block level element + // causes a line break. In all other browsers it's collapsed. + var IE_BR_FIX = IE_VER && IE_VER < 11; + + + /** + * Map of all the commands for SCEditor + * @type {Object} + * @name commands + * @memberOf jQuery.sceditor + */ + var defaultCommnds = { + // START_COMMAND: Bold + bold: { + exec: 'bold', + tooltip: 'Bold', + shortcut: 'Ctrl+B' + }, + // END_COMMAND + // START_COMMAND: Italic + italic: { + exec: 'italic', + tooltip: 'Italic', + shortcut: 'Ctrl+I' + }, + // END_COMMAND + // START_COMMAND: Underline + underline: { + exec: 'underline', + tooltip: 'Underline', + shortcut: 'Ctrl+U' + }, + // END_COMMAND + // START_COMMAND: Strikethrough + strike: { + exec: 'strikethrough', + tooltip: 'Strikethrough' + }, + // END_COMMAND + // START_COMMAND: Subscript + subscript: { + exec: 'subscript', + tooltip: 'Subscript' + }, + // END_COMMAND + // START_COMMAND: Superscript + superscript: { + exec: 'superscript', + tooltip: 'Superscript' + }, + // END_COMMAND + + // START_COMMAND: Left + left: { + exec: 'justifyleft', + tooltip: 'Align left' + }, + // END_COMMAND + // START_COMMAND: Centre + center: { + exec: 'justifycenter', + tooltip: 'Center' + }, + // END_COMMAND + // START_COMMAND: Right + right: { + exec: 'justifyright', + tooltip: 'Align right' + }, + // END_COMMAND + // START_COMMAND: Justify + justify: { + exec: 'justifyfull', + tooltip: 'Justify' + }, + // END_COMMAND + + // START_COMMAND: Font + font: { + _dropDown: function (editor, caller, callback) { + var fontIdx = 0, + fonts = editor.opts.fonts.split(','), + content = $('
'), + /** @private */ + clickFunc = function () { + callback($(this).data('font')); + editor.closeDropDown(true); + return false; + }; + + for (; fontIdx < fonts.length; fontIdx++) { + content.append( + _tmpl('fontOpt', { + font: fonts[fontIdx] + }, true).click(clickFunc) + ); + } + + editor.createDropDown(caller, 'font-picker', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.font._dropDown( + editor, + caller, + function (fontName) { + editor.execCommand('fontname', fontName); + } + ); + }, + tooltip: 'Font Name' + }, + // END_COMMAND + // START_COMMAND: Size + size: { + _dropDown: function (editor, caller, callback) { + var content = $('
'), + /** @private */ + clickFunc = function (e) { + callback($(this).data('size')); + editor.closeDropDown(true); + e.preventDefault(); + }; + + for (var i = 1; i <= 7; i++) { + content.append(_tmpl('sizeOpt', { + size: i + }, true).click(clickFunc)); + } + + editor.createDropDown(caller, 'fontsize-picker', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.size._dropDown( + editor, + caller, + function (fontSize) { + editor.execCommand('fontsize', fontSize); + } + ); + }, + tooltip: 'Font Size' + }, + // END_COMMAND + // START_COMMAND: Colour + color: { + _dropDown: function (editor, caller, callback) { + var i, x, color, colors, + genColor = {r: 255, g: 255, b: 255}, + content = $('
'), + colorColumns = editor.opts.colors ? + editor.opts.colors.split('|') : new Array(21), + // IE is slow at string concatenation so use an array + html = [], + cmd = defaultCommnds.color; + + if (!cmd._htmlCache) { + for (i = 0; i < colorColumns.length; ++i) { + colors = colorColumns[i] ? + colorColumns[i].split(',') : new Array(21); + + html.push('
'); + + for (x = 0; x < colors.length; ++x) { + // use pre defined colour if can otherwise use the + // generated color + color = colors[x] || '#' + + genColor.r.toString(16) + + genColor.g.toString(16) + + genColor.b.toString(16); + + html.push( + '' + ); + + if (x % 5 === 0) { + genColor.g -= 51; + genColor.b = 255; + } else { + genColor.b -= 51; + } + } + + html.push('
'); + + if (i % 5 === 0) { + genColor.r -= 51; + genColor.g = 255; + genColor.b = 255; + } else { + genColor.g = 255; + genColor.b = 255; + } + } + + cmd._htmlCache = html.join(''); + } + + content.append(cmd._htmlCache) + .find('a') + .click(function (e) { + callback($(this).attr('data-color')); + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'color-picker', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.color._dropDown( + editor, + caller, + function (color) { + editor.execCommand('forecolor', color); + } + ); + }, + tooltip: 'Font Color' + }, + // END_COMMAND + // START_COMMAND: Remove Format + removeformat: { + exec: 'removeformat', + tooltip: 'Remove Formatting' + }, + // END_COMMAND + + // START_COMMAND: Cut + cut: { + exec: 'cut', + tooltip: 'Cut', + errorMessage: 'Your browser does not allow the cut command. ' + + 'Please use the keyboard shortcut Ctrl/Cmd-X' + }, + // END_COMMAND + // START_COMMAND: Copy + copy: { + exec: 'copy', + tooltip: 'Copy', + errorMessage: 'Your browser does not allow the copy command. ' + + 'Please use the keyboard shortcut Ctrl/Cmd-C' + }, + // END_COMMAND + // START_COMMAND: Paste + paste: { + exec: 'paste', + tooltip: 'Paste', + errorMessage: 'Your browser does not allow the paste command. ' + + 'Please use the keyboard shortcut Ctrl/Cmd-V' + }, + // END_COMMAND + // START_COMMAND: Paste Text + pastetext: { + exec: function (caller) { + var val, content, + editor = this; + + content = _tmpl('pastetext', { + label: editor._( + 'Paste your text inside the following box:' + ), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + val = content.find('#txt').val(); + + if (val) { + editor.wysiwygEditorInsertText(val); + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'pastetext', content); + }, + tooltip: 'Paste Text' + }, + // END_COMMAND + // START_COMMAND: Bullet List + bulletlist: { + exec: 'insertunorderedlist', + tooltip: 'Bullet list' + }, + // END_COMMAND + // START_COMMAND: Ordered List + orderedlist: { + exec: 'insertorderedlist', + tooltip: 'Numbered list' + }, + // END_COMMAND + // START_COMMAND: Indent + indent: { + state: function (parents, firstBlock) { + // Only works with lists, for now + // This is a nested list, so it will always work + var range, startParent, endParent, + $firstBlock = $(firstBlock), + parentLists = $firstBlock.parents('ul,ol,menu'), + parentList = parentLists.first(); + + // in case it's a list with only a single
  • + if (parentLists.length > 1 || + parentList.children().length > 1) { + return 0; + } + + if ($firstBlock.is('ul,ol,menu')) { + // if the whole list is selected, then this must be + // invalidated because the browser will place a + //
    there + range = this.getRangeHelper().selectedRange(); + + if (window.Range && range instanceof Range) { + startParent = range.startContainer.parentNode; + endParent = range.endContainer.parentNode; + + // TODO: could use nodeType for this? + // Maybe just check the firstBlock contains both the start and end containers + // Select the tag, not the textNode + // (that's why the parentNode) + if (startParent !== + startParent.parentNode.firstElementChild || + // work around a bug in FF + ($(endParent).is('li') && endParent !== + endParent.parentNode.lastElementChild)) { + return 0; + } + // it's IE... As it is impossible to know well when to + // accept, better safe than sorry + } else { + return $firstBlock.is('li,ul,ol,menu') ? 0 : -1; + } + } + + return -1; + }, + exec: function () { + var editor = this, + $elm = $(editor.getRangeHelper().getFirstBlockParent()); + + editor.focus(); + + // An indent system is quite complicated as there are loads + // of complications and issues around how to indent text + // As default, let's just stay with indenting the lists, + // at least, for now. + if ($elm.parents('ul,ol,menu')) { + editor.execCommand('indent'); + } + }, + tooltip: 'Add indent' + }, + // END_COMMAND + // START_COMMAND: Outdent + outdent: { + state: function (parents, firstBlock) { + return $(firstBlock).is('ul,ol,menu') || + $(firstBlock).parents('ul,ol,menu').length > 0 ? 0 : -1; + }, + exec: function () { + var editor = this, + $elm = $(editor.getRangeHelper().getFirstBlockParent()); + + if ($elm.parents('ul,ol,menu')) { + editor.execCommand('outdent'); + } + }, + tooltip: 'Remove one indent' + }, + // END_COMMAND + + // START_COMMAND: Table + table: { + forceNewLineAfter: ['table'], + exec: function (caller) { + var editor = this, + content = _tmpl('table', { + rows: editor._('Rows:'), + cols: editor._('Cols:'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var row, col, + rows = content.find('#rows').val() - 0, + cols = content.find('#cols').val() - 0, + html = ''; + + if (rows < 1 || cols < 1) { + return; + } + + for (row = 0; row < rows; row++) { + html += ''; + + for (col = 0; col < cols; col++) { + html += ''; + } + + html += ''; + } + + html += '
    ' + + (IE_BR_FIX ? '' : '
    ') + + '
    '; + + editor.wysiwygEditorInsertHtml(html); + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'inserttable', content); + }, + tooltip: 'Insert a table' + }, + // END_COMMAND + + // START_COMMAND: Horizontal Rule + horizontalrule: { + exec: 'inserthorizontalrule', + tooltip: 'Insert a horizontal rule' + }, + // END_COMMAND + + // START_COMMAND: Code + code: { + forceNewLineAfter: ['code'], + exec: function () { + this.wysiwygEditorInsertHtml( + '', + (IE_BR_FIX ? '' : '
    ') + '
    ' + ); + }, + tooltip: 'Code' + }, + // END_COMMAND + + // START_COMMAND: Image + image: { + exec: function (caller) { + var editor = this, + content = _tmpl('image', { + url: editor._('URL:'), + width: editor._('Width (optional):'), + height: editor._('Height (optional):'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content.find('#image').val(), + width = content.find('#width').val(), + height = content.find('#height').val(), + attrs = ''; + + if (width) { + attrs += ' width="' + width + '"'; + } + + if (height) { + attrs += ' height="' + height + '"'; + } + + if (val) { + editor.wysiwygEditorInsertHtml( + '' + ); + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertimage', content); + }, + tooltip: 'Insert an image' + }, + // END_COMMAND + + // START_COMMAND: E-mail + email: { + exec: function (caller) { + var editor = this, + content = _tmpl('email', { + label: editor._('E-mail:'), + desc: editor._('Description (optional):'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content.find('#email').val(), + description = content.find('#des').val(); + + if (val) { + // needed for IE to reset the last range + editor.focus(); + + if (!editor.getRangeHelper().selectedHtml() || + description) { + description = description || val; + + editor.wysiwygEditorInsertHtml( + '' + + description + + '' + ); + } else { + editor.execCommand('createlink', 'mailto:' + val); + } + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertemail', content); + }, + tooltip: 'Insert an email' + }, + // END_COMMAND + + // START_COMMAND: Link + link: { + exec: function (caller) { + var editor = this, + content = _tmpl('link', { + url: editor._('URL:'), + desc: editor._('Description (optional):'), + ins: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content.find('#link').val(), + description = content.find('#des').val(); + + if (val) { + // needed for IE to restore the last range + editor.focus(); + + // If there is no selected text then must set the URL as + // the text. Most browsers do this automatically, sadly + // IE doesn't. + if (!editor.getRangeHelper().selectedHtml() || + description) { + description = description || val; + + editor.wysiwygEditorInsertHtml( + '' + description + '' + ); + } else { + editor.execCommand('createlink', val); + } + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertlink', content); + }, + tooltip: 'Insert a link' + }, + // END_COMMAND + + // START_COMMAND: Unlink + unlink: { + state: function () { + var $current = $(this.currentNode()); + return $current.is('a') || + $current.parents('a').length > 0 ? 0 : -1; + }, + exec: function () { + var $current = $(this.currentNode()), + $anchor = $current.is('a') ? $current : + $current.parents('a').first(); + + if ($anchor.length) { + $anchor.replaceWith($anchor.contents()); + } + }, + tooltip: 'Unlink' + }, + // END_COMMAND + + + // START_COMMAND: Quote + quote: { + forceNewLineAfter: ['blockquote'], + exec: function (caller, html, author) { + var before = '
    ', + end = '
    '; + + // if there is HTML passed set end to null so any selected + // text is replaced + if (html) { + author = (author ? '' + author + '' : ''); + before = before + author + html + end; + end = null; + // if not add a newline to the end of the inserted quote + } else if (this.getRangeHelper().selectedHtml() === '') { + end = (IE_BR_FIX ? '' : '
    ') + end; + } + + this.wysiwygEditorInsertHtml(before, end); + }, + tooltip: 'Insert a Quote' + }, + // END_COMMAND + + // START_COMMAND: Emoticons + emoticon: { + exec: function (caller) { + var editor = this; + + var createContent = function (includeMore) { + var $moreLink, + emoticonsCompat = editor.opts.emoticonsCompat, + rangeHelper = editor.getRangeHelper(), + startSpace = emoticonsCompat && + rangeHelper.getOuterText(true, 1) !== ' ' ? + ' ' : '', + endSpace = emoticonsCompat && + rangeHelper.getOuterText(false, 1) !== ' ' ? + ' ' : '', + $content = $('
    '), + $line = $('
    ').appendTo($content), + perLine = 0, + emoticons = $.extend( + {}, + editor.opts.emoticons.dropdown, + includeMore ? editor.opts.emoticons.more : {} + ); + + $.each(emoticons, function () { + perLine++; + }); + perLine = Math.sqrt(perLine); + + $.each(emoticons, function (code, emoticon) { + $line.append( + $('').attr({ + src: emoticon.url || emoticon, + alt: code, + title: emoticon.tooltip || code + }).click(function () { + editor.insert(startSpace + $(this).attr('alt') + + endSpace, null, false).closeDropDown(true); + + return false; + }) + ); + + if ($line.children().length >= perLine) { + $line = $('
    ').appendTo($content); + } + }); + + if (!includeMore && editor.opts.emoticons.more) { + $moreLink = $( + '' + + editor._('More') + '' + ).click(function () { + editor.createDropDown( + caller, + 'more-emoticons', + createContent(true) + ); + + return false; + }); + + $content.append($moreLink); + } + + return $content; + }; + + editor.createDropDown( + caller, + 'emoticons', + createContent(false) + ); + }, + txtExec: function (caller) { + defaultCommnds.emoticon.exec.call(this, caller); + }, + tooltip: 'Insert an emoticon' + }, + // END_COMMAND + + // START_COMMAND: YouTube + youtube: { + _dropDown: function (editor, caller, handleIdFunc) { + var matches, + content = _tmpl('youtubeMenu', { + label: editor._('Video URL:'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content + .find('#link') + .val(); + + if (val) { + matches = val.match( + /(?:v=|v\/|embed\/|youtu.be\/)(.{11})/ + ); + + if (matches) { + val = matches[1]; + } + + if (/^[a-zA-Z0-9_\-]{11}$/.test(val)) { + handleIdFunc(val); + } else { + /*global alert:false*/ + alert('Invalid YouTube video'); + } + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertlink', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.youtube._dropDown( + editor, + caller, + function (id) { + editor.wysiwygEditorInsertHtml(_tmpl('youtube', { + id: id + })); + } + ); + }, + tooltip: 'Insert a YouTube video' + }, + // END_COMMAND + + // START_COMMAND: Date + date: { + _date: function (editor) { + var now = new Date(), + year = now.getYear(), + month = now.getMonth() + 1, + day = now.getDate(); + + if (year < 2000) { + year = 1900 + year; + } + + if (month < 10) { + month = '0' + month; + } + + if (day < 10) { + day = '0' + day; + } + + return editor.opts.dateFormat + .replace(/year/i, year) + .replace(/month/i, month) + .replace(/day/i, day); + }, + exec: function () { + this.insertText(defaultCommnds.date._date(this)); + }, + txtExec: function () { + this.insertText(defaultCommnds.date._date(this)); + }, + tooltip: 'Insert current date' + }, + // END_COMMAND + + // START_COMMAND: Time + time: { + _time: function () { + var now = new Date(), + hours = now.getHours(), + mins = now.getMinutes(), + secs = now.getSeconds(); + + if (hours < 10) { + hours = '0' + hours; + } + + if (mins < 10) { + mins = '0' + mins; + } + + if (secs < 10) { + secs = '0' + secs; + } + + return hours + ':' + mins + ':' + secs; + }, + exec: function () { + this.insertText(defaultCommnds.time._time()); + }, + txtExec: function () { + this.insertText(defaultCommnds.time._time()); + }, + tooltip: 'Insert current time' + }, + // END_COMMAND + + + // START_COMMAND: Ltr + ltr: { + state: function (parents, firstBlock) { + return firstBlock && firstBlock.style.direction === 'ltr'; + }, + exec: function () { + var editor = this, + elm = editor.getRangeHelper().getFirstBlockParent(), + $elm = $(elm); + + editor.focus(); + + if (!elm || $elm.is('body')) { + editor.execCommand('formatBlock', 'p'); + + elm = editor.getRangeHelper().getFirstBlockParent(); + $elm = $(elm); + + if (!elm || $elm.is('body')) { + return; + } + } + + if ($elm.css('direction') === 'ltr') { + $elm.css('direction', ''); + } else { + $elm.css('direction', 'ltr'); + } + }, + tooltip: 'Left-to-Right' + }, + // END_COMMAND + + // START_COMMAND: Rtl + rtl: { + state: function (parents, firstBlock) { + return firstBlock && firstBlock.style.direction === 'rtl'; + }, + exec: function () { + var editor = this, + elm = editor.getRangeHelper().getFirstBlockParent(), + $elm = $(elm); + + editor.focus(); + + if (!elm || $elm.is('body')) { + editor.execCommand('formatBlock', 'p'); + + elm = editor.getRangeHelper().getFirstBlockParent(); + $elm = $(elm); + + if (!elm || $elm.is('body')) { + return; + } + } + + if ($elm.css('direction') === 'rtl') { + $elm.css('direction', ''); + } else { + $elm.css('direction', 'rtl'); + } + }, + tooltip: 'Right-to-Left' + }, + // END_COMMAND + + + // START_COMMAND: Print + print: { + exec: 'print', + tooltip: 'Print' + }, + // END_COMMAND + + // START_COMMAND: Maximize + maximize: { + state: function () { + return this.maximize(); + }, + exec: function () { + this.maximize(!this.maximize()); + }, + txtExec: function () { + this.maximize(!this.maximize()); + }, + tooltip: 'Maximize', + shortcut: 'Ctrl+Shift+M' + }, + // END_COMMAND + + // START_COMMAND: Source + source: { + state: function () { + return this.sourceMode(); + }, + exec: function () { + this.toggleSourceMode(); + }, + txtExec: function () { + this.toggleSourceMode(); + }, + tooltip: 'View source', + shortcut: 'Ctrl+Shift+S' + }, + // END_COMMAND + + // this is here so that commands above can be removed + // without having to remove the , after the last one. + // Needed for IE. + ignore: {} + }; + + return defaultCommnds; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + + + /** + * Default options for SCEditor + * @type {Object} + */ + return { + /** @lends jQuery.sceditor.defaultOptions */ + /** + * Toolbar buttons order and groups. Should be comma separated and + * have a bar | to separate groups + * + * @type {String} + */ + toolbar: 'bold,italic,underline,strike,subscript,superscript|' + + 'left,center,right,justify|font,size,color,removeformat|' + + 'cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|' + + 'table|code,quote|horizontalrule,image,email,link,unlink|' + + 'emoticon,youtube,date,time|ltr,rtl|print,maximize,source', + + /** + * Comma separated list of commands to excludes from the toolbar + * + * @type {String} + */ + toolbarExclude: null, + + /** + * Stylesheet to include in the WYSIWYG editor. This is what will style + * the WYSIWYG elements + * + * @type {String} + */ + style: 'jquery.sceditor.default.css', + + /** + * Comma separated list of fonts for the font selector + * + * @type {String} + */ + fonts: 'Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,' + + 'Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana', + + /** + * Colors should be comma separated and have a bar | to signal a new + * column. + * + * If null the colors will be auto generated. + * + * @type {string} + */ + colors: null, + + /** + * The locale to use. + * @type {String} + */ + locale: $('html').attr('lang') || 'en', + + /** + * The Charset to use + * @type {String} + */ + charset: 'utf-8', + + /** + * Compatibility mode for emoticons. + * + * Helps if you have emoticons such as :/ which would put an emoticon + * inside http:// + * + * This mode requires emoticons to be surrounded by whitespace or end of + * line chars. This mode has limited As You Type emoticon conversion + * support. It will not replace AYT for end of line chars, only + * emoticons surrounded by whitespace. They will still be replaced + * correctly when loaded just not AYT. + * + * @type {Boolean} + */ + emoticonsCompat: false, + + /** + * If to enable emoticons. Can be changes at runtime using the + * emoticons() method. + * + * @type {Boolean} + * @since 1.4.2 + */ + emoticonsEnabled: true, + + /** + * Emoticon root URL + * + * @type {String} + */ + emoticonsRoot: '', + emoticons: { + dropdown: { + ':)': 'emoticons/smile.png', + ':angel:': 'emoticons/angel.png', + ':angry:': 'emoticons/angry.png', + '8-)': 'emoticons/cool.png', + ':\'(': 'emoticons/cwy.png', + ':ermm:': 'emoticons/ermm.png', + ':D': 'emoticons/grin.png', + '<3': 'emoticons/heart.png', + ':(': 'emoticons/sad.png', + ':O': 'emoticons/shocked.png', + ':P': 'emoticons/tongue.png', + ';)': 'emoticons/wink.png' + }, + more: { + ':alien:': 'emoticons/alien.png', + ':blink:': 'emoticons/blink.png', + ':blush:': 'emoticons/blush.png', + ':cheerful:': 'emoticons/cheerful.png', + ':devil:': 'emoticons/devil.png', + ':dizzy:': 'emoticons/dizzy.png', + ':getlost:': 'emoticons/getlost.png', + ':happy:': 'emoticons/happy.png', + ':kissing:': 'emoticons/kissing.png', + ':ninja:': 'emoticons/ninja.png', + ':pinch:': 'emoticons/pinch.png', + ':pouty:': 'emoticons/pouty.png', + ':sick:': 'emoticons/sick.png', + ':sideways:': 'emoticons/sideways.png', + ':silly:': 'emoticons/silly.png', + ':sleeping:': 'emoticons/sleeping.png', + ':unsure:': 'emoticons/unsure.png', + ':woot:': 'emoticons/w00t.png', + ':wassat:': 'emoticons/wassat.png' + }, + hidden: { + ':whistling:': 'emoticons/whistling.png', + ':love:': 'emoticons/wub.png' + } + }, + + /** + * Width of the editor. Set to null for automatic with + * + * @type {int} + */ + width: null, + + /** + * Height of the editor including toolbar. Set to null for automatic + * height + * + * @type {int} + */ + height: null, + + /** + * If to allow the editor to be resized + * + * @type {Boolean} + */ + resizeEnabled: true, + + /** + * Min resize to width, set to null for half textarea width or -1 for + * unlimited + * + * @type {int} + */ + resizeMinWidth: null, + /** + * Min resize to height, set to null for half textarea height or -1 for + * unlimited + * + * @type {int} + */ + resizeMinHeight: null, + /** + * Max resize to height, set to null for double textarea height or -1 + * for unlimited + * + * @type {int} + */ + resizeMaxHeight: null, + /** + * Max resize to width, set to null for double textarea width or -1 for + * unlimited + * + * @type {int} + */ + resizeMaxWidth: null, + /** + * If resizing by height is enabled + * + * @type {Boolean} + */ + resizeHeight: true, + /** + * If resizing by width is enabled + * + * @type {Boolean} + */ + resizeWidth: true, + + /** + * Date format, will be overridden if locale specifies one. + * + * The words year, month and day will be replaced with the users current + * year, month and day. + * + * @type {String} + */ + dateFormat: 'year-month-day', + + /** + * Element to inset the toolbar into. + * + * @type {HTMLElement} + */ + toolbarContainer: null, + + /** + * If to enable paste filtering. This is currently experimental, please + * report any issues. + * + * @type {Boolean} + */ + enablePasteFiltering: false, + + /** + * If to completely disable pasting into the editor + * + * @type {Boolean} + */ + disablePasting: false, + + /** + * If the editor is read only. + * + * @type {Boolean} + */ + readOnly: false, + + /** + * If to set the editor to right-to-left mode. + * + * If set to null the direction will be automatically detected. + * + * @type {Boolean} + */ + rtl: false, + + /** + * If to auto focus the editor on page load + * + * @type {Boolean} + */ + autofocus: false, + + /** + * If to auto focus the editor to the end of the content + * + * @type {Boolean} + */ + autofocusEnd: true, + + /** + * If to auto expand the editor to fix the content + * + * @type {Boolean} + */ + autoExpand: false, + + /** + * If to auto update original textbox on blur + * + * @type {Boolean} + */ + autoUpdate: false, + + /** + * If to enable the browsers built in spell checker + * + * @type {Boolean} + */ + spellcheck: true, + + /** + * If to run the source editor when there is no WYSIWYG support. Only + * really applies to mobile OS's. + * + * @type {Boolean} + */ + runWithoutWysiwygSupport: false, + + /** + * If to load the editor in source mode and still allow switching + * between WYSIWYG and source mode + * + * @type {Boolean} + */ + startInSourceMode: false, + + /** + * Optional ID to give the editor. + * + * @type {String} + */ + id: null, + + /** + * Comma separated list of plugins + * + * @type {String} + */ + plugins: '', + + /** + * z-index to set the editor container to. Needed for jQuery UI dialog. + * + * @type {Int} + */ + zIndex: null, + + /** + * If to trim the BBCode. Removes any spaces at the start and end of the + * BBCode string. + * + * @type {Boolean} + */ + bbcodeTrim: false, + + /** + * If to disable removing block level elements by pressing backspace at + * the start of them + * + * @type {Boolean} + */ + disableBlockRemove: false, + + /** + * BBCode parser options, only applies if using the editor in BBCode + * mode. + * + * See SCEditor.BBCodeParser.defaults for list of valid options + * + * @type {Object} + */ + parserOptions: { }, + + /** + * CSS that will be added to the to dropdown menu (eg. z-index) + * + * @type {Object} + */ + dropDownCss: { } + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ } +/******/ ]);;/** + * SCEditor BBCode Plugin + * http://www.sceditor.com/ + * + * Copyright (C) 2011-2014, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * @fileoverview SCEditor BBCode Plugin + * @author Sam Clarke + * @requires jQuery + */ +/*global prompt: true*/ +/*jshint maxdepth: false*/ +// TODO: Tidy this code up and consider seperating the BBCode parser into a +// standalone module that can be used with other JS/NodeJS +(function ($, window, document) { + 'use strict'; + + var SCEditor = $.sceditor; + var sceditorPlugins = SCEditor.plugins; + var escapeEntities = SCEditor.escapeEntities; + var escapeUriScheme = SCEditor.escapeUriScheme; + + var IE_VER = SCEditor.ie; + + // In IE < 11 a BR at the end of a block level element + // causes a double line break. + var IE_BR_FIX = IE_VER && IE_VER < 11; + + + + var getEditorCommand = SCEditor.command.get; + + var defaultCommandsOverrides = { + bold: { + txtExec: ['[b]', '[/b]'] + }, + italic: { + txtExec: ['[i]', '[/i]'] + }, + underline: { + txtExec: ['[u]', '[/u]'] + }, + strike: { + txtExec: ['[s]', '[/s]'] + }, + subscript: { + txtExec: ['[sub]', '[/sub]'] + }, + superscript: { + txtExec: ['[sup]', '[/sup]'] + }, + left: { + txtExec: ['[left]', '[/left]'] + }, + center: { + txtExec: ['[center]', '[/center]'] + }, + right: { + txtExec: ['[right]', '[/right]'] + }, + justify: { + txtExec: ['[justify]', '[/justify]'] + }, + font: { + txtExec: function (caller) { + var editor = this; + + getEditorCommand('font')._dropDown( + editor, + caller, + function (fontName) { + editor.insertText( + '[font=' + fontName + ']', + '[/font]' + ); + } + ); + } + }, + size: { + txtExec: function (caller) { + var editor = this; + + getEditorCommand('size')._dropDown( + editor, + caller, + function (fontSize) { + editor.insertText( + '[size=' + fontSize + ']', + '[/size]' + ); + } + ); + } + }, + color: { + txtExec: function (caller) { + var editor = this; + + getEditorCommand('color')._dropDown( + editor, + caller, + function (color) { + editor.insertText( + '[color=' + color + ']', + '[/color]' + ); + } + ); + } + }, + bulletlist: { + txtExec: function (caller, selected) { + var content = ''; + + $.each(selected.split(/\r?\n/), function () { + content += (content ? '\n' : '') + + '[li]' + this + '[/li]'; + }); + + this.insertText('[ul]\n' + content + '\n[/ul]'); + } + }, + orderedlist: { + txtExec: function (caller, selected) { + var content = ''; + + $.each(selected.split(/\r?\n/), function () { + content += (content ? '\n' : '') + + '[li]' + this + '[/li]'; + }); + + sceditorPlugins.bbcode.bbcode.get(''); + + this.insertText('[ol]\n' + content + '\n[/ol]'); + } + }, + table: { + txtExec: ['[table][tr][td]', '[/td][/tr][/table]'] + }, + horizontalrule: { + txtExec: ['[hr]'] + }, + code: { + txtExec: ['[code]', '[/code]'] + }, + image: { + txtExec: function (caller, selected) { + var editor = this, + url = prompt(editor._('Enter the image URL:'), selected); + + if (url) { + editor.insertText('[img]' + url + '[/img]'); + } + } + }, + email: { + txtExec: function (caller, selected) { + var editor = this, + display = selected && selected.indexOf('@') > -1 ? + null : selected, + email = prompt(editor._('Enter the e-mail address:'), + (display ? '' : selected)), + text = prompt(editor._('Enter the displayed text:'), + display || email) || email; + + if (email) { + editor.insertText('[email=' + email + ']' + + text + '[/email]'); + } + } + }, + link: { + txtExec: function (caller, selected) { + var editor = this, + display = /^[a-z]+:\/\//i.test($.trim(selected)) ? + null : selected, + url = prompt(editor._('Enter URL:'), + (display ? 'http://' : $.trim(selected))), + text = prompt(editor._('Enter the displayed text:'), + display || url) || url; + + if (url) { + editor.insertText('[url=' + url + ']' + text + '[/url]'); + } + } + }, + quote: { + txtExec: ['[quote]', '[/quote]'] + }, + youtube: { + txtExec: function (caller) { + var editor = this; + + getEditorCommand('youtube')._dropDown( + editor, + caller, + function (id) { + editor.insertText('[youtube]' + id + '[/youtube]'); + } + ); + } + }, + rtl: { + txtExec: ['[rtl]', '[/rtl]'] + }, + ltr: { + txtExec: ['[ltr]', '[/ltr]'] + } + }; + + /** + * Removes any leading or trailing quotes ('") + * + * @return string + * @since v1.4.0 + */ + var _stripQuotes = function (str) { + return str ? + str.replace(/\\(.)/g, '$1').replace(/^(["'])(.*?)\1$/, '$2') : str; + }; + + /** + * Formats a string replacing {0}, {1}, {2}, ect. with + * the params provided + * + * @param {String} str The string to format + * @param {string} args... The strings to replace + * @return {String} + * @since v1.4.0 + */ + var _formatString = function () { + var undef; + var args = arguments; + + return args[0].replace(/\{(\d+)\}/g, function (str, p1) { + return args[p1 - 0 + 1] !== undef ? + args[p1 - 0 + 1] : + '{' + p1 + '}'; + }); + }; + + /** + * Enum of valid token types + * @type {Object} + * @private + */ + var TokenType = { + OPEN: 'open', + CONTENT: 'content', + NEWLINE: 'newline', + CLOSE: 'close' + }; + + + /** + * Tokenize token object + * + * @param {String} type The type of token this is, + * should be one of tokenType + * @param {String} name The name of this token + * @param {String} val The originally matched string + * @param {Array} attrs Any attributes. Only set on + * TokenType.OPEN tokens + * @param {Array} children Any children of this token + * @param {TokenizeToken} closing This tokens closing tag. + * Only set on TokenType.OPEN tokens + * @class TokenizeToken + * @name TokenizeToken + * @memberOf jQuery.sceditor.BBCodeParser.prototype + */ + var TokenizeToken = function ( + /*jshint maxparams: false*/ + type, name, val, attrs, children, closing + ) { + var base = this; + + base.type = type; + base.name = name; + base.val = val; + base.attrs = attrs || {}; + base.children = children || []; + base.closing = closing || null; + }; + + TokenizeToken.prototype = { + /** @lends jQuery.sceditor.BBCodeParser.prototype.TokenizeToken */ + /** + * Clones this token + * + * @param {Bool} includeChildren If to include the children in + * the clone. Defaults to false. + * @return {TokenizeToken} + */ + clone: function (includeChildren) { + var base = this; + + return new TokenizeToken( + base.type, + base.name, + base.val, + base.attrs, + includeChildren ? base.children : [], + base.closing ? base.closing.clone() : null + ); + }, + /** + * Splits this token at the specified child + * + * @param {TokenizeToken|Int} splitAt The child to split at or the + * index of the child + * @return {TokenizeToken} The right half of the split token or + * null if failed + */ + splitAt: function (splitAt) { + var clone; + var base = this; + var splitAtLength = 0; + var childrenLen = base.children.length; + + if (typeof splitAt !== 'number') { + splitAt = $.inArray(splitAt, base.children); + } + + if (splitAt < 0 || splitAt > childrenLen) { + return null; + } + + // Work out how many items are on the right side of the split + // to pass to splice() + while (childrenLen--) { + if (childrenLen >= splitAt) { + splitAtLength++; + } else { + childrenLen = 0; + } + } + + clone = base.clone(); + clone.children = base.children.splice(splitAt, splitAtLength); + return clone; + } + }; + + + /** + * SCEditor BBCode parser class + * + * @param {Object} options + * @class BBCodeParser + * @name jQuery.sceditor.BBCodeParser + * @since v1.4.0 + */ + var BBCodeParser = function (options) { + // make sure this is not being called as a function + if (!(this instanceof BBCodeParser)) { + return new BBCodeParser(options); + } + + var base = this; + + // Private methods + var init, + tokenizeTag, + tokenizeAttrs, + parseTokens, + normaliseNewLines, + fixNesting, + isChildAllowed, + removeEmpty, + fixChildren, + convertToHTML, + convertToBBCode, + hasTag, + quote, + lower, + last; + + + init = function () { + base.bbcodes = sceditorPlugins.bbcode.bbcodes; + base.opts = $.extend( + {}, + BBCodeParser.defaults, + options + ); + }; + + /** + * Takes a BBCode string and splits it into open, + * content and close tags. + * + * It does no checking to verify a tag has a matching open + * or closing tag or if the tag is valid child of any tag + * before it. For that the tokens should be passed to the + * parse function. + * + * @param {String} str + * @return {Array} + * @memberOf jQuery.sceditor.BBCodeParser.prototype + */ + base.tokenize = function (str) { + var matches, type, i; + var toks = []; + var tokens = [ + // Close must come before open as they are + // the same except close has a / at the start. + { + type: TokenType.CLOSE, + regex: /^\[\/[^\[\]]+\]/ + }, + { + type: TokenType.OPEN, + regex: /^\[[^\[\]]+\]/ + }, + { + type: TokenType.NEWLINE, + regex: /^(\r\n|\r|\n)/ + }, + { + type: TokenType.CONTENT, + regex: /^([^\[\r\n]+|\[)/ + } + ]; + + tokens.reverse(); + + strloop: + while (str.length) { + i = tokens.length; + while (i--) { + type = tokens[i].type; + + // Check if the string matches any of the tokens + if (!(matches = str.match(tokens[i].regex)) || + !matches[0]) { + continue; + } + + // Add the match to the tokens list + toks.push(tokenizeTag(type, matches[0])); + + // Remove the match from the string + str = str.substr(matches[0].length); + + // The token has been added so start again + continue strloop; + } + + // If there is anything left in the string which doesn't match + // any of the tokens then just assume it's content and add it. + if (str.length) { + toks.push(tokenizeTag(TokenType.CONTENT, str)); + } + + str = ''; + } + + return toks; + }; + + /** + * Extracts the name an params from a tag + * + * @param {tokenType} type + * @param {string} val + * @return {Object} + * @private + */ + tokenizeTag = function (type, val) { + var matches, attrs, name, + openRegex = /\[([^\]\s=]+)(?:([^\]]+))?\]/, + closeRegex = /\[\/([^\[\]]+)\]/; + + // Extract the name and attributes from opening tags and + // just the name from closing tags. + if (type === TokenType.OPEN && (matches = val.match(openRegex))) { + name = lower(matches[1]); + + if (matches[2] && (matches[2] = $.trim(matches[2]))) { + attrs = tokenizeAttrs(matches[2]); + } + } + + if (type === TokenType.CLOSE && (matches = val.match(closeRegex))) { + name = lower(matches[1]); + } + + if (type === TokenType.NEWLINE) { + name = '#newline'; + } + + // Treat all tokens without a name and + // all unknown BBCodes as content + if (!name || + ((type === TokenType.OPEN || type === TokenType.CLOSE) && + !sceditorPlugins.bbcode.bbcodes[name])) { + type = TokenType.CONTENT; + name = '#'; + } + + return new TokenizeToken(type, name, val, attrs); + }; + + /** + * Extracts the individual attributes from a string containing + * all the attributes. + * + * @param {String} attrs + * @return {Array} Assoc array of attributes + * @private + */ + tokenizeAttrs = function (attrs) { + var matches, + /* + ([^\s=]+) Anything that's not a space or equals + = Equals sign = + (?: + (?: + (["']) The opening quote + ( + (?:\\\2|[^\2])*? Anything that isn't the + unescaped opening quote + ) + \2 The opening quote again which + will close the string + ) + | If not a quoted string then match + ( + (?:.(?!\s\S+=))*.? Anything that isn't part of + [space][non-space][=] which + would be a new attribute + ) + ) + */ + attrRegex = + /([^\s=]+)=(?:(?:(["'])((?:\\\2|[^\2])*?)\2)|((?:.(?!\s\S+=))*.))/g, + ret = {}; + + // if only one attribute then remove the = from the start and + // strip any quotes + if (attrs.charAt(0) === '=' && attrs.indexOf('=', 1) < 0) { + ret.defaultattr = _stripQuotes(attrs.substr(1)); + } else { + if (attrs.charAt(0) === '=') { + attrs = 'defaultattr' + attrs; + } + + // No need to strip quotes here, the regex will do that. + while ((matches = attrRegex.exec(attrs))) { + ret[lower(matches[1])] = + _stripQuotes(matches[3]) || matches[4]; + } + } + + return ret; + }; + + /** + * Parses a string into an array of BBCodes + * + * @param {string} str + * @param {boolean} preserveNewLines If to preserve all new lines, not + * strip any based on the passed + * formatting options + * @return {Array} Array of BBCode objects + * @memberOf jQuery.sceditor.BBCodeParser.prototype + */ + base.parse = function (str, preserveNewLines) { + var ret = parseTokens(base.tokenize(str)); + var opts = base.opts; + + if (opts.fixInvalidChildren) { + fixChildren(ret); + } + + if (opts.removeEmptyTags) { + removeEmpty(ret); + } + + if (opts.fixInvalidNesting) { + fixNesting(ret); + } + + normaliseNewLines(ret, null, preserveNewLines); + + if (opts.removeEmptyTags) { + removeEmpty(ret); + } + + return ret; + }; + + /** + * Checks if an array of TokenizeToken's contains the + * specified token. + * + * Checks the tokens name and type match another tokens + * name and type in the array. + * + * @param {string} name + * @param {tokenType} type + * @param {Array} arr + * @return {Boolean} + * @private + */ + hasTag = function (name, type, arr) { + var i = arr.length; + + while (i--) { + if (arr[i].type === type && arr[i].name === name) { + return true; + } + } + + return false; + }; + + /** + * Checks if the child tag is allowed as one + * of the parent tags children. + * + * @param {TokenizeToken} parent + * @param {TokenizeToken} child + * @return {Boolean} + * @private + */ + isChildAllowed = function (parent, child) { + var parentBBCode = parent ? base.bbcodes[parent.name] : {}, + allowedChildren = parentBBCode.allowedChildren; + + if (base.opts.fixInvalidChildren && allowedChildren) { + return $.inArray(child.name || '#', allowedChildren) > -1; + } + + return true; + }; + +// TODO: Tidy this parseTokens() function up a bit. + /** + * Parses an array of tokens created by tokenize() + * + * @param {Array} toks + * @return {Array} Parsed tokens + * @see tokenize() + * @private + */ + parseTokens = function (toks) { + var token, bbcode, curTok, clone, i, previous, next, + cloned = [], + output = [], + openTags = [], + /** + * Returns the currently open tag or undefined + * @return {TokenizeToken} + */ + currentOpenTag = function () { + return last(openTags); + }, + /** + * Adds a tag to either the current tags children + * or to the output array. + * @param {TokenizeToken} token + * @private + */ + addTag = function (token) { + if (currentOpenTag()) { + currentOpenTag().children.push(token); + } else { + output.push(token); + } + }, + /** + * Checks if this tag closes the current tag + * @param {String} name + * @return {Void} + */ + closesCurrentTag = function (name) { + return currentOpenTag() && + (bbcode = base.bbcodes[currentOpenTag().name]) && + bbcode.closedBy && + $.inArray(name, bbcode.closedBy) > -1; + }; + + while ((token = toks.shift())) { + next = toks[0]; + + /* jshint indent:false */ + switch (token.type) { + case TokenType.OPEN: + // Check it this closes a parent, + // e.g. for lists [*]one [*]two + if (closesCurrentTag(token.name)) { + openTags.pop(); + } + + addTag(token); + bbcode = base.bbcodes[token.name]; + + // If this tag is not self closing and it has a closing + // tag then it is open and has children so add it to the + // list of open tags. If has the closedBy property then + // it is closed by other tags so include everything as + // it's children until one of those tags is reached. + if ((!bbcode || !bbcode.isSelfClosing) && + (bbcode.closedBy || + hasTag(token.name, TokenType.CLOSE, toks))) { + openTags.push(token); + } else if (!bbcode || !bbcode.isSelfClosing) { + token.type = TokenType.CONTENT; + } + break; + + case TokenType.CLOSE: + // check if this closes the current tag, + // e.g. [/list] would close an open [*] + if (currentOpenTag() && + token.name !== currentOpenTag().name && + closesCurrentTag('/' + token.name)) { + openTags.pop(); + } + + // If this is closing the currently open tag just pop + // the close tag off the open tags array + if (currentOpenTag() && + token.name === currentOpenTag().name) { + currentOpenTag().closing = token; + openTags.pop(); + + // If this is closing an open tag that is the parent of + // the current tag then clone all the tags including the + // current one until reaching the parent that is being + // closed. Close the parent and then add the clones back + // in. + } else if (hasTag(token.name, TokenType.OPEN, + openTags)) { + + // Remove the tag from the open tags + while ((curTok = openTags.pop())) { + + // If it's the tag that is being closed then + // discard it and break the loop. + if (curTok.name === token.name) { + curTok.closing = token; + break; + } + + // Otherwise clone this tag and then add any + // previously cloned tags as it's children + clone = curTok.clone(); + + if (cloned.length) { + clone.children.push(last(cloned)); + } + + cloned.push(clone); + } + + // Add the last cloned child to the now current tag + // (the parent of the tag which was being closed) + addTag(last(cloned)); + + // Add all the cloned tags to the open tags list + i = cloned.length; + while (i--) { + openTags.push(cloned[i]); + } + + cloned.length = 0; + + // This tag is closing nothing so treat it as content + } else { + token.type = TokenType.CONTENT; + addTag(token); + } + break; + + case TokenType.NEWLINE: + // handle things like + // [*]list\nitem\n[*]list1 + // where it should come out as + // [*]list\nitem[/*]\n[*]list1[/*] + // instead of + // [*]list\nitem\n[/*][*]list1[/*] + if (currentOpenTag() && next && + closesCurrentTag( + (next.type === TokenType.CLOSE ? '/' : '') + + next.name + )) { + // skip if the next tag is the closing tag for + // the option tag, i.e. [/*] + if (!(next.type === TokenType.CLOSE && + next.name === currentOpenTag().name)) { + bbcode = base.bbcodes[currentOpenTag().name]; + + if (bbcode && bbcode.breakAfter) { + openTags.pop(); + } else if (bbcode && + bbcode.isInline === false && + base.opts.breakAfterBlock && + bbcode.breakAfter !== false) { + openTags.pop(); + } + } + } + + addTag(token); + break; + + default: // content + addTag(token); + break; + } + + previous = token; + } + + return output; + }; + + /** + * Normalise all new lines + * + * Removes any formatting new lines from the BBCode + * leaving only content ones. I.e. for a list: + * + * [list] + * [*] list item one + * with a line break + * [*] list item two + * [/list] + * + * would become + * + * [list] [*] list item one + * with a line break [*] list item two [/list] + * + * Which makes it easier to convert to HTML or add + * the formatting new lines back in when converting + * back to BBCode + * + * @param {Array} children + * @param {TokenizeToken} parent + * @param {Bool} onlyRemoveBreakAfter + * @return {void} + */ + normaliseNewLines = function (children, parent, onlyRemoveBreakAfter) { + var token, left, right, parentBBCode, bbcode, + removedBreakEnd, removedBreakBefore, remove; + var childrenLength = children.length; +// TODO: this function really needs tidying up + if (parent) { + parentBBCode = base.bbcodes[parent.name]; + } + + var i = childrenLength; + while (i--) { + if (!(token = children[i])) { + continue; + } + + if (token.type === TokenType.NEWLINE) { + left = i > 0 ? children[i - 1] : null; + right = i < childrenLength - 1 ? children[i + 1] : null; + remove = false; + + // Handle the start and end new lines + // e.g. [tag]\n and \n[/tag] + if (!onlyRemoveBreakAfter && parentBBCode && + parentBBCode.isSelfClosing !== true) { + // First child of parent so must be opening line break + // (breakStartBlock, breakStart) e.g. [tag]\n + if (!left) { + if (parentBBCode.isInline === false && + base.opts.breakStartBlock && + parentBBCode.breakStart !== false) { + remove = true; + } + + if (parentBBCode.breakStart) { + remove = true; + } + // Last child of parent so must be end line break + // (breakEndBlock, breakEnd) + // e.g. \n[/tag] + // remove last line break (breakEndBlock, breakEnd) + } else if (!removedBreakEnd && !right) { + if (parentBBCode.isInline === false && + base.opts.breakEndBlock && + parentBBCode.breakEnd !== false) { + remove = true; + } + + if (parentBBCode.breakEnd) { + remove = true; + } + + removedBreakEnd = remove; + } + } + + if (left && left.type === TokenType.OPEN) { + if ((bbcode = base.bbcodes[left.name])) { + if (!onlyRemoveBreakAfter) { + if (bbcode.isInline === false && + base.opts.breakAfterBlock && + bbcode.breakAfter !== false) { + remove = true; + } + + if (bbcode.breakAfter) { + remove = true; + } + } else if (bbcode.isInline === false) { + remove = true; + } + } + } + + if (!onlyRemoveBreakAfter && !removedBreakBefore && + right && right.type === TokenType.OPEN) { + + if ((bbcode = base.bbcodes[right.name])) { + if (bbcode.isInline === false && + base.opts.breakBeforeBlock && + bbcode.breakBefore !== false) { + remove = true; + } + + if (bbcode.breakBefore) { + remove = true; + } + + removedBreakBefore = remove; + + if (remove) { + children.splice(i, 1); + continue; + } + } + } + + if (remove) { + children.splice(i, 1); + } + + // reset double removedBreakBefore removal protection. + // This is needed for cases like \n\n[\tag] where + // only 1 \n should be removed but without this they both + // would be. + removedBreakBefore = false; + } else if (token.type === TokenType.OPEN) { + normaliseNewLines(token.children, token, + onlyRemoveBreakAfter); + } + } + }; + + /** + * Fixes any invalid nesting. + * + * If it is a block level element inside 1 or more inline elements + * then those inline elements will be split at the point where the + * block level is and the block level element placed between the split + * parts. i.e. + * [inline]A[blocklevel]B[/blocklevel]C[/inline] + * Will become: + * [inline]A[/inline][blocklevel]B[/blocklevel][inline]C[/inline] + * + * @param {Array} children + * @param {Array} [parents] Null if there is no parents + * @param {Array} [insideInline] Boolean, if inside an inline element + * @param {Array} [rootArr] Root array if there is one + * @return {Array} + * @private + */ + fixNesting = function (children, parents, insideInline, rootArr) { + var token, i, parent, parentIndex, parentParentChildren, right; + + var isInline = function (token) { + var bbcode = base.bbcodes[token.name]; + + return !bbcode || bbcode.isInline !== false; + }; + + parents = parents || []; + rootArr = rootArr || children; + + // This must check the length each time as it can change when + // tokens are moved to fix the nesting. + for (i = 0; i < children.length; i++) { + if (!(token = children[i]) || token.type !== TokenType.OPEN) { + continue; + } + + if (!isInline(token) && insideInline) { + // if this is a blocklevel element inside an inline one then + // split the parent at the block level element + parent = last(parents); + right = parent.splitAt(token); + + parentParentChildren = parents.length > 1 ? + parents[parents.length - 2].children : rootArr; + + parentIndex = $.inArray(parent, parentParentChildren); + if (parentIndex > -1) { + // remove the block level token from the right side of + // the split inline element + right.children.splice( + $.inArray(token, right.children), 1); + + // insert the block level token and the right side after + // the left side of the inline token + parentParentChildren.splice( + parentIndex + 1, 0, token, right + ); + + // return to parents loop as the + // children have now increased + return; + } + + } + + parents.push(token); + + fixNesting( + token.children, + parents, + insideInline || isInline(token), + rootArr + ); + + parents.pop(token); + } + }; + + /** + * Fixes any invalid children. + * + * If it is an element which isn't allowed as a child of it's parent + * then it will be converted to content of the parent element. i.e. + * [code]Code [b]only[/b] allows text.[/code] + * Will become: + * Code [b]only[/b] allows text. + * Instead of: + * Code only allows text. + * + * @param {Array} children + * @param {Array} [parent] Null if there is no parents + * @private + */ + fixChildren = function (children, parent) { + var token, args; + + var i = children.length; + while (i--) { + if (!(token = children[i])) { + continue; + } + + if (!isChildAllowed(parent, token)) { + // if it is not then convert it to text and see if it + // is allowed + token.name = null; + token.type = TokenType.CONTENT; + + if (isChildAllowed(parent, token)) { + args = [i + 1, 0].concat(token.children); + + if (token.closing) { + token.closing.name = null; + token.closing.type = TokenType.CONTENT; + args.push(token.closing); + } + + i += args.length - 1; + Array.prototype.splice.apply(children, args); + } else { + parent.children.splice(i, 1); + } + } + + if (token.type === TokenType.OPEN) { + fixChildren(token.children, token); + } + } + }; + + /** + * Removes any empty BBCodes which are not allowed to be empty. + * + * @param {Array} tokens + * @private + */ + removeEmpty = function (tokens) { + var token, bbcode; + + /** + * Checks if all children are whitespace or not + * @private + */ + var isTokenWhiteSpace = function (children) { + var j = children.length; + + while (j--) { + var type = children[j].type; + + if (type === TokenType.OPEN || type === TokenType.CLOSE) { + return false; + } + + if (type === TokenType.CONTENT && + /\S|\u00A0/.test(children[j].val)) { + return false; + } + } + + return true; + }; + + var i = tokens.length; + while (i--) { + // So skip anything that isn't a tag since only tags can be + // empty, content can't + if (!(token = tokens[i]) || token.type !== TokenType.OPEN) { + continue; + } + + bbcode = base.bbcodes[token.name]; + + // Remove any empty children of this tag first so that if they + // are all removed this one doesn't think it's not empty. + removeEmpty(token.children); + + if (isTokenWhiteSpace(token.children) && bbcode && + !bbcode.isSelfClosing && !bbcode.allowsEmpty) { + tokens.splice.apply( + tokens, + $.merge([i, 1], token.children) + ); + } + } + }; + + /** + * Converts a BBCode string to HTML + * + * @param {String} str + * @param {Bool} preserveNewLines If to preserve all new lines, not + * strip any based on the passed + * formatting options + * @return {String} + * @memberOf jQuery.sceditor.BBCodeParser.prototype + */ + base.toHTML = function (str, preserveNewLines) { + return convertToHTML(base.parse(str, preserveNewLines), true); + }; + + /** + * @private + */ + convertToHTML = function (tokens, isRoot) { + var undef, token, bbcode, content, html, needsBlockWrap, + blockWrapOpen, isInline, lastChild, + ret = []; + + isInline = function (bbcode) { + return (!bbcode || (bbcode.isHtmlInline !== undef ? + bbcode.isHtmlInline : bbcode.isInline)) !== false; + }; + + while (tokens.length > 0) { + if (!(token = tokens.shift())) { + continue; + } + + if (token.type === TokenType.OPEN) { + lastChild = + token.children[token.children.length - 1] || {}; + bbcode = base.bbcodes[token.name]; + needsBlockWrap = isRoot && isInline(bbcode); + content = convertToHTML(token.children, false); + + if (bbcode && bbcode.html) { + // Only add a line break to the end if this is + // blocklevel and the last child wasn't block-level + if (!isInline(bbcode) && + isInline(base.bbcodes[lastChild.name]) && + !bbcode.isPreFormatted && + !bbcode.skipLastLineBreak) { + // Add placeholder br to end of block level elements + // in all browsers apart from IE < 9 which handle + // new lines differently and doesn't need one. + if (!IE_BR_FIX) { + content += '
    '; + } + } + + if (!$.isFunction(bbcode.html)) { + token.attrs['0'] = content; + html = sceditorPlugins.bbcode.formatBBCodeString( + bbcode.html, + token.attrs + ); + } else { + html = bbcode.html.call( + base, + token, + token.attrs, + content + ); + } + } else { + html = token.val + content + + (token.closing ? token.closing.val : ''); + } + } else if (token.type === TokenType.NEWLINE) { + if (!isRoot) { + ret.push('
    '); + continue; + } + + // If not already in a block wrap then start a new block + if (!blockWrapOpen) { + ret.push('
    '); + + // If it's an empty DIV and compatibility mode is below + // IE8 then we must add a non-breaking space to the div + // otherwise the div will be collapsed. Adding a BR + // works but when you press enter to make a newline it + // suddenly goes back to the normal IE div behavior and + // creates two lines, one for the newline and one for + // the BR. I'm sure there must be a better fix but I've + // yet to find one. + // Cannot do zoom: 1; or set a height on the div to fix + // it as that causes resize handles to be added to the + // div when it's clicked on. + if (IE_VER < 8 || (document.documentMode && + document.documentMode < 8)) { + ret.push('\u00a0'); + } + } + + // Putting BR in a div in IE causes it + // to do a double line break. + if (!IE_BR_FIX) { + ret.push('
    '); + } + + // Normally the div acts as a line-break with by moving + // whatever comes after onto a new line. + // If this is the last token, add an extra line-break so it + // shows as there will be nothing after it. + if (!tokens.length) { + ret.push('
    '); + } + + ret.push('
    \n'); + blockWrapOpen = false; + continue; + // content + } else { + needsBlockWrap = isRoot; + html = escapeEntities(token.val, true); + } + + if (needsBlockWrap && !blockWrapOpen) { + ret.push('
    '); + blockWrapOpen = true; + } else if (!needsBlockWrap && blockWrapOpen) { + ret.push('
    \n'); + blockWrapOpen = false; + } + + ret.push(html); + } + + if (blockWrapOpen) { + ret.push('
    \n'); + } + + return ret.join(''); + }; + + /** + * Takes a BBCode string, parses it then converts it back to BBCode. + * + * This will auto fix the BBCode and format it with the specified + * options. + * + * @param {String} str + * @param {Bool} preserveNewLines If to preserve all new lines, not + * strip any based on the passed + * formatting options + * @return {String} + * @memberOf jQuery.sceditor.BBCodeParser.prototype + */ + base.toBBCode = function (str, preserveNewLines) { + return convertToBBCode(base.parse(str, preserveNewLines)); + }; + + /** + * Converts parsed tokens back into BBCode with the + * formatting specified in the options and with any + * fixes specified. + * + * @param {Array} toks Array of parsed tokens from base.parse() + * @return {String} + * @private + */ + convertToBBCode = function (toks) { + var token, attr, bbcode, isBlock, isSelfClosing, quoteType, + breakBefore, breakStart, breakEnd, breakAfter, + // Create an array of strings which are joined together + // before being returned as this is faster in slow browsers. + // (Old versions of IE). + ret = []; + + while (toks.length > 0) { + if (!(token = toks.shift())) { + continue; + } +// TODO: tidy this + bbcode = base.bbcodes[token.name]; + isBlock = !(!bbcode || bbcode.isInline !== false); + isSelfClosing = bbcode && bbcode.isSelfClosing; + + breakBefore = (isBlock && base.opts.breakBeforeBlock && + bbcode.breakBefore !== false) || + (bbcode && bbcode.breakBefore); + + breakStart = (isBlock && !isSelfClosing && + base.opts.breakStartBlock && + bbcode.breakStart !== false) || + (bbcode && bbcode.breakStart); + + breakEnd = (isBlock && base.opts.breakEndBlock && + bbcode.breakEnd !== false) || + (bbcode && bbcode.breakEnd); + + breakAfter = (isBlock && base.opts.breakAfterBlock && + bbcode.breakAfter !== false) || + (bbcode && bbcode.breakAfter); + + quoteType = (bbcode ? bbcode.quoteType : null) || + base.opts.quoteType || BBCodeParser.QuoteType.auto; + + if (!bbcode && token.type === TokenType.OPEN) { + ret.push(token.val); + + if (token.children) { + ret.push(convertToBBCode(token.children)); + } + + if (token.closing) { + ret.push(token.closing.val); + } + } else if (token.type === TokenType.OPEN) { + if (breakBefore) { + ret.push('\n'); + } + + // Convert the tag and it's attributes to BBCode + ret.push('[' + token.name); + if (token.attrs) { + if (token.attrs.defaultattr) { + ret.push('=', quote( + token.attrs.defaultattr, + quoteType, + 'defaultattr' + )); + + delete token.attrs.defaultattr; + } + + for (attr in token.attrs) { + if (token.attrs.hasOwnProperty(attr)) { + ret.push(' ', attr, '=', + quote(token.attrs[attr], quoteType, attr)); + } + } + } + ret.push(']'); + + if (breakStart) { + ret.push('\n'); + } + + // Convert the tags children to BBCode + if (token.children) { + ret.push(convertToBBCode(token.children)); + } + + // add closing tag if not self closing + if (!isSelfClosing && !bbcode.excludeClosing) { + if (breakEnd) { + ret.push('\n'); + } + + ret.push('[/' + token.name + ']'); + } + + if (breakAfter) { + ret.push('\n'); + } + + // preserve whatever was recognized as the + // closing tag if it is a self closing tag + if (token.closing && isSelfClosing) { + ret.push(token.closing.val); + } + } else { + ret.push(token.val); + } + } + + return ret.join(''); + }; + + /** + * Quotes an attribute + * + * @param {String} str + * @param {BBCodeParser.QuoteType} quoteType + * @param {String} name + * @return {String} + * @private + */ + quote = function (str, quoteType, name) { + var QuoteTypes = BBCodeParser.QuoteType, + needsQuotes = /\s|=/.test(str); + + if ($.isFunction(quoteType)) { + return quoteType(str, name); + } + + if (quoteType === QuoteTypes.never || + (quoteType === QuoteTypes.auto && !needsQuotes)) { + return str; + } + + return '"' + str.replace('\\', '\\\\').replace('"', '\\"') + '"'; + }; + + /** + * Returns the last element of an array or null + * + * @param {Array} arr + * @return {Object} Last element + * @private + */ + last = function (arr) { + if (arr.length) { + return arr[arr.length - 1]; + } + + return null; + }; + + /** + * Converts a string to lowercase. + * + * @param {String} str + * @return {String} Lowercase version of str + * @private + */ + lower = function (str) { + return str.toLowerCase(); + }; + + init(); + }; + + /** + * Quote type + * @type {Object} + * @class QuoteType + * @name jQuery.sceditor.BBCodeParser.QuoteType + * @since v1.4.0 + */ + BBCodeParser.QuoteType = { + /** @lends jQuery.sceditor.BBCodeParser.QuoteType */ + /** + * Always quote the attribute value + * @type {Number} + */ + always: 1, + + /** + * Never quote the attributes value + * @type {Number} + */ + never: 2, + + /** + * Only quote the attributes value when it contains spaces to equals + * @type {Number} + */ + auto: 3 + }; + + /** + * Default BBCode parser options + * @type {Object} + */ + BBCodeParser.defaults = { + /** + * If to add a new line before block level elements + * + * @type {Boolean} + */ + breakBeforeBlock: false, + + /** + * If to add a new line after the start of block level elements + * + * @type {Boolean} + */ + breakStartBlock: false, + + /** + * If to add a new line before the end of block level elements + * + * @type {Boolean} + */ + breakEndBlock: false, + + /** + * If to add a new line after block level elements + * + * @type {Boolean} + */ + breakAfterBlock: true, + + /** + * If to remove empty tags + * + * @type {Boolean} + */ + removeEmptyTags: true, + + /** + * If to fix invalid nesting, + * i.e. block level elements inside inline elements. + * + * @type {Boolean} + */ + fixInvalidNesting: true, + + /** + * If to fix invalid children. + * i.e. A tag which is inside a parent that doesn't + * allow that type of tag. + * + * @type {Boolean} + */ + fixInvalidChildren: true, + + /** + * Attribute quote type + * + * @type {BBCodeParser.QuoteType} + * @since 1.4.1 + */ + quoteType: BBCodeParser.QuoteType.auto + }; + + /** + * Deprecated, use sceditorPlugins.bbcode + * + * @class sceditorBBCodePlugin + * @name jQuery.sceditor.sceditorBBCodePlugin + * @deprecated + */ + $.sceditorBBCodePlugin = + /** + * BBCode plugin for SCEditor + * + * @class bbcode + * @name jQuery.sceditor.plugins.bbcode + * @since 1.4.1 + */ + sceditorPlugins.bbcode = function () { + var base = this; + + /** + * Private methods + * @private + */ + var buildBbcodeCache, + handleStyles, + handleTags, + removeFirstLastDiv; + + base.bbcodes = sceditorPlugins.bbcode.bbcodes; + base.stripQuotes = _stripQuotes; + + /** + * cache of all the tags pointing to their bbcodes to enable + * faster lookup of which bbcode a tag should have + * @private + */ + var tagsToBBCodes = {}; + + /** + * Same as tagsToBBCodes but instead of HTML tags it's styles + * @private + */ + var stylesToBBCodes = {}; + + /** + * Allowed children of specific HTML tags. Empty array if no + * children other than text nodes are allowed + * @private + */ + var validChildren = { + ul: ['li', 'ol', 'ul'], + ol: ['li', 'ol', 'ul'], + table: ['tr'], + tr: ['td', 'th'], + code: ['br', 'p', 'div'] + }; + + /** + * Initializer + * @private + */ + base.init = function () { + base.opts = this.opts; + + // build the BBCode cache + buildBbcodeCache(); + + this.commands = $.extend( + true, {}, defaultCommandsOverrides, this.commands + ); + + // Add BBCode helper methods + this.toBBCode = base.signalToSource; + this.fromBBCode = base.signalToWysiwyg; + }; + + /** + * Populates tagsToBBCodes and stylesToBBCodes to enable faster lookups + * + * @private + */ + buildBbcodeCache = function () { + $.each(base.bbcodes, function (bbcode) { + var isBlock, + tags = base.bbcodes[bbcode].tags, + styles = base.bbcodes[bbcode].styles; + + if (tags) { + $.each(tags, function (tag, values) { + isBlock = base.bbcodes[bbcode].isInline === false; + + tagsToBBCodes[tag] = tagsToBBCodes[tag] || {}; + + tagsToBBCodes[tag][isBlock] = + tagsToBBCodes[tag][isBlock] || {}; + + tagsToBBCodes[tag][isBlock][bbcode] = values; + }); + } + + if (styles) { + $.each(styles, function (style, values) { + isBlock = base.bbcodes[bbcode].isInline === false; + + stylesToBBCodes[isBlock] = + stylesToBBCodes[isBlock] || {}; + + stylesToBBCodes[isBlock][style] = + stylesToBBCodes[isBlock][style] || {}; + + stylesToBBCodes[isBlock][style][bbcode] = values; + }); + } + }); + }; + + /** + * Checks if any bbcode styles match the elements styles + * + * @return string Content with any matching + * bbcode tags wrapped around it. + * @private + */ + handleStyles = function ($element, content, blockLevel) { + var styleValue, format, + getStyle = SCEditor.dom.getStyle; + + // convert blockLevel to boolean + blockLevel = !!blockLevel; + + if (!stylesToBBCodes[blockLevel]) { + return content; + } + + $.each(stylesToBBCodes[blockLevel], function (property, bbcodes) { + styleValue = getStyle($element[0], property); + + // if the parent has the same style use that instead of this one + // so you don't end up with [i]parent[i]child[/i][/i] + if (!styleValue || + getStyle($element.parent()[0], property) === styleValue) { + return; + } + + $.each(bbcodes, function (bbcode, values) { + if (!values || + $.inArray(styleValue.toString(), values) > -1) { + format = base.bbcodes[bbcode].format; + + if ($.isFunction(format)) { + content = format.call(base, $element, content); + } else { + content = _formatString(format, content); + } + } + }); + }); + + return content; + }; + + /** + * Handles a HTML tag and finds any matching bbcodes + * + * @param {jQuery} $element The element to convert + * @param {String} content The Tags text content + * @param {Bool} blockLevel If to convert block level tags + * @return {String} Content with any matching bbcode tags + * wrapped around it. + * @private + */ + handleTags = function ($element, content, blockLevel) { + var convertBBCode, format, + element = $element[0], + tag = element.nodeName.toLowerCase(); + + // convert blockLevel to boolean + blockLevel = !!blockLevel; + + if (tagsToBBCodes[tag] && tagsToBBCodes[tag][blockLevel]) { + // loop all bbcodes for this tag + $.each(tagsToBBCodes[tag][blockLevel], function ( + bbcode, bbcodeAttribs) { + // if the bbcode requires any attributes then check this has + // all needed + if (bbcodeAttribs) { + convertBBCode = false; + + // loop all the bbcode attribs + $.each(bbcodeAttribs, function (attrib, values) { + // Skip if the element doesn't have the attibue or + // the attribute doesn't match one of the require + // values + if (!$element.attr(attrib) || (values && + $.inArray($element.attr(attrib), values) < 0)) { + return; + } + + // break this loop as we have matched this bbcode + convertBBCode = true; + return false; + }); + + if (!convertBBCode) { + return; + } + } + + format = base.bbcodes[bbcode].format; + + if ($.isFunction(format)) { + content = format.call(base, $element, content); + } else { + content = _formatString(format, content); + } + }); + } + + var isInline = SCEditor.dom.isInline; + if (blockLevel && (!isInline(element, true) || tag === 'br')) { + var isLastBlockChild, parent, parentLastChild, + previousSibling = element.previousSibling; + + // Skips selection makers and ignored elements + // Skip empty inline elements + while (previousSibling && + previousSibling.nodeType === 1 && + !$(previousSibling).is('br') && + isInline(previousSibling, true) && + !previousSibling.firstChild) { + previousSibling = previousSibling.previousSibling; + } + + // If it's the last block of an inline that is the last + // child of a block then it shouldn't cause a line break + // except in IE < 11 + //
    + do { + parent = element.parentNode; + parentLastChild = parent.lastChild; + + isLastBlockChild = parentLastChild === element; + element = parent; + } while (parent && isLastBlockChild && isInline(parent, true)); + + // If this block is: + // * Not the last child of a block level element + // * Is a
  • tag (lists are blocks) + // * Is IE < 11 and the tag is BR. IE < 11 never collapses BR + // tags. + if (!isLastBlockChild || tag === 'li' || + (tag === 'br' && IE_BR_FIX)) { + content += '\n'; + } + + // Check for: + // texttext + // + // The second opening opening tag should cause a + // line break because the previous sibing is inline. + if (tag !== 'br' && previousSibling && + !$(previousSibling).is('br') && + isInline(previousSibling, true)) { + content = '\n' + content; + } + } + + return content; + }; + + /** + * Converts HTML to BBCode + * + * @param {String} html Html string, this function ignores this, + * it works off domBody + * @param {jQuery} $body Editors dom body object to convert + * @return {String} BBCode which has been converted from HTML + * @memberOf jQuery.plugins.bbcode.prototype + */ + base.signalToSource = function (html, $body) { + var $tmpContainer, bbcode, + parser = new BBCodeParser(base.opts.parserOptions); + + if (!$body) { + if (typeof html === 'string') { + $tmpContainer = $('
    ') + .css('visibility', 'hidden') + .appendTo(document.body) + .html(html); + + $body = $tmpContainer; + } else { + $body = $(html); + } + } + + if (!$body || !$body.jquery) { + return ''; + } + + SCEditor.dom.removeWhiteSpace($body[0]); + + // Remove all the stuff that is meant to be ignored + $('.sceditor-ignore', $body).remove(); + + bbcode = base.elementToBbcode($body); + + if ($tmpContainer) { + $tmpContainer.remove(); + } + + bbcode = parser.toBBCode(bbcode, true); + + if (base.opts.bbcodeTrim) { + bbcode = $.trim(bbcode); + } + + return bbcode; + }; + + /** + * Converts a HTML dom element to BBCode starting from + * the innermost element and working backwards + * + * @private + * @param {jQuery} $element The element to convert to BBCode + * @return {string} BBCode + * @memberOf jQuery.plugins.bbcode.prototype + */ + base.elementToBbcode = function ($element) { + var toBBCode = function (node, vChildren) { + var ret = ''; +// TODO: Move to BBCode class? + SCEditor.dom.traverse(node, function (node) { + var $node = $(node), + curTag = '', + nodeType = node.nodeType, + tag = node.nodeName.toLowerCase(), + vChild = validChildren[tag], + firstChild = node.firstChild, + isValidChild = true; + + if (typeof vChildren === 'object') { + isValidChild = $.inArray(tag, vChildren) > -1; + + // Emoticons should always be converted + if ($node.is('img') && + $node.data('sceditor-emoticon')) { + isValidChild = true; + } + + // if this tag is one of the parents allowed children + // then set this tags allowed children to whatever it + // allows, otherwise set to what the parent allows + if (!isValidChild) { + vChild = vChildren; + } + } + + // 3 = text and 1 = element + if (nodeType !== 3 && nodeType !== 1) { + return; + } + + if (nodeType === 1) { + // skip empty nlf elements (new lines automatically + // added after block level elements like quotes) + if ($node.hasClass('sceditor-nlf')) { + if (!firstChild || (!IE_BR_FIX && + node.childNodes.length === 1 && + /br/i.test(firstChild.nodeName))) { + return; + } + } + + // don't loop inside iframes + if (tag !== 'iframe') { + curTag = toBBCode(node, vChild); + } + +// TODO: isValidChild is no longer needed. Should use valid children bbcodes +// instead by creating BBCode tokens like the parser. + if (isValidChild) { + // code tags should skip most styles + if (tag !== 'code') { + // handle inline bbcodes + curTag = handleStyles($node, curTag); + curTag = handleTags($node, curTag); + + // handle blocklevel bbcodes + curTag = handleStyles($node, curTag, true); + } + + ret += handleTags($node, curTag, true); + } else { + ret += curTag; + } + } else { + ret += node.nodeValue; + } + }, false, true); + + return ret; + }; + + return toBBCode($element[0]); + }; + + /** + * Converts BBCode to HTML + * + * @param {String} text + * @param {Bool} asFragment + * @return {String} HTML + * @memberOf jQuery.plugins.bbcode.prototype + */ + base.signalToWysiwyg = function (text, asFragment) { + var parser = new BBCodeParser(base.opts.parserOptions), + html = parser.toHTML(base.opts.bbcodeTrim ? + $.trim(text) : text); + + return asFragment ? removeFirstLastDiv(html) : html; + }; + + /** + * Removes the first and last divs from the HTML. + * + * This is needed for pasting + * @param {String} html + * @return {String} + * @private + */ + removeFirstLastDiv = function (html) { + var node, next, removeDiv, + $output = $('
    ').hide().appendTo(document.body), + output = $output[0]; + + removeDiv = function (node, isFirst) { + // Don't remove divs that have styling + if (SCEditor.dom.hasStyling(node)) { + return; + } + + if (IE_BR_FIX || (node.childNodes.length !== 1 || + !$(node.firstChild).is('br'))) { + while ((next = node.firstChild)) { + output.insertBefore(next, node); + } + } + + if (isFirst) { + var lastChild = output.lastChild; + + if (node !== lastChild && $(lastChild).is('div') && + node.nextSibling === lastChild) { + output.insertBefore(document.createElement('br'), node); + } + } + + output.removeChild(node); + }; + + output.innerHTML = html.replace(/<\/div>\n/g, '
    '); + + if ((node = output.firstChild) && $(node).is('div')) { + removeDiv(node, true); + } + + if ((node = output.lastChild) && $(node).is('div')) { + removeDiv(node); + } + + output = output.innerHTML; + $output.remove(); + + return output; + }; + }; + + + + /** + * Formats a string replacing {name} with the values of + * obj.name properties. + * + * If there is no property for the specified {name} then + * it will be left intact. + * + * @param {String} str + * @param {Object} obj + * @return {String} + * @since 1.4.5 + */ + sceditorPlugins.bbcode.formatBBCodeString = function (str, obj) { + return str.replace(/\{([^}]+)\}/g, function (match, group) { + var undef, + escape = true; + + if (group.charAt(0) === '!') { + escape = false; + group = group.substring(1); + } + + if (group === '0') { + escape = false; + } + + if (obj[group] === undef) { + return match; + } + + return escape ? + escapeEntities(obj[group], true) : + obj[group]; + }); + }; + + /** + * Converts a number 0-255 to hex. + * + * Will return 00 if number is not a valid number. + * + * @param {Number} number + * @return {String} + * @private + */ + var toHex = function (number) { + number = parseInt(number, 10); + + if (isNaN(number)) { + return '00'; + } + + number = Math.max(0, Math.min(number, 255)).toString(16); + + return number.length < 2 ? '0' + number : number; + }; + + var _normaliseColour = function (colorStr) { + var match; + + colorStr = colorStr || '#000'; + + // rgb(n,n,n); + if ((match = + colorStr.match(/rgb\((\d{1,3}),\s*?(\d{1,3}),\s*?(\d{1,3})\)/i))) { + return '#' + + toHex(match[1]) + + toHex(match[2] - 0) + + toHex(match[3] - 0); + } + + // expand shorthand + if ((match = colorStr.match(/#([0-f])([0-f])([0-f])\s*?$/i))) { + return '#' + + match[1] + match[1] + + match[2] + match[2] + + match[3] + match[3]; + } + + return colorStr; + }; + + var bbcodes = { + // START_COMMAND: Bold + b: { + tags: { + b: null, + strong: null + }, + styles: { + // 401 is for FF 3.5 + 'font-weight': ['bold', 'bolder', '401', '700', '800', '900'] + }, + format: '[b]{0}[/b]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Italic + i: { + tags: { + i: null, + em: null + }, + styles: { + 'font-style': ['italic', 'oblique'] + }, + format: '[i]{0}[/i]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Underline + u: { + tags: { + u: null + }, + styles: { + 'text-decoration': ['underline'] + }, + format: '[u]{0}[/u]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Strikethrough + s: { + tags: { + s: null, + strike: null + }, + styles: { + 'text-decoration': ['line-through'] + }, + format: '[s]{0}[/s]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Subscript + sub: { + tags: { + sub: null + }, + format: '[sub]{0}[/sub]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Superscript + sup: { + tags: { + sup: null + }, + format: '[sup]{0}[/sup]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Font + font: { + tags: { + font: { + face: null + } + }, + styles: { + 'font-family': null + }, + quoteType: BBCodeParser.QuoteType.never, + format: function ($element, content) { + var font; + + if (!$element.is('font') || !(font = $element.attr('face'))) { + font = $element.css('font-family'); + } + + return '[font=' + _stripQuotes(font) + ']' + + content + '[/font]'; + }, + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Size + size: { + tags: { + font: { + size: null + } + }, + styles: { + 'font-size': null + }, + format: function (element, content) { + var fontSize = element.attr('size'), + size = 2; + + if (!fontSize) { + fontSize = element.css('fontSize'); + } + + // Most browsers return px value but IE returns 1-7 + if (fontSize.indexOf('px') > -1) { + // convert size to an int + fontSize = fontSize.replace('px', '') - 0; + + if (fontSize < 12) { + size = 1; + } + if (fontSize > 15) { + size = 3; + } + if (fontSize > 17) { + size = 4; + } + if (fontSize > 23) { + size = 5; + } + if (fontSize > 31) { + size = 6; + } + if (fontSize > 47) { + size = 7; + } + } else { + size = fontSize; + } + + return '[size=' + size + ']' + content + '[/size]'; + }, + html: '{!0}' + }, + // END_COMMAND + + // START_COMMAND: Color + color: { + tags: { + font: { + color: null + } + }, + styles: { + color: null + }, + quoteType: BBCodeParser.QuoteType.never, + format: function ($element, content) { + var color; + + if (!$element.is('font') || !(color = $element.attr('color'))) { + color = $element[0].style.color || $element.css('color'); + } + + return '[color=' + _normaliseColour(color) + ']' + + content + '[/color]'; + }, + html: function (token, attrs, content) { + return '' + content + ''; + } + }, + // END_COMMAND + + // START_COMMAND: Lists + ul: { + tags: { + ul: null + }, + breakStart: true, + isInline: false, + skipLastLineBreak: true, + format: '[ul]{0}[/ul]', + html: '
      {0}
    ' + }, + list: { + breakStart: true, + isInline: false, + skipLastLineBreak: true, + html: '
      {0}
    ' + }, + ol: { + tags: { + ol: null + }, + breakStart: true, + isInline: false, + skipLastLineBreak: true, + format: '[ol]{0}[/ol]', + html: '
      {0}
    ' + }, + li: { + tags: { + li: null + }, + isInline: false, + closedBy: ['/ul', '/ol', '/list', '*', 'li'], + format: '[li]{0}[/li]', + html: '
  • {0}
  • ' + }, + '*': { + isInline: false, + closedBy: ['/ul', '/ol', '/list', '*', 'li'], + html: '
  • {0}
  • ' + }, + // END_COMMAND + + // START_COMMAND: Table + table: { + tags: { + table: null + }, + isInline: false, + isHtmlInline: true, + skipLastLineBreak: true, + format: '[table]{0}[/table]', + html: '{0}
    ' + }, + tr: { + tags: { + tr: null + }, + isInline: false, + skipLastLineBreak: true, + format: '[tr]{0}[/tr]', + html: '{0}' + }, + th: { + tags: { + th: null + }, + allowsEmpty: true, + isInline: false, + format: '[th]{0}[/th]', + html: '{0}' + }, + td: { + tags: { + td: null + }, + allowsEmpty: true, + isInline: false, + format: '[td]{0}[/td]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Emoticons + emoticon: { + allowsEmpty: true, + tags: { + img: { + src: null, + 'data-sceditor-emoticon': null + } + }, + format: function ($elm, content) { + return $elm.data('sceditor-emoticon') + content; + }, + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Horizontal Rule + hr: { + tags: { + hr: null + }, + allowsEmpty: true, + isSelfClosing: true, + isInline: false, + format: '[hr]{0}', + html: '
    ' + }, + // END_COMMAND + + // START_COMMAND: Image + img: { + allowsEmpty: true, + tags: { + img: { + src: null + } + }, + allowedChildren: ['#'], + quoteType: BBCodeParser.QuoteType.never, + format: function ($element, content) { + var width, height, + attribs = '', + element = $element[0], + style = function (name) { + return element.style ? element.style[name] : null; + }; + + // check if this is an emoticon image + if ($element.attr('data-sceditor-emoticon')) { + return content; + } + + width = $element.attr('width') || style('width'); + height = $element.attr('height') || style('height'); + + // only add width and height if one is specified + if ((element.complete && (width || height)) || + (width && height)) { + attribs = '=' + $element.width() + 'x' + $element.height(); + } + + return '[img' + attribs + ']' + $element.attr('src') + '[/img]'; + }, + html: function (token, attrs, content) { + var undef, width, height, match, + attribs = ''; + + // handle [img width=340 height=240]url[/img] + width = attrs.width; + height = attrs.height; + + // handle [img=340x240]url[/img] + if (attrs.defaultattr) { + match = attrs.defaultattr.split(/x/i); + + width = match[0]; + height = (match.length === 2 ? match[1] : match[0]); + } + + if (width !== undef) { + attribs += ' width="' + escapeEntities(width, true) + '"'; + } + + if (height !== undef) { + attribs += ' height="' + escapeEntities(height, true) + '"'; + } + + return ''; + } + }, + // END_COMMAND + + // START_COMMAND: URL + url: { + allowsEmpty: true, + tags: { + a: { + href: null + } + }, + quoteType: BBCodeParser.QuoteType.never, + format: function (element, content) { + var url = element.attr('href'); + + // make sure this link is not an e-mail, + // if it is return e-mail BBCode + if (url.substr(0, 7) === 'mailto:') { + return '[email="' + url.substr(7) + '"]' + + content + '[/email]'; + } + + return '[url=' + url + ']' + content + '[/url]'; + }, + html: function (token, attrs, content) { + attrs.defaultattr = + escapeEntities(attrs.defaultattr, true) || content; + + return '' + content + ''; + } + }, + // END_COMMAND + + // START_COMMAND: E-mail + email: { + quoteType: BBCodeParser.QuoteType.never, + html: function (token, attrs, content) { + return '' + content + ''; + } + }, + // END_COMMAND + + // START_COMMAND: Quote + quote: { + tags: { + blockquote: null + }, + isInline: false, + quoteType: BBCodeParser.QuoteType.never, + format: function (element, content) { + var author = ''; + var $elm = $(element); + var $cite = $elm.children('cite').first(); + + if ($cite.length === 1 || $elm.data('author')) { + author = $cite.text() || $elm.data('author'); + + $elm.data('author', author); + $cite.remove(); + + content = this.elementToBbcode($(element)); + author = '=' + author.replace(/(^\s+|\s+$)/g, ''); + + $elm.prepend($cite); + } + + return '[quote' + author + ']' + content + '[/quote]'; + }, + html: function (token, attrs, content) { + if (attrs.defaultattr) { + content = '' + escapeEntities(attrs.defaultattr) + + '' + content; + } + + return '
    ' + content + '
    '; + } + }, + // END_COMMAND + + // START_COMMAND: Code + code: { + tags: { + code: null + }, + isInline: false, + allowedChildren: ['#', '#newline'], + format: '[code]{0}[/code]', + html: '{0}' + }, + // END_COMMAND + + + // START_COMMAND: Left + left: { + styles: { + 'text-align': [ + 'left', + '-webkit-left', + '-moz-left', + '-khtml-left' + ] + }, + isInline: false, + format: '[left]{0}[/left]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // START_COMMAND: Centre + center: { + styles: { + 'text-align': [ + 'center', + '-webkit-center', + '-moz-center', + '-khtml-center' + ] + }, + isInline: false, + format: '[center]{0}[/center]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // START_COMMAND: Right + right: { + styles: { + 'text-align': [ + 'right', + '-webkit-right', + '-moz-right', + '-khtml-right' + ] + }, + isInline: false, + format: '[right]{0}[/right]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // START_COMMAND: Justify + justify: { + styles: { + 'text-align': [ + 'justify', + '-webkit-justify', + '-moz-justify', + '-khtml-justify' + ] + }, + isInline: false, + format: '[justify]{0}[/justify]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // START_COMMAND: YouTube + youtube: { + allowsEmpty: true, + tags: { + iframe: { + 'data-youtube-id': null + } + }, + format: function (element, content) { + element = element.attr('data-youtube-id'); + + return element ? '[youtube]' + element + '[/youtube]' : content; + }, + html: '' + }, + // END_COMMAND + + + // START_COMMAND: Rtl + rtl: { + styles: { + direction: ['rtl'] + }, + format: '[rtl]{0}[/rtl]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // START_COMMAND: Ltr + ltr: { + styles: { + direction: ['ltr'] + }, + format: '[ltr]{0}[/ltr]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // this is here so that commands above can be removed + // without having to remove the , after the last one. + // Needed for IE. + ignore: {} + }; + + /** + * Static BBCode helper class + * @class command + * @name jQuery.plugins.bbcode.bbcode + */ + sceditorPlugins.bbcode.bbcode = + /** @lends jQuery.plugins.bbcode.bbcode */ + { + /** + * Gets a BBCode + * + * @param {String} name + * @return {Object|null} + * @since v1.3.5 + */ + get: function (name) { + return bbcodes[name] || null; + }, + + /** + *

    Adds a BBCode to the parser or updates an existing + * BBCode if a BBCode with the specified name already exists.

    + * + * @param {String} name + * @param {Object} bbcode + * @return {this|false} Returns false if name or bbcode is false + * @since v1.3.5 + */ + set: function (name, bbcode) { + if (!name || !bbcode) { + return false; + } + + // merge any existing command properties + bbcode = $.extend(bbcodes[name] || {}, bbcode); + + bbcode.remove = function () { + delete bbcodes[name]; + }; + + bbcodes[name] = bbcode; + + return this; + }, + + /** + * Renames a BBCode + * + * This does not change the format or HTML handling, those must be + * changed manually. + * + * @param {String} name [description] + * @param {String} newName [description] + * @return {this|false} + * @since v1.4.0 + */ + rename: function (name, newName) { + if (name in bbcodes) { + bbcodes[newName] = bbcodes[name]; + + delete bbcodes[name]; + } else { + return false; + } + + return this; + }, + + /** + * Removes a BBCode + * + * @param {String} name + * @return {this} + * @since v1.3.5 + */ + remove: function (name) { + if (name in bbcodes) { + delete bbcodes[name]; + } + + return this; + } + }; + + /** + * Deprecated, use plugins: option instead. I.e.: + * + * $('textarea').sceditor({ + * plugins: 'bbcode' + * }); + * + * @deprecated + */ + $.fn.sceditorBBCodePlugin = function (options) { + options = options || {}; + + if ($.isPlainObject(options)) { + options.plugins = (options.plugins || '') + 'bbcode'; + } + + return this.sceditor(options); + }; + + /** + * Converts CSS RGB and hex shorthand into hex + * + * @since v1.4.0 + * @param {String} colorStr + * @return {String} + * @deprecated + */ + sceditorPlugins.bbcode.normaliseColour = _normaliseColour; + sceditorPlugins.bbcode.formatString = _formatString; + sceditorPlugins.bbcode.stripQuotes = _stripQuotes; + sceditorPlugins.bbcode.bbcodes = bbcodes; + SCEditor.BBCodeParser = BBCodeParser; +})(jQuery, window, document); diff --git a/js/sceditor/development/jquery.sceditor.default.css b/js/sceditor/development/jquery.sceditor.default.css new file mode 100644 index 00000000..9c542d38 --- /dev/null +++ b/js/sceditor/development/jquery.sceditor.default.css @@ -0,0 +1,83 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */ +html, body, p, code:before, table { + margin: 0; + padding: 0; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 13px; + color: #111; +} +html { + height: 100%; + + /* Needed for iOS scrolling bug fix */ + overflow: auto; + -webkit-overflow-scrolling: touch; +} +body { + /* Needed for iOS scrolling bug fix */ + position: relative; + overflow: auto; + + /* Needed to make sure body covers the whole editor and that + long lines don't cause horizontal scrolling */ + min-height: 100%; + word-wrap: break-word; +} + +ul, ol { + margin-top: 0; + margin-bottom: 0; + padding-top: 0; + padding-bottom: 0; +} + +table, td { + border: 1px dotted #000; + empty-cells: show; +} + +code:before { + position: absolute; + content: 'Code:'; + top: -1.35em; + left: 0; +} +code { + margin-top: 1.5em; + position: relative; + background: #eee; + border: 1px solid #aaa; + white-space: pre; + padding: .25em; + display: block; +} +.ie6 code, .ie7 code { + margin-top: 0; +} +code:before, code { + display: block; + text-align: left; +} + +blockquote { + position: relative; + background: #fff6c7; + margin: .25em 0; + border: 1px solid #aaa; + padding: .25em; +} +blockquote cite { + font-weight: bold; + display: block; + font-size: 1em; + border-bottom: 1px solid #aaa; +} + +h1, h2, h3, h4, h5, h6 { + padding: 0; margin: 0; +} + +/* Prevent empty paragraphs from collapsing */ +div, p { + min-height: 1.25em; +} diff --git a/js/sceditor/development/jquery.sceditor.js b/js/sceditor/development/jquery.sceditor.js new file mode 100644 index 00000000..551afcd4 --- /dev/null +++ b/js/sceditor/development/jquery.sceditor.js @@ -0,0 +1,7230 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/** + * SCEditor + * http://www.sceditor.com/ + * + * Copyright (C) 2014, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * @fileoverview SCEditor - A lightweight WYSIWYG BBCode and HTML editor + * @author Sam Clarke + * @requires jQuery + */ + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var SCEditor = __webpack_require__(2); + var PluginManager = __webpack_require__(3); + var browser = __webpack_require__(6); + var escape = __webpack_require__(7); + + + // For backwards compatibility + $.sceditor = SCEditor; + + SCEditor.commands = __webpack_require__(9); + SCEditor.defaultOptions = __webpack_require__(10); + SCEditor.RangeHelper = __webpack_require__(4); + SCEditor.dom = __webpack_require__(5); + + SCEditor.ie = browser.ie; + SCEditor.ios = browser.ios; + SCEditor.isWysiwygSupported = browser.isWysiwygSupported; + + SCEditor.regexEscape = escape.regex; + SCEditor.escapeEntities = escape.entities; + SCEditor.escapeUriScheme = escape.uriScheme; + + SCEditor.PluginManager = PluginManager; + SCEditor.plugins = PluginManager.plugins; + + + /** + * Creates an instance of sceditor on all textareas + * matched by the jQuery selector. + * + * If options is set to "state" it will return bool value + * indicating if the editor has been initialised on the + * matched textarea(s). If there is only one textarea + * it will return the bool value for that textarea. + * If more than one textarea is matched it will + * return an array of bool values for each textarea. + * + * If options is set to "instance" it will return the + * current editor instance for the textarea(s). Like the + * state option, if only one textarea is matched this will + * return just the instance for that textarea. If more than + * one textarea is matched it will return an array of + * instances each textarea. + * + * @param {Object|String} options Should either be an Object of options or + * the strings "state" or "instance" + * @return {this|Array|jQuery.sceditor|Bool} + */ + $.fn.sceditor = function (options) { + var $this, instance, + ret = []; + + options = options || {}; + + if (!options.runWithoutWysiwygSupport && !browser.isWysiwygSupported) { + return; + } + + this.each(function () { + $this = this.jquery ? this : $(this); + instance = $this.data('sceditor'); + + // Don't allow the editor to be initialised + // on it's own source editor + if ($this.parents('.sceditor-container').length > 0) { + return; + } + + // Add state of instance to ret if that is what options is set to + if (options === 'state') { + ret.push(!!instance); + } else if (options === 'instance') { + ret.push(instance); + } else if (!instance) { + /*jshint -W031*/ + (new SCEditor(this, options)); + } + }); + + // If nothing in the ret array then must be init so return this + if (!ret.length) { + return this; + } + + return ret.length === 1 ? ret[0] : $(ret); + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + module.exports = jQuery; + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var PluginManager = __webpack_require__(3); + var RangeHelper = __webpack_require__(4); + var dom = __webpack_require__(5); + var escape = __webpack_require__(7); + var browser = __webpack_require__(6); + var _tmpl = __webpack_require__(8); + + var globalWin = window; + var globalDoc = document; + var $globalWin = $(globalWin); + var $globalDoc = $(globalDoc); + + var IE_VER = browser.ie; + + // In IE < 11 a BR at the end of a block level element + // causes a line break. In all other browsers it's collapsed. + var IE_BR_FIX = IE_VER && IE_VER < 11; + + + /** + * SCEditor - A lightweight WYSIWYG editor + * + * @param {Element} el The textarea to be converted + * @return {Object} options + * @class sceditor + * @name jQuery.sceditor + */ + var SCEditor = function (el, options) { + /** + * Alias of this + * + * @private + */ + var base = this; + + /** + * The textarea element being replaced + * + * @private + */ + var original = el.get ? el.get(0) : el; + var $original = $(original); + + /** + * The div which contains the editor and toolbar + * + * @private + */ + var $editorContainer; + + /** + * The editors toolbar + * + * @private + */ + var $toolbar; + + /** + * The editors iframe which should be in design mode + * + * @private + */ + var $wysiwygEditor; + var wysiwygEditor; + + /** + * The WYSIWYG editors body element + * + * @private + */ + var $wysiwygBody; + + /** + * The WYSIWYG editors document + * + * @private + */ + var $wysiwygDoc; + + /** + * The editors textarea for viewing source + * + * @private + */ + var $sourceEditor; + var sourceEditor; + + /** + * The current dropdown + * + * @private + */ + var $dropdown; + + /** + * Store the last cursor position. Needed for IE because it forgets + * + * @private + */ + var lastRange; + + /** + * The editors locale + * + * @private + */ + var locale; + + /** + * Stores a cache of preloaded images + * + * @private + * @type {Array} + */ + var preLoadCache = []; + + /** + * The editors rangeHelper instance + * + * @type {jQuery.sceditor.rangeHelper} + * @private + */ + var rangeHelper; + + /** + * Tags which require the new line fix + * + * @type {Array} + * @private + */ + var requireNewLineFix = []; + + /** + * An array of button state handlers + * + * @type {Array} + * @private + */ + var btnStateHandlers = []; + + /** + * Plugin manager instance + * + * @type {jQuery.sceditor.PluginManager} + * @private + */ + var pluginManager; + + /** + * The current node containing the selection/caret + * + * @type {Node} + * @private + */ + var currentNode; + + /** + * The first block level parent of the current node + * + * @type {node} + * @private + */ + var currentBlockNode; + + /** + * The current node selection/caret + * + * @type {Object} + * @private + */ + var currentSelection; + + /** + * Used to make sure only 1 selection changed + * check is called every 100ms. + * + * Helps improve performance as it is checked a lot. + * + * @type {Boolean} + * @private + */ + var isSelectionCheckPending; + + /** + * If content is required (equivalent to the HTML5 required attribute) + * + * @type {Boolean} + * @private + */ + var isRequired; + + /** + * The inline CSS style element. Will be undefined + * until css() is called for the first time. + * + * @type {HTMLElement} + * @private + */ + var inlineCss; + + /** + * Object containing a list of shortcut handlers + * + * @type {Object} + * @private + */ + var shortcutHandlers = {}; + + /** + * An array of all the current emoticons. + * + * Only used or populated when emoticonsCompat is enabled. + * + * @type {Array} + * @private + */ + var currentEmoticons = []; + + /** + * Cache of the current toolbar buttons + * + * @type {Object} + * @private + */ + var toolbarButtons = {}; + + /** + * If the current autoUpdate action is canceled. + * + * @type {Boolean} + * @private + */ + var autoUpdateCanceled; + + /** + * Private functions + * @private + */ + var init, + replaceEmoticons, + handleCommand, + saveRange, + initEditor, + initPlugins, + initLocale, + initToolBar, + initOptions, + initEvents, + initCommands, + initResize, + initEmoticons, + getWysiwygDoc, + handlePasteEvt, + handlePasteData, + handleKeyDown, + handleBackSpace, + handleKeyPress, + handleFormReset, + handleMouseDown, + handleEvent, + handleDocumentClick, + handleWindowResize, + updateToolBar, + updateActiveButtons, + sourceEditorSelectedText, + appendNewLine, + checkSelectionChanged, + checkNodeChanged, + autofocus, + emoticonsKeyPress, + emoticonsCheckWhitespace, + currentStyledBlockNode, + triggerValueChanged, + valueChangedBlur, + valueChangedKeyUp, + autoUpdate; + + /** + * All the commands supported by the editor + * @name commands + * @memberOf jQuery.sceditor.prototype + */ + base.commands = $.extend( + true, + {}, + (options.commands || SCEditor.commands) + ); + + /** + * Options for this editor instance + * @name opts + * @memberOf jQuery.sceditor.prototype + */ + base.opts = options = $.extend({}, SCEditor.defaultOptions, options); + + + /** + * Creates the editor iframe and textarea + * @private + */ + init = function () { + $original.data('sceditor', base); + + // Clone any objects in options + $.each(options, function (key, val) { + if ($.isPlainObject(val)) { + options[key] = $.extend(true, {}, val); + } + }); + + // Load locale + if (options.locale && options.locale !== 'en') { + initLocale(); + } + + $editorContainer = $('
    ') + .insertAfter($original) + .css('z-index', options.zIndex); + + // Add IE version to the container to allow IE specific CSS + // fixes without using CSS hacks or conditional comments + if (IE_VER) { + $editorContainer.addClass('ie ie' + IE_VER); + } + + isRequired = !!$original.attr('required'); + $original.removeAttr('required'); + + // create the editor + initPlugins(); + initEmoticons(); + initToolBar(); + initEditor(!!options.startInSourceMode); + initCommands(); + initOptions(); + initEvents(); + + // force into source mode if is a browser that can't handle + // full editing + if (!browser.isWysiwygSupported) { + base.toggleSourceMode(); + } + + updateActiveButtons(); + + var loaded = function () { + $globalWin.off('load', loaded); + + if (options.autofocus) { + autofocus(); + } + + if (options.autoExpand) { + base.expandToContent(); + } + + // Page width might have changed after CSS is loaded so + // call handleWindowResize to update any % based dimensions + handleWindowResize(); + + pluginManager.call('ready'); + }; + $globalWin.on('load', loaded); + if (globalDoc.readyState && globalDoc.readyState === 'complete') { + loaded(); + } + }; + + initPlugins = function () { + var plugins = options.plugins; + + plugins = plugins ? plugins.toString().split(',') : []; + pluginManager = new PluginManager(base); + + $.each(plugins, function (idx, plugin) { + pluginManager.register($.trim(plugin)); + }); + }; + + /** + * Init the locale variable with the specified locale if possible + * @private + * @return void + */ + initLocale = function () { + var lang; + + locale = SCEditor.locale[options.locale]; + + if (!locale) { + lang = options.locale.split('-'); + locale = SCEditor.locale[lang[0]]; + } + + // Locale DateTime format overrides any specified in the options + if (locale && locale.dateFormat) { + options.dateFormat = locale.dateFormat; + } + }; + + /** + * Creates the editor iframe and textarea + * @param {boolean} startInSourceMode Force loading the editor in this + * mode + * @private + */ + initEditor = function (startInSourceMode) { + var doc, tabIndex; + + $sourceEditor = $(''); + $wysiwygEditor = $( + '' + ); + + /* This needs to be done right after they are created because, + * for any reason, the user may not want the value to be tinkered + * by any filters. + */ + if (startInSourceMode) { + $editorContainer.addClass('sourceMode'); + $wysiwygEditor.hide(); + } else { + $editorContainer.addClass('wysiwygMode'); + $sourceEditor.hide(); + } + + if (!options.spellcheck) { + $sourceEditor.attr('spellcheck', 'false'); + } + + /*jshint scripturl: true*/ + if (globalWin.location.protocol === 'https:') { + $wysiwygEditor.attr('src', 'javascript:false'); + } + + // Add the editor to the container + $editorContainer.append($wysiwygEditor).append($sourceEditor); + wysiwygEditor = $wysiwygEditor[0]; + sourceEditor = $sourceEditor[0]; + + base.dimensions( + options.width || $original.width(), + options.height || $original.height() + ); + + doc = getWysiwygDoc(); + doc.open(); + doc.write(_tmpl('html', { + // Add IE version class to the HTML element so can apply + // conditional styling without CSS hacks + attrs: IE_VER ? ' class="ie ie' + IE_VER + '"' : '', + spellcheck: options.spellcheck ? '' : 'spellcheck="false"', + charset: options.charset, + style: options.style + })); + doc.close(); + + $wysiwygDoc = $(doc); + $wysiwygBody = $(doc.body); + + base.readOnly(!!options.readOnly); + + // iframe overflow fix for iOS, also fixes an IE issue with the + // editor not getting focus when clicking inside + if (browser.ios || IE_VER) { + $wysiwygBody.height('100%'); + + if (!IE_VER) { + $wysiwygBody.on('touchend', base.focus); + } + } + + tabIndex = $original.attr('tabindex'); + $sourceEditor.attr('tabindex', tabIndex); + $wysiwygEditor.attr('tabindex', tabIndex); + + rangeHelper = new RangeHelper(wysiwygEditor.contentWindow); + + // load any textarea value into the editor + base.val($original.hide().val()); + }; + + /** + * Initialises options + * @private + */ + initOptions = function () { + // auto-update original textbox on blur if option set to true + if (options.autoUpdate) { + $wysiwygBody.on('blur', autoUpdate); + $sourceEditor.on('blur', autoUpdate); + } + + if (options.rtl === null) { + options.rtl = $sourceEditor.css('direction') === 'rtl'; + } + + base.rtl(!!options.rtl); + + if (options.autoExpand) { + $wysiwygDoc.on('keyup', base.expandToContent); + } + + if (options.resizeEnabled) { + initResize(); + } + + $editorContainer.attr('id', options.id); + base.emoticons(options.emoticonsEnabled); + }; + + /** + * Initialises events + * @private + */ + initEvents = function () { + var CHECK_SELECTION_EVENTS = IE_VER ? + 'selectionchange' : + 'keyup focus blur contextmenu mouseup touchend click'; + + var EVENTS_TO_FORWARD = 'keydown keyup keypress ' + + 'focus blur contextmenu'; + + $globalDoc.click(handleDocumentClick); + + $(original.form) + .on('reset', handleFormReset) + .submit(base.updateOriginal); + + $globalWin.on('resize orientationChanged', handleWindowResize); + + $wysiwygBody + .keypress(handleKeyPress) + .keydown(handleKeyDown) + .keydown(handleBackSpace) + .keyup(appendNewLine) + .blur(valueChangedBlur) + .keyup(valueChangedKeyUp) + .on('paste', handlePasteEvt) + .on(CHECK_SELECTION_EVENTS, checkSelectionChanged) + .on(EVENTS_TO_FORWARD, handleEvent); + + if (options.emoticonsCompat && globalWin.getSelection) { + $wysiwygBody.keyup(emoticonsCheckWhitespace); + } + + $sourceEditor + .blur(valueChangedBlur) + .keyup(valueChangedKeyUp) + .keydown(handleKeyDown) + .on(EVENTS_TO_FORWARD, handleEvent); + + $wysiwygDoc + .mousedown(handleMouseDown) + .blur(valueChangedBlur) + .on(CHECK_SELECTION_EVENTS, checkSelectionChanged) + .on('beforedeactivate keyup mouseup', saveRange) + .keyup(appendNewLine) + .focus(function () { + lastRange = null; + }); + + $editorContainer + .on('selectionchanged', checkNodeChanged) + .on('selectionchanged', updateActiveButtons) + .on('selectionchanged valuechanged nodechanged', handleEvent); + }; + + /** + * Creates the toolbar and appends it to the container + * @private + */ + initToolBar = function () { + var $group, + commands = base.commands, + exclude = (options.toolbarExclude || '').split(','), + groups = options.toolbar.split('|'); + + $toolbar = $('
    '); + + $.each(groups, function (idx, group) { + $group = $('
    '); + + $.each(group.split(','), function (idx, commandName) { + var $button, shortcut, + command = commands[commandName]; + + // The commandName must be a valid command and not excluded + if (!command || $.inArray(commandName, exclude) > -1) { + return; + } + + shortcut = command.shortcut; + $button = _tmpl('toolbarButton', { + name: commandName, + dispName: base._(command.name || + command.tooltip || commandName) + }, true); + + $button + .data('sceditor-txtmode', !!command.txtExec) + .data('sceditor-wysiwygmode', !!command.exec) + .toggleClass('disabled', !command.exec) + .mousedown(function () { + // IE < 8 supports unselectable attribute + // so don't need this + if (!IE_VER || IE_VER < 9) { + autoUpdateCanceled = true; + } + }) + .click(function () { + var $this = $(this); + + if (!$this.hasClass('disabled')) { + handleCommand($this, command); + } + + updateActiveButtons(); + return false; + }); + + if (command.tooltip) { + $button.attr( + 'title', + base._(command.tooltip) + + (shortcut ? ' (' + shortcut + ')' : '') + ); + } + + if (shortcut) { + base.addShortcut(shortcut, commandName); + } + + if (command.state) { + btnStateHandlers.push({ + name: commandName, + state: command.state + }); + // exec string commands can be passed to queryCommandState + } else if (typeof command.exec === 'string') { + btnStateHandlers.push({ + name: commandName, + state: command.exec + }); + } + + $group.append($button); + toolbarButtons[commandName] = $button; + }); + + // Exclude empty groups + if ($group[0].firstChild) { + $toolbar.append($group); + } + }); + + // Append the toolbar to the toolbarContainer option if given + $(options.toolbarContainer || $editorContainer).append($toolbar); + }; + + /** + * Creates an array of all the key press functions + * like emoticons, ect. + * @private + */ + initCommands = function () { + $.each(base.commands, function (name, cmd) { + if (cmd.forceNewLineAfter && $.isArray(cmd.forceNewLineAfter)) { + requireNewLineFix = $.merge( + requireNewLineFix, + cmd.forceNewLineAfter + ); + } + }); + + appendNewLine(); + }; + + /** + * Creates the resizer. + * @private + */ + initResize = function () { + var minHeight, maxHeight, minWidth, maxWidth, + mouseMoveFunc, mouseUpFunc, + $grip = $('
    '), + // Cover is used to cover the editor iframe so document + // still gets mouse move events + $cover = $('
    '), + moveEvents = 'touchmove mousemove', + endEvents = 'touchcancel touchend mouseup', + startX = 0, + startY = 0, + newX = 0, + newY = 0, + startWidth = 0, + startHeight = 0, + origWidth = $editorContainer.width(), + origHeight = $editorContainer.height(), + isDragging = false, + rtl = base.rtl(); + + minHeight = options.resizeMinHeight || origHeight / 1.5; + maxHeight = options.resizeMaxHeight || origHeight * 2.5; + minWidth = options.resizeMinWidth || origWidth / 1.25; + maxWidth = options.resizeMaxWidth || origWidth * 1.25; + + mouseMoveFunc = function (e) { + // iOS uses window.event + if (e.type === 'touchmove') { + e = globalWin.event; + newX = e.changedTouches[0].pageX; + newY = e.changedTouches[0].pageY; + } else { + newX = e.pageX; + newY = e.pageY; + } + + var newHeight = startHeight + (newY - startY), + newWidth = rtl ? + startWidth - (newX - startX) : + startWidth + (newX - startX); + + if (maxWidth > 0 && newWidth > maxWidth) { + newWidth = maxWidth; + } + if (minWidth > 0 && newWidth < minWidth) { + newWidth = minWidth; + } + if (!options.resizeWidth) { + newWidth = false; + } + + if (maxHeight > 0 && newHeight > maxHeight) { + newHeight = maxHeight; + } + if (minHeight > 0 && newHeight < minHeight) { + newHeight = minHeight; + } + if (!options.resizeHeight) { + newHeight = false; + } + + if (newWidth || newHeight) { + base.dimensions(newWidth, newHeight); + + // The resize cover will not fill the container + // in IE6 unless a height is specified. + if (IE_VER < 7) { + $editorContainer.height(newHeight); + } + } + + e.preventDefault(); + }; + + mouseUpFunc = function (e) { + if (!isDragging) { + return; + } + + isDragging = false; + + $cover.hide(); + $editorContainer.removeClass('resizing').height('auto'); + $globalDoc.off(moveEvents, mouseMoveFunc); + $globalDoc.off(endEvents, mouseUpFunc); + + e.preventDefault(); + }; + + $editorContainer.append($grip); + $editorContainer.append($cover.hide()); + + $grip.on('touchstart mousedown', function (e) { + // iOS uses window.event + if (e.type === 'touchstart') { + e = globalWin.event; + startX = e.touches[0].pageX; + startY = e.touches[0].pageY; + } else { + startX = e.pageX; + startY = e.pageY; + } + + startWidth = $editorContainer.width(); + startHeight = $editorContainer.height(); + isDragging = true; + + $editorContainer.addClass('resizing'); + $cover.show(); + $globalDoc.on(moveEvents, mouseMoveFunc); + $globalDoc.on(endEvents, mouseUpFunc); + + // The resize cover will not fill the container in + // IE6 unless a height is specified. + if (IE_VER < 7) { + $editorContainer.height(startHeight); + } + + e.preventDefault(); + }); + }; + + /** + * Prefixes and preloads the emoticon images + * @private + */ + initEmoticons = function () { + var emoticon, + emoticons = options.emoticons, + root = options.emoticonsRoot; + + if (!$.isPlainObject(emoticons) || !options.emoticonsEnabled) { + return; + } + + $.each(emoticons, function (idx, val) { + $.each(val, function (key, url) { + // Prefix emoticon root to emoticon urls + if (root) { + url = { + url: root + (url.url || url), + tooltip: url.tooltip || key + }; + + emoticons[idx][key] = url; + } + + // Preload the emoticon + emoticon = globalDoc.createElement('img'); + emoticon.src = url.url || url; + preLoadCache.push(emoticon); + }); + }); + }; + + /** + * Autofocus the editor + * @private + */ + autofocus = function () { + var range, txtPos, + doc = $wysiwygDoc[0], + body = $wysiwygBody[0], + node = body.firstChild, + focusEnd = !!options.autofocusEnd; + + // Can't focus invisible elements + if (!$editorContainer.is(':visible')) { + return; + } + + if (base.sourceMode()) { + txtPos = focusEnd ? sourceEditor.value.length : 0; + + if (sourceEditor.setSelectionRange) { + sourceEditor.setSelectionRange(txtPos, txtPos); + } else { + range = sourceEditor.createTextRange(); + range.moveEnd('character', txtPos); + range.collapse(false); + range.select(); + } + + return; + } + + dom.removeWhiteSpace(body); + + if (focusEnd) { + if (!(node = body.lastChild)) { + node = doc.createElement('p'); + $wysiwygBody.append(node); + } + + while (node.lastChild) { + node = node.lastChild; + + // IE < 11 should place the cursor after the
    as + // it will show it as a newline. IE >= 11 and all + // other browsers should place the cursor before. + if (!IE_BR_FIX && $(node).is('br') && + node.previousSibling) { + node = node.previousSibling; + } + } + } + + if (doc.createRange) { + range = doc.createRange(); + + if (!dom.canHaveChildren(node)) { + range.setStartBefore(node); + + if (focusEnd) { + range.setStartAfter(node); + } + } else { + range.selectNodeContents(node); + } + } else { + range = body.createTextRange(); + range.moveToElementText(node.nodeType !== 3 ? + node : node.parentNode); + } + + range.collapse(!focusEnd); + rangeHelper.selectRange(range); + currentSelection = range; + + if (focusEnd) { + $wysiwygDoc.scrollTop(body.scrollHeight); + $wysiwygBody.scrollTop(body.scrollHeight); + } + + base.focus(); + }; + + /** + * Gets if the editor is read only + * + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name readOnly + * @return {Boolean} + */ + /** + * Sets if the editor is read only + * + * @param {boolean} readOnly + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name readOnly^2 + * @return {this} + */ + base.readOnly = function (readOnly) { + if (typeof readOnly !== 'boolean') { + return $sourceEditor.attr('readonly') === 'readonly'; + } + + $wysiwygBody[0].contentEditable = !readOnly; + + if (!readOnly) { + $sourceEditor.removeAttr('readonly'); + } else { + $sourceEditor.attr('readonly', 'readonly'); + } + + updateToolBar(readOnly); + + return base; + }; + + /** + * Gets if the editor is in RTL mode + * + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name rtl + * @return {Boolean} + */ + /** + * Sets if the editor is in RTL mode + * + * @param {boolean} rtl + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name rtl^2 + * @return {this} + */ + base.rtl = function (rtl) { + var dir = rtl ? 'rtl' : 'ltr'; + + if (typeof rtl !== 'boolean') { + return $sourceEditor.attr('dir') === 'rtl'; + } + + $wysiwygBody.attr('dir', dir); + $sourceEditor.attr('dir', dir); + + $editorContainer + .removeClass('rtl') + .removeClass('ltr') + .addClass(dir); + + return base; + }; + + /** + * Updates the toolbar to disable/enable the appropriate buttons + * @private + */ + updateToolBar = function (disable) { + var mode = base.inSourceMode() ? 'txtmode' : 'wysiwygmode'; + + $.each(toolbarButtons, function (idx, $button) { + if (disable === true || !$button.data('sceditor-' + mode)) { + $button.addClass('disabled'); + } else { + $button.removeClass('disabled'); + } + }); + }; + + /** + * Gets the width of the editor in pixels + * + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name width + * @return {int} + */ + /** + * Sets the width of the editor + * + * @param {int} width Width in pixels + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name width^2 + * @return {this} + */ + /** + * Sets the width of the editor + * + * The saveWidth specifies if to save the width. The stored width can be + * used for things like restoring from maximized state. + * + * @param {int} width Width in pixels + * @param {boolean} [saveWidth=true] If to store the width + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name width^3 + * @return {this} + */ + base.width = function (width, saveWidth) { + if (!width && width !== 0) { + return $editorContainer.width(); + } + + base.dimensions(width, null, saveWidth); + + return base; + }; + + /** + * Returns an object with the properties width and height + * which are the width and height of the editor in px. + * + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name dimensions + * @return {object} + */ + /** + *

    Sets the width and/or height of the editor.

    + * + *

    If width or height is not numeric it is ignored.

    + * + * @param {int} width Width in px + * @param {int} height Height in px + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name dimensions^2 + * @return {this} + */ + /** + *

    Sets the width and/or height of the editor.

    + * + *

    If width or height is not numeric it is ignored.

    + * + *

    The save argument specifies if to save the new sizes. + * The saved sizes can be used for things like restoring from + * maximized state. This should normally be left as true.

    + * + * @param {int} width Width in px + * @param {int} height Height in px + * @param {boolean} [save=true] If to store the new sizes + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name dimensions^3 + * @return {this} + */ + base.dimensions = function (width, height, save) { + // IE6 & IE7 add 2 pixels to the source mode textarea + // height which must be ignored. + // Doesn't seem to be any way to fix it with only CSS + var ieBorder = IE_VER < 8 || globalDoc.documentMode < 8 ? 2 : 0; + var undef; + + // set undefined width/height to boolean false + width = (!width && width !== 0) ? false : width; + height = (!height && height !== 0) ? false : height; + + if (width === false && height === false) { + return { width: base.width(), height: base.height() }; + } + + if ($wysiwygEditor.data('outerWidthOffset') === undef) { + base.updateStyleCache(); + } + + if (width !== false) { + if (save !== false) { + options.width = width; + } + // This is the problem + if (height === false) { + height = $editorContainer.height(); + save = false; + } + + $editorContainer.width(width); + if (width && width.toString().indexOf('%') > -1) { + width = $editorContainer.width(); + } + + $wysiwygEditor.width( + width - $wysiwygEditor.data('outerWidthOffset') + ); + + $sourceEditor.width( + width - $sourceEditor.data('outerWidthOffset') + ); + + // Fix overflow issue with iOS not + // breaking words unless a width is set + if (browser.ios && $wysiwygBody) { + $wysiwygBody.width( + width - $wysiwygEditor.data('outerWidthOffset') - + ($wysiwygBody.outerWidth(true) - $wysiwygBody.width()) + ); + } + } + + if (height !== false) { + if (save !== false) { + options.height = height; + } + + // Convert % based heights to px + if (height && height.toString().indexOf('%') > -1) { + height = $editorContainer.height(height).height(); + $editorContainer.height('auto'); + } + + height -= !options.toolbarContainer ? + $toolbar.outerHeight(true) : 0; + + $wysiwygEditor.height( + height - $wysiwygEditor.data('outerHeightOffset') + ); + + $sourceEditor.height( + height - ieBorder - $sourceEditor.data('outerHeightOffset') + ); + } + + return base; + }; + + /** + * Updates the CSS styles cache. + * + * This shouldn't be needed unless changing the editors theme. + *F + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name updateStyleCache + * @return {int} + */ + base.updateStyleCache = function () { + // caching these improves FF resize performance + $wysiwygEditor.data( + 'outerWidthOffset', + $wysiwygEditor.outerWidth(true) - $wysiwygEditor.width() + ); + $sourceEditor.data( + 'outerWidthOffset', + $sourceEditor.outerWidth(true) - $sourceEditor.width() + ); + + $wysiwygEditor.data( + 'outerHeightOffset', + $wysiwygEditor.outerHeight(true) - $wysiwygEditor.height() + ); + $sourceEditor.data( + 'outerHeightOffset', + $sourceEditor.outerHeight(true) - $sourceEditor.height() + ); + }; + + /** + * Gets the height of the editor in px + * + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name height + * @return {int} + */ + /** + * Sets the height of the editor + * + * @param {int} height Height in px + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name height^2 + * @return {this} + */ + /** + * Sets the height of the editor + * + * The saveHeight specifies if to save the height. + * + * The stored height can be used for things like + * restoring from maximized state. + * + * @param {int} height Height in px + * @param {boolean} [saveHeight=true] If to store the height + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name height^3 + * @return {this} + */ + base.height = function (height, saveHeight) { + if (!height && height !== 0) { + return $editorContainer.height(); + } + + base.dimensions(null, height, saveHeight); + + return base; + }; + + /** + * Gets if the editor is maximised or not + * + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name maximize + * @return {boolean} + */ + /** + * Sets if the editor is maximised or not + * + * @param {boolean} maximize If to maximise the editor + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name maximize^2 + * @return {this} + */ + base.maximize = function (maximize) { + if (typeof maximize === 'undefined') { + return $editorContainer.is('.sceditor-maximize'); + } + + maximize = !!maximize; + + // IE 6 fix + if (IE_VER < 7) { + $('html, body').toggleClass('sceditor-maximize', maximize); + } + + $editorContainer.toggleClass('sceditor-maximize', maximize); + base.width(maximize ? '100%' : options.width, false); + base.height(maximize ? '100%' : options.height, false); + + return base; + }; + + /** + * Expands the editors height to the height of it's content + * + * Unless ignoreMaxHeight is set to true it will not expand + * higher than the maxHeight option. + * + * @since 1.3.5 + * @param {Boolean} [ignoreMaxHeight=false] + * @function + * @name expandToContent + * @memberOf jQuery.sceditor.prototype + * @see #resizeToContent + */ + base.expandToContent = function (ignoreMaxHeight) { + var currentHeight = $editorContainer.height(), + padding = (currentHeight - $wysiwygEditor.height()), + height = $wysiwygBody[0].scrollHeight || + $wysiwygDoc[0].documentElement.scrollHeight, + maxHeight = options.resizeMaxHeight || + ((options.height || $original.height()) * 2); + + height += padding; + + if ((ignoreMaxHeight === true || height <= maxHeight) && + height > currentHeight) { + base.height(height); + } + }; + + /** + * Destroys the editor, removing all elements and + * event handlers. + * + * Leaves only the original textarea. + * + * @function + * @name destroy + * @memberOf jQuery.sceditor.prototype + */ + base.destroy = function () { + // Don't destroy if the editor has already been destroyed + if (!pluginManager) { + return; + } + + pluginManager.destroy(); + + rangeHelper = null; + lastRange = null; + pluginManager = null; + + if ($dropdown) { + $dropdown.off().remove(); + } + + $globalDoc.off('click', handleDocumentClick); + $globalWin.off('resize orientationChanged', handleWindowResize); + + $(original.form) + .off('reset', handleFormReset) + .off('submit', base.updateOriginal); + + $wysiwygBody.off(); + $wysiwygDoc.off().find('*').remove(); + + $sourceEditor.off().remove(); + $toolbar.remove(); + $editorContainer.off().find('*').off().remove(); + $editorContainer.remove(); + + $original + .removeData('sceditor') + .removeData('sceditorbbcode') + .show(); + + if (isRequired) { + $original.attr('required', 'required'); + } + }; + + + /** + * Creates a menu item drop down + * + * @param {HTMLElement} menuItem The button to align the dropdown with + * @param {string} name Used for styling the dropdown, will be + * a class sceditor-name + * @param {HTMLElement} content The HTML content of the dropdown + * @param {bool} ieFix If to add the unselectable attribute + * to all the contents elements. Stops + * IE from deselecting the text in the + * editor + * @function + * @name createDropDown + * @memberOf jQuery.sceditor.prototype + */ + base.createDropDown = function (menuItem, name, content, ieFix) { + // first click for create second click for close + var dropDownCss, + cssClass = 'sceditor-' + name, + onlyclose = $dropdown && $dropdown.is('.' + cssClass); + + // Will re-focus the editor. This is needed for IE + // as it has special logic to save/restore the selection + base.closeDropDown(true); + + if (onlyclose) { + return; + } + + // IE needs unselectable attr to stop it from + // unselecting the text in the editor. + // SCEditor can cope if IE does unselect the + // text it's just not nice. + if (ieFix !== false) { + $(content) + .find(':not(input,textarea)') + .filter(function () { + return this.nodeType === 1; + }) + .attr('unselectable', 'on'); + } + + dropDownCss = { + top: menuItem.offset().top, + left: menuItem.offset().left, + marginTop: menuItem.outerHeight() + }; + $.extend(dropDownCss, options.dropDownCss); + + $dropdown = $('
    ') + .css(dropDownCss) + .append(content) + .appendTo($('body')) + .on('click focusin', function (e) { + // stop clicks within the dropdown from being handled + e.stopPropagation(); + }); + + // If try to focus the first input immediately IE will + // place the cursor at the start of the editor instead + // of focusing on the input. + setTimeout(function () { + if ($dropdown) { + $dropdown.find('input,textarea').first().focus(); + } + }); + }; + + /** + * Handles any document click and closes the dropdown if open + * @private + */ + handleDocumentClick = function (e) { + // ignore right clicks + if (e.which !== 3 && $dropdown) { + autoUpdate(); + + base.closeDropDown(); + } + }; + + /** + * Handles the WYSIWYG editors paste event + * @private + */ + handlePasteEvt = function (e) { + var html, handlePaste, scrollTop, + elm = $wysiwygBody[0], + doc = $wysiwygDoc[0], + checkCount = 0, + pastearea = globalDoc.createElement('div'), + prePasteContent = doc.createDocumentFragment(), + clipboardData = e ? e.clipboardData : false; + + if (options.disablePasting) { + return false; + } + + if (!options.enablePasteFiltering) { + return; + } + + rangeHelper.saveRange(); + globalDoc.body.appendChild(pastearea); + + if (clipboardData && clipboardData.getData) { + if ((html = clipboardData.getData('text/html')) || + (html = clipboardData.getData('text/plain'))) { + pastearea.innerHTML = html; + handlePasteData(elm, pastearea); + + return false; + } + } + + // Save the scroll position so can be restored + // when contents is restored + scrollTop = $wysiwygBody.scrollTop() || $wysiwygDoc.scrollTop(); + + while (elm.firstChild) { + prePasteContent.appendChild(elm.firstChild); + } + + // try make pastearea contenteditable and redirect to that? Might work. + // Check the tests if still exist, if not re-0create + handlePaste = function (elm, pastearea) { + if (elm.childNodes.length > 0 || checkCount > 25) { + while (elm.firstChild) { + pastearea.appendChild(elm.firstChild); + } + + while (prePasteContent.firstChild) { + elm.appendChild(prePasteContent.firstChild); + } + + $wysiwygBody.scrollTop(scrollTop); + $wysiwygDoc.scrollTop(scrollTop); + + if (pastearea.childNodes.length > 0) { + handlePasteData(elm, pastearea); + } else { + rangeHelper.restoreRange(); + } + } else { + // Allow max 25 checks before giving up. + // Needed in case an empty string is pasted or + // something goes wrong. + checkCount++; + setTimeout(function () { + handlePaste(elm, pastearea); + }, 20); + } + }; + handlePaste(elm, pastearea); + + base.focus(); + return true; + }; + + /** + * Gets the pasted data, filters it and then inserts it. + * @param {Element} elm + * @param {Element} pastearea + * @private + */ + handlePasteData = function (elm, pastearea) { + // fix any invalid nesting + dom.fixNesting(pastearea); + // TODO: Trigger custom paste event to allow filtering + // (pre and post converstion?) + var pasteddata = pastearea.innerHTML; + + if (pluginManager.hasHandler('toSource')) { + pasteddata = pluginManager.callOnlyFirst( + 'toSource', pasteddata, $(pastearea) + ); + } + + pastearea.parentNode.removeChild(pastearea); + + if (pluginManager.hasHandler('toWysiwyg')) { + pasteddata = pluginManager.callOnlyFirst( + 'toWysiwyg', pasteddata, true + ); + } + + rangeHelper.restoreRange(); + base.wysiwygEditorInsertHtml(pasteddata, null, true); + }; + + /** + * Closes any currently open drop down + * + * @param {bool} [focus=false] If to focus the editor + * after closing the drop down + * @function + * @name closeDropDown + * @memberOf jQuery.sceditor.prototype + */ + base.closeDropDown = function (focus) { + if ($dropdown) { + $dropdown.off().remove(); + $dropdown = null; + } + + if (focus === true) { + base.focus(); + } + }; + + /** + * Gets the WYSIWYG editors document + * @private + */ + getWysiwygDoc = function () { + if (wysiwygEditor.contentDocument) { + return wysiwygEditor.contentDocument; + } + + if (wysiwygEditor.contentWindow && + wysiwygEditor.contentWindow.document) { + return wysiwygEditor.contentWindow.document; + } + + return wysiwygEditor.document; + }; + + + /** + *

    Inserts HTML into WYSIWYG editor.

    + * + *

    If endHtml is specified, any selected text will be placed + * between html and endHtml. If there is no selected text html + * and endHtml will just be concatenate together.

    + * + * @param {string} html + * @param {string} [endHtml=null] + * @param {boolean} [overrideCodeBlocking=false] If to insert the html + * into code tags, by + * default code tags only + * support text. + * @function + * @name wysiwygEditorInsertHtml + * @memberOf jQuery.sceditor.prototype + */ + base.wysiwygEditorInsertHtml = function ( + html, endHtml, overrideCodeBlocking + ) { + var $marker, scrollTop, scrollTo, + editorHeight = $wysiwygEditor.height(); + + base.focus(); + + // TODO: This code tag should be configurable and + // should maybe convert the HTML into text instead + // Don't apply to code elements + if (!overrideCodeBlocking && ($(currentBlockNode).is('code') || + $(currentBlockNode).parents('code').length !== 0)) { + return; + } + + // Insert the HTML and save the range so the editor can be scrolled + // to the end of the selection. Also allows emoticons to be replaced + // without affecting the cursor position + rangeHelper.insertHTML(html, endHtml); + rangeHelper.saveRange(); + replaceEmoticons($wysiwygBody[0]); + + // Scroll the editor after the end of the selection + $marker = $wysiwygBody.find('#sceditor-end-marker').show(); + scrollTop = $wysiwygBody.scrollTop() || $wysiwygDoc.scrollTop(); + scrollTo = (dom.getOffset($marker[0]).top + + ($marker.outerHeight(true) * 1.5)) - editorHeight; + $marker.hide(); + + // Only scroll if marker isn't already visible + if (scrollTo > scrollTop || scrollTo + editorHeight < scrollTop) { + $wysiwygBody.scrollTop(scrollTo); + $wysiwygDoc.scrollTop(scrollTo); + } + + triggerValueChanged(false); + rangeHelper.restoreRange(); + + // Add a new line after the last block element + // so can always add text after it + appendNewLine(); + }; + + /** + * Like wysiwygEditorInsertHtml except it will convert any HTML + * into text before inserting it. + * + * @param {String} text + * @param {String} [endText=null] + * @function + * @name wysiwygEditorInsertText + * @memberOf jQuery.sceditor.prototype + */ + base.wysiwygEditorInsertText = function (text, endText) { + base.wysiwygEditorInsertHtml( + escape.entities(text), escape.entities(endText) + ); + }; + + /** + *

    Inserts text into the WYSIWYG or source editor depending on which + * mode the editor is in.

    + * + *

    If endText is specified any selected text will be placed between + * text and endText. If no text is selected text and endText will + * just be concatenate together.

    + * + * @param {String} text + * @param {String} [endText=null] + * @since 1.3.5 + * @function + * @name insertText + * @memberOf jQuery.sceditor.prototype + */ + base.insertText = function (text, endText) { + if (base.inSourceMode()) { + base.sourceEditorInsertText(text, endText); + } else { + base.wysiwygEditorInsertText(text, endText); + } + + return base; + }; + + /** + *

    Like wysiwygEditorInsertHtml but inserts text into the + * source mode editor instead.

    + * + *

    If endText is specified any selected text will be placed between + * text and endText. If no text is selected text and endText will + * just be concatenate together.

    + * + *

    The cursor will be placed after the text param. If endText is + * specified the cursor will be placed before endText, so passing:
    + * + * '[b]', '[/b]'

    + * + *

    Would cause the cursor to be placed:
    + * + * [b]Selected text|[/b]

    + * + * @param {String} text + * @param {String} [endText=null] + * @since 1.4.0 + * @function + * @name sourceEditorInsertText + * @memberOf jQuery.sceditor.prototype + */ + base.sourceEditorInsertText = function (text, endText) { + var range, scrollTop, currentValue, + startPos = sourceEditor.selectionStart, + endPos = sourceEditor.selectionEnd; + + scrollTop = sourceEditor.scrollTop; + sourceEditor.focus(); + + // All browsers except IE < 9 + if (typeof startPos !== 'undefined') { + currentValue = sourceEditor.value; + + if (endText) { + text += currentValue.substring(startPos, endPos) + endText; + } + + sourceEditor.value = currentValue.substring(0, startPos) + + text + + currentValue.substring(endPos, currentValue.length); + + sourceEditor.selectionStart = (startPos + text.length) - + (endText ? endText.length : 0); + sourceEditor.selectionEnd = sourceEditor.selectionStart; + // IE < 9 + } else { + range = globalDoc.selection.createRange(); + + if (endText) { + text += range.text + endText; + } + + range.text = text; + + if (endText) { + range.moveEnd('character', 0 - endText.length); + } + + range.moveStart('character', range.End - range.Start); + range.select(); + } + + sourceEditor.scrollTop = scrollTop; + sourceEditor.focus(); + + triggerValueChanged(); + }; + + /** + * Gets the current instance of the rangeHelper class + * for the editor. + * + * @return jQuery.sceditor.rangeHelper + * @function + * @name getRangeHelper + * @memberOf jQuery.sceditor.prototype + */ + base.getRangeHelper = function () { + return rangeHelper; + }; + + /** + * Gets the source editors textarea. + * + * This shouldn't be used to insert text + * + * @return {jQuery} + * @function + * @since 1.4.5 + * @name sourceEditorCaret + * @memberOf jQuery.sceditor.prototype + */ + base.sourceEditorCaret = function (position) { + var range, + ret = {}; + + sourceEditor.focus(); + + // All browsers except IE <= 8 + if (typeof sourceEditor.selectionStart !== 'undefined') { + if (position) { + sourceEditor.selectionStart = position.start; + sourceEditor.selectionEnd = position.end; + } else { + ret.start = sourceEditor.selectionStart; + ret.end = sourceEditor.selectionEnd; + } + + // IE8 and below + } else { + range = globalDoc.selection.createRange(); + + if (position) { + range.moveEnd('character', position.end); + range.moveStart('character', position.start); + range.select(); + } else { + ret.start = range.Start; + ret.end = range.End; + } + } + + return position ? this : ret; + }; + + /** + *

    Gets the value of the editor.

    + * + *

    If the editor is in WYSIWYG mode it will return the filtered + * HTML from it (converted to BBCode if using the BBCode plugin). + * It it's in Source Mode it will return the unfiltered contents + * of the source editor (if using the BBCode plugin this will be + * BBCode again).

    + * + * @since 1.3.5 + * @return {string} + * @function + * @name val + * @memberOf jQuery.sceditor.prototype + */ + /** + *

    Sets the value of the editor.

    + * + *

    If filter set true the val will be passed through the filter + * function. If using the BBCode plugin it will pass the val to + * the BBCode filter to convert any BBCode into HTML.

    + * + * @param {String} val + * @param {Boolean} [filter=true] + * @return {this} + * @since 1.3.5 + * @function + * @name val^2 + * @memberOf jQuery.sceditor.prototype + */ + base.val = function (val, filter) { + if (typeof val !== 'string') { + return base.inSourceMode() ? + base.getSourceEditorValue(false) : + base.getWysiwygEditorValue(filter); + } + + if (!base.inSourceMode()) { + if (filter !== false && + pluginManager.hasHandler('toWysiwyg')) { + val = pluginManager.callOnlyFirst('toWysiwyg', val); + } + + base.setWysiwygEditorValue(val); + } else { + base.setSourceEditorValue(val); + } + + return base; + }; + + /** + *

    Inserts HTML/BBCode into the editor

    + * + *

    If end is supplied any selected text will be placed between + * start and end. If there is no selected text start and end + * will be concatenate together.

    + * + *

    If the filter param is set to true, the HTML/BBCode will be + * passed through any plugin filters. If using the BBCode plugin + * this will convert any BBCode into HTML.

    + * + * @param {String} start + * @param {String} [end=null] + * @param {Boolean} [filter=true] + * @param {Boolean} [convertEmoticons=true] If to convert emoticons + * @return {this} + * @since 1.3.5 + * @function + * @name insert + * @memberOf jQuery.sceditor.prototype + */ + /** + *

    Inserts HTML/BBCode into the editor

    + * + *

    If end is supplied any selected text will be placed between + * start and end. If there is no selected text start and end + * will be concatenate together.

    + * + *

    If the filter param is set to true, the HTML/BBCode will be + * passed through any plugin filters. If using the BBCode plugin + * this will convert any BBCode into HTML.

    + * + *

    If the allowMixed param is set to true, HTML any will not be + * escaped

    + * + * @param {String} start + * @param {String} [end=null] + * @param {Boolean} [filter=true] + * @param {Boolean} [convertEmoticons=true] If to convert emoticons + * @param {Boolean} [allowMixed=false] + * @return {this} + * @since 1.4.3 + * @function + * @name insert^2 + * @memberOf jQuery.sceditor.prototype + */ + base.insert = function ( + /*jshint maxparams: false */ + start, end, filter, convertEmoticons, allowMixed + ) { + if (base.inSourceMode()) { + base.sourceEditorInsertText(start, end); + return base; + } + + // Add the selection between start and end + if (end) { + var html = rangeHelper.selectedHtml(), + $div = $('
    ').appendTo($('body')).hide().html(html); + + if (filter !== false && pluginManager.hasHandler('toSource')) { + html = pluginManager.callOnlyFirst('toSource', html, $div); + } + + $div.remove(); + + start += html + end; + } + // TODO: This filter should allow empty tags as it's inserting. + if (filter !== false && pluginManager.hasHandler('toWysiwyg')) { + start = pluginManager.callOnlyFirst('toWysiwyg', start, true); + } + + // Convert any escaped HTML back into HTML if mixed is allowed + if (filter !== false && allowMixed === true) { + start = start.replace(/</g, '<') + .replace(/>/g, '>') + .replace(/&/g, '&'); + } + + base.wysiwygEditorInsertHtml(start); + + return base; + }; + + /** + * Gets the WYSIWYG editors HTML value. + * + * If using a plugin that filters the Ht Ml like the BBCode plugin + * it will return the result of the filtering (BBCode) unless the + * filter param is set to false. + * + * @param {bool} [filter=true] + * @return {string} + * @function + * @name getWysiwygEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.getWysiwygEditorValue = function (filter) { + var html; + // Create a tmp node to store contents so it can be modified + // without affecting anything else. + var $tmp = $('
    ') + .appendTo(document.body) + .append($($wysiwygBody[0].childNodes).clone()); + + dom.fixNesting($tmp[0]); + + html = $tmp.html(); + + // filter the HTML and DOM through any plugins + if (filter !== false && pluginManager.hasHandler('toSource')) { + html = pluginManager.callOnlyFirst('toSource', html, $tmp); + } + + $tmp.remove(); + + return html; + }; + + /** + * Gets the WYSIWYG editor's iFrame Body. + * + * @return {jQuery} + * @function + * @since 1.4.3 + * @name getBody + * @memberOf jQuery.sceditor.prototype + */ + base.getBody = function () { + return $wysiwygBody; + }; + + /** + * Gets the WYSIWYG editors container area (whole iFrame). + * + * @return {Node} + * @function + * @since 1.4.3 + * @name getContentAreaContainer + * @memberOf jQuery.sceditor.prototype + */ + base.getContentAreaContainer = function () { + return $wysiwygEditor; + }; + + /** + * Gets the text editor value + * + * If using a plugin that filters the text like the BBCode plugin + * it will return the result of the filtering which is BBCode to + * HTML so it will return HTML. If filter is set to false it will + * just return the contents of the source editor (BBCode). + * + * @param {bool} [filter=true] + * @return {string} + * @function + * @since 1.4.0 + * @name getSourceEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.getSourceEditorValue = function (filter) { + var val = $sourceEditor.val(); + + if (filter !== false && pluginManager.hasHandler('toWysiwyg')) { + val = pluginManager.callOnlyFirst('toWysiwyg', val); + } + + return val; + }; + + /** + * Sets the WYSIWYG HTML editor value. Should only be the HTML + * contained within the body tags + * + * @param {string} value + * @function + * @name setWysiwygEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.setWysiwygEditorValue = function (value) { + if (!value) { + value = '

    ' + (IE_VER ? '' : '
    ') + '

    '; + } + + $wysiwygBody[0].innerHTML = value; + replaceEmoticons($wysiwygBody[0]); + + appendNewLine(); + triggerValueChanged(); + }; + + /** + * Sets the text editor value + * + * @param {string} value + * @function + * @name setSourceEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.setSourceEditorValue = function (value) { + $sourceEditor.val(value); + + triggerValueChanged(); + }; + + /** + * Updates the textarea that the editor is replacing + * with the value currently inside the editor. + * + * @function + * @name updateOriginal + * @since 1.4.0 + * @memberOf jQuery.sceditor.prototype + */ + base.updateOriginal = function () { + $original.val(base.val()); + }; + + /** + * Replaces any emoticon codes in the passed HTML + * with their emoticon images + * @private + */ + replaceEmoticons = function (node) { + // TODO: Make this tag configurable. + if (!options.emoticonsEnabled || $(node).parents('code').length) { + return; + } + + var doc = node.ownerDocument, + whitespace = '\\s|\xA0|\u2002|\u2003|\u2009| ', + emoticonCodes = [], + emoticonRegex = [], + emoticons = $.extend( + {}, + options.emoticons.more, + options.emoticons.dropdown, + options.emoticons.hidden + ); + // TODO: cache the emoticonCodes and emoticonCodes objects and share them with + // the AYT converstion + $.each(emoticons, function (key) { + if (options.emoticonsCompat) { + emoticonRegex[key] = new RegExp( + '(>|^|' + whitespace + ')' + + escape.regex(key) + + '($|<|' + whitespace + ')' + ); + } + + emoticonCodes.push(key); + }); + // TODO: tidy below + var convertEmoticons = function (node) { + node = node.firstChild; + + while (node) { + var parts, key, emoticon, parsedHtml, + emoticonIdx, nextSibling, matchPos, + nodeParent = node.parentNode, + nodeValue = node.nodeValue; + + // All none textnodes + if (node.nodeType !== 3) { + // TODO: Make this tag configurable. + if (!$(node).is('code')) { + convertEmoticons(node); + } + } else if (nodeValue) { + emoticonIdx = emoticonCodes.length; + while (emoticonIdx--) { + key = emoticonCodes[emoticonIdx]; + matchPos = options.emoticonsCompat ? + nodeValue.search(emoticonRegex[key]) : + nodeValue.indexOf(key); + + if (matchPos > -1) { + nextSibling = node.nextSibling; + emoticon = emoticons[key]; + parts = nodeValue + .substr(matchPos).split(key); + nodeValue = nodeValue + .substr(0, matchPos) + parts.shift(); + node.nodeValue = nodeValue; + + parsedHtml = dom.parseHTML(_tmpl('emoticon', { + key: key, + url: emoticon.url || emoticon, + tooltip: emoticon.tooltip || key + }), doc); + + nodeParent.insertBefore( + parsedHtml[0], + nextSibling + ); + + nodeParent.insertBefore( + doc.createTextNode(parts.join(key)), + nextSibling + ); + } + } + } + + node = node.nextSibling; + } + }; + + convertEmoticons(node); + + if (options.emoticonsCompat) { + currentEmoticons = $wysiwygBody + .find('img[data-sceditor-emoticon]'); + } + }; + + /** + * If the editor is in source code mode + * + * @return {bool} + * @function + * @name inSourceMode + * @memberOf jQuery.sceditor.prototype + */ + base.inSourceMode = function () { + return $editorContainer.hasClass('sourceMode'); + }; + + /** + * Gets if the editor is in sourceMode + * + * @return boolean + * @function + * @name sourceMode + * @memberOf jQuery.sceditor.prototype + */ + /** + * Sets if the editor is in sourceMode + * + * @param {bool} enable + * @return {this} + * @function + * @name sourceMode^2 + * @memberOf jQuery.sceditor.prototype + */ + base.sourceMode = function (enable) { + var inSourceMode = base.inSourceMode(); + + if (typeof enable !== 'boolean') { + return inSourceMode; + } + + if ((inSourceMode && !enable) || (!inSourceMode && enable)) { + base.toggleSourceMode(); + } + + return base; + }; + + /** + * Switches between the WYSIWYG and source modes + * + * @function + * @name toggleSourceMode + * @since 1.4.0 + * @memberOf jQuery.sceditor.prototype + */ + base.toggleSourceMode = function () { + var sourceMode = base.inSourceMode(); + + // don't allow switching to WYSIWYG if doesn't support it + if (!browser.isWysiwygSupported && sourceMode) { + return; + } + + if (!sourceMode) { + rangeHelper.saveRange(); + rangeHelper.clear(); + } + + base.blur(); + + if (sourceMode) { + base.setWysiwygEditorValue(base.getSourceEditorValue()); + } else { + base.setSourceEditorValue(base.getWysiwygEditorValue()); + } + + lastRange = null; + $sourceEditor.toggle(); + $wysiwygEditor.toggle(); + $editorContainer + .toggleClass('wysiwygMode', sourceMode) + .toggleClass('sourceMode', !sourceMode); + + updateToolBar(); + updateActiveButtons(); + }; + + /** + * Gets the selected text of the source editor + * @return {String} + * @private + */ + sourceEditorSelectedText = function () { + sourceEditor.focus(); + + if (typeof sourceEditor.selectionStart !== 'undefined') { + return sourceEditor.value.substring( + sourceEditor.selectionStart, + sourceEditor.selectionEnd + ); + } else { + return globalDoc.selection.createRange().text; + } + }; + + /** + * Handles the passed command + * @private + */ + handleCommand = function (caller, cmd) { + // check if in text mode and handle text commands + if (base.inSourceMode()) { + if (cmd.txtExec) { + if ($.isArray(cmd.txtExec)) { + base.sourceEditorInsertText.apply(base, cmd.txtExec); + } else { + cmd.txtExec.call( + base, + caller, + sourceEditorSelectedText() + ); + } + } + } else if (cmd.exec) { + if ($.isFunction(cmd.exec)) { + cmd.exec.call(base, caller); + } else { + base.execCommand( + cmd.exec, + cmd.hasOwnProperty('execParam') ? + cmd.execParam : null + ); + } + } + + }; + + /** + * Saves the current range. Needed for IE because it forgets + * where the cursor was and what was selected + * @private + */ + saveRange = function () { + /* this is only needed for IE */ + if (IE_VER) { + lastRange = rangeHelper.selectedRange(); + } + }; + + /** + * Executes a command on the WYSIWYG editor + * + * @param {String} command + * @param {String|Boolean} [param] + * @function + * @name execCommand + * @memberOf jQuery.sceditor.prototype + */ + base.execCommand = function (command, param) { + var executed = false, + commandObj = base.commands[command], + $parentNode = $(rangeHelper.parentNode()); + + base.focus(); + + // TODO: make configurable + // don't apply any commands to code elements + if ($parentNode.is('code') || + $parentNode.parents('code').length !== 0) { + return; + } + + try { + executed = $wysiwygDoc[0].execCommand(command, false, param); + } catch (ex) {} + + // show error if execution failed and an error message exists + if (!executed && commandObj && commandObj.errorMessage) { + /*global alert:false*/ + alert(base._(commandObj.errorMessage)); + } + + updateActiveButtons(); + }; + + /** + * Checks if the current selection has changed and triggers + * the selectionchanged event if it has. + * + * In browsers other than IE, it will check at most once every 100ms. + * This is because only IE has a selection changed event. + * @private + */ + checkSelectionChanged = function () { + function check () { + // rangeHelper could be null if editor was destroyed + // before the timeout had finished + if (rangeHelper && !rangeHelper.compare(currentSelection)) { + currentSelection = rangeHelper.cloneSelected(); + $editorContainer.trigger($.Event('selectionchanged')); + } + + isSelectionCheckPending = false; + } + + if (isSelectionCheckPending) { + return; + } + + isSelectionCheckPending = true; + + // In IE, this is only called on the selectionchange event so no + // need to limit checking as it should always be valid to do. + if (IE_VER) { + check(); + } else { + setTimeout(check, 100); + } + }; + + /** + * Checks if the current node has changed and triggers + * the nodechanged event if it has + * @private + */ + checkNodeChanged = function () { + // check if node has changed + var oldNode, + node = rangeHelper.parentNode(); + + if (currentNode !== node) { + oldNode = currentNode; + currentNode = node; + currentBlockNode = rangeHelper.getFirstBlockParent(node); + + $editorContainer.trigger($.Event('nodechanged', { + oldNode: oldNode, + newNode: currentNode + })); + } + }; + + /** + *

    Gets the current node that contains the selection/caret in + * WYSIWYG mode.

    + * + *

    Will be null in sourceMode or if there is no selection.

    + * @return {Node} + * @function + * @name currentNode + * @memberOf jQuery.sceditor.prototype + */ + base.currentNode = function () { + return currentNode; + }; + + /** + *

    Gets the first block level node that contains the + * selection/caret in WYSIWYG mode.

    + * + *

    Will be null in sourceMode or if there is no selection.

    + * @return {Node} + * @function + * @name currentBlockNode + * @memberOf jQuery.sceditor.prototype + * @since 1.4.4 + */ + base.currentBlockNode = function () { + return currentBlockNode; + }; + + /** + * Updates if buttons are active or not + * @private + */ + updateActiveButtons = function (e) { + var firstBlock, parent; + var activeClass = 'active'; + var doc = $wysiwygDoc[0]; + var isSource = base.sourceMode(); + + if (base.readOnly()) { + $toolbar.find(activeClass).removeClass(activeClass); + return; + } + + if (!isSource) { + parent = e ? e.newNode : rangeHelper.parentNode(); + firstBlock = rangeHelper.getFirstBlockParent(parent); + } + + for (var i = 0; i < btnStateHandlers.length; i++) { + var state = 0; + var $btn = toolbarButtons[btnStateHandlers[i].name]; + var stateFn = btnStateHandlers[i].state; + var isDisabled = (isSource && !$btn.data('sceditor-txtmode')) || + (!isSource && !$btn.data('sceditor-wysiwygmode')); + + if (typeof stateFn === 'string') { + if (!isSource) { + try { + state = doc.queryCommandEnabled(stateFn) ? 0 : -1; + + /*jshint maxdepth: false*/ + if (state > -1) { + state = doc.queryCommandState(stateFn) ? 1 : 0; + } + } catch (ex) {} + } + } else if (!isDisabled) { + state = stateFn.call(base, parent, firstBlock); + } + + $btn + .toggleClass('disabled', isDisabled || state < 0) + .toggleClass(activeClass, state > 0); + } + }; + + /** + * Handles any key press in the WYSIWYG editor + * + * @private + */ + handleKeyPress = function (e) { + var $closestTag, br, brParent, lastChild; + + // TODO: improve this so isn't set list, probably should just use + // dom.hasStyling to all block parents and if one does insert a br + var DUPLICATED_TAGS = 'code,blockquote,pre'; + var LIST_TAGS = 'li,ul,ol'; + + // FF bug: https://bugzilla.mozilla.org/show_bug.cgi?id=501496 + if (e.originalEvent.defaultPrevented) { + return; + } + + base.closeDropDown(); + + $closestTag = $(currentBlockNode) + .closest(DUPLICATED_TAGS + ',' + LIST_TAGS) + .first(); + + // "Fix" (OK it's a cludge) for blocklevel elements being + // duplicated in some browsers when enter is pressed instead + // of inserting a newline + if (e.which === 13 && $closestTag.length && + !$closestTag.is(LIST_TAGS)) { + lastRange = null; + + br = $wysiwygDoc[0].createElement('br'); + rangeHelper.insertNode(br); + + // Last
    of a block will be collapsed unless it is + // IE < 11 so need to make sure the
    that was inserted + // isn't the last node of a block. + if (!IE_BR_FIX) { + brParent = br.parentNode; + lastChild = brParent.lastChild; + + // Sometimes an empty next node is created after the
    + if (lastChild && lastChild.nodeType === 3 && + lastChild.nodeValue === '') { + brParent.removeChild(lastChild); + lastChild = brParent.lastChild; + } + + // If this is the last BR of a block and the previous + // sibling is inline then will need an extra BR. This + // is needed because the last BR of a block will be + // collapsed. Fixes issue #248 + if (!dom.isInline(brParent, true) && lastChild === br && + dom.isInline(br.previousSibling)) { + rangeHelper.insertHTML('
    '); + } + } + + return false; + } + }; + + /** + * Makes sure that if there is a code or quote tag at the + * end of the editor, that there is a new line after it. + * + * If there wasn't a new line at the end you wouldn't be able + * to enter any text after a code/quote tag + * @return {void} + * @private + */ + appendNewLine = function () { + var name, requiresNewLine, paragraph, + body = $wysiwygBody[0]; + + dom.rTraverse(body, function (node) { + name = node.nodeName.toLowerCase(); + // TODO: Replace requireNewLineFix with just a block level fix for any + // block that has styling and any block that isn't a plain

    or

    + if ($.inArray(name, requireNewLineFix) > -1) { + requiresNewLine = true; + } + // TODO: tidy this up + // find the last non-empty text node or line break. + if ((node.nodeType === 3 && !/^\s*$/.test(node.nodeValue)) || + name === 'br' || (IE_BR_FIX && !node.firstChild && + !dom.isInline(node, false))) { + + // this is the last text or br node, if its in a code or + // quote tag then add a newline to the end of the editor + if (requiresNewLine) { + paragraph = $wysiwygDoc[0].createElement('p'); + paragraph.className = 'sceditor-nlf'; + paragraph.innerHTML = !IE_BR_FIX ? '
    ' : ''; + body.appendChild(paragraph); + } + + return false; + } + }); + }; + + /** + * Handles form reset event + * @private + */ + handleFormReset = function () { + base.val($original.val()); + }; + + /** + * Handles any mousedown press in the WYSIWYG editor + * @private + */ + handleMouseDown = function () { + base.closeDropDown(); + lastRange = null; + }; + + /** + * Handles the window resize event. Needed to resize then editor + * when the window size changes in fluid designs. + * @ignore + */ + handleWindowResize = function () { + var height = options.height, + width = options.width; + + if (!base.maximize()) { + if ((height && height.toString().indexOf('%') > -1) || + (width && width.toString().indexOf('%') > -1)) { + base.dimensions(width, height); + } + } else { + base.dimensions('100%', '100%', false); + } + }; + + /** + * Translates the string into the locale language. + * + * Replaces any {0}, {1}, {2}, ect. with the params provided. + * + * @param {string} str + * @param {...String} args + * @return {string} + * @function + * @name _ + * @memberOf jQuery.sceditor.prototype + */ + base._ = function () { + var undef, + args = arguments; + + if (locale && locale[args[0]]) { + args[0] = locale[args[0]]; + } + + return args[0].replace(/\{(\d+)\}/g, function (str, p1) { + return args[p1 - 0 + 1] !== undef ? + args[p1 - 0 + 1] : + '{' + p1 + '}'; + }); + }; + + /** + * Passes events on to any handlers + * @private + * @return void + */ + handleEvent = function (e) { + // Send event to all plugins + pluginManager.call(e.type + 'Event', e, base); + + // convert the event into a custom event to send + var prefix = e.target === sourceEditor ? 'scesrc' : 'scewys'; + var customEvent = $.Event(e); + customEvent.type = prefix + e.type; + + $editorContainer.trigger(customEvent, base); + }; + + /** + *

    Binds a handler to the specified events

    + * + *

    This function only binds to a limited list of + * supported events.
    + * The supported events are: + *

      + *
    • keyup
    • + *
    • keydown
    • + *
    • Keypress
    • + *
    • blur
    • + *
    • focus
    • + *
    • nodechanged
      + * When the current node containing the selection changes + * in WYSIWYG mode
    • + *
    • contextmenu
    • + *
    • selectionchanged
    • + *
    • valuechanged
    • + *
    + *

    + * + *

    The events param should be a string containing the event(s) + * to bind this handler to. If multiple, they should be separated + * by spaces.

    + * + * @param {String} events + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name bind + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.bind = function (events, handler, excludeWysiwyg, excludeSource) { + events = events.split(' '); + + var i = events.length; + while (i--) { + if ($.isFunction(handler)) { + // Use custom events to allow passing the instance as the + // 2nd argument. + // Also allows unbinding without unbinding the editors own + // event handlers. + if (!excludeWysiwyg) { + $editorContainer.on('scewys' + events[i], handler); + } + + if (!excludeSource) { + $editorContainer.on('scesrc' + events[i], handler); + } + + // Start sending value changed events + if (events[i] === 'valuechanged') { + triggerValueChanged.hasHandler = true; + } + } + } + + return base; + }; + + /** + * Unbinds an event that was bound using bind(). + * + * @param {String} events + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude unbinding this + * handler from the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude unbinding this + * handler from the source editor + * @return {this} + * @function + * @name unbind + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + * @see bind + */ + base.unbind = function ( + events, handler, excludeWysiwyg, excludeSource + ) { + events = events.split(' '); + + var i = events.length; + while (i--) { + if ($.isFunction(handler)) { + if (!excludeWysiwyg) { + $editorContainer.off('scewys' + events[i], handler); + } + + if (!excludeSource) { + $editorContainer.off('scesrc' + events[i], handler); + } + } + } + + return base; + }; + + /** + * Blurs the editors input area + * + * @return {this} + * @function + * @name blur + * @memberOf jQuery.sceditor.prototype + * @since 1.3.6 + */ + /** + * Adds a handler to the editors blur event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name blur^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.blur = function (handler, excludeWysiwyg, excludeSource) { + if ($.isFunction(handler)) { + base.bind('blur', handler, excludeWysiwyg, excludeSource); + } else if (!base.sourceMode()) { + $wysiwygBody.blur(); + } else { + $sourceEditor.blur(); + } + + return base; + }; + + /** + * Focuses the editors input area + * + * @return {this} + * @function + * @name focus + * @memberOf jQuery.sceditor.prototype + */ + /** + * Adds an event handler to the focus event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name focus^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.focus = function (handler, excludeWysiwyg, excludeSource) { + if ($.isFunction(handler)) { + base.bind('focus', handler, excludeWysiwyg, excludeSource); + } else if (!base.inSourceMode()) { + var container, + rng = rangeHelper.selectedRange(); + + // Fix FF bug where it shows the cursor in the wrong place + // if the editor hasn't had focus before. See issue #393 + if (!currentSelection && !rangeHelper.hasSelection()) { + autofocus(); + } + + // Check if cursor is set after a BR when the BR is the only + // child of the parent. In Firefox this causes a line break + // to occur when something is typed. See issue #321 + if (!IE_BR_FIX && rng && rng.endOffset === 1 && rng.collapsed) { + container = rng.endContainer; + + if (container && container.childNodes.length === 1 && + $(container.firstChild).is('br')) { + rng.setStartBefore(container.firstChild); + rng.collapse(true); + rangeHelper.selectRange(rng); + } + } + + wysiwygEditor.contentWindow.focus(); + $wysiwygBody[0].focus(); + + // Needed for IE < 9 + if (lastRange) { + rangeHelper.selectRange(lastRange); + + // remove the stored range after being set. + // If the editor loses focus it should be + // saved again. + lastRange = null; + } + } else { + sourceEditor.focus(); + } + + updateActiveButtons(); + + return base; + }; + + /** + * Adds a handler to the key down event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name keyDown + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.keyDown = function (handler, excludeWysiwyg, excludeSource) { + return base.bind('keydown', handler, excludeWysiwyg, excludeSource); + }; + + /** + * Adds a handler to the key press event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name keyPress + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.keyPress = function (handler, excludeWysiwyg, excludeSource) { + return base + .bind('keypress', handler, excludeWysiwyg, excludeSource); + }; + + /** + * Adds a handler to the key up event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name keyUp + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.keyUp = function (handler, excludeWysiwyg, excludeSource) { + return base.bind('keyup', handler, excludeWysiwyg, excludeSource); + }; + + /** + *

    Adds a handler to the node changed event.

    + * + *

    Happens whenever the node containing the selection/caret + * changes in WYSIWYG mode.

    + * + * @param {Function} handler + * @return {this} + * @function + * @name nodeChanged + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.nodeChanged = function (handler) { + return base.bind('nodechanged', handler, false, true); + }; + + /** + *

    Adds a handler to the selection changed event

    + * + *

    Happens whenever the selection changes in WYSIWYG mode.

    + * + * @param {Function} handler + * @return {this} + * @function + * @name selectionChanged + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.selectionChanged = function (handler) { + return base.bind('selectionchanged', handler, false, true); + }; + + /** + *

    Adds a handler to the value changed event

    + * + *

    Happens whenever the current editor value changes.

    + * + *

    Whenever anything is inserted, the value changed or + * 1.5 secs after text is typed. If a space is typed it will + * cause the event to be triggered immediately instead of + * after 1.5 seconds

    + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name valueChanged + * @memberOf jQuery.sceditor.prototype + * @since 1.4.5 + */ + base.valueChanged = function (handler, excludeWysiwyg, excludeSource) { + return base + .bind('valuechanged', handler, excludeWysiwyg, excludeSource); + }; + + /** + * Emoticons keypress handler + * @private + */ + emoticonsKeyPress = function (e) { + var replacedEmoticon, + cachePos = 0, + emoticonsCache = base.emoticonsCache, + curChar = String.fromCharCode(e.which); + // TODO: Make configurable + if ($(currentBlockNode).is('code') || + $(currentBlockNode).parents('code').length) { + return; + } + + if (!emoticonsCache) { + emoticonsCache = []; + + $.each($.extend( + {}, + options.emoticons.more, + options.emoticons.dropdown, + options.emoticons.hidden + ), function (key, url) { + emoticonsCache[cachePos++] = [ + key, + _tmpl('emoticon', { + key: key, + url: url.url || url, + tooltip: url.tooltip || key + }) + ]; + }); + + emoticonsCache.sort(function (a, b) { + return a[0].length - b[0].length; + }); + + base.emoticonsCache = emoticonsCache; + base.longestEmoticonCode = + emoticonsCache[emoticonsCache.length - 1][0].length; + } + + replacedEmoticon = rangeHelper.replaceKeyword( + base.emoticonsCache, + true, + true, + base.longestEmoticonCode, + options.emoticonsCompat, + curChar + ); + + if (replacedEmoticon && options.emoticonsCompat) { + currentEmoticons = $wysiwygBody + .find('img[data-sceditor-emoticon]'); + + return /^\s$/.test(curChar); + } + + return !replacedEmoticon; + }; + + /** + * Makes sure emoticons are surrounded by whitespace + * @private + */ + emoticonsCheckWhitespace = function () { + if (!currentEmoticons.length) { + return; + } + + var prev, next, parent, range, previousText, rangeStartContainer, + currentBlock = base.currentBlockNode(), + rangeStart = false, + noneWsRegex = /[^\s\xA0\u2002\u2003\u2009\u00a0]+/; + + currentEmoticons = $.map(currentEmoticons, function (emoticon) { + // Ignore emoticons that have been removed from DOM + if (!emoticon || !emoticon.parentNode) { + return null; + } + + if (!$.contains(currentBlock, emoticon)) { + return emoticon; + } + + prev = emoticon.previousSibling; + next = emoticon.nextSibling; + previousText = prev.nodeValue; + + // For IE's HTMLPhraseElement + if (previousText === null) { + previousText = prev.innerText || ''; + } + + if ((!prev || !noneWsRegex.test(prev.nodeValue.slice(-1))) && + (!next || !noneWsRegex.test((next.nodeValue || '')[0]))) { + return emoticon; + } + + parent = emoticon.parentNode; + range = rangeHelper.cloneSelected(); + rangeStartContainer = range.startContainer; + previousText = previousText + + $(emoticon).data('sceditor-emoticon'); + + // Store current caret position + if (rangeStartContainer === next) { + rangeStart = previousText.length + range.startOffset; + } else if (rangeStartContainer === currentBlock && + currentBlock.childNodes[range.startOffset] === next) { + rangeStart = previousText.length; + } else if (rangeStartContainer === prev) { + rangeStart = range.startOffset; + } + + if (!next || next.nodeType !== 3) { + next = parent.insertBefore( + parent.ownerDocument.createTextNode(''), next + ); + } + + next.insertData(0, previousText); + parent.removeChild(prev); + parent.removeChild(emoticon); + + // Need to update the range starting + // position if it has been modified + if (rangeStart !== false) { + range.setStart(next, rangeStart); + range.collapse(true); + rangeHelper.selectRange(range); + } + + return null; + }); + }; + + /** + * Gets if emoticons are currently enabled + * @return {boolean} + * @function + * @name emoticons + * @memberOf jQuery.sceditor.prototype + * @since 1.4.2 + */ + /** + * Enables/disables emoticons + * + * @param {boolean} enable + * @return {this} + * @function + * @name emoticons^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.2 + */ + base.emoticons = function (enable) { + if (!enable && enable !== false) { + return options.emoticonsEnabled; + } + + options.emoticonsEnabled = enable; + + if (enable) { + $wysiwygBody.keypress(emoticonsKeyPress); + + if (!base.sourceMode()) { + rangeHelper.saveRange(); + + replaceEmoticons($wysiwygBody[0]); + currentEmoticons = $wysiwygBody + .find('img[data-sceditor-emoticon]'); + triggerValueChanged(false); + + rangeHelper.restoreRange(); + } + } else { + $wysiwygBody + .find('img[data-sceditor-emoticon]') + .replaceWith(function () { + return $(this).data('sceditor-emoticon'); + }); + + currentEmoticons = []; + $wysiwygBody.off('keypress', emoticonsKeyPress); + + triggerValueChanged(); + } + + return base; + }; + + /** + * Gets the current WYSIWYG editors inline CSS + * + * @return {string} + * @function + * @name css + * @memberOf jQuery.sceditor.prototype + * @since 1.4.3 + */ + /** + * Sets inline CSS for the WYSIWYG editor + * + * @param {string} css + * @return {this} + * @function + * @name css^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.3 + */ + base.css = function (css) { + if (!inlineCss) { + inlineCss = $('' + + '' + + '' + + '' + + '

    ' + + '', + + toolbarButton: '' + + '
    {dispName}
    ', + + emoticon: '', + + fontOpt: '{font}', + + sizeOpt: '{size}', + + pastetext: + '
    ' + + '
    ' + + '
    ' + + '
    ', + + table: + '
    ' + + '
    ' + + '
    ', + + image: + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ', + + email: + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ', + + link: + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ', + + youtubeMenu: + '
    ' + + '
    ' + + '
    ' + + '
    ', + + youtube: + '' + }; + + /** + *

    Replaces any params in a template with the passed params.

    + * + *

    If createHtml is passed it will use jQuery to create the HTML. The + * same as doing: $(editor.tmpl("html", {params...}));

    + * + * @param {string} name + * @param {Object} params + * @param {Boolean} createHtml + * @private + */ + return function (name, params, createHtml) { + var template = _templates[name]; + + $.each(params, function (name, val) { + template = template.replace( + new RegExp('\\{' + name + '\\}', 'g'), val + ); + }); + + if (createHtml) { + template = $(template); + } + + return template; + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var IE_VER = __webpack_require__(6).ie; + var _tmpl = __webpack_require__(8); + + // In IE < 11 a BR at the end of a block level element + // causes a line break. In all other browsers it's collapsed. + var IE_BR_FIX = IE_VER && IE_VER < 11; + + + /** + * Map of all the commands for SCEditor + * @type {Object} + * @name commands + * @memberOf jQuery.sceditor + */ + var defaultCommnds = { + // START_COMMAND: Bold + bold: { + exec: 'bold', + tooltip: 'Bold', + shortcut: 'Ctrl+B' + }, + // END_COMMAND + // START_COMMAND: Italic + italic: { + exec: 'italic', + tooltip: 'Italic', + shortcut: 'Ctrl+I' + }, + // END_COMMAND + // START_COMMAND: Underline + underline: { + exec: 'underline', + tooltip: 'Underline', + shortcut: 'Ctrl+U' + }, + // END_COMMAND + // START_COMMAND: Strikethrough + strike: { + exec: 'strikethrough', + tooltip: 'Strikethrough' + }, + // END_COMMAND + // START_COMMAND: Subscript + subscript: { + exec: 'subscript', + tooltip: 'Subscript' + }, + // END_COMMAND + // START_COMMAND: Superscript + superscript: { + exec: 'superscript', + tooltip: 'Superscript' + }, + // END_COMMAND + + // START_COMMAND: Left + left: { + exec: 'justifyleft', + tooltip: 'Align left' + }, + // END_COMMAND + // START_COMMAND: Centre + center: { + exec: 'justifycenter', + tooltip: 'Center' + }, + // END_COMMAND + // START_COMMAND: Right + right: { + exec: 'justifyright', + tooltip: 'Align right' + }, + // END_COMMAND + // START_COMMAND: Justify + justify: { + exec: 'justifyfull', + tooltip: 'Justify' + }, + // END_COMMAND + + // START_COMMAND: Font + font: { + _dropDown: function (editor, caller, callback) { + var fontIdx = 0, + fonts = editor.opts.fonts.split(','), + content = $('
    '), + /** @private */ + clickFunc = function () { + callback($(this).data('font')); + editor.closeDropDown(true); + return false; + }; + + for (; fontIdx < fonts.length; fontIdx++) { + content.append( + _tmpl('fontOpt', { + font: fonts[fontIdx] + }, true).click(clickFunc) + ); + } + + editor.createDropDown(caller, 'font-picker', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.font._dropDown( + editor, + caller, + function (fontName) { + editor.execCommand('fontname', fontName); + } + ); + }, + tooltip: 'Font Name' + }, + // END_COMMAND + // START_COMMAND: Size + size: { + _dropDown: function (editor, caller, callback) { + var content = $('
    '), + /** @private */ + clickFunc = function (e) { + callback($(this).data('size')); + editor.closeDropDown(true); + e.preventDefault(); + }; + + for (var i = 1; i <= 7; i++) { + content.append(_tmpl('sizeOpt', { + size: i + }, true).click(clickFunc)); + } + + editor.createDropDown(caller, 'fontsize-picker', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.size._dropDown( + editor, + caller, + function (fontSize) { + editor.execCommand('fontsize', fontSize); + } + ); + }, + tooltip: 'Font Size' + }, + // END_COMMAND + // START_COMMAND: Colour + color: { + _dropDown: function (editor, caller, callback) { + var i, x, color, colors, + genColor = {r: 255, g: 255, b: 255}, + content = $('
    '), + colorColumns = editor.opts.colors ? + editor.opts.colors.split('|') : new Array(21), + // IE is slow at string concatenation so use an array + html = [], + cmd = defaultCommnds.color; + + if (!cmd._htmlCache) { + for (i = 0; i < colorColumns.length; ++i) { + colors = colorColumns[i] ? + colorColumns[i].split(',') : new Array(21); + + html.push('
    '); + + for (x = 0; x < colors.length; ++x) { + // use pre defined colour if can otherwise use the + // generated color + color = colors[x] || '#' + + genColor.r.toString(16) + + genColor.g.toString(16) + + genColor.b.toString(16); + + html.push( + '' + ); + + if (x % 5 === 0) { + genColor.g -= 51; + genColor.b = 255; + } else { + genColor.b -= 51; + } + } + + html.push('
    '); + + if (i % 5 === 0) { + genColor.r -= 51; + genColor.g = 255; + genColor.b = 255; + } else { + genColor.g = 255; + genColor.b = 255; + } + } + + cmd._htmlCache = html.join(''); + } + + content.append(cmd._htmlCache) + .find('a') + .click(function (e) { + callback($(this).attr('data-color')); + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'color-picker', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.color._dropDown( + editor, + caller, + function (color) { + editor.execCommand('forecolor', color); + } + ); + }, + tooltip: 'Font Color' + }, + // END_COMMAND + // START_COMMAND: Remove Format + removeformat: { + exec: 'removeformat', + tooltip: 'Remove Formatting' + }, + // END_COMMAND + + // START_COMMAND: Cut + cut: { + exec: 'cut', + tooltip: 'Cut', + errorMessage: 'Your browser does not allow the cut command. ' + + 'Please use the keyboard shortcut Ctrl/Cmd-X' + }, + // END_COMMAND + // START_COMMAND: Copy + copy: { + exec: 'copy', + tooltip: 'Copy', + errorMessage: 'Your browser does not allow the copy command. ' + + 'Please use the keyboard shortcut Ctrl/Cmd-C' + }, + // END_COMMAND + // START_COMMAND: Paste + paste: { + exec: 'paste', + tooltip: 'Paste', + errorMessage: 'Your browser does not allow the paste command. ' + + 'Please use the keyboard shortcut Ctrl/Cmd-V' + }, + // END_COMMAND + // START_COMMAND: Paste Text + pastetext: { + exec: function (caller) { + var val, content, + editor = this; + + content = _tmpl('pastetext', { + label: editor._( + 'Paste your text inside the following box:' + ), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + val = content.find('#txt').val(); + + if (val) { + editor.wysiwygEditorInsertText(val); + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'pastetext', content); + }, + tooltip: 'Paste Text' + }, + // END_COMMAND + // START_COMMAND: Bullet List + bulletlist: { + exec: 'insertunorderedlist', + tooltip: 'Bullet list' + }, + // END_COMMAND + // START_COMMAND: Ordered List + orderedlist: { + exec: 'insertorderedlist', + tooltip: 'Numbered list' + }, + // END_COMMAND + // START_COMMAND: Indent + indent: { + state: function (parents, firstBlock) { + // Only works with lists, for now + // This is a nested list, so it will always work + var range, startParent, endParent, + $firstBlock = $(firstBlock), + parentLists = $firstBlock.parents('ul,ol,menu'), + parentList = parentLists.first(); + + // in case it's a list with only a single
  • + if (parentLists.length > 1 || + parentList.children().length > 1) { + return 0; + } + + if ($firstBlock.is('ul,ol,menu')) { + // if the whole list is selected, then this must be + // invalidated because the browser will place a + //
    there + range = this.getRangeHelper().selectedRange(); + + if (window.Range && range instanceof Range) { + startParent = range.startContainer.parentNode; + endParent = range.endContainer.parentNode; + + // TODO: could use nodeType for this? + // Maybe just check the firstBlock contains both the start and end containers + // Select the tag, not the textNode + // (that's why the parentNode) + if (startParent !== + startParent.parentNode.firstElementChild || + // work around a bug in FF + ($(endParent).is('li') && endParent !== + endParent.parentNode.lastElementChild)) { + return 0; + } + // it's IE... As it is impossible to know well when to + // accept, better safe than sorry + } else { + return $firstBlock.is('li,ul,ol,menu') ? 0 : -1; + } + } + + return -1; + }, + exec: function () { + var editor = this, + $elm = $(editor.getRangeHelper().getFirstBlockParent()); + + editor.focus(); + + // An indent system is quite complicated as there are loads + // of complications and issues around how to indent text + // As default, let's just stay with indenting the lists, + // at least, for now. + if ($elm.parents('ul,ol,menu')) { + editor.execCommand('indent'); + } + }, + tooltip: 'Add indent' + }, + // END_COMMAND + // START_COMMAND: Outdent + outdent: { + state: function (parents, firstBlock) { + return $(firstBlock).is('ul,ol,menu') || + $(firstBlock).parents('ul,ol,menu').length > 0 ? 0 : -1; + }, + exec: function () { + var editor = this, + $elm = $(editor.getRangeHelper().getFirstBlockParent()); + + if ($elm.parents('ul,ol,menu')) { + editor.execCommand('outdent'); + } + }, + tooltip: 'Remove one indent' + }, + // END_COMMAND + + // START_COMMAND: Table + table: { + forceNewLineAfter: ['table'], + exec: function (caller) { + var editor = this, + content = _tmpl('table', { + rows: editor._('Rows:'), + cols: editor._('Cols:'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var row, col, + rows = content.find('#rows').val() - 0, + cols = content.find('#cols').val() - 0, + html = ''; + + if (rows < 1 || cols < 1) { + return; + } + + for (row = 0; row < rows; row++) { + html += ''; + + for (col = 0; col < cols; col++) { + html += ''; + } + + html += ''; + } + + html += '
    ' + + (IE_BR_FIX ? '' : '
    ') + + '
    '; + + editor.wysiwygEditorInsertHtml(html); + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'inserttable', content); + }, + tooltip: 'Insert a table' + }, + // END_COMMAND + + // START_COMMAND: Horizontal Rule + horizontalrule: { + exec: 'inserthorizontalrule', + tooltip: 'Insert a horizontal rule' + }, + // END_COMMAND + + // START_COMMAND: Code + code: { + forceNewLineAfter: ['code'], + exec: function () { + this.wysiwygEditorInsertHtml( + '', + (IE_BR_FIX ? '' : '
    ') + '
    ' + ); + }, + tooltip: 'Code' + }, + // END_COMMAND + + // START_COMMAND: Image + image: { + exec: function (caller) { + var editor = this, + content = _tmpl('image', { + url: editor._('URL:'), + width: editor._('Width (optional):'), + height: editor._('Height (optional):'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content.find('#image').val(), + width = content.find('#width').val(), + height = content.find('#height').val(), + attrs = ''; + + if (width) { + attrs += ' width="' + width + '"'; + } + + if (height) { + attrs += ' height="' + height + '"'; + } + + if (val) { + editor.wysiwygEditorInsertHtml( + '' + ); + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertimage', content); + }, + tooltip: 'Insert an image' + }, + // END_COMMAND + + // START_COMMAND: E-mail + email: { + exec: function (caller) { + var editor = this, + content = _tmpl('email', { + label: editor._('E-mail:'), + desc: editor._('Description (optional):'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content.find('#email').val(), + description = content.find('#des').val(); + + if (val) { + // needed for IE to reset the last range + editor.focus(); + + if (!editor.getRangeHelper().selectedHtml() || + description) { + description = description || val; + + editor.wysiwygEditorInsertHtml( + '' + + description + + '' + ); + } else { + editor.execCommand('createlink', 'mailto:' + val); + } + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertemail', content); + }, + tooltip: 'Insert an email' + }, + // END_COMMAND + + // START_COMMAND: Link + link: { + exec: function (caller) { + var editor = this, + content = _tmpl('link', { + url: editor._('URL:'), + desc: editor._('Description (optional):'), + ins: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content.find('#link').val(), + description = content.find('#des').val(); + + if (val) { + // needed for IE to restore the last range + editor.focus(); + + // If there is no selected text then must set the URL as + // the text. Most browsers do this automatically, sadly + // IE doesn't. + if (!editor.getRangeHelper().selectedHtml() || + description) { + description = description || val; + + editor.wysiwygEditorInsertHtml( + '' + description + '' + ); + } else { + editor.execCommand('createlink', val); + } + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertlink', content); + }, + tooltip: 'Insert a link' + }, + // END_COMMAND + + // START_COMMAND: Unlink + unlink: { + state: function () { + var $current = $(this.currentNode()); + return $current.is('a') || + $current.parents('a').length > 0 ? 0 : -1; + }, + exec: function () { + var $current = $(this.currentNode()), + $anchor = $current.is('a') ? $current : + $current.parents('a').first(); + + if ($anchor.length) { + $anchor.replaceWith($anchor.contents()); + } + }, + tooltip: 'Unlink' + }, + // END_COMMAND + + + // START_COMMAND: Quote + quote: { + forceNewLineAfter: ['blockquote'], + exec: function (caller, html, author) { + var before = '
    ', + end = '
    '; + + // if there is HTML passed set end to null so any selected + // text is replaced + if (html) { + author = (author ? '' + author + '' : ''); + before = before + author + html + end; + end = null; + // if not add a newline to the end of the inserted quote + } else if (this.getRangeHelper().selectedHtml() === '') { + end = (IE_BR_FIX ? '' : '
    ') + end; + } + + this.wysiwygEditorInsertHtml(before, end); + }, + tooltip: 'Insert a Quote' + }, + // END_COMMAND + + // START_COMMAND: Emoticons + emoticon: { + exec: function (caller) { + var editor = this; + + var createContent = function (includeMore) { + var $moreLink, + emoticonsCompat = editor.opts.emoticonsCompat, + rangeHelper = editor.getRangeHelper(), + startSpace = emoticonsCompat && + rangeHelper.getOuterText(true, 1) !== ' ' ? + ' ' : '', + endSpace = emoticonsCompat && + rangeHelper.getOuterText(false, 1) !== ' ' ? + ' ' : '', + $content = $('
    '), + $line = $('
    ').appendTo($content), + perLine = 0, + emoticons = $.extend( + {}, + editor.opts.emoticons.dropdown, + includeMore ? editor.opts.emoticons.more : {} + ); + + $.each(emoticons, function () { + perLine++; + }); + perLine = Math.sqrt(perLine); + + $.each(emoticons, function (code, emoticon) { + $line.append( + $('').attr({ + src: emoticon.url || emoticon, + alt: code, + title: emoticon.tooltip || code + }).click(function () { + editor.insert(startSpace + $(this).attr('alt') + + endSpace, null, false).closeDropDown(true); + + return false; + }) + ); + + if ($line.children().length >= perLine) { + $line = $('
    ').appendTo($content); + } + }); + + if (!includeMore && editor.opts.emoticons.more) { + $moreLink = $( + '' + + editor._('More') + '' + ).click(function () { + editor.createDropDown( + caller, + 'more-emoticons', + createContent(true) + ); + + return false; + }); + + $content.append($moreLink); + } + + return $content; + }; + + editor.createDropDown( + caller, + 'emoticons', + createContent(false) + ); + }, + txtExec: function (caller) { + defaultCommnds.emoticon.exec.call(this, caller); + }, + tooltip: 'Insert an emoticon' + }, + // END_COMMAND + + // START_COMMAND: YouTube + youtube: { + _dropDown: function (editor, caller, handleIdFunc) { + var matches, + content = _tmpl('youtubeMenu', { + label: editor._('Video URL:'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content + .find('#link') + .val(); + + if (val) { + matches = val.match( + /(?:v=|v\/|embed\/|youtu.be\/)(.{11})/ + ); + + if (matches) { + val = matches[1]; + } + + if (/^[a-zA-Z0-9_\-]{11}$/.test(val)) { + handleIdFunc(val); + } else { + /*global alert:false*/ + alert('Invalid YouTube video'); + } + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertlink', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.youtube._dropDown( + editor, + caller, + function (id) { + editor.wysiwygEditorInsertHtml(_tmpl('youtube', { + id: id + })); + } + ); + }, + tooltip: 'Insert a YouTube video' + }, + // END_COMMAND + + // START_COMMAND: Date + date: { + _date: function (editor) { + var now = new Date(), + year = now.getYear(), + month = now.getMonth() + 1, + day = now.getDate(); + + if (year < 2000) { + year = 1900 + year; + } + + if (month < 10) { + month = '0' + month; + } + + if (day < 10) { + day = '0' + day; + } + + return editor.opts.dateFormat + .replace(/year/i, year) + .replace(/month/i, month) + .replace(/day/i, day); + }, + exec: function () { + this.insertText(defaultCommnds.date._date(this)); + }, + txtExec: function () { + this.insertText(defaultCommnds.date._date(this)); + }, + tooltip: 'Insert current date' + }, + // END_COMMAND + + // START_COMMAND: Time + time: { + _time: function () { + var now = new Date(), + hours = now.getHours(), + mins = now.getMinutes(), + secs = now.getSeconds(); + + if (hours < 10) { + hours = '0' + hours; + } + + if (mins < 10) { + mins = '0' + mins; + } + + if (secs < 10) { + secs = '0' + secs; + } + + return hours + ':' + mins + ':' + secs; + }, + exec: function () { + this.insertText(defaultCommnds.time._time()); + }, + txtExec: function () { + this.insertText(defaultCommnds.time._time()); + }, + tooltip: 'Insert current time' + }, + // END_COMMAND + + + // START_COMMAND: Ltr + ltr: { + state: function (parents, firstBlock) { + return firstBlock && firstBlock.style.direction === 'ltr'; + }, + exec: function () { + var editor = this, + elm = editor.getRangeHelper().getFirstBlockParent(), + $elm = $(elm); + + editor.focus(); + + if (!elm || $elm.is('body')) { + editor.execCommand('formatBlock', 'p'); + + elm = editor.getRangeHelper().getFirstBlockParent(); + $elm = $(elm); + + if (!elm || $elm.is('body')) { + return; + } + } + + if ($elm.css('direction') === 'ltr') { + $elm.css('direction', ''); + } else { + $elm.css('direction', 'ltr'); + } + }, + tooltip: 'Left-to-Right' + }, + // END_COMMAND + + // START_COMMAND: Rtl + rtl: { + state: function (parents, firstBlock) { + return firstBlock && firstBlock.style.direction === 'rtl'; + }, + exec: function () { + var editor = this, + elm = editor.getRangeHelper().getFirstBlockParent(), + $elm = $(elm); + + editor.focus(); + + if (!elm || $elm.is('body')) { + editor.execCommand('formatBlock', 'p'); + + elm = editor.getRangeHelper().getFirstBlockParent(); + $elm = $(elm); + + if (!elm || $elm.is('body')) { + return; + } + } + + if ($elm.css('direction') === 'rtl') { + $elm.css('direction', ''); + } else { + $elm.css('direction', 'rtl'); + } + }, + tooltip: 'Right-to-Left' + }, + // END_COMMAND + + + // START_COMMAND: Print + print: { + exec: 'print', + tooltip: 'Print' + }, + // END_COMMAND + + // START_COMMAND: Maximize + maximize: { + state: function () { + return this.maximize(); + }, + exec: function () { + this.maximize(!this.maximize()); + }, + txtExec: function () { + this.maximize(!this.maximize()); + }, + tooltip: 'Maximize', + shortcut: 'Ctrl+Shift+M' + }, + // END_COMMAND + + // START_COMMAND: Source + source: { + state: function () { + return this.sourceMode(); + }, + exec: function () { + this.toggleSourceMode(); + }, + txtExec: function () { + this.toggleSourceMode(); + }, + tooltip: 'View source', + shortcut: 'Ctrl+Shift+S' + }, + // END_COMMAND + + // this is here so that commands above can be removed + // without having to remove the , after the last one. + // Needed for IE. + ignore: {} + }; + + return defaultCommnds; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + + + /** + * Default options for SCEditor + * @type {Object} + */ + return { + /** @lends jQuery.sceditor.defaultOptions */ + /** + * Toolbar buttons order and groups. Should be comma separated and + * have a bar | to separate groups + * + * @type {String} + */ + toolbar: 'bold,italic,underline,strike,subscript,superscript|' + + 'left,center,right,justify|font,size,color,removeformat|' + + 'cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|' + + 'table|code,quote|horizontalrule,image,email,link,unlink|' + + 'emoticon,youtube,date,time|ltr,rtl|print,maximize,source', + + /** + * Comma separated list of commands to excludes from the toolbar + * + * @type {String} + */ + toolbarExclude: null, + + /** + * Stylesheet to include in the WYSIWYG editor. This is what will style + * the WYSIWYG elements + * + * @type {String} + */ + style: 'jquery.sceditor.default.css', + + /** + * Comma separated list of fonts for the font selector + * + * @type {String} + */ + fonts: 'Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,' + + 'Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana', + + /** + * Colors should be comma separated and have a bar | to signal a new + * column. + * + * If null the colors will be auto generated. + * + * @type {string} + */ + colors: null, + + /** + * The locale to use. + * @type {String} + */ + locale: $('html').attr('lang') || 'en', + + /** + * The Charset to use + * @type {String} + */ + charset: 'utf-8', + + /** + * Compatibility mode for emoticons. + * + * Helps if you have emoticons such as :/ which would put an emoticon + * inside http:// + * + * This mode requires emoticons to be surrounded by whitespace or end of + * line chars. This mode has limited As You Type emoticon conversion + * support. It will not replace AYT for end of line chars, only + * emoticons surrounded by whitespace. They will still be replaced + * correctly when loaded just not AYT. + * + * @type {Boolean} + */ + emoticonsCompat: false, + + /** + * If to enable emoticons. Can be changes at runtime using the + * emoticons() method. + * + * @type {Boolean} + * @since 1.4.2 + */ + emoticonsEnabled: true, + + /** + * Emoticon root URL + * + * @type {String} + */ + emoticonsRoot: '', + emoticons: { + dropdown: { + ':)': 'emoticons/smile.png', + ':angel:': 'emoticons/angel.png', + ':angry:': 'emoticons/angry.png', + '8-)': 'emoticons/cool.png', + ':\'(': 'emoticons/cwy.png', + ':ermm:': 'emoticons/ermm.png', + ':D': 'emoticons/grin.png', + '<3': 'emoticons/heart.png', + ':(': 'emoticons/sad.png', + ':O': 'emoticons/shocked.png', + ':P': 'emoticons/tongue.png', + ';)': 'emoticons/wink.png' + }, + more: { + ':alien:': 'emoticons/alien.png', + ':blink:': 'emoticons/blink.png', + ':blush:': 'emoticons/blush.png', + ':cheerful:': 'emoticons/cheerful.png', + ':devil:': 'emoticons/devil.png', + ':dizzy:': 'emoticons/dizzy.png', + ':getlost:': 'emoticons/getlost.png', + ':happy:': 'emoticons/happy.png', + ':kissing:': 'emoticons/kissing.png', + ':ninja:': 'emoticons/ninja.png', + ':pinch:': 'emoticons/pinch.png', + ':pouty:': 'emoticons/pouty.png', + ':sick:': 'emoticons/sick.png', + ':sideways:': 'emoticons/sideways.png', + ':silly:': 'emoticons/silly.png', + ':sleeping:': 'emoticons/sleeping.png', + ':unsure:': 'emoticons/unsure.png', + ':woot:': 'emoticons/w00t.png', + ':wassat:': 'emoticons/wassat.png' + }, + hidden: { + ':whistling:': 'emoticons/whistling.png', + ':love:': 'emoticons/wub.png' + } + }, + + /** + * Width of the editor. Set to null for automatic with + * + * @type {int} + */ + width: null, + + /** + * Height of the editor including toolbar. Set to null for automatic + * height + * + * @type {int} + */ + height: null, + + /** + * If to allow the editor to be resized + * + * @type {Boolean} + */ + resizeEnabled: true, + + /** + * Min resize to width, set to null for half textarea width or -1 for + * unlimited + * + * @type {int} + */ + resizeMinWidth: null, + /** + * Min resize to height, set to null for half textarea height or -1 for + * unlimited + * + * @type {int} + */ + resizeMinHeight: null, + /** + * Max resize to height, set to null for double textarea height or -1 + * for unlimited + * + * @type {int} + */ + resizeMaxHeight: null, + /** + * Max resize to width, set to null for double textarea width or -1 for + * unlimited + * + * @type {int} + */ + resizeMaxWidth: null, + /** + * If resizing by height is enabled + * + * @type {Boolean} + */ + resizeHeight: true, + /** + * If resizing by width is enabled + * + * @type {Boolean} + */ + resizeWidth: true, + + /** + * Date format, will be overridden if locale specifies one. + * + * The words year, month and day will be replaced with the users current + * year, month and day. + * + * @type {String} + */ + dateFormat: 'year-month-day', + + /** + * Element to inset the toolbar into. + * + * @type {HTMLElement} + */ + toolbarContainer: null, + + /** + * If to enable paste filtering. This is currently experimental, please + * report any issues. + * + * @type {Boolean} + */ + enablePasteFiltering: false, + + /** + * If to completely disable pasting into the editor + * + * @type {Boolean} + */ + disablePasting: false, + + /** + * If the editor is read only. + * + * @type {Boolean} + */ + readOnly: false, + + /** + * If to set the editor to right-to-left mode. + * + * If set to null the direction will be automatically detected. + * + * @type {Boolean} + */ + rtl: false, + + /** + * If to auto focus the editor on page load + * + * @type {Boolean} + */ + autofocus: false, + + /** + * If to auto focus the editor to the end of the content + * + * @type {Boolean} + */ + autofocusEnd: true, + + /** + * If to auto expand the editor to fix the content + * + * @type {Boolean} + */ + autoExpand: false, + + /** + * If to auto update original textbox on blur + * + * @type {Boolean} + */ + autoUpdate: false, + + /** + * If to enable the browsers built in spell checker + * + * @type {Boolean} + */ + spellcheck: true, + + /** + * If to run the source editor when there is no WYSIWYG support. Only + * really applies to mobile OS's. + * + * @type {Boolean} + */ + runWithoutWysiwygSupport: false, + + /** + * If to load the editor in source mode and still allow switching + * between WYSIWYG and source mode + * + * @type {Boolean} + */ + startInSourceMode: false, + + /** + * Optional ID to give the editor. + * + * @type {String} + */ + id: null, + + /** + * Comma separated list of plugins + * + * @type {String} + */ + plugins: '', + + /** + * z-index to set the editor container to. Needed for jQuery UI dialog. + * + * @type {Int} + */ + zIndex: null, + + /** + * If to trim the BBCode. Removes any spaces at the start and end of the + * BBCode string. + * + * @type {Boolean} + */ + bbcodeTrim: false, + + /** + * If to disable removing block level elements by pressing backspace at + * the start of them + * + * @type {Boolean} + */ + disableBlockRemove: false, + + /** + * BBCode parser options, only applies if using the editor in BBCode + * mode. + * + * See SCEditor.BBCodeParser.defaults for list of valid options + * + * @type {Object} + */ + parserOptions: { }, + + /** + * CSS that will be added to the to dropdown menu (eg. z-index) + * + * @type {Object} + */ + dropDownCss: { } + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ } +/******/ ]); \ No newline at end of file diff --git a/js/sceditor/development/jquery.sceditor.xhtml.js b/js/sceditor/development/jquery.sceditor.xhtml.js new file mode 100644 index 00000000..948e648f --- /dev/null +++ b/js/sceditor/development/jquery.sceditor.xhtml.js @@ -0,0 +1,8548 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; + +/******/ // The require function +/******/ function __webpack_require__(moduleId) { + +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; + +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; + +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + +/******/ // Flag the module as loaded +/******/ module.loaded = true; + +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } + + +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; + +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; + +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; + +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;/** + * SCEditor + * http://www.sceditor.com/ + * + * Copyright (C) 2014, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * @fileoverview SCEditor - A lightweight WYSIWYG BBCode and HTML editor + * @author Sam Clarke + * @requires jQuery + */ + !(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var SCEditor = __webpack_require__(2); + var PluginManager = __webpack_require__(3); + var browser = __webpack_require__(6); + var escape = __webpack_require__(7); + + + // For backwards compatibility + $.sceditor = SCEditor; + + SCEditor.commands = __webpack_require__(9); + SCEditor.defaultOptions = __webpack_require__(10); + SCEditor.RangeHelper = __webpack_require__(4); + SCEditor.dom = __webpack_require__(5); + + SCEditor.ie = browser.ie; + SCEditor.ios = browser.ios; + SCEditor.isWysiwygSupported = browser.isWysiwygSupported; + + SCEditor.regexEscape = escape.regex; + SCEditor.escapeEntities = escape.entities; + SCEditor.escapeUriScheme = escape.uriScheme; + + SCEditor.PluginManager = PluginManager; + SCEditor.plugins = PluginManager.plugins; + + + /** + * Creates an instance of sceditor on all textareas + * matched by the jQuery selector. + * + * If options is set to "state" it will return bool value + * indicating if the editor has been initialised on the + * matched textarea(s). If there is only one textarea + * it will return the bool value for that textarea. + * If more than one textarea is matched it will + * return an array of bool values for each textarea. + * + * If options is set to "instance" it will return the + * current editor instance for the textarea(s). Like the + * state option, if only one textarea is matched this will + * return just the instance for that textarea. If more than + * one textarea is matched it will return an array of + * instances each textarea. + * + * @param {Object|String} options Should either be an Object of options or + * the strings "state" or "instance" + * @return {this|Array|jQuery.sceditor|Bool} + */ + $.fn.sceditor = function (options) { + var $this, instance, + ret = []; + + options = options || {}; + + if (!options.runWithoutWysiwygSupport && !browser.isWysiwygSupported) { + return; + } + + this.each(function () { + $this = this.jquery ? this : $(this); + instance = $this.data('sceditor'); + + // Don't allow the editor to be initialised + // on it's own source editor + if ($this.parents('.sceditor-container').length > 0) { + return; + } + + // Add state of instance to ret if that is what options is set to + if (options === 'state') { + ret.push(!!instance); + } else if (options === 'instance') { + ret.push(instance); + } else if (!instance) { + /*jshint -W031*/ + (new SCEditor(this, options)); + } + }); + + // If nothing in the ret array then must be init so return this + if (!ret.length) { + return this; + } + + return ret.length === 1 ? ret[0] : $(ret); + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 1 */ +/***/ function(module, exports) { + + module.exports = jQuery; + +/***/ }, +/* 2 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var PluginManager = __webpack_require__(3); + var RangeHelper = __webpack_require__(4); + var dom = __webpack_require__(5); + var escape = __webpack_require__(7); + var browser = __webpack_require__(6); + var _tmpl = __webpack_require__(8); + + var globalWin = window; + var globalDoc = document; + var $globalWin = $(globalWin); + var $globalDoc = $(globalDoc); + + var IE_VER = browser.ie; + + // In IE < 11 a BR at the end of a block level element + // causes a line break. In all other browsers it's collapsed. + var IE_BR_FIX = IE_VER && IE_VER < 11; + + + /** + * SCEditor - A lightweight WYSIWYG editor + * + * @param {Element} el The textarea to be converted + * @return {Object} options + * @class sceditor + * @name jQuery.sceditor + */ + var SCEditor = function (el, options) { + /** + * Alias of this + * + * @private + */ + var base = this; + + /** + * The textarea element being replaced + * + * @private + */ + var original = el.get ? el.get(0) : el; + var $original = $(original); + + /** + * The div which contains the editor and toolbar + * + * @private + */ + var $editorContainer; + + /** + * The editors toolbar + * + * @private + */ + var $toolbar; + + /** + * The editors iframe which should be in design mode + * + * @private + */ + var $wysiwygEditor; + var wysiwygEditor; + + /** + * The WYSIWYG editors body element + * + * @private + */ + var $wysiwygBody; + + /** + * The WYSIWYG editors document + * + * @private + */ + var $wysiwygDoc; + + /** + * The editors textarea for viewing source + * + * @private + */ + var $sourceEditor; + var sourceEditor; + + /** + * The current dropdown + * + * @private + */ + var $dropdown; + + /** + * Store the last cursor position. Needed for IE because it forgets + * + * @private + */ + var lastRange; + + /** + * The editors locale + * + * @private + */ + var locale; + + /** + * Stores a cache of preloaded images + * + * @private + * @type {Array} + */ + var preLoadCache = []; + + /** + * The editors rangeHelper instance + * + * @type {jQuery.sceditor.rangeHelper} + * @private + */ + var rangeHelper; + + /** + * Tags which require the new line fix + * + * @type {Array} + * @private + */ + var requireNewLineFix = []; + + /** + * An array of button state handlers + * + * @type {Array} + * @private + */ + var btnStateHandlers = []; + + /** + * Plugin manager instance + * + * @type {jQuery.sceditor.PluginManager} + * @private + */ + var pluginManager; + + /** + * The current node containing the selection/caret + * + * @type {Node} + * @private + */ + var currentNode; + + /** + * The first block level parent of the current node + * + * @type {node} + * @private + */ + var currentBlockNode; + + /** + * The current node selection/caret + * + * @type {Object} + * @private + */ + var currentSelection; + + /** + * Used to make sure only 1 selection changed + * check is called every 100ms. + * + * Helps improve performance as it is checked a lot. + * + * @type {Boolean} + * @private + */ + var isSelectionCheckPending; + + /** + * If content is required (equivalent to the HTML5 required attribute) + * + * @type {Boolean} + * @private + */ + var isRequired; + + /** + * The inline CSS style element. Will be undefined + * until css() is called for the first time. + * + * @type {HTMLElement} + * @private + */ + var inlineCss; + + /** + * Object containing a list of shortcut handlers + * + * @type {Object} + * @private + */ + var shortcutHandlers = {}; + + /** + * An array of all the current emoticons. + * + * Only used or populated when emoticonsCompat is enabled. + * + * @type {Array} + * @private + */ + var currentEmoticons = []; + + /** + * Cache of the current toolbar buttons + * + * @type {Object} + * @private + */ + var toolbarButtons = {}; + + /** + * If the current autoUpdate action is canceled. + * + * @type {Boolean} + * @private + */ + var autoUpdateCanceled; + + /** + * Private functions + * @private + */ + var init, + replaceEmoticons, + handleCommand, + saveRange, + initEditor, + initPlugins, + initLocale, + initToolBar, + initOptions, + initEvents, + initCommands, + initResize, + initEmoticons, + getWysiwygDoc, + handlePasteEvt, + handlePasteData, + handleKeyDown, + handleBackSpace, + handleKeyPress, + handleFormReset, + handleMouseDown, + handleEvent, + handleDocumentClick, + handleWindowResize, + updateToolBar, + updateActiveButtons, + sourceEditorSelectedText, + appendNewLine, + checkSelectionChanged, + checkNodeChanged, + autofocus, + emoticonsKeyPress, + emoticonsCheckWhitespace, + currentStyledBlockNode, + triggerValueChanged, + valueChangedBlur, + valueChangedKeyUp, + autoUpdate; + + /** + * All the commands supported by the editor + * @name commands + * @memberOf jQuery.sceditor.prototype + */ + base.commands = $.extend( + true, + {}, + (options.commands || SCEditor.commands) + ); + + /** + * Options for this editor instance + * @name opts + * @memberOf jQuery.sceditor.prototype + */ + base.opts = options = $.extend({}, SCEditor.defaultOptions, options); + + + /** + * Creates the editor iframe and textarea + * @private + */ + init = function () { + $original.data('sceditor', base); + + // Clone any objects in options + $.each(options, function (key, val) { + if ($.isPlainObject(val)) { + options[key] = $.extend(true, {}, val); + } + }); + + // Load locale + if (options.locale && options.locale !== 'en') { + initLocale(); + } + + $editorContainer = $('
    ') + .insertAfter($original) + .css('z-index', options.zIndex); + + // Add IE version to the container to allow IE specific CSS + // fixes without using CSS hacks or conditional comments + if (IE_VER) { + $editorContainer.addClass('ie ie' + IE_VER); + } + + isRequired = !!$original.attr('required'); + $original.removeAttr('required'); + + // create the editor + initPlugins(); + initEmoticons(); + initToolBar(); + initEditor(!!options.startInSourceMode); + initCommands(); + initOptions(); + initEvents(); + + // force into source mode if is a browser that can't handle + // full editing + if (!browser.isWysiwygSupported) { + base.toggleSourceMode(); + } + + updateActiveButtons(); + + var loaded = function () { + $globalWin.off('load', loaded); + + if (options.autofocus) { + autofocus(); + } + + if (options.autoExpand) { + base.expandToContent(); + } + + // Page width might have changed after CSS is loaded so + // call handleWindowResize to update any % based dimensions + handleWindowResize(); + + pluginManager.call('ready'); + }; + $globalWin.on('load', loaded); + if (globalDoc.readyState && globalDoc.readyState === 'complete') { + loaded(); + } + }; + + initPlugins = function () { + var plugins = options.plugins; + + plugins = plugins ? plugins.toString().split(',') : []; + pluginManager = new PluginManager(base); + + $.each(plugins, function (idx, plugin) { + pluginManager.register($.trim(plugin)); + }); + }; + + /** + * Init the locale variable with the specified locale if possible + * @private + * @return void + */ + initLocale = function () { + var lang; + + locale = SCEditor.locale[options.locale]; + + if (!locale) { + lang = options.locale.split('-'); + locale = SCEditor.locale[lang[0]]; + } + + // Locale DateTime format overrides any specified in the options + if (locale && locale.dateFormat) { + options.dateFormat = locale.dateFormat; + } + }; + + /** + * Creates the editor iframe and textarea + * @param {boolean} startInSourceMode Force loading the editor in this + * mode + * @private + */ + initEditor = function (startInSourceMode) { + var doc, tabIndex; + + $sourceEditor = $(''); + $wysiwygEditor = $( + '' + ); + + /* This needs to be done right after they are created because, + * for any reason, the user may not want the value to be tinkered + * by any filters. + */ + if (startInSourceMode) { + $editorContainer.addClass('sourceMode'); + $wysiwygEditor.hide(); + } else { + $editorContainer.addClass('wysiwygMode'); + $sourceEditor.hide(); + } + + if (!options.spellcheck) { + $sourceEditor.attr('spellcheck', 'false'); + } + + /*jshint scripturl: true*/ + if (globalWin.location.protocol === 'https:') { + $wysiwygEditor.attr('src', 'javascript:false'); + } + + // Add the editor to the container + $editorContainer.append($wysiwygEditor).append($sourceEditor); + wysiwygEditor = $wysiwygEditor[0]; + sourceEditor = $sourceEditor[0]; + + base.dimensions( + options.width || $original.width(), + options.height || $original.height() + ); + + doc = getWysiwygDoc(); + doc.open(); + doc.write(_tmpl('html', { + // Add IE version class to the HTML element so can apply + // conditional styling without CSS hacks + attrs: IE_VER ? ' class="ie ie' + IE_VER + '"' : '', + spellcheck: options.spellcheck ? '' : 'spellcheck="false"', + charset: options.charset, + style: options.style + })); + doc.close(); + + $wysiwygDoc = $(doc); + $wysiwygBody = $(doc.body); + + base.readOnly(!!options.readOnly); + + // iframe overflow fix for iOS, also fixes an IE issue with the + // editor not getting focus when clicking inside + if (browser.ios || IE_VER) { + $wysiwygBody.height('100%'); + + if (!IE_VER) { + $wysiwygBody.on('touchend', base.focus); + } + } + + tabIndex = $original.attr('tabindex'); + $sourceEditor.attr('tabindex', tabIndex); + $wysiwygEditor.attr('tabindex', tabIndex); + + rangeHelper = new RangeHelper(wysiwygEditor.contentWindow); + + // load any textarea value into the editor + base.val($original.hide().val()); + }; + + /** + * Initialises options + * @private + */ + initOptions = function () { + // auto-update original textbox on blur if option set to true + if (options.autoUpdate) { + $wysiwygBody.on('blur', autoUpdate); + $sourceEditor.on('blur', autoUpdate); + } + + if (options.rtl === null) { + options.rtl = $sourceEditor.css('direction') === 'rtl'; + } + + base.rtl(!!options.rtl); + + if (options.autoExpand) { + $wysiwygDoc.on('keyup', base.expandToContent); + } + + if (options.resizeEnabled) { + initResize(); + } + + $editorContainer.attr('id', options.id); + base.emoticons(options.emoticonsEnabled); + }; + + /** + * Initialises events + * @private + */ + initEvents = function () { + var CHECK_SELECTION_EVENTS = IE_VER ? + 'selectionchange' : + 'keyup focus blur contextmenu mouseup touchend click'; + + var EVENTS_TO_FORWARD = 'keydown keyup keypress ' + + 'focus blur contextmenu'; + + $globalDoc.click(handleDocumentClick); + + $(original.form) + .on('reset', handleFormReset) + .submit(base.updateOriginal); + + $globalWin.on('resize orientationChanged', handleWindowResize); + + $wysiwygBody + .keypress(handleKeyPress) + .keydown(handleKeyDown) + .keydown(handleBackSpace) + .keyup(appendNewLine) + .blur(valueChangedBlur) + .keyup(valueChangedKeyUp) + .on('paste', handlePasteEvt) + .on(CHECK_SELECTION_EVENTS, checkSelectionChanged) + .on(EVENTS_TO_FORWARD, handleEvent); + + if (options.emoticonsCompat && globalWin.getSelection) { + $wysiwygBody.keyup(emoticonsCheckWhitespace); + } + + $sourceEditor + .blur(valueChangedBlur) + .keyup(valueChangedKeyUp) + .keydown(handleKeyDown) + .on(EVENTS_TO_FORWARD, handleEvent); + + $wysiwygDoc + .mousedown(handleMouseDown) + .blur(valueChangedBlur) + .on(CHECK_SELECTION_EVENTS, checkSelectionChanged) + .on('beforedeactivate keyup mouseup', saveRange) + .keyup(appendNewLine) + .focus(function () { + lastRange = null; + }); + + $editorContainer + .on('selectionchanged', checkNodeChanged) + .on('selectionchanged', updateActiveButtons) + .on('selectionchanged valuechanged nodechanged', handleEvent); + }; + + /** + * Creates the toolbar and appends it to the container + * @private + */ + initToolBar = function () { + var $group, + commands = base.commands, + exclude = (options.toolbarExclude || '').split(','), + groups = options.toolbar.split('|'); + + $toolbar = $('
    '); + + $.each(groups, function (idx, group) { + $group = $('
    '); + + $.each(group.split(','), function (idx, commandName) { + var $button, shortcut, + command = commands[commandName]; + + // The commandName must be a valid command and not excluded + if (!command || $.inArray(commandName, exclude) > -1) { + return; + } + + shortcut = command.shortcut; + $button = _tmpl('toolbarButton', { + name: commandName, + dispName: base._(command.name || + command.tooltip || commandName) + }, true); + + $button + .data('sceditor-txtmode', !!command.txtExec) + .data('sceditor-wysiwygmode', !!command.exec) + .toggleClass('disabled', !command.exec) + .mousedown(function () { + // IE < 8 supports unselectable attribute + // so don't need this + if (!IE_VER || IE_VER < 9) { + autoUpdateCanceled = true; + } + }) + .click(function () { + var $this = $(this); + + if (!$this.hasClass('disabled')) { + handleCommand($this, command); + } + + updateActiveButtons(); + return false; + }); + + if (command.tooltip) { + $button.attr( + 'title', + base._(command.tooltip) + + (shortcut ? ' (' + shortcut + ')' : '') + ); + } + + if (shortcut) { + base.addShortcut(shortcut, commandName); + } + + if (command.state) { + btnStateHandlers.push({ + name: commandName, + state: command.state + }); + // exec string commands can be passed to queryCommandState + } else if (typeof command.exec === 'string') { + btnStateHandlers.push({ + name: commandName, + state: command.exec + }); + } + + $group.append($button); + toolbarButtons[commandName] = $button; + }); + + // Exclude empty groups + if ($group[0].firstChild) { + $toolbar.append($group); + } + }); + + // Append the toolbar to the toolbarContainer option if given + $(options.toolbarContainer || $editorContainer).append($toolbar); + }; + + /** + * Creates an array of all the key press functions + * like emoticons, ect. + * @private + */ + initCommands = function () { + $.each(base.commands, function (name, cmd) { + if (cmd.forceNewLineAfter && $.isArray(cmd.forceNewLineAfter)) { + requireNewLineFix = $.merge( + requireNewLineFix, + cmd.forceNewLineAfter + ); + } + }); + + appendNewLine(); + }; + + /** + * Creates the resizer. + * @private + */ + initResize = function () { + var minHeight, maxHeight, minWidth, maxWidth, + mouseMoveFunc, mouseUpFunc, + $grip = $('
    '), + // Cover is used to cover the editor iframe so document + // still gets mouse move events + $cover = $('
    '), + moveEvents = 'touchmove mousemove', + endEvents = 'touchcancel touchend mouseup', + startX = 0, + startY = 0, + newX = 0, + newY = 0, + startWidth = 0, + startHeight = 0, + origWidth = $editorContainer.width(), + origHeight = $editorContainer.height(), + isDragging = false, + rtl = base.rtl(); + + minHeight = options.resizeMinHeight || origHeight / 1.5; + maxHeight = options.resizeMaxHeight || origHeight * 2.5; + minWidth = options.resizeMinWidth || origWidth / 1.25; + maxWidth = options.resizeMaxWidth || origWidth * 1.25; + + mouseMoveFunc = function (e) { + // iOS uses window.event + if (e.type === 'touchmove') { + e = globalWin.event; + newX = e.changedTouches[0].pageX; + newY = e.changedTouches[0].pageY; + } else { + newX = e.pageX; + newY = e.pageY; + } + + var newHeight = startHeight + (newY - startY), + newWidth = rtl ? + startWidth - (newX - startX) : + startWidth + (newX - startX); + + if (maxWidth > 0 && newWidth > maxWidth) { + newWidth = maxWidth; + } + if (minWidth > 0 && newWidth < minWidth) { + newWidth = minWidth; + } + if (!options.resizeWidth) { + newWidth = false; + } + + if (maxHeight > 0 && newHeight > maxHeight) { + newHeight = maxHeight; + } + if (minHeight > 0 && newHeight < minHeight) { + newHeight = minHeight; + } + if (!options.resizeHeight) { + newHeight = false; + } + + if (newWidth || newHeight) { + base.dimensions(newWidth, newHeight); + + // The resize cover will not fill the container + // in IE6 unless a height is specified. + if (IE_VER < 7) { + $editorContainer.height(newHeight); + } + } + + e.preventDefault(); + }; + + mouseUpFunc = function (e) { + if (!isDragging) { + return; + } + + isDragging = false; + + $cover.hide(); + $editorContainer.removeClass('resizing').height('auto'); + $globalDoc.off(moveEvents, mouseMoveFunc); + $globalDoc.off(endEvents, mouseUpFunc); + + e.preventDefault(); + }; + + $editorContainer.append($grip); + $editorContainer.append($cover.hide()); + + $grip.on('touchstart mousedown', function (e) { + // iOS uses window.event + if (e.type === 'touchstart') { + e = globalWin.event; + startX = e.touches[0].pageX; + startY = e.touches[0].pageY; + } else { + startX = e.pageX; + startY = e.pageY; + } + + startWidth = $editorContainer.width(); + startHeight = $editorContainer.height(); + isDragging = true; + + $editorContainer.addClass('resizing'); + $cover.show(); + $globalDoc.on(moveEvents, mouseMoveFunc); + $globalDoc.on(endEvents, mouseUpFunc); + + // The resize cover will not fill the container in + // IE6 unless a height is specified. + if (IE_VER < 7) { + $editorContainer.height(startHeight); + } + + e.preventDefault(); + }); + }; + + /** + * Prefixes and preloads the emoticon images + * @private + */ + initEmoticons = function () { + var emoticon, + emoticons = options.emoticons, + root = options.emoticonsRoot; + + if (!$.isPlainObject(emoticons) || !options.emoticonsEnabled) { + return; + } + + $.each(emoticons, function (idx, val) { + $.each(val, function (key, url) { + // Prefix emoticon root to emoticon urls + if (root) { + url = { + url: root + (url.url || url), + tooltip: url.tooltip || key + }; + + emoticons[idx][key] = url; + } + + // Preload the emoticon + emoticon = globalDoc.createElement('img'); + emoticon.src = url.url || url; + preLoadCache.push(emoticon); + }); + }); + }; + + /** + * Autofocus the editor + * @private + */ + autofocus = function () { + var range, txtPos, + doc = $wysiwygDoc[0], + body = $wysiwygBody[0], + node = body.firstChild, + focusEnd = !!options.autofocusEnd; + + // Can't focus invisible elements + if (!$editorContainer.is(':visible')) { + return; + } + + if (base.sourceMode()) { + txtPos = focusEnd ? sourceEditor.value.length : 0; + + if (sourceEditor.setSelectionRange) { + sourceEditor.setSelectionRange(txtPos, txtPos); + } else { + range = sourceEditor.createTextRange(); + range.moveEnd('character', txtPos); + range.collapse(false); + range.select(); + } + + return; + } + + dom.removeWhiteSpace(body); + + if (focusEnd) { + if (!(node = body.lastChild)) { + node = doc.createElement('p'); + $wysiwygBody.append(node); + } + + while (node.lastChild) { + node = node.lastChild; + + // IE < 11 should place the cursor after the
    as + // it will show it as a newline. IE >= 11 and all + // other browsers should place the cursor before. + if (!IE_BR_FIX && $(node).is('br') && + node.previousSibling) { + node = node.previousSibling; + } + } + } + + if (doc.createRange) { + range = doc.createRange(); + + if (!dom.canHaveChildren(node)) { + range.setStartBefore(node); + + if (focusEnd) { + range.setStartAfter(node); + } + } else { + range.selectNodeContents(node); + } + } else { + range = body.createTextRange(); + range.moveToElementText(node.nodeType !== 3 ? + node : node.parentNode); + } + + range.collapse(!focusEnd); + rangeHelper.selectRange(range); + currentSelection = range; + + if (focusEnd) { + $wysiwygDoc.scrollTop(body.scrollHeight); + $wysiwygBody.scrollTop(body.scrollHeight); + } + + base.focus(); + }; + + /** + * Gets if the editor is read only + * + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name readOnly + * @return {Boolean} + */ + /** + * Sets if the editor is read only + * + * @param {boolean} readOnly + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name readOnly^2 + * @return {this} + */ + base.readOnly = function (readOnly) { + if (typeof readOnly !== 'boolean') { + return $sourceEditor.attr('readonly') === 'readonly'; + } + + $wysiwygBody[0].contentEditable = !readOnly; + + if (!readOnly) { + $sourceEditor.removeAttr('readonly'); + } else { + $sourceEditor.attr('readonly', 'readonly'); + } + + updateToolBar(readOnly); + + return base; + }; + + /** + * Gets if the editor is in RTL mode + * + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name rtl + * @return {Boolean} + */ + /** + * Sets if the editor is in RTL mode + * + * @param {boolean} rtl + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name rtl^2 + * @return {this} + */ + base.rtl = function (rtl) { + var dir = rtl ? 'rtl' : 'ltr'; + + if (typeof rtl !== 'boolean') { + return $sourceEditor.attr('dir') === 'rtl'; + } + + $wysiwygBody.attr('dir', dir); + $sourceEditor.attr('dir', dir); + + $editorContainer + .removeClass('rtl') + .removeClass('ltr') + .addClass(dir); + + return base; + }; + + /** + * Updates the toolbar to disable/enable the appropriate buttons + * @private + */ + updateToolBar = function (disable) { + var mode = base.inSourceMode() ? 'txtmode' : 'wysiwygmode'; + + $.each(toolbarButtons, function (idx, $button) { + if (disable === true || !$button.data('sceditor-' + mode)) { + $button.addClass('disabled'); + } else { + $button.removeClass('disabled'); + } + }); + }; + + /** + * Gets the width of the editor in pixels + * + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name width + * @return {int} + */ + /** + * Sets the width of the editor + * + * @param {int} width Width in pixels + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name width^2 + * @return {this} + */ + /** + * Sets the width of the editor + * + * The saveWidth specifies if to save the width. The stored width can be + * used for things like restoring from maximized state. + * + * @param {int} width Width in pixels + * @param {boolean} [saveWidth=true] If to store the width + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name width^3 + * @return {this} + */ + base.width = function (width, saveWidth) { + if (!width && width !== 0) { + return $editorContainer.width(); + } + + base.dimensions(width, null, saveWidth); + + return base; + }; + + /** + * Returns an object with the properties width and height + * which are the width and height of the editor in px. + * + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name dimensions + * @return {object} + */ + /** + *

    Sets the width and/or height of the editor.

    + * + *

    If width or height is not numeric it is ignored.

    + * + * @param {int} width Width in px + * @param {int} height Height in px + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name dimensions^2 + * @return {this} + */ + /** + *

    Sets the width and/or height of the editor.

    + * + *

    If width or height is not numeric it is ignored.

    + * + *

    The save argument specifies if to save the new sizes. + * The saved sizes can be used for things like restoring from + * maximized state. This should normally be left as true.

    + * + * @param {int} width Width in px + * @param {int} height Height in px + * @param {boolean} [save=true] If to store the new sizes + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name dimensions^3 + * @return {this} + */ + base.dimensions = function (width, height, save) { + // IE6 & IE7 add 2 pixels to the source mode textarea + // height which must be ignored. + // Doesn't seem to be any way to fix it with only CSS + var ieBorder = IE_VER < 8 || globalDoc.documentMode < 8 ? 2 : 0; + var undef; + + // set undefined width/height to boolean false + width = (!width && width !== 0) ? false : width; + height = (!height && height !== 0) ? false : height; + + if (width === false && height === false) { + return { width: base.width(), height: base.height() }; + } + + if ($wysiwygEditor.data('outerWidthOffset') === undef) { + base.updateStyleCache(); + } + + if (width !== false) { + if (save !== false) { + options.width = width; + } + // This is the problem + if (height === false) { + height = $editorContainer.height(); + save = false; + } + + $editorContainer.width(width); + if (width && width.toString().indexOf('%') > -1) { + width = $editorContainer.width(); + } + + $wysiwygEditor.width( + width - $wysiwygEditor.data('outerWidthOffset') + ); + + $sourceEditor.width( + width - $sourceEditor.data('outerWidthOffset') + ); + + // Fix overflow issue with iOS not + // breaking words unless a width is set + if (browser.ios && $wysiwygBody) { + $wysiwygBody.width( + width - $wysiwygEditor.data('outerWidthOffset') - + ($wysiwygBody.outerWidth(true) - $wysiwygBody.width()) + ); + } + } + + if (height !== false) { + if (save !== false) { + options.height = height; + } + + // Convert % based heights to px + if (height && height.toString().indexOf('%') > -1) { + height = $editorContainer.height(height).height(); + $editorContainer.height('auto'); + } + + height -= !options.toolbarContainer ? + $toolbar.outerHeight(true) : 0; + + $wysiwygEditor.height( + height - $wysiwygEditor.data('outerHeightOffset') + ); + + $sourceEditor.height( + height - ieBorder - $sourceEditor.data('outerHeightOffset') + ); + } + + return base; + }; + + /** + * Updates the CSS styles cache. + * + * This shouldn't be needed unless changing the editors theme. + *F + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name updateStyleCache + * @return {int} + */ + base.updateStyleCache = function () { + // caching these improves FF resize performance + $wysiwygEditor.data( + 'outerWidthOffset', + $wysiwygEditor.outerWidth(true) - $wysiwygEditor.width() + ); + $sourceEditor.data( + 'outerWidthOffset', + $sourceEditor.outerWidth(true) - $sourceEditor.width() + ); + + $wysiwygEditor.data( + 'outerHeightOffset', + $wysiwygEditor.outerHeight(true) - $wysiwygEditor.height() + ); + $sourceEditor.data( + 'outerHeightOffset', + $sourceEditor.outerHeight(true) - $sourceEditor.height() + ); + }; + + /** + * Gets the height of the editor in px + * + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name height + * @return {int} + */ + /** + * Sets the height of the editor + * + * @param {int} height Height in px + * @since 1.3.5 + * @function + * @memberOf jQuery.sceditor.prototype + * @name height^2 + * @return {this} + */ + /** + * Sets the height of the editor + * + * The saveHeight specifies if to save the height. + * + * The stored height can be used for things like + * restoring from maximized state. + * + * @param {int} height Height in px + * @param {boolean} [saveHeight=true] If to store the height + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name height^3 + * @return {this} + */ + base.height = function (height, saveHeight) { + if (!height && height !== 0) { + return $editorContainer.height(); + } + + base.dimensions(null, height, saveHeight); + + return base; + }; + + /** + * Gets if the editor is maximised or not + * + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name maximize + * @return {boolean} + */ + /** + * Sets if the editor is maximised or not + * + * @param {boolean} maximize If to maximise the editor + * @since 1.4.1 + * @function + * @memberOf jQuery.sceditor.prototype + * @name maximize^2 + * @return {this} + */ + base.maximize = function (maximize) { + if (typeof maximize === 'undefined') { + return $editorContainer.is('.sceditor-maximize'); + } + + maximize = !!maximize; + + // IE 6 fix + if (IE_VER < 7) { + $('html, body').toggleClass('sceditor-maximize', maximize); + } + + $editorContainer.toggleClass('sceditor-maximize', maximize); + base.width(maximize ? '100%' : options.width, false); + base.height(maximize ? '100%' : options.height, false); + + return base; + }; + + /** + * Expands the editors height to the height of it's content + * + * Unless ignoreMaxHeight is set to true it will not expand + * higher than the maxHeight option. + * + * @since 1.3.5 + * @param {Boolean} [ignoreMaxHeight=false] + * @function + * @name expandToContent + * @memberOf jQuery.sceditor.prototype + * @see #resizeToContent + */ + base.expandToContent = function (ignoreMaxHeight) { + var currentHeight = $editorContainer.height(), + padding = (currentHeight - $wysiwygEditor.height()), + height = $wysiwygBody[0].scrollHeight || + $wysiwygDoc[0].documentElement.scrollHeight, + maxHeight = options.resizeMaxHeight || + ((options.height || $original.height()) * 2); + + height += padding; + + if ((ignoreMaxHeight === true || height <= maxHeight) && + height > currentHeight) { + base.height(height); + } + }; + + /** + * Destroys the editor, removing all elements and + * event handlers. + * + * Leaves only the original textarea. + * + * @function + * @name destroy + * @memberOf jQuery.sceditor.prototype + */ + base.destroy = function () { + // Don't destroy if the editor has already been destroyed + if (!pluginManager) { + return; + } + + pluginManager.destroy(); + + rangeHelper = null; + lastRange = null; + pluginManager = null; + + if ($dropdown) { + $dropdown.off().remove(); + } + + $globalDoc.off('click', handleDocumentClick); + $globalWin.off('resize orientationChanged', handleWindowResize); + + $(original.form) + .off('reset', handleFormReset) + .off('submit', base.updateOriginal); + + $wysiwygBody.off(); + $wysiwygDoc.off().find('*').remove(); + + $sourceEditor.off().remove(); + $toolbar.remove(); + $editorContainer.off().find('*').off().remove(); + $editorContainer.remove(); + + $original + .removeData('sceditor') + .removeData('sceditorbbcode') + .show(); + + if (isRequired) { + $original.attr('required', 'required'); + } + }; + + + /** + * Creates a menu item drop down + * + * @param {HTMLElement} menuItem The button to align the dropdown with + * @param {string} name Used for styling the dropdown, will be + * a class sceditor-name + * @param {HTMLElement} content The HTML content of the dropdown + * @param {bool} ieFix If to add the unselectable attribute + * to all the contents elements. Stops + * IE from deselecting the text in the + * editor + * @function + * @name createDropDown + * @memberOf jQuery.sceditor.prototype + */ + base.createDropDown = function (menuItem, name, content, ieFix) { + // first click for create second click for close + var dropDownCss, + cssClass = 'sceditor-' + name, + onlyclose = $dropdown && $dropdown.is('.' + cssClass); + + // Will re-focus the editor. This is needed for IE + // as it has special logic to save/restore the selection + base.closeDropDown(true); + + if (onlyclose) { + return; + } + + // IE needs unselectable attr to stop it from + // unselecting the text in the editor. + // SCEditor can cope if IE does unselect the + // text it's just not nice. + if (ieFix !== false) { + $(content) + .find(':not(input,textarea)') + .filter(function () { + return this.nodeType === 1; + }) + .attr('unselectable', 'on'); + } + + dropDownCss = { + top: menuItem.offset().top, + left: menuItem.offset().left, + marginTop: menuItem.outerHeight() + }; + $.extend(dropDownCss, options.dropDownCss); + + $dropdown = $('
    ') + .css(dropDownCss) + .append(content) + .appendTo($('body')) + .on('click focusin', function (e) { + // stop clicks within the dropdown from being handled + e.stopPropagation(); + }); + + // If try to focus the first input immediately IE will + // place the cursor at the start of the editor instead + // of focusing on the input. + setTimeout(function () { + if ($dropdown) { + $dropdown.find('input,textarea').first().focus(); + } + }); + }; + + /** + * Handles any document click and closes the dropdown if open + * @private + */ + handleDocumentClick = function (e) { + // ignore right clicks + if (e.which !== 3 && $dropdown) { + autoUpdate(); + + base.closeDropDown(); + } + }; + + /** + * Handles the WYSIWYG editors paste event + * @private + */ + handlePasteEvt = function (e) { + var html, handlePaste, scrollTop, + elm = $wysiwygBody[0], + doc = $wysiwygDoc[0], + checkCount = 0, + pastearea = globalDoc.createElement('div'), + prePasteContent = doc.createDocumentFragment(), + clipboardData = e ? e.clipboardData : false; + + if (options.disablePasting) { + return false; + } + + if (!options.enablePasteFiltering) { + return; + } + + rangeHelper.saveRange(); + globalDoc.body.appendChild(pastearea); + + if (clipboardData && clipboardData.getData) { + if ((html = clipboardData.getData('text/html')) || + (html = clipboardData.getData('text/plain'))) { + pastearea.innerHTML = html; + handlePasteData(elm, pastearea); + + return false; + } + } + + // Save the scroll position so can be restored + // when contents is restored + scrollTop = $wysiwygBody.scrollTop() || $wysiwygDoc.scrollTop(); + + while (elm.firstChild) { + prePasteContent.appendChild(elm.firstChild); + } + + // try make pastearea contenteditable and redirect to that? Might work. + // Check the tests if still exist, if not re-0create + handlePaste = function (elm, pastearea) { + if (elm.childNodes.length > 0 || checkCount > 25) { + while (elm.firstChild) { + pastearea.appendChild(elm.firstChild); + } + + while (prePasteContent.firstChild) { + elm.appendChild(prePasteContent.firstChild); + } + + $wysiwygBody.scrollTop(scrollTop); + $wysiwygDoc.scrollTop(scrollTop); + + if (pastearea.childNodes.length > 0) { + handlePasteData(elm, pastearea); + } else { + rangeHelper.restoreRange(); + } + } else { + // Allow max 25 checks before giving up. + // Needed in case an empty string is pasted or + // something goes wrong. + checkCount++; + setTimeout(function () { + handlePaste(elm, pastearea); + }, 20); + } + }; + handlePaste(elm, pastearea); + + base.focus(); + return true; + }; + + /** + * Gets the pasted data, filters it and then inserts it. + * @param {Element} elm + * @param {Element} pastearea + * @private + */ + handlePasteData = function (elm, pastearea) { + // fix any invalid nesting + dom.fixNesting(pastearea); + // TODO: Trigger custom paste event to allow filtering + // (pre and post converstion?) + var pasteddata = pastearea.innerHTML; + + if (pluginManager.hasHandler('toSource')) { + pasteddata = pluginManager.callOnlyFirst( + 'toSource', pasteddata, $(pastearea) + ); + } + + pastearea.parentNode.removeChild(pastearea); + + if (pluginManager.hasHandler('toWysiwyg')) { + pasteddata = pluginManager.callOnlyFirst( + 'toWysiwyg', pasteddata, true + ); + } + + rangeHelper.restoreRange(); + base.wysiwygEditorInsertHtml(pasteddata, null, true); + }; + + /** + * Closes any currently open drop down + * + * @param {bool} [focus=false] If to focus the editor + * after closing the drop down + * @function + * @name closeDropDown + * @memberOf jQuery.sceditor.prototype + */ + base.closeDropDown = function (focus) { + if ($dropdown) { + $dropdown.off().remove(); + $dropdown = null; + } + + if (focus === true) { + base.focus(); + } + }; + + /** + * Gets the WYSIWYG editors document + * @private + */ + getWysiwygDoc = function () { + if (wysiwygEditor.contentDocument) { + return wysiwygEditor.contentDocument; + } + + if (wysiwygEditor.contentWindow && + wysiwygEditor.contentWindow.document) { + return wysiwygEditor.contentWindow.document; + } + + return wysiwygEditor.document; + }; + + + /** + *

    Inserts HTML into WYSIWYG editor.

    + * + *

    If endHtml is specified, any selected text will be placed + * between html and endHtml. If there is no selected text html + * and endHtml will just be concatenate together.

    + * + * @param {string} html + * @param {string} [endHtml=null] + * @param {boolean} [overrideCodeBlocking=false] If to insert the html + * into code tags, by + * default code tags only + * support text. + * @function + * @name wysiwygEditorInsertHtml + * @memberOf jQuery.sceditor.prototype + */ + base.wysiwygEditorInsertHtml = function ( + html, endHtml, overrideCodeBlocking + ) { + var $marker, scrollTop, scrollTo, + editorHeight = $wysiwygEditor.height(); + + base.focus(); + + // TODO: This code tag should be configurable and + // should maybe convert the HTML into text instead + // Don't apply to code elements + if (!overrideCodeBlocking && ($(currentBlockNode).is('code') || + $(currentBlockNode).parents('code').length !== 0)) { + return; + } + + // Insert the HTML and save the range so the editor can be scrolled + // to the end of the selection. Also allows emoticons to be replaced + // without affecting the cursor position + rangeHelper.insertHTML(html, endHtml); + rangeHelper.saveRange(); + replaceEmoticons($wysiwygBody[0]); + + // Scroll the editor after the end of the selection + $marker = $wysiwygBody.find('#sceditor-end-marker').show(); + scrollTop = $wysiwygBody.scrollTop() || $wysiwygDoc.scrollTop(); + scrollTo = (dom.getOffset($marker[0]).top + + ($marker.outerHeight(true) * 1.5)) - editorHeight; + $marker.hide(); + + // Only scroll if marker isn't already visible + if (scrollTo > scrollTop || scrollTo + editorHeight < scrollTop) { + $wysiwygBody.scrollTop(scrollTo); + $wysiwygDoc.scrollTop(scrollTo); + } + + triggerValueChanged(false); + rangeHelper.restoreRange(); + + // Add a new line after the last block element + // so can always add text after it + appendNewLine(); + }; + + /** + * Like wysiwygEditorInsertHtml except it will convert any HTML + * into text before inserting it. + * + * @param {String} text + * @param {String} [endText=null] + * @function + * @name wysiwygEditorInsertText + * @memberOf jQuery.sceditor.prototype + */ + base.wysiwygEditorInsertText = function (text, endText) { + base.wysiwygEditorInsertHtml( + escape.entities(text), escape.entities(endText) + ); + }; + + /** + *

    Inserts text into the WYSIWYG or source editor depending on which + * mode the editor is in.

    + * + *

    If endText is specified any selected text will be placed between + * text and endText. If no text is selected text and endText will + * just be concatenate together.

    + * + * @param {String} text + * @param {String} [endText=null] + * @since 1.3.5 + * @function + * @name insertText + * @memberOf jQuery.sceditor.prototype + */ + base.insertText = function (text, endText) { + if (base.inSourceMode()) { + base.sourceEditorInsertText(text, endText); + } else { + base.wysiwygEditorInsertText(text, endText); + } + + return base; + }; + + /** + *

    Like wysiwygEditorInsertHtml but inserts text into the + * source mode editor instead.

    + * + *

    If endText is specified any selected text will be placed between + * text and endText. If no text is selected text and endText will + * just be concatenate together.

    + * + *

    The cursor will be placed after the text param. If endText is + * specified the cursor will be placed before endText, so passing:
    + * + * '[b]', '[/b]'

    + * + *

    Would cause the cursor to be placed:
    + * + * [b]Selected text|[/b]

    + * + * @param {String} text + * @param {String} [endText=null] + * @since 1.4.0 + * @function + * @name sourceEditorInsertText + * @memberOf jQuery.sceditor.prototype + */ + base.sourceEditorInsertText = function (text, endText) { + var range, scrollTop, currentValue, + startPos = sourceEditor.selectionStart, + endPos = sourceEditor.selectionEnd; + + scrollTop = sourceEditor.scrollTop; + sourceEditor.focus(); + + // All browsers except IE < 9 + if (typeof startPos !== 'undefined') { + currentValue = sourceEditor.value; + + if (endText) { + text += currentValue.substring(startPos, endPos) + endText; + } + + sourceEditor.value = currentValue.substring(0, startPos) + + text + + currentValue.substring(endPos, currentValue.length); + + sourceEditor.selectionStart = (startPos + text.length) - + (endText ? endText.length : 0); + sourceEditor.selectionEnd = sourceEditor.selectionStart; + // IE < 9 + } else { + range = globalDoc.selection.createRange(); + + if (endText) { + text += range.text + endText; + } + + range.text = text; + + if (endText) { + range.moveEnd('character', 0 - endText.length); + } + + range.moveStart('character', range.End - range.Start); + range.select(); + } + + sourceEditor.scrollTop = scrollTop; + sourceEditor.focus(); + + triggerValueChanged(); + }; + + /** + * Gets the current instance of the rangeHelper class + * for the editor. + * + * @return jQuery.sceditor.rangeHelper + * @function + * @name getRangeHelper + * @memberOf jQuery.sceditor.prototype + */ + base.getRangeHelper = function () { + return rangeHelper; + }; + + /** + * Gets the source editors textarea. + * + * This shouldn't be used to insert text + * + * @return {jQuery} + * @function + * @since 1.4.5 + * @name sourceEditorCaret + * @memberOf jQuery.sceditor.prototype + */ + base.sourceEditorCaret = function (position) { + var range, + ret = {}; + + sourceEditor.focus(); + + // All browsers except IE <= 8 + if (typeof sourceEditor.selectionStart !== 'undefined') { + if (position) { + sourceEditor.selectionStart = position.start; + sourceEditor.selectionEnd = position.end; + } else { + ret.start = sourceEditor.selectionStart; + ret.end = sourceEditor.selectionEnd; + } + + // IE8 and below + } else { + range = globalDoc.selection.createRange(); + + if (position) { + range.moveEnd('character', position.end); + range.moveStart('character', position.start); + range.select(); + } else { + ret.start = range.Start; + ret.end = range.End; + } + } + + return position ? this : ret; + }; + + /** + *

    Gets the value of the editor.

    + * + *

    If the editor is in WYSIWYG mode it will return the filtered + * HTML from it (converted to BBCode if using the BBCode plugin). + * It it's in Source Mode it will return the unfiltered contents + * of the source editor (if using the BBCode plugin this will be + * BBCode again).

    + * + * @since 1.3.5 + * @return {string} + * @function + * @name val + * @memberOf jQuery.sceditor.prototype + */ + /** + *

    Sets the value of the editor.

    + * + *

    If filter set true the val will be passed through the filter + * function. If using the BBCode plugin it will pass the val to + * the BBCode filter to convert any BBCode into HTML.

    + * + * @param {String} val + * @param {Boolean} [filter=true] + * @return {this} + * @since 1.3.5 + * @function + * @name val^2 + * @memberOf jQuery.sceditor.prototype + */ + base.val = function (val, filter) { + if (typeof val !== 'string') { + return base.inSourceMode() ? + base.getSourceEditorValue(false) : + base.getWysiwygEditorValue(filter); + } + + if (!base.inSourceMode()) { + if (filter !== false && + pluginManager.hasHandler('toWysiwyg')) { + val = pluginManager.callOnlyFirst('toWysiwyg', val); + } + + base.setWysiwygEditorValue(val); + } else { + base.setSourceEditorValue(val); + } + + return base; + }; + + /** + *

    Inserts HTML/BBCode into the editor

    + * + *

    If end is supplied any selected text will be placed between + * start and end. If there is no selected text start and end + * will be concatenate together.

    + * + *

    If the filter param is set to true, the HTML/BBCode will be + * passed through any plugin filters. If using the BBCode plugin + * this will convert any BBCode into HTML.

    + * + * @param {String} start + * @param {String} [end=null] + * @param {Boolean} [filter=true] + * @param {Boolean} [convertEmoticons=true] If to convert emoticons + * @return {this} + * @since 1.3.5 + * @function + * @name insert + * @memberOf jQuery.sceditor.prototype + */ + /** + *

    Inserts HTML/BBCode into the editor

    + * + *

    If end is supplied any selected text will be placed between + * start and end. If there is no selected text start and end + * will be concatenate together.

    + * + *

    If the filter param is set to true, the HTML/BBCode will be + * passed through any plugin filters. If using the BBCode plugin + * this will convert any BBCode into HTML.

    + * + *

    If the allowMixed param is set to true, HTML any will not be + * escaped

    + * + * @param {String} start + * @param {String} [end=null] + * @param {Boolean} [filter=true] + * @param {Boolean} [convertEmoticons=true] If to convert emoticons + * @param {Boolean} [allowMixed=false] + * @return {this} + * @since 1.4.3 + * @function + * @name insert^2 + * @memberOf jQuery.sceditor.prototype + */ + base.insert = function ( + /*jshint maxparams: false */ + start, end, filter, convertEmoticons, allowMixed + ) { + if (base.inSourceMode()) { + base.sourceEditorInsertText(start, end); + return base; + } + + // Add the selection between start and end + if (end) { + var html = rangeHelper.selectedHtml(), + $div = $('
    ').appendTo($('body')).hide().html(html); + + if (filter !== false && pluginManager.hasHandler('toSource')) { + html = pluginManager.callOnlyFirst('toSource', html, $div); + } + + $div.remove(); + + start += html + end; + } + // TODO: This filter should allow empty tags as it's inserting. + if (filter !== false && pluginManager.hasHandler('toWysiwyg')) { + start = pluginManager.callOnlyFirst('toWysiwyg', start, true); + } + + // Convert any escaped HTML back into HTML if mixed is allowed + if (filter !== false && allowMixed === true) { + start = start.replace(/</g, '<') + .replace(/>/g, '>') + .replace(/&/g, '&'); + } + + base.wysiwygEditorInsertHtml(start); + + return base; + }; + + /** + * Gets the WYSIWYG editors HTML value. + * + * If using a plugin that filters the Ht Ml like the BBCode plugin + * it will return the result of the filtering (BBCode) unless the + * filter param is set to false. + * + * @param {bool} [filter=true] + * @return {string} + * @function + * @name getWysiwygEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.getWysiwygEditorValue = function (filter) { + var html; + // Create a tmp node to store contents so it can be modified + // without affecting anything else. + var $tmp = $('
    ') + .appendTo(document.body) + .append($($wysiwygBody[0].childNodes).clone()); + + dom.fixNesting($tmp[0]); + + html = $tmp.html(); + + // filter the HTML and DOM through any plugins + if (filter !== false && pluginManager.hasHandler('toSource')) { + html = pluginManager.callOnlyFirst('toSource', html, $tmp); + } + + $tmp.remove(); + + return html; + }; + + /** + * Gets the WYSIWYG editor's iFrame Body. + * + * @return {jQuery} + * @function + * @since 1.4.3 + * @name getBody + * @memberOf jQuery.sceditor.prototype + */ + base.getBody = function () { + return $wysiwygBody; + }; + + /** + * Gets the WYSIWYG editors container area (whole iFrame). + * + * @return {Node} + * @function + * @since 1.4.3 + * @name getContentAreaContainer + * @memberOf jQuery.sceditor.prototype + */ + base.getContentAreaContainer = function () { + return $wysiwygEditor; + }; + + /** + * Gets the text editor value + * + * If using a plugin that filters the text like the BBCode plugin + * it will return the result of the filtering which is BBCode to + * HTML so it will return HTML. If filter is set to false it will + * just return the contents of the source editor (BBCode). + * + * @param {bool} [filter=true] + * @return {string} + * @function + * @since 1.4.0 + * @name getSourceEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.getSourceEditorValue = function (filter) { + var val = $sourceEditor.val(); + + if (filter !== false && pluginManager.hasHandler('toWysiwyg')) { + val = pluginManager.callOnlyFirst('toWysiwyg', val); + } + + return val; + }; + + /** + * Sets the WYSIWYG HTML editor value. Should only be the HTML + * contained within the body tags + * + * @param {string} value + * @function + * @name setWysiwygEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.setWysiwygEditorValue = function (value) { + if (!value) { + value = '

    ' + (IE_VER ? '' : '
    ') + '

    '; + } + + $wysiwygBody[0].innerHTML = value; + replaceEmoticons($wysiwygBody[0]); + + appendNewLine(); + triggerValueChanged(); + }; + + /** + * Sets the text editor value + * + * @param {string} value + * @function + * @name setSourceEditorValue + * @memberOf jQuery.sceditor.prototype + */ + base.setSourceEditorValue = function (value) { + $sourceEditor.val(value); + + triggerValueChanged(); + }; + + /** + * Updates the textarea that the editor is replacing + * with the value currently inside the editor. + * + * @function + * @name updateOriginal + * @since 1.4.0 + * @memberOf jQuery.sceditor.prototype + */ + base.updateOriginal = function () { + $original.val(base.val()); + }; + + /** + * Replaces any emoticon codes in the passed HTML + * with their emoticon images + * @private + */ + replaceEmoticons = function (node) { + // TODO: Make this tag configurable. + if (!options.emoticonsEnabled || $(node).parents('code').length) { + return; + } + + var doc = node.ownerDocument, + whitespace = '\\s|\xA0|\u2002|\u2003|\u2009| ', + emoticonCodes = [], + emoticonRegex = [], + emoticons = $.extend( + {}, + options.emoticons.more, + options.emoticons.dropdown, + options.emoticons.hidden + ); + // TODO: cache the emoticonCodes and emoticonCodes objects and share them with + // the AYT converstion + $.each(emoticons, function (key) { + if (options.emoticonsCompat) { + emoticonRegex[key] = new RegExp( + '(>|^|' + whitespace + ')' + + escape.regex(key) + + '($|<|' + whitespace + ')' + ); + } + + emoticonCodes.push(key); + }); + // TODO: tidy below + var convertEmoticons = function (node) { + node = node.firstChild; + + while (node) { + var parts, key, emoticon, parsedHtml, + emoticonIdx, nextSibling, matchPos, + nodeParent = node.parentNode, + nodeValue = node.nodeValue; + + // All none textnodes + if (node.nodeType !== 3) { + // TODO: Make this tag configurable. + if (!$(node).is('code')) { + convertEmoticons(node); + } + } else if (nodeValue) { + emoticonIdx = emoticonCodes.length; + while (emoticonIdx--) { + key = emoticonCodes[emoticonIdx]; + matchPos = options.emoticonsCompat ? + nodeValue.search(emoticonRegex[key]) : + nodeValue.indexOf(key); + + if (matchPos > -1) { + nextSibling = node.nextSibling; + emoticon = emoticons[key]; + parts = nodeValue + .substr(matchPos).split(key); + nodeValue = nodeValue + .substr(0, matchPos) + parts.shift(); + node.nodeValue = nodeValue; + + parsedHtml = dom.parseHTML(_tmpl('emoticon', { + key: key, + url: emoticon.url || emoticon, + tooltip: emoticon.tooltip || key + }), doc); + + nodeParent.insertBefore( + parsedHtml[0], + nextSibling + ); + + nodeParent.insertBefore( + doc.createTextNode(parts.join(key)), + nextSibling + ); + } + } + } + + node = node.nextSibling; + } + }; + + convertEmoticons(node); + + if (options.emoticonsCompat) { + currentEmoticons = $wysiwygBody + .find('img[data-sceditor-emoticon]'); + } + }; + + /** + * If the editor is in source code mode + * + * @return {bool} + * @function + * @name inSourceMode + * @memberOf jQuery.sceditor.prototype + */ + base.inSourceMode = function () { + return $editorContainer.hasClass('sourceMode'); + }; + + /** + * Gets if the editor is in sourceMode + * + * @return boolean + * @function + * @name sourceMode + * @memberOf jQuery.sceditor.prototype + */ + /** + * Sets if the editor is in sourceMode + * + * @param {bool} enable + * @return {this} + * @function + * @name sourceMode^2 + * @memberOf jQuery.sceditor.prototype + */ + base.sourceMode = function (enable) { + var inSourceMode = base.inSourceMode(); + + if (typeof enable !== 'boolean') { + return inSourceMode; + } + + if ((inSourceMode && !enable) || (!inSourceMode && enable)) { + base.toggleSourceMode(); + } + + return base; + }; + + /** + * Switches between the WYSIWYG and source modes + * + * @function + * @name toggleSourceMode + * @since 1.4.0 + * @memberOf jQuery.sceditor.prototype + */ + base.toggleSourceMode = function () { + var sourceMode = base.inSourceMode(); + + // don't allow switching to WYSIWYG if doesn't support it + if (!browser.isWysiwygSupported && sourceMode) { + return; + } + + if (!sourceMode) { + rangeHelper.saveRange(); + rangeHelper.clear(); + } + + base.blur(); + + if (sourceMode) { + base.setWysiwygEditorValue(base.getSourceEditorValue()); + } else { + base.setSourceEditorValue(base.getWysiwygEditorValue()); + } + + lastRange = null; + $sourceEditor.toggle(); + $wysiwygEditor.toggle(); + $editorContainer + .toggleClass('wysiwygMode', sourceMode) + .toggleClass('sourceMode', !sourceMode); + + updateToolBar(); + updateActiveButtons(); + }; + + /** + * Gets the selected text of the source editor + * @return {String} + * @private + */ + sourceEditorSelectedText = function () { + sourceEditor.focus(); + + if (typeof sourceEditor.selectionStart !== 'undefined') { + return sourceEditor.value.substring( + sourceEditor.selectionStart, + sourceEditor.selectionEnd + ); + } else { + return globalDoc.selection.createRange().text; + } + }; + + /** + * Handles the passed command + * @private + */ + handleCommand = function (caller, cmd) { + // check if in text mode and handle text commands + if (base.inSourceMode()) { + if (cmd.txtExec) { + if ($.isArray(cmd.txtExec)) { + base.sourceEditorInsertText.apply(base, cmd.txtExec); + } else { + cmd.txtExec.call( + base, + caller, + sourceEditorSelectedText() + ); + } + } + } else if (cmd.exec) { + if ($.isFunction(cmd.exec)) { + cmd.exec.call(base, caller); + } else { + base.execCommand( + cmd.exec, + cmd.hasOwnProperty('execParam') ? + cmd.execParam : null + ); + } + } + + }; + + /** + * Saves the current range. Needed for IE because it forgets + * where the cursor was and what was selected + * @private + */ + saveRange = function () { + /* this is only needed for IE */ + if (IE_VER) { + lastRange = rangeHelper.selectedRange(); + } + }; + + /** + * Executes a command on the WYSIWYG editor + * + * @param {String} command + * @param {String|Boolean} [param] + * @function + * @name execCommand + * @memberOf jQuery.sceditor.prototype + */ + base.execCommand = function (command, param) { + var executed = false, + commandObj = base.commands[command], + $parentNode = $(rangeHelper.parentNode()); + + base.focus(); + + // TODO: make configurable + // don't apply any commands to code elements + if ($parentNode.is('code') || + $parentNode.parents('code').length !== 0) { + return; + } + + try { + executed = $wysiwygDoc[0].execCommand(command, false, param); + } catch (ex) {} + + // show error if execution failed and an error message exists + if (!executed && commandObj && commandObj.errorMessage) { + /*global alert:false*/ + alert(base._(commandObj.errorMessage)); + } + + updateActiveButtons(); + }; + + /** + * Checks if the current selection has changed and triggers + * the selectionchanged event if it has. + * + * In browsers other than IE, it will check at most once every 100ms. + * This is because only IE has a selection changed event. + * @private + */ + checkSelectionChanged = function () { + function check () { + // rangeHelper could be null if editor was destroyed + // before the timeout had finished + if (rangeHelper && !rangeHelper.compare(currentSelection)) { + currentSelection = rangeHelper.cloneSelected(); + $editorContainer.trigger($.Event('selectionchanged')); + } + + isSelectionCheckPending = false; + } + + if (isSelectionCheckPending) { + return; + } + + isSelectionCheckPending = true; + + // In IE, this is only called on the selectionchange event so no + // need to limit checking as it should always be valid to do. + if (IE_VER) { + check(); + } else { + setTimeout(check, 100); + } + }; + + /** + * Checks if the current node has changed and triggers + * the nodechanged event if it has + * @private + */ + checkNodeChanged = function () { + // check if node has changed + var oldNode, + node = rangeHelper.parentNode(); + + if (currentNode !== node) { + oldNode = currentNode; + currentNode = node; + currentBlockNode = rangeHelper.getFirstBlockParent(node); + + $editorContainer.trigger($.Event('nodechanged', { + oldNode: oldNode, + newNode: currentNode + })); + } + }; + + /** + *

    Gets the current node that contains the selection/caret in + * WYSIWYG mode.

    + * + *

    Will be null in sourceMode or if there is no selection.

    + * @return {Node} + * @function + * @name currentNode + * @memberOf jQuery.sceditor.prototype + */ + base.currentNode = function () { + return currentNode; + }; + + /** + *

    Gets the first block level node that contains the + * selection/caret in WYSIWYG mode.

    + * + *

    Will be null in sourceMode or if there is no selection.

    + * @return {Node} + * @function + * @name currentBlockNode + * @memberOf jQuery.sceditor.prototype + * @since 1.4.4 + */ + base.currentBlockNode = function () { + return currentBlockNode; + }; + + /** + * Updates if buttons are active or not + * @private + */ + updateActiveButtons = function (e) { + var firstBlock, parent; + var activeClass = 'active'; + var doc = $wysiwygDoc[0]; + var isSource = base.sourceMode(); + + if (base.readOnly()) { + $toolbar.find(activeClass).removeClass(activeClass); + return; + } + + if (!isSource) { + parent = e ? e.newNode : rangeHelper.parentNode(); + firstBlock = rangeHelper.getFirstBlockParent(parent); + } + + for (var i = 0; i < btnStateHandlers.length; i++) { + var state = 0; + var $btn = toolbarButtons[btnStateHandlers[i].name]; + var stateFn = btnStateHandlers[i].state; + var isDisabled = (isSource && !$btn.data('sceditor-txtmode')) || + (!isSource && !$btn.data('sceditor-wysiwygmode')); + + if (typeof stateFn === 'string') { + if (!isSource) { + try { + state = doc.queryCommandEnabled(stateFn) ? 0 : -1; + + /*jshint maxdepth: false*/ + if (state > -1) { + state = doc.queryCommandState(stateFn) ? 1 : 0; + } + } catch (ex) {} + } + } else if (!isDisabled) { + state = stateFn.call(base, parent, firstBlock); + } + + $btn + .toggleClass('disabled', isDisabled || state < 0) + .toggleClass(activeClass, state > 0); + } + }; + + /** + * Handles any key press in the WYSIWYG editor + * + * @private + */ + handleKeyPress = function (e) { + var $closestTag, br, brParent, lastChild; + + // TODO: improve this so isn't set list, probably should just use + // dom.hasStyling to all block parents and if one does insert a br + var DUPLICATED_TAGS = 'code,blockquote,pre'; + var LIST_TAGS = 'li,ul,ol'; + + // FF bug: https://bugzilla.mozilla.org/show_bug.cgi?id=501496 + if (e.originalEvent.defaultPrevented) { + return; + } + + base.closeDropDown(); + + $closestTag = $(currentBlockNode) + .closest(DUPLICATED_TAGS + ',' + LIST_TAGS) + .first(); + + // "Fix" (OK it's a cludge) for blocklevel elements being + // duplicated in some browsers when enter is pressed instead + // of inserting a newline + if (e.which === 13 && $closestTag.length && + !$closestTag.is(LIST_TAGS)) { + lastRange = null; + + br = $wysiwygDoc[0].createElement('br'); + rangeHelper.insertNode(br); + + // Last
    of a block will be collapsed unless it is + // IE < 11 so need to make sure the
    that was inserted + // isn't the last node of a block. + if (!IE_BR_FIX) { + brParent = br.parentNode; + lastChild = brParent.lastChild; + + // Sometimes an empty next node is created after the
    + if (lastChild && lastChild.nodeType === 3 && + lastChild.nodeValue === '') { + brParent.removeChild(lastChild); + lastChild = brParent.lastChild; + } + + // If this is the last BR of a block and the previous + // sibling is inline then will need an extra BR. This + // is needed because the last BR of a block will be + // collapsed. Fixes issue #248 + if (!dom.isInline(brParent, true) && lastChild === br && + dom.isInline(br.previousSibling)) { + rangeHelper.insertHTML('
    '); + } + } + + return false; + } + }; + + /** + * Makes sure that if there is a code or quote tag at the + * end of the editor, that there is a new line after it. + * + * If there wasn't a new line at the end you wouldn't be able + * to enter any text after a code/quote tag + * @return {void} + * @private + */ + appendNewLine = function () { + var name, requiresNewLine, paragraph, + body = $wysiwygBody[0]; + + dom.rTraverse(body, function (node) { + name = node.nodeName.toLowerCase(); + // TODO: Replace requireNewLineFix with just a block level fix for any + // block that has styling and any block that isn't a plain

    or

    + if ($.inArray(name, requireNewLineFix) > -1) { + requiresNewLine = true; + } + // TODO: tidy this up + // find the last non-empty text node or line break. + if ((node.nodeType === 3 && !/^\s*$/.test(node.nodeValue)) || + name === 'br' || (IE_BR_FIX && !node.firstChild && + !dom.isInline(node, false))) { + + // this is the last text or br node, if its in a code or + // quote tag then add a newline to the end of the editor + if (requiresNewLine) { + paragraph = $wysiwygDoc[0].createElement('p'); + paragraph.className = 'sceditor-nlf'; + paragraph.innerHTML = !IE_BR_FIX ? '
    ' : ''; + body.appendChild(paragraph); + } + + return false; + } + }); + }; + + /** + * Handles form reset event + * @private + */ + handleFormReset = function () { + base.val($original.val()); + }; + + /** + * Handles any mousedown press in the WYSIWYG editor + * @private + */ + handleMouseDown = function () { + base.closeDropDown(); + lastRange = null; + }; + + /** + * Handles the window resize event. Needed to resize then editor + * when the window size changes in fluid designs. + * @ignore + */ + handleWindowResize = function () { + var height = options.height, + width = options.width; + + if (!base.maximize()) { + if ((height && height.toString().indexOf('%') > -1) || + (width && width.toString().indexOf('%') > -1)) { + base.dimensions(width, height); + } + } else { + base.dimensions('100%', '100%', false); + } + }; + + /** + * Translates the string into the locale language. + * + * Replaces any {0}, {1}, {2}, ect. with the params provided. + * + * @param {string} str + * @param {...String} args + * @return {string} + * @function + * @name _ + * @memberOf jQuery.sceditor.prototype + */ + base._ = function () { + var undef, + args = arguments; + + if (locale && locale[args[0]]) { + args[0] = locale[args[0]]; + } + + return args[0].replace(/\{(\d+)\}/g, function (str, p1) { + return args[p1 - 0 + 1] !== undef ? + args[p1 - 0 + 1] : + '{' + p1 + '}'; + }); + }; + + /** + * Passes events on to any handlers + * @private + * @return void + */ + handleEvent = function (e) { + // Send event to all plugins + pluginManager.call(e.type + 'Event', e, base); + + // convert the event into a custom event to send + var prefix = e.target === sourceEditor ? 'scesrc' : 'scewys'; + var customEvent = $.Event(e); + customEvent.type = prefix + e.type; + + $editorContainer.trigger(customEvent, base); + }; + + /** + *

    Binds a handler to the specified events

    + * + *

    This function only binds to a limited list of + * supported events.
    + * The supported events are: + *

      + *
    • keyup
    • + *
    • keydown
    • + *
    • Keypress
    • + *
    • blur
    • + *
    • focus
    • + *
    • nodechanged
      + * When the current node containing the selection changes + * in WYSIWYG mode
    • + *
    • contextmenu
    • + *
    • selectionchanged
    • + *
    • valuechanged
    • + *
    + *

    + * + *

    The events param should be a string containing the event(s) + * to bind this handler to. If multiple, they should be separated + * by spaces.

    + * + * @param {String} events + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name bind + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.bind = function (events, handler, excludeWysiwyg, excludeSource) { + events = events.split(' '); + + var i = events.length; + while (i--) { + if ($.isFunction(handler)) { + // Use custom events to allow passing the instance as the + // 2nd argument. + // Also allows unbinding without unbinding the editors own + // event handlers. + if (!excludeWysiwyg) { + $editorContainer.on('scewys' + events[i], handler); + } + + if (!excludeSource) { + $editorContainer.on('scesrc' + events[i], handler); + } + + // Start sending value changed events + if (events[i] === 'valuechanged') { + triggerValueChanged.hasHandler = true; + } + } + } + + return base; + }; + + /** + * Unbinds an event that was bound using bind(). + * + * @param {String} events + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude unbinding this + * handler from the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude unbinding this + * handler from the source editor + * @return {this} + * @function + * @name unbind + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + * @see bind + */ + base.unbind = function ( + events, handler, excludeWysiwyg, excludeSource + ) { + events = events.split(' '); + + var i = events.length; + while (i--) { + if ($.isFunction(handler)) { + if (!excludeWysiwyg) { + $editorContainer.off('scewys' + events[i], handler); + } + + if (!excludeSource) { + $editorContainer.off('scesrc' + events[i], handler); + } + } + } + + return base; + }; + + /** + * Blurs the editors input area + * + * @return {this} + * @function + * @name blur + * @memberOf jQuery.sceditor.prototype + * @since 1.3.6 + */ + /** + * Adds a handler to the editors blur event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name blur^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.blur = function (handler, excludeWysiwyg, excludeSource) { + if ($.isFunction(handler)) { + base.bind('blur', handler, excludeWysiwyg, excludeSource); + } else if (!base.sourceMode()) { + $wysiwygBody.blur(); + } else { + $sourceEditor.blur(); + } + + return base; + }; + + /** + * Focuses the editors input area + * + * @return {this} + * @function + * @name focus + * @memberOf jQuery.sceditor.prototype + */ + /** + * Adds an event handler to the focus event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource if to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name focus^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.focus = function (handler, excludeWysiwyg, excludeSource) { + if ($.isFunction(handler)) { + base.bind('focus', handler, excludeWysiwyg, excludeSource); + } else if (!base.inSourceMode()) { + var container, + rng = rangeHelper.selectedRange(); + + // Fix FF bug where it shows the cursor in the wrong place + // if the editor hasn't had focus before. See issue #393 + if (!currentSelection && !rangeHelper.hasSelection()) { + autofocus(); + } + + // Check if cursor is set after a BR when the BR is the only + // child of the parent. In Firefox this causes a line break + // to occur when something is typed. See issue #321 + if (!IE_BR_FIX && rng && rng.endOffset === 1 && rng.collapsed) { + container = rng.endContainer; + + if (container && container.childNodes.length === 1 && + $(container.firstChild).is('br')) { + rng.setStartBefore(container.firstChild); + rng.collapse(true); + rangeHelper.selectRange(rng); + } + } + + wysiwygEditor.contentWindow.focus(); + $wysiwygBody[0].focus(); + + // Needed for IE < 9 + if (lastRange) { + rangeHelper.selectRange(lastRange); + + // remove the stored range after being set. + // If the editor loses focus it should be + // saved again. + lastRange = null; + } + } else { + sourceEditor.focus(); + } + + updateActiveButtons(); + + return base; + }; + + /** + * Adds a handler to the key down event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name keyDown + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.keyDown = function (handler, excludeWysiwyg, excludeSource) { + return base.bind('keydown', handler, excludeWysiwyg, excludeSource); + }; + + /** + * Adds a handler to the key press event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name keyPress + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.keyPress = function (handler, excludeWysiwyg, excludeSource) { + return base + .bind('keypress', handler, excludeWysiwyg, excludeSource); + }; + + /** + * Adds a handler to the key up event + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name keyUp + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.keyUp = function (handler, excludeWysiwyg, excludeSource) { + return base.bind('keyup', handler, excludeWysiwyg, excludeSource); + }; + + /** + *

    Adds a handler to the node changed event.

    + * + *

    Happens whenever the node containing the selection/caret + * changes in WYSIWYG mode.

    + * + * @param {Function} handler + * @return {this} + * @function + * @name nodeChanged + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.nodeChanged = function (handler) { + return base.bind('nodechanged', handler, false, true); + }; + + /** + *

    Adds a handler to the selection changed event

    + * + *

    Happens whenever the selection changes in WYSIWYG mode.

    + * + * @param {Function} handler + * @return {this} + * @function + * @name selectionChanged + * @memberOf jQuery.sceditor.prototype + * @since 1.4.1 + */ + base.selectionChanged = function (handler) { + return base.bind('selectionchanged', handler, false, true); + }; + + /** + *

    Adds a handler to the value changed event

    + * + *

    Happens whenever the current editor value changes.

    + * + *

    Whenever anything is inserted, the value changed or + * 1.5 secs after text is typed. If a space is typed it will + * cause the event to be triggered immediately instead of + * after 1.5 seconds

    + * + * @param {Function} handler + * @param {Boolean} excludeWysiwyg If to exclude adding this handler + * to the WYSIWYG editor + * @param {Boolean} excludeSource If to exclude adding this handler + * to the source editor + * @return {this} + * @function + * @name valueChanged + * @memberOf jQuery.sceditor.prototype + * @since 1.4.5 + */ + base.valueChanged = function (handler, excludeWysiwyg, excludeSource) { + return base + .bind('valuechanged', handler, excludeWysiwyg, excludeSource); + }; + + /** + * Emoticons keypress handler + * @private + */ + emoticonsKeyPress = function (e) { + var replacedEmoticon, + cachePos = 0, + emoticonsCache = base.emoticonsCache, + curChar = String.fromCharCode(e.which); + // TODO: Make configurable + if ($(currentBlockNode).is('code') || + $(currentBlockNode).parents('code').length) { + return; + } + + if (!emoticonsCache) { + emoticonsCache = []; + + $.each($.extend( + {}, + options.emoticons.more, + options.emoticons.dropdown, + options.emoticons.hidden + ), function (key, url) { + emoticonsCache[cachePos++] = [ + key, + _tmpl('emoticon', { + key: key, + url: url.url || url, + tooltip: url.tooltip || key + }) + ]; + }); + + emoticonsCache.sort(function (a, b) { + return a[0].length - b[0].length; + }); + + base.emoticonsCache = emoticonsCache; + base.longestEmoticonCode = + emoticonsCache[emoticonsCache.length - 1][0].length; + } + + replacedEmoticon = rangeHelper.replaceKeyword( + base.emoticonsCache, + true, + true, + base.longestEmoticonCode, + options.emoticonsCompat, + curChar + ); + + if (replacedEmoticon && options.emoticonsCompat) { + currentEmoticons = $wysiwygBody + .find('img[data-sceditor-emoticon]'); + + return /^\s$/.test(curChar); + } + + return !replacedEmoticon; + }; + + /** + * Makes sure emoticons are surrounded by whitespace + * @private + */ + emoticonsCheckWhitespace = function () { + if (!currentEmoticons.length) { + return; + } + + var prev, next, parent, range, previousText, rangeStartContainer, + currentBlock = base.currentBlockNode(), + rangeStart = false, + noneWsRegex = /[^\s\xA0\u2002\u2003\u2009\u00a0]+/; + + currentEmoticons = $.map(currentEmoticons, function (emoticon) { + // Ignore emoticons that have been removed from DOM + if (!emoticon || !emoticon.parentNode) { + return null; + } + + if (!$.contains(currentBlock, emoticon)) { + return emoticon; + } + + prev = emoticon.previousSibling; + next = emoticon.nextSibling; + previousText = prev.nodeValue; + + // For IE's HTMLPhraseElement + if (previousText === null) { + previousText = prev.innerText || ''; + } + + if ((!prev || !noneWsRegex.test(prev.nodeValue.slice(-1))) && + (!next || !noneWsRegex.test((next.nodeValue || '')[0]))) { + return emoticon; + } + + parent = emoticon.parentNode; + range = rangeHelper.cloneSelected(); + rangeStartContainer = range.startContainer; + previousText = previousText + + $(emoticon).data('sceditor-emoticon'); + + // Store current caret position + if (rangeStartContainer === next) { + rangeStart = previousText.length + range.startOffset; + } else if (rangeStartContainer === currentBlock && + currentBlock.childNodes[range.startOffset] === next) { + rangeStart = previousText.length; + } else if (rangeStartContainer === prev) { + rangeStart = range.startOffset; + } + + if (!next || next.nodeType !== 3) { + next = parent.insertBefore( + parent.ownerDocument.createTextNode(''), next + ); + } + + next.insertData(0, previousText); + parent.removeChild(prev); + parent.removeChild(emoticon); + + // Need to update the range starting + // position if it has been modified + if (rangeStart !== false) { + range.setStart(next, rangeStart); + range.collapse(true); + rangeHelper.selectRange(range); + } + + return null; + }); + }; + + /** + * Gets if emoticons are currently enabled + * @return {boolean} + * @function + * @name emoticons + * @memberOf jQuery.sceditor.prototype + * @since 1.4.2 + */ + /** + * Enables/disables emoticons + * + * @param {boolean} enable + * @return {this} + * @function + * @name emoticons^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.2 + */ + base.emoticons = function (enable) { + if (!enable && enable !== false) { + return options.emoticonsEnabled; + } + + options.emoticonsEnabled = enable; + + if (enable) { + $wysiwygBody.keypress(emoticonsKeyPress); + + if (!base.sourceMode()) { + rangeHelper.saveRange(); + + replaceEmoticons($wysiwygBody[0]); + currentEmoticons = $wysiwygBody + .find('img[data-sceditor-emoticon]'); + triggerValueChanged(false); + + rangeHelper.restoreRange(); + } + } else { + $wysiwygBody + .find('img[data-sceditor-emoticon]') + .replaceWith(function () { + return $(this).data('sceditor-emoticon'); + }); + + currentEmoticons = []; + $wysiwygBody.off('keypress', emoticonsKeyPress); + + triggerValueChanged(); + } + + return base; + }; + + /** + * Gets the current WYSIWYG editors inline CSS + * + * @return {string} + * @function + * @name css + * @memberOf jQuery.sceditor.prototype + * @since 1.4.3 + */ + /** + * Sets inline CSS for the WYSIWYG editor + * + * @param {string} css + * @return {this} + * @function + * @name css^2 + * @memberOf jQuery.sceditor.prototype + * @since 1.4.3 + */ + base.css = function (css) { + if (!inlineCss) { + inlineCss = $('' + + '' + + '' + + '' + + '

    ' + + '', + + toolbarButton: '' + + '
    {dispName}
    ', + + emoticon: '', + + fontOpt: '{font}', + + sizeOpt: '{size}', + + pastetext: + '
    ' + + '
    ' + + '
    ' + + '
    ', + + table: + '
    ' + + '
    ' + + '
    ', + + image: + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ', + + email: + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ', + + link: + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ', + + youtubeMenu: + '
    ' + + '
    ' + + '
    ' + + '
    ', + + youtube: + '' + }; + + /** + *

    Replaces any params in a template with the passed params.

    + * + *

    If createHtml is passed it will use jQuery to create the HTML. The + * same as doing: $(editor.tmpl("html", {params...}));

    + * + * @param {string} name + * @param {Object} params + * @param {Boolean} createHtml + * @private + */ + return function (name, params, createHtml) { + var template = _templates[name]; + + $.each(params, function (name, val) { + template = template.replace( + new RegExp('\\{' + name + '\\}', 'g'), val + ); + }); + + if (createHtml) { + template = $(template); + } + + return template; + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var IE_VER = __webpack_require__(6).ie; + var _tmpl = __webpack_require__(8); + + // In IE < 11 a BR at the end of a block level element + // causes a line break. In all other browsers it's collapsed. + var IE_BR_FIX = IE_VER && IE_VER < 11; + + + /** + * Map of all the commands for SCEditor + * @type {Object} + * @name commands + * @memberOf jQuery.sceditor + */ + var defaultCommnds = { + // START_COMMAND: Bold + bold: { + exec: 'bold', + tooltip: 'Bold', + shortcut: 'Ctrl+B' + }, + // END_COMMAND + // START_COMMAND: Italic + italic: { + exec: 'italic', + tooltip: 'Italic', + shortcut: 'Ctrl+I' + }, + // END_COMMAND + // START_COMMAND: Underline + underline: { + exec: 'underline', + tooltip: 'Underline', + shortcut: 'Ctrl+U' + }, + // END_COMMAND + // START_COMMAND: Strikethrough + strike: { + exec: 'strikethrough', + tooltip: 'Strikethrough' + }, + // END_COMMAND + // START_COMMAND: Subscript + subscript: { + exec: 'subscript', + tooltip: 'Subscript' + }, + // END_COMMAND + // START_COMMAND: Superscript + superscript: { + exec: 'superscript', + tooltip: 'Superscript' + }, + // END_COMMAND + + // START_COMMAND: Left + left: { + exec: 'justifyleft', + tooltip: 'Align left' + }, + // END_COMMAND + // START_COMMAND: Centre + center: { + exec: 'justifycenter', + tooltip: 'Center' + }, + // END_COMMAND + // START_COMMAND: Right + right: { + exec: 'justifyright', + tooltip: 'Align right' + }, + // END_COMMAND + // START_COMMAND: Justify + justify: { + exec: 'justifyfull', + tooltip: 'Justify' + }, + // END_COMMAND + + // START_COMMAND: Font + font: { + _dropDown: function (editor, caller, callback) { + var fontIdx = 0, + fonts = editor.opts.fonts.split(','), + content = $('
    '), + /** @private */ + clickFunc = function () { + callback($(this).data('font')); + editor.closeDropDown(true); + return false; + }; + + for (; fontIdx < fonts.length; fontIdx++) { + content.append( + _tmpl('fontOpt', { + font: fonts[fontIdx] + }, true).click(clickFunc) + ); + } + + editor.createDropDown(caller, 'font-picker', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.font._dropDown( + editor, + caller, + function (fontName) { + editor.execCommand('fontname', fontName); + } + ); + }, + tooltip: 'Font Name' + }, + // END_COMMAND + // START_COMMAND: Size + size: { + _dropDown: function (editor, caller, callback) { + var content = $('
    '), + /** @private */ + clickFunc = function (e) { + callback($(this).data('size')); + editor.closeDropDown(true); + e.preventDefault(); + }; + + for (var i = 1; i <= 7; i++) { + content.append(_tmpl('sizeOpt', { + size: i + }, true).click(clickFunc)); + } + + editor.createDropDown(caller, 'fontsize-picker', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.size._dropDown( + editor, + caller, + function (fontSize) { + editor.execCommand('fontsize', fontSize); + } + ); + }, + tooltip: 'Font Size' + }, + // END_COMMAND + // START_COMMAND: Colour + color: { + _dropDown: function (editor, caller, callback) { + var i, x, color, colors, + genColor = {r: 255, g: 255, b: 255}, + content = $('
    '), + colorColumns = editor.opts.colors ? + editor.opts.colors.split('|') : new Array(21), + // IE is slow at string concatenation so use an array + html = [], + cmd = defaultCommnds.color; + + if (!cmd._htmlCache) { + for (i = 0; i < colorColumns.length; ++i) { + colors = colorColumns[i] ? + colorColumns[i].split(',') : new Array(21); + + html.push('
    '); + + for (x = 0; x < colors.length; ++x) { + // use pre defined colour if can otherwise use the + // generated color + color = colors[x] || '#' + + genColor.r.toString(16) + + genColor.g.toString(16) + + genColor.b.toString(16); + + html.push( + '' + ); + + if (x % 5 === 0) { + genColor.g -= 51; + genColor.b = 255; + } else { + genColor.b -= 51; + } + } + + html.push('
    '); + + if (i % 5 === 0) { + genColor.r -= 51; + genColor.g = 255; + genColor.b = 255; + } else { + genColor.g = 255; + genColor.b = 255; + } + } + + cmd._htmlCache = html.join(''); + } + + content.append(cmd._htmlCache) + .find('a') + .click(function (e) { + callback($(this).attr('data-color')); + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'color-picker', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.color._dropDown( + editor, + caller, + function (color) { + editor.execCommand('forecolor', color); + } + ); + }, + tooltip: 'Font Color' + }, + // END_COMMAND + // START_COMMAND: Remove Format + removeformat: { + exec: 'removeformat', + tooltip: 'Remove Formatting' + }, + // END_COMMAND + + // START_COMMAND: Cut + cut: { + exec: 'cut', + tooltip: 'Cut', + errorMessage: 'Your browser does not allow the cut command. ' + + 'Please use the keyboard shortcut Ctrl/Cmd-X' + }, + // END_COMMAND + // START_COMMAND: Copy + copy: { + exec: 'copy', + tooltip: 'Copy', + errorMessage: 'Your browser does not allow the copy command. ' + + 'Please use the keyboard shortcut Ctrl/Cmd-C' + }, + // END_COMMAND + // START_COMMAND: Paste + paste: { + exec: 'paste', + tooltip: 'Paste', + errorMessage: 'Your browser does not allow the paste command. ' + + 'Please use the keyboard shortcut Ctrl/Cmd-V' + }, + // END_COMMAND + // START_COMMAND: Paste Text + pastetext: { + exec: function (caller) { + var val, content, + editor = this; + + content = _tmpl('pastetext', { + label: editor._( + 'Paste your text inside the following box:' + ), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + val = content.find('#txt').val(); + + if (val) { + editor.wysiwygEditorInsertText(val); + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'pastetext', content); + }, + tooltip: 'Paste Text' + }, + // END_COMMAND + // START_COMMAND: Bullet List + bulletlist: { + exec: 'insertunorderedlist', + tooltip: 'Bullet list' + }, + // END_COMMAND + // START_COMMAND: Ordered List + orderedlist: { + exec: 'insertorderedlist', + tooltip: 'Numbered list' + }, + // END_COMMAND + // START_COMMAND: Indent + indent: { + state: function (parents, firstBlock) { + // Only works with lists, for now + // This is a nested list, so it will always work + var range, startParent, endParent, + $firstBlock = $(firstBlock), + parentLists = $firstBlock.parents('ul,ol,menu'), + parentList = parentLists.first(); + + // in case it's a list with only a single
  • + if (parentLists.length > 1 || + parentList.children().length > 1) { + return 0; + } + + if ($firstBlock.is('ul,ol,menu')) { + // if the whole list is selected, then this must be + // invalidated because the browser will place a + //
    there + range = this.getRangeHelper().selectedRange(); + + if (window.Range && range instanceof Range) { + startParent = range.startContainer.parentNode; + endParent = range.endContainer.parentNode; + + // TODO: could use nodeType for this? + // Maybe just check the firstBlock contains both the start and end containers + // Select the tag, not the textNode + // (that's why the parentNode) + if (startParent !== + startParent.parentNode.firstElementChild || + // work around a bug in FF + ($(endParent).is('li') && endParent !== + endParent.parentNode.lastElementChild)) { + return 0; + } + // it's IE... As it is impossible to know well when to + // accept, better safe than sorry + } else { + return $firstBlock.is('li,ul,ol,menu') ? 0 : -1; + } + } + + return -1; + }, + exec: function () { + var editor = this, + $elm = $(editor.getRangeHelper().getFirstBlockParent()); + + editor.focus(); + + // An indent system is quite complicated as there are loads + // of complications and issues around how to indent text + // As default, let's just stay with indenting the lists, + // at least, for now. + if ($elm.parents('ul,ol,menu')) { + editor.execCommand('indent'); + } + }, + tooltip: 'Add indent' + }, + // END_COMMAND + // START_COMMAND: Outdent + outdent: { + state: function (parents, firstBlock) { + return $(firstBlock).is('ul,ol,menu') || + $(firstBlock).parents('ul,ol,menu').length > 0 ? 0 : -1; + }, + exec: function () { + var editor = this, + $elm = $(editor.getRangeHelper().getFirstBlockParent()); + + if ($elm.parents('ul,ol,menu')) { + editor.execCommand('outdent'); + } + }, + tooltip: 'Remove one indent' + }, + // END_COMMAND + + // START_COMMAND: Table + table: { + forceNewLineAfter: ['table'], + exec: function (caller) { + var editor = this, + content = _tmpl('table', { + rows: editor._('Rows:'), + cols: editor._('Cols:'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var row, col, + rows = content.find('#rows').val() - 0, + cols = content.find('#cols').val() - 0, + html = ''; + + if (rows < 1 || cols < 1) { + return; + } + + for (row = 0; row < rows; row++) { + html += ''; + + for (col = 0; col < cols; col++) { + html += ''; + } + + html += ''; + } + + html += '
    ' + + (IE_BR_FIX ? '' : '
    ') + + '
    '; + + editor.wysiwygEditorInsertHtml(html); + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'inserttable', content); + }, + tooltip: 'Insert a table' + }, + // END_COMMAND + + // START_COMMAND: Horizontal Rule + horizontalrule: { + exec: 'inserthorizontalrule', + tooltip: 'Insert a horizontal rule' + }, + // END_COMMAND + + // START_COMMAND: Code + code: { + forceNewLineAfter: ['code'], + exec: function () { + this.wysiwygEditorInsertHtml( + '', + (IE_BR_FIX ? '' : '
    ') + '
    ' + ); + }, + tooltip: 'Code' + }, + // END_COMMAND + + // START_COMMAND: Image + image: { + exec: function (caller) { + var editor = this, + content = _tmpl('image', { + url: editor._('URL:'), + width: editor._('Width (optional):'), + height: editor._('Height (optional):'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content.find('#image').val(), + width = content.find('#width').val(), + height = content.find('#height').val(), + attrs = ''; + + if (width) { + attrs += ' width="' + width + '"'; + } + + if (height) { + attrs += ' height="' + height + '"'; + } + + if (val) { + editor.wysiwygEditorInsertHtml( + '' + ); + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertimage', content); + }, + tooltip: 'Insert an image' + }, + // END_COMMAND + + // START_COMMAND: E-mail + email: { + exec: function (caller) { + var editor = this, + content = _tmpl('email', { + label: editor._('E-mail:'), + desc: editor._('Description (optional):'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content.find('#email').val(), + description = content.find('#des').val(); + + if (val) { + // needed for IE to reset the last range + editor.focus(); + + if (!editor.getRangeHelper().selectedHtml() || + description) { + description = description || val; + + editor.wysiwygEditorInsertHtml( + '' + + description + + '' + ); + } else { + editor.execCommand('createlink', 'mailto:' + val); + } + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertemail', content); + }, + tooltip: 'Insert an email' + }, + // END_COMMAND + + // START_COMMAND: Link + link: { + exec: function (caller) { + var editor = this, + content = _tmpl('link', { + url: editor._('URL:'), + desc: editor._('Description (optional):'), + ins: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content.find('#link').val(), + description = content.find('#des').val(); + + if (val) { + // needed for IE to restore the last range + editor.focus(); + + // If there is no selected text then must set the URL as + // the text. Most browsers do this automatically, sadly + // IE doesn't. + if (!editor.getRangeHelper().selectedHtml() || + description) { + description = description || val; + + editor.wysiwygEditorInsertHtml( + '' + description + '' + ); + } else { + editor.execCommand('createlink', val); + } + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertlink', content); + }, + tooltip: 'Insert a link' + }, + // END_COMMAND + + // START_COMMAND: Unlink + unlink: { + state: function () { + var $current = $(this.currentNode()); + return $current.is('a') || + $current.parents('a').length > 0 ? 0 : -1; + }, + exec: function () { + var $current = $(this.currentNode()), + $anchor = $current.is('a') ? $current : + $current.parents('a').first(); + + if ($anchor.length) { + $anchor.replaceWith($anchor.contents()); + } + }, + tooltip: 'Unlink' + }, + // END_COMMAND + + + // START_COMMAND: Quote + quote: { + forceNewLineAfter: ['blockquote'], + exec: function (caller, html, author) { + var before = '
    ', + end = '
    '; + + // if there is HTML passed set end to null so any selected + // text is replaced + if (html) { + author = (author ? '' + author + '' : ''); + before = before + author + html + end; + end = null; + // if not add a newline to the end of the inserted quote + } else if (this.getRangeHelper().selectedHtml() === '') { + end = (IE_BR_FIX ? '' : '
    ') + end; + } + + this.wysiwygEditorInsertHtml(before, end); + }, + tooltip: 'Insert a Quote' + }, + // END_COMMAND + + // START_COMMAND: Emoticons + emoticon: { + exec: function (caller) { + var editor = this; + + var createContent = function (includeMore) { + var $moreLink, + emoticonsCompat = editor.opts.emoticonsCompat, + rangeHelper = editor.getRangeHelper(), + startSpace = emoticonsCompat && + rangeHelper.getOuterText(true, 1) !== ' ' ? + ' ' : '', + endSpace = emoticonsCompat && + rangeHelper.getOuterText(false, 1) !== ' ' ? + ' ' : '', + $content = $('
    '), + $line = $('
    ').appendTo($content), + perLine = 0, + emoticons = $.extend( + {}, + editor.opts.emoticons.dropdown, + includeMore ? editor.opts.emoticons.more : {} + ); + + $.each(emoticons, function () { + perLine++; + }); + perLine = Math.sqrt(perLine); + + $.each(emoticons, function (code, emoticon) { + $line.append( + $('').attr({ + src: emoticon.url || emoticon, + alt: code, + title: emoticon.tooltip || code + }).click(function () { + editor.insert(startSpace + $(this).attr('alt') + + endSpace, null, false).closeDropDown(true); + + return false; + }) + ); + + if ($line.children().length >= perLine) { + $line = $('
    ').appendTo($content); + } + }); + + if (!includeMore && editor.opts.emoticons.more) { + $moreLink = $( + '' + + editor._('More') + '' + ).click(function () { + editor.createDropDown( + caller, + 'more-emoticons', + createContent(true) + ); + + return false; + }); + + $content.append($moreLink); + } + + return $content; + }; + + editor.createDropDown( + caller, + 'emoticons', + createContent(false) + ); + }, + txtExec: function (caller) { + defaultCommnds.emoticon.exec.call(this, caller); + }, + tooltip: 'Insert an emoticon' + }, + // END_COMMAND + + // START_COMMAND: YouTube + youtube: { + _dropDown: function (editor, caller, handleIdFunc) { + var matches, + content = _tmpl('youtubeMenu', { + label: editor._('Video URL:'), + insert: editor._('Insert') + }, true); + + content.find('.button').click(function (e) { + var val = content + .find('#link') + .val(); + + if (val) { + matches = val.match( + /(?:v=|v\/|embed\/|youtu.be\/)(.{11})/ + ); + + if (matches) { + val = matches[1]; + } + + if (/^[a-zA-Z0-9_\-]{11}$/.test(val)) { + handleIdFunc(val); + } else { + /*global alert:false*/ + alert('Invalid YouTube video'); + } + } + + editor.closeDropDown(true); + e.preventDefault(); + }); + + editor.createDropDown(caller, 'insertlink', content); + }, + exec: function (caller) { + var editor = this; + + defaultCommnds.youtube._dropDown( + editor, + caller, + function (id) { + editor.wysiwygEditorInsertHtml(_tmpl('youtube', { + id: id + })); + } + ); + }, + tooltip: 'Insert a YouTube video' + }, + // END_COMMAND + + // START_COMMAND: Date + date: { + _date: function (editor) { + var now = new Date(), + year = now.getYear(), + month = now.getMonth() + 1, + day = now.getDate(); + + if (year < 2000) { + year = 1900 + year; + } + + if (month < 10) { + month = '0' + month; + } + + if (day < 10) { + day = '0' + day; + } + + return editor.opts.dateFormat + .replace(/year/i, year) + .replace(/month/i, month) + .replace(/day/i, day); + }, + exec: function () { + this.insertText(defaultCommnds.date._date(this)); + }, + txtExec: function () { + this.insertText(defaultCommnds.date._date(this)); + }, + tooltip: 'Insert current date' + }, + // END_COMMAND + + // START_COMMAND: Time + time: { + _time: function () { + var now = new Date(), + hours = now.getHours(), + mins = now.getMinutes(), + secs = now.getSeconds(); + + if (hours < 10) { + hours = '0' + hours; + } + + if (mins < 10) { + mins = '0' + mins; + } + + if (secs < 10) { + secs = '0' + secs; + } + + return hours + ':' + mins + ':' + secs; + }, + exec: function () { + this.insertText(defaultCommnds.time._time()); + }, + txtExec: function () { + this.insertText(defaultCommnds.time._time()); + }, + tooltip: 'Insert current time' + }, + // END_COMMAND + + + // START_COMMAND: Ltr + ltr: { + state: function (parents, firstBlock) { + return firstBlock && firstBlock.style.direction === 'ltr'; + }, + exec: function () { + var editor = this, + elm = editor.getRangeHelper().getFirstBlockParent(), + $elm = $(elm); + + editor.focus(); + + if (!elm || $elm.is('body')) { + editor.execCommand('formatBlock', 'p'); + + elm = editor.getRangeHelper().getFirstBlockParent(); + $elm = $(elm); + + if (!elm || $elm.is('body')) { + return; + } + } + + if ($elm.css('direction') === 'ltr') { + $elm.css('direction', ''); + } else { + $elm.css('direction', 'ltr'); + } + }, + tooltip: 'Left-to-Right' + }, + // END_COMMAND + + // START_COMMAND: Rtl + rtl: { + state: function (parents, firstBlock) { + return firstBlock && firstBlock.style.direction === 'rtl'; + }, + exec: function () { + var editor = this, + elm = editor.getRangeHelper().getFirstBlockParent(), + $elm = $(elm); + + editor.focus(); + + if (!elm || $elm.is('body')) { + editor.execCommand('formatBlock', 'p'); + + elm = editor.getRangeHelper().getFirstBlockParent(); + $elm = $(elm); + + if (!elm || $elm.is('body')) { + return; + } + } + + if ($elm.css('direction') === 'rtl') { + $elm.css('direction', ''); + } else { + $elm.css('direction', 'rtl'); + } + }, + tooltip: 'Right-to-Left' + }, + // END_COMMAND + + + // START_COMMAND: Print + print: { + exec: 'print', + tooltip: 'Print' + }, + // END_COMMAND + + // START_COMMAND: Maximize + maximize: { + state: function () { + return this.maximize(); + }, + exec: function () { + this.maximize(!this.maximize()); + }, + txtExec: function () { + this.maximize(!this.maximize()); + }, + tooltip: 'Maximize', + shortcut: 'Ctrl+Shift+M' + }, + // END_COMMAND + + // START_COMMAND: Source + source: { + state: function () { + return this.sourceMode(); + }, + exec: function () { + this.toggleSourceMode(); + }, + txtExec: function () { + this.toggleSourceMode(); + }, + tooltip: 'View source', + shortcut: 'Ctrl+Shift+S' + }, + // END_COMMAND + + // this is here so that commands above can be removed + // without having to remove the , after the last one. + // Needed for IE. + ignore: {} + }; + + return defaultCommnds; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + + + /** + * Default options for SCEditor + * @type {Object} + */ + return { + /** @lends jQuery.sceditor.defaultOptions */ + /** + * Toolbar buttons order and groups. Should be comma separated and + * have a bar | to separate groups + * + * @type {String} + */ + toolbar: 'bold,italic,underline,strike,subscript,superscript|' + + 'left,center,right,justify|font,size,color,removeformat|' + + 'cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|' + + 'table|code,quote|horizontalrule,image,email,link,unlink|' + + 'emoticon,youtube,date,time|ltr,rtl|print,maximize,source', + + /** + * Comma separated list of commands to excludes from the toolbar + * + * @type {String} + */ + toolbarExclude: null, + + /** + * Stylesheet to include in the WYSIWYG editor. This is what will style + * the WYSIWYG elements + * + * @type {String} + */ + style: 'jquery.sceditor.default.css', + + /** + * Comma separated list of fonts for the font selector + * + * @type {String} + */ + fonts: 'Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,' + + 'Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana', + + /** + * Colors should be comma separated and have a bar | to signal a new + * column. + * + * If null the colors will be auto generated. + * + * @type {string} + */ + colors: null, + + /** + * The locale to use. + * @type {String} + */ + locale: $('html').attr('lang') || 'en', + + /** + * The Charset to use + * @type {String} + */ + charset: 'utf-8', + + /** + * Compatibility mode for emoticons. + * + * Helps if you have emoticons such as :/ which would put an emoticon + * inside http:// + * + * This mode requires emoticons to be surrounded by whitespace or end of + * line chars. This mode has limited As You Type emoticon conversion + * support. It will not replace AYT for end of line chars, only + * emoticons surrounded by whitespace. They will still be replaced + * correctly when loaded just not AYT. + * + * @type {Boolean} + */ + emoticonsCompat: false, + + /** + * If to enable emoticons. Can be changes at runtime using the + * emoticons() method. + * + * @type {Boolean} + * @since 1.4.2 + */ + emoticonsEnabled: true, + + /** + * Emoticon root URL + * + * @type {String} + */ + emoticonsRoot: '', + emoticons: { + dropdown: { + ':)': 'emoticons/smile.png', + ':angel:': 'emoticons/angel.png', + ':angry:': 'emoticons/angry.png', + '8-)': 'emoticons/cool.png', + ':\'(': 'emoticons/cwy.png', + ':ermm:': 'emoticons/ermm.png', + ':D': 'emoticons/grin.png', + '<3': 'emoticons/heart.png', + ':(': 'emoticons/sad.png', + ':O': 'emoticons/shocked.png', + ':P': 'emoticons/tongue.png', + ';)': 'emoticons/wink.png' + }, + more: { + ':alien:': 'emoticons/alien.png', + ':blink:': 'emoticons/blink.png', + ':blush:': 'emoticons/blush.png', + ':cheerful:': 'emoticons/cheerful.png', + ':devil:': 'emoticons/devil.png', + ':dizzy:': 'emoticons/dizzy.png', + ':getlost:': 'emoticons/getlost.png', + ':happy:': 'emoticons/happy.png', + ':kissing:': 'emoticons/kissing.png', + ':ninja:': 'emoticons/ninja.png', + ':pinch:': 'emoticons/pinch.png', + ':pouty:': 'emoticons/pouty.png', + ':sick:': 'emoticons/sick.png', + ':sideways:': 'emoticons/sideways.png', + ':silly:': 'emoticons/silly.png', + ':sleeping:': 'emoticons/sleeping.png', + ':unsure:': 'emoticons/unsure.png', + ':woot:': 'emoticons/w00t.png', + ':wassat:': 'emoticons/wassat.png' + }, + hidden: { + ':whistling:': 'emoticons/whistling.png', + ':love:': 'emoticons/wub.png' + } + }, + + /** + * Width of the editor. Set to null for automatic with + * + * @type {int} + */ + width: null, + + /** + * Height of the editor including toolbar. Set to null for automatic + * height + * + * @type {int} + */ + height: null, + + /** + * If to allow the editor to be resized + * + * @type {Boolean} + */ + resizeEnabled: true, + + /** + * Min resize to width, set to null for half textarea width or -1 for + * unlimited + * + * @type {int} + */ + resizeMinWidth: null, + /** + * Min resize to height, set to null for half textarea height or -1 for + * unlimited + * + * @type {int} + */ + resizeMinHeight: null, + /** + * Max resize to height, set to null for double textarea height or -1 + * for unlimited + * + * @type {int} + */ + resizeMaxHeight: null, + /** + * Max resize to width, set to null for double textarea width or -1 for + * unlimited + * + * @type {int} + */ + resizeMaxWidth: null, + /** + * If resizing by height is enabled + * + * @type {Boolean} + */ + resizeHeight: true, + /** + * If resizing by width is enabled + * + * @type {Boolean} + */ + resizeWidth: true, + + /** + * Date format, will be overridden if locale specifies one. + * + * The words year, month and day will be replaced with the users current + * year, month and day. + * + * @type {String} + */ + dateFormat: 'year-month-day', + + /** + * Element to inset the toolbar into. + * + * @type {HTMLElement} + */ + toolbarContainer: null, + + /** + * If to enable paste filtering. This is currently experimental, please + * report any issues. + * + * @type {Boolean} + */ + enablePasteFiltering: false, + + /** + * If to completely disable pasting into the editor + * + * @type {Boolean} + */ + disablePasting: false, + + /** + * If the editor is read only. + * + * @type {Boolean} + */ + readOnly: false, + + /** + * If to set the editor to right-to-left mode. + * + * If set to null the direction will be automatically detected. + * + * @type {Boolean} + */ + rtl: false, + + /** + * If to auto focus the editor on page load + * + * @type {Boolean} + */ + autofocus: false, + + /** + * If to auto focus the editor to the end of the content + * + * @type {Boolean} + */ + autofocusEnd: true, + + /** + * If to auto expand the editor to fix the content + * + * @type {Boolean} + */ + autoExpand: false, + + /** + * If to auto update original textbox on blur + * + * @type {Boolean} + */ + autoUpdate: false, + + /** + * If to enable the browsers built in spell checker + * + * @type {Boolean} + */ + spellcheck: true, + + /** + * If to run the source editor when there is no WYSIWYG support. Only + * really applies to mobile OS's. + * + * @type {Boolean} + */ + runWithoutWysiwygSupport: false, + + /** + * If to load the editor in source mode and still allow switching + * between WYSIWYG and source mode + * + * @type {Boolean} + */ + startInSourceMode: false, + + /** + * Optional ID to give the editor. + * + * @type {String} + */ + id: null, + + /** + * Comma separated list of plugins + * + * @type {String} + */ + plugins: '', + + /** + * z-index to set the editor container to. Needed for jQuery UI dialog. + * + * @type {Int} + */ + zIndex: null, + + /** + * If to trim the BBCode. Removes any spaces at the start and end of the + * BBCode string. + * + * @type {Boolean} + */ + bbcodeTrim: false, + + /** + * If to disable removing block level elements by pressing backspace at + * the start of them + * + * @type {Boolean} + */ + disableBlockRemove: false, + + /** + * BBCode parser options, only applies if using the editor in BBCode + * mode. + * + * See SCEditor.BBCodeParser.defaults for list of valid options + * + * @type {Object} + */ + parserOptions: { }, + + /** + * CSS that will be added to the to dropdown menu (eg. z-index) + * + * @type {Object} + */ + dropDownCss: { } + }; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ } +/******/ ]);;/** + * SCEditor XHTML Plugin + * http://www.sceditor.com/ + * + * Copyright (C) 2011-2013, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * @author Sam Clarke + * @requires jQuery + */ +/*global prompt: true*/ +(function ($) { + 'use strict'; + + var SCEditor = $.sceditor; + var sceditorPlugins = SCEditor.plugins; + var dom = SCEditor.dom; + + var defaultCommandsOverrides = { + bold: { + txtExec: [ + '', + '' + ] + }, + italic: { + txtExec: [ + '', + '' + ] + }, + underline: { + txtExec: [ + '', + '' + ] + }, + strike: { + txtExec: [ + '', + '' + ] + }, + subscript: { + txtExec: [ + '', + '' + ] + }, + superscript: { + txtExec: [ + '', + '' + ] + }, + left: { + txtExec: [ + '
    ', + '
    ' + ] + }, + center: { + txtExec: [ + '
    ', + '
    ' + ] + }, + right: { + txtExec: [ + '
    ', + '
    ' + ] + }, + justify: { + txtExec: [ + '
    ', + '
    ' + ] + }, + font: { + txtExec: function (caller) { + var editor = this; + + SCEditor.command.get('font')._dropDown( + editor, + caller, + function (fontName) { + editor.insertText('', ''); + } + ); + } + }, + size: { + txtExec: function (caller) { + var editor = this; + + SCEditor.command.get('size')._dropDown( + editor, + caller, + function (fontSize) { + editor.insertText('', ''); + } + ); + } + }, + color: { + txtExec: function (caller) { + var editor = this; + + SCEditor.command.get('color')._dropDown( + editor, + caller, + function (color) { + editor.insertText('', ''); + } + ); + } + }, + bulletlist: { + txtExec: [ + '
    • ', + '
    ' + ] + }, + orderedlist: { + txtExec: [ + '
    1. ', + '
    ' + ] + }, + table: { + txtExec: [ + '
    ', + '
    ' + ] + }, + horizontalrule: { + txtExec: [ + '
    ' + ] + }, + code: { + txtExec: [ + '', + '' + ] + }, + image: { + txtExec: function (caller, selected) { + var url = prompt(this._('Enter the image URL:'), selected); + + if (url) { + this.insertText(''); + } + } + }, + email: { + txtExec: function (caller, sel) { + var email, text, + display = sel && sel.indexOf('@') > -1 ? null : sel; + + email = prompt( + this._('Enter the e-mail address:'), + (display ? '' : sel) + ); + + text = prompt( + this._('Enter the displayed text:'), + display || email + ) || email; + + if (email) { + this.insertText( + '' + text + '' + ); + } + } + }, + link: { + txtExec: function (caller, sel) { + var display = sel && sel.indexOf('http://') > -1 ? null : sel, + url = prompt(this._('Enter URL:'), + (display ? 'http://' : sel)), + text = prompt(this._('Enter the displayed text:'), + display || url) || url; + + if (url) { + this.insertText( + '' + text + '' + ); + } + } + }, + quote: { + txtExec: [ + '
    ', + '
    ' + ] + }, + youtube: { + txtExec: function (caller) { + var editor = this; + + SCEditor.command.get('youtube')._dropDown( + editor, + caller, + function (id) { + editor.insertText( + '' + ); + } + ); + } + }, + rtl: { + txtExec: [ + '
    ', + '
    ' + ] + }, + ltr: { + txtExec: [ + '
    ', + '
    ' + ] + } + }; + + /** + * XHTMLSerializer part of the XHTML plugin. + * + * @class XHTMLSerializer + * @name jQuery.sceditor.XHTMLSerializer + * @since v1.4.1 + */ + SCEditor.XHTMLSerializer = function () { + var base = this; + + var opts = { + indentStr: '\t' + }; + + /** + * Array containing the output, used as it's faster + * than string concatenation in slow browsers. + * @type {Array} + * @private + */ + var outputStringBuilder = []; + + /** + * Current indention level + * @type {Number} + * @private + */ + var currentIndent = 0; + + /** + * @private + */ + var escapeEntites, + trim, + serializeNode, + handleDoc, + handleElement, + handleCdata, + handleComment, + handleText, + output, + canIndent; +// TODO: use escape.entities + /** + * Escapes XHTML entities + * + * @param {String} str + * @return {String} + * @private + */ + escapeEntites = function (str) { + var entites = { + '&': '&', + '<': '<', + '>': '>', + '"': '"' + }; + + return !str ? '' : str.replace(/[&<>"]/g, function (entity) { + return entites[entity] || entity; + }); + }; + + /** + * @param {string} str + * @return {string} + * @private + */ + trim = function (str) { + return str + // New lines will be shown as spaces so just convert to spaces. + .replace(/[\r\n]/, ' ') + .replace(/[^\S|\u00A0]+/g, ' '); + }; + + /** + * Serializes a node to XHTML + * + * @param {Node} node Node to serialize + * @param {Boolean} onlyChildren If to only serialize the nodes + * children and not the node + * itself + * @return {String} The serialized node + * @name serialize + * @memberOf jQuery.sceditor.XHTMLSerializer.prototype + * @since v1.4.1 + */ + base.serialize = function (node, onlyChildren) { + outputStringBuilder = []; + + if (onlyChildren) { + node = node.firstChild; + + while (node) { + serializeNode(node); + node = node.nextSibling; + } + } else { + serializeNode(node); + } + + return outputStringBuilder.join(''); + }; + + /** + * Serializes a node to the outputStringBuilder + * + * @param {Node} node + * @return {Void} + * @private + */ + serializeNode = function (node, parentIsPre) { + switch (node.nodeType) { + case 1: // element + var tagName = node.nodeName.toLowerCase(); + + // IE comment + if (tagName === '!') { + handleComment(node); + } else { + handleElement(node, parentIsPre); + } + break; + + case 3: // text + handleText(node, parentIsPre); + break; + + case 4: // cdata section + handleCdata(node); + break; + + case 8: // comment + handleComment(node); + break; + + case 9: // document + case 11: // document fragment + handleDoc(node); + break; + + // Ignored types + case 2: // attribute + case 5: // entity ref + case 6: // entity + case 7: // processing instruction + case 10: // document type + case 12: // notation + break; + } + }; + + /** + * Handles doc node + * @param {Node} node + * @return {void} + * @private + */ + handleDoc = function (node) { + var child = node.firstChild; + + while (child) { + serializeNode(child); + child = child.nextSibling; + } + }; + + /** + * Handles element nodes + * @param {Node} node + * @return {void} + * @private + */ + handleElement = function (node, parentIsPre) { + var child, attr, attrValue, + tagName = node.nodeName.toLowerCase(), + isIframe = tagName === 'iframe', + attrIdx = node.attributes.length, + firstChild = node.firstChild, + // pre || pre-wrap with any vendor prefix + isPre = parentIsPre || + /pre(?:\-wrap)?$/i.test($(node).css('whiteSpace')), + selfClosing = !node.firstChild && !dom.canHaveChildren(node) && + !isIframe; + + if ($(node).hasClass('sceditor-ignore')) { + return; + } + + output('<' + tagName, !parentIsPre && canIndent(node)); + while (attrIdx--) { + attr = node.attributes[attrIdx]; + + // IE < 8 returns all possible attributes not just specified + // ones. IE < 8 also doesn't say value on input is specified + // so just assume it is. + if (!SCEditor.ie || attr.specified || + (tagName === 'input' && attr.name === 'value')) { + // IE < 8 doesn't return the CSS for the style attribute + if (SCEditor.ie < 8 && /style/i.test(attr.name)) { + attrValue = node.style.cssText; + } else { + attrValue = attr.value; + } + + output(' ' + attr.name.toLowerCase() + '="' + + escapeEntites(attrValue) + '"', false); + } + } + output(selfClosing ? ' />' : '>', false); + + if (!isIframe) { + child = firstChild; + } + + while (child) { + currentIndent++; + + serializeNode(child, isPre); + child = child.nextSibling; + + currentIndent--; + } + + if (!selfClosing) { + output( + '', + !isPre && !isIframe && canIndent(node) && + firstChild && canIndent(firstChild) + ); + } + }; + + /** + * Handles CDATA nodes + * @param {Node} node + * @return {void} + * @private + */ + handleCdata = function (node) { + output(''); + }; + + /** + * Handles comment nodes + * @param {Node} node + * @return {void} + * @private + */ + handleComment = function (node) { + output(''); + }; + + /** + * Handles text nodes + * @param {Node} node + * @return {void} + * @private + */ + handleText = function (node, parentIsPre) { + var text = node.nodeValue; + + if (!parentIsPre) { + text = trim(text); + } + + if (text) { + output(escapeEntites(text), !parentIsPre && canIndent(node)); + } + }; + + /** + * Adds a string to the outputStringBuilder. + * + * The string will be indented unless indent is set to boolean false. + * @param {String} str + * @param {Boolean} indent + * @return {void} + * @private + */ + output = function (str, indent) { + var i = currentIndent; + + if (indent !== false) { + // Don't add a new line if it's the first element + if (outputStringBuilder.length) { + outputStringBuilder.push('\n'); + } + + while (i--) { + outputStringBuilder.push(opts.indentStr); + } + } + + outputStringBuilder.push(str); + }; + + /** + * Checks if should indent the node or not + * @param {Node} node + * @return {boolean} + * @private + */ + canIndent = function (node) { + var prev = node.previousSibling; + + if (node.nodeType !== 1 && prev) { + return !dom.isInline(prev); + } + + // first child of a block element + if (!prev && !dom.isInline(node.parentNode)) { + return true; + } + + return !dom.isInline(node); + }; + }; + + /** + * SCEditor XHTML plugin + * @class xhtml + * @name jQuery.sceditor.plugins.xhtml + * @since v1.4.1 + */ + sceditorPlugins.xhtml = function () { + var base = this; + + /** + * Tag converstions cache + * @type {Object} + * @private + */ + var tagConvertersCache = {}; + + /** + * Attributes filter cache + * @type {Object} + * @private + */ + var attrsCache = {}; + + /** + * Private methods + * @private + */ + var convertTags, + convertNode, + isEmpty, + removeTags, + mergeAttribsFilters, + removeAttribs, + wrapInlines; + + + /** + * Init + * @return {void} + */ + base.init = function () { + if (!$.isEmptyObject(sceditorPlugins.xhtml.converters || {})) { + $.each( + sceditorPlugins.xhtml.converters, + function (idx, converter) { + $.each(converter.tags, function (tagname) { + if (!tagConvertersCache[tagname]) { + tagConvertersCache[tagname] = []; + } + + tagConvertersCache[tagname].push(converter); + }); + } + ); + } + + this.commands = $.extend(true, + {}, defaultCommandsOverrides, this.commands); + }; + + /** + * Converts the WYSIWYG content to XHTML + * @param {String} html + * @param {Node} domBody + * @return {String} + * @memberOf jQuery.sceditor.plugins.xhtml.prototype + */ + base.signalToSource = function (html, domBody) { + domBody = domBody.jquery ? domBody[0] : domBody; + + convertTags(domBody); + removeTags(domBody); + removeAttribs(domBody); + wrapInlines(domBody); + + return (new SCEditor.XHTMLSerializer()).serialize(domBody, true); + }; + + /** + * Converts the XHTML to WYSIWYG content. + * + * This doesn't currently do anything as XHTML + * is valid WYSIWYG content. + * @param {String} text + * @return {String} + * @memberOf jQuery.sceditor.plugins.xhtml.prototype + */ + base.signalToWysiwyg = function (text) { + return text; + }; + + /** + * Deprecated, use dom.convertElement() instead. + * @deprecated + */ + base.convertTagTo = dom.convertElement; + + /** + * Runs all converters for the specified tagName + * against the DOM node. + * @param {String} tagName + * @param {jQuery} $node + * @return {Node} node + * @private + */ + convertNode = function (tagName, $node, node) { + if (!tagConvertersCache[tagName]) { + return; + } + + $.each(tagConvertersCache[tagName], function (idx, converter) { + if (converter.tags[tagName]) { + $.each(converter.tags[tagName], function (attr, values) { + if (!node.getAttributeNode) { + return; + } + + attr = node.getAttributeNode(attr); + + // IE < 8 always returns an attribute regardless of if + // it has been specified so must check it. + if (!attr || (SCEditor.ie < 8 && !attr.specified)) { + return; + } + + if (values && $.inArray(attr.value, values) < 0) { + return; + } + + converter.conv.call(base, node, $node); + }); + } else if (converter.conv) { + converter.conv.call(base, node, $node); + } + }); + }; + + /** + * Converts any tags/attributes to their XHTML equivalents + * @param {Node} node + * @return {Void} + * @private + */ + convertTags = function (node) { + dom.traverse(node, function (node) { + var $node = $(node), + tagName = node.nodeName.toLowerCase(); + + convertNode('*', $node, node); + convertNode(tagName, $node, node); + }, true); + }; + + /** + * Tests if a node is empty and can be removed. + * + * @param {Node} node + * @return {Boolean} + * @private + */ + isEmpty = function (node, excludeBr) { + var childNodes = node.childNodes, + tagName = node.nodeName.toLowerCase(), + nodeValue = node.nodeValue, + childrenLength = childNodes.length; + + if (excludeBr && tagName === 'br') { + return true; + } + + if ($(node).hasClass('sceditor-ignore')) { + return true; + } + + if (!dom.canHaveChildren(node)) { + return false; + } + + // \S|\u00A0 = any non space char + if (nodeValue && /\S|\u00A0/.test(nodeValue)) { + return false; + } + + while (childrenLength--) { + if (!isEmpty(childNodes[childrenLength], + excludeBr && !node.previousSibling && !node.nextSibling)) { + return false; + } + } + + return true; + }; + + /** + * Removes any tags that are not white listed or if no + * tags are white listed it will remove any tags that + * are black listed. + * + * @param {Node} rootNode + * @return {Void} + * @private + */ + removeTags = function (rootNode) { + dom.traverse(rootNode, function (node) { + var remove, + tagName = node.nodeName.toLowerCase(), + parentNode = node.parentNode, + nodeType = node.nodeType, + isBlock = !dom.isInline(node), + previousSibling = node.previousSibling, + nextSibling = node.nextSibling, + isTopLevel = parentNode === rootNode, + noSiblings = !previousSibling && !nextSibling, + empty = tagName !== 'iframe' && isEmpty(node, + isTopLevel && noSiblings && tagName !== 'br'), + document = node.ownerDocument, + allowedtags = sceditorPlugins.xhtml.allowedTags, + disallowedTags = sceditorPlugins.xhtml.disallowedTags; + + // 3 = text node + if (nodeType === 3) { + return; + } + + if (nodeType === 4) { + tagName = '!cdata'; + } else if (tagName === '!' || nodeType === 8) { + tagName = '!comment'; + } + + if (empty) { + remove = true; + // 3 is text node which do not get filtered + } else if (allowedtags && allowedtags.length) { + remove = ($.inArray(tagName, allowedtags) < 0); + } else if (disallowedTags && disallowedTags.length) { + remove = ($.inArray(tagName, disallowedTags) > -1); + } + + if (remove) { + if (!empty) { + if (isBlock && previousSibling && + dom.isInline(previousSibling)) { + parentNode.insertBefore( + document.createTextNode(' '), node); + } + + // Insert all the childen after node + while (node.firstChild) { + parentNode.insertBefore(node.firstChild, + nextSibling); + } + + if (isBlock && nextSibling && + dom.isInline(nextSibling)) { + parentNode.insertBefore( + document.createTextNode(' '), nextSibling); + } + } + + parentNode.removeChild(node); + } + }, true); + }; + + /** + * Merges two sets of attribute filters into one + * + * @param {Object} filtersA + * @param {Object} filtersB + * @return {Object} + * @private + */ + mergeAttribsFilters = function (filtersA, filtersB) { + var ret = {}; + + if (filtersA) { + $.extend(ret, filtersA); + } + + if (!filtersB) { + return ret; + } + + $.each(filtersB, function (attrName, values) { + if ($.isArray(values)) { + ret[attrName] = $.merge(ret[attrName] || [], values); + } else if (!ret[attrName]) { + ret[attrName] = null; + } + }); + + return ret; + }; + + /** + * Wraps adjacent inline child nodes of root + * in paragraphs. + * + * @param {Node} root + * @private + */ + wrapInlines = function (root) { + var adjacentInlines = []; + var wrapAdjacents = function () { + if (adjacentInlines.length) { + $('

    ', root.ownerDocument) + .insertBefore(adjacentInlines[0]) + .append(adjacentInlines); + + adjacentInlines = []; + } + }; + + // Strip empty text nodes so they don't get wrapped. + dom.removeWhiteSpace(root); + + var node = root.firstChild; + while (node) { + if (dom.isInline(node) && !$(node).is('.sceditor-ignore')) { + adjacentInlines.push(node); + } else { + wrapAdjacents(); + } + + node = node.nextSibling; + } + + wrapAdjacents(); + }; + + /** + * Removes any attributes that are not white listed or + * if no attributes are white listed it will remove + * any attributes that are black listed. + * @param {Node} node + * @return {Void} + * @private + */ + removeAttribs = function (node) { + var tagName, attr, attrName, attrsLength, validValues, remove, + allowedAttribs = sceditorPlugins.xhtml.allowedAttribs, + isAllowed = allowedAttribs && + !$.isEmptyObject(allowedAttribs), + disallowedAttribs = sceditorPlugins.xhtml.disallowedAttribs, + isDisallowed = disallowedAttribs && + !$.isEmptyObject(disallowedAttribs); + + attrsCache = {}; + + dom.traverse(node, function (node) { + if (!node.attributes) { + return; + } + + tagName = node.nodeName.toLowerCase(); + attrsLength = node.attributes.length; + + if (attrsLength) { + if (!attrsCache[tagName]) { + if (isAllowed) { + attrsCache[tagName] = mergeAttribsFilters( + allowedAttribs['*'], + allowedAttribs[tagName] + ); + } else { + attrsCache[tagName] = mergeAttribsFilters( + disallowedAttribs['*'], + disallowedAttribs[tagName] + ); + } + } + + while (attrsLength--) { + attr = node.attributes[attrsLength]; + attrName = attr.name; + validValues = attrsCache[tagName][attrName]; + remove = false; + + if (isAllowed) { + remove = validValues !== null && + (!$.isArray(validValues) || + $.inArray(attr.value, validValues) < 0); + } else if (isDisallowed) { + remove = validValues === null || + ($.isArray(validValues) && + $.inArray(attr.value, validValues) > -1); + } + + if (remove) { + node.removeAttribute(attrName); + } + } + } + }); + }; + }; + + /** + * Tag conveters, a converter is applied to all + * tags that match the criteria. + * @type {Array} + * @name jQuery.sceditor.plugins.xhtml.converters + * @since v1.4.1 + */ + sceditorPlugins.xhtml.converters = [ + { + tags: { + '*': { + width: null + } + }, + conv: function (node, $node) { + $node.css('width', $node.attr('width')).removeAttr('width'); + } + }, + { + tags: { + '*': { + height: null + } + }, + conv: function (node, $node) { + $node.css('height', $node.attr('height')).removeAttr('height'); + } + }, + { + tags: { + 'li': { + value: null + } + }, + conv: function (node, $node) { + if (SCEditor.ie < 8) { + node.removeAttribute('value'); + } else { + $node.removeAttr('value'); + } + } + }, + { + tags: { + '*': { + text: null + } + }, + conv: function (node, $node) { + $node.css('color', $node.attr('text')).removeAttr('text'); + } + }, + { + tags: { + '*': { + color: null + } + }, + conv: function (node, $node) { + $node.css('color', $node.attr('color')).removeAttr('color'); + } + }, + { + tags: { + '*': { + face: null + } + }, + conv: function (node, $node) { + $node.css('fontFamily', $node.attr('face')).removeAttr('face'); + } + }, + { + tags: { + '*': { + align: null + } + }, + conv: function (node, $node) { + $node.css('textAlign', $node.attr('align')).removeAttr('align'); + } + }, + { + tags: { + '*': { + border: null + } + }, + conv: function (node, $node) { + $node + .css('borderWidth',$node.attr('border')) + .removeAttr('border'); + } + }, + { + tags: { + applet: { + name: null + }, + img: { + name: null + }, + layer: { + name: null + }, + map: { + name: null + }, + object: { + name: null + }, + param: { + name: null + } + }, + conv: function (node, $node) { + if (!$node.attr('id')) { + $node.attr('id', $node.attr('name')); + } + + $node.removeAttr('name'); + } + }, + { + tags: { + '*': { + vspace: null + } + }, + conv: function (node, $node) { + $node + .css('marginTop', $node.attr('vspace') - 0) + .css('marginBottom', $node.attr('vspace') - 0) + .removeAttr('vspace'); + } + }, + { + tags: { + '*': { + hspace: null + } + }, + conv: function (node, $node) { + $node + .css('marginLeft', $node.attr('hspace') - 0) + .css('marginRight', $node.attr('hspace') - 0) + .removeAttr('hspace'); + } + }, + { + tags: { + 'hr': { + noshade: null + } + }, + conv: function (node, $node) { + $node.css('borderStyle', 'solid').removeAttr('noshade'); + } + }, + { + tags: { + '*': { + nowrap: null + } + }, + conv: function (node, $node) { + $node.css('white-space', 'nowrap').removeAttr('nowrap'); + } + }, + { + tags: { + big: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'span')).css('fontSize', 'larger'); + } + }, + { + tags: { + small: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'span')).css('fontSize', 'smaller'); + } + }, + { + tags: { + b: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'strong')); + } + }, + { + tags: { + u: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'span')) + .css('textDecoration', 'underline'); + } + }, + { + tags: { + i: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'em')); + } + }, + { + tags: { + s: null, + strike: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'span')) + .css('textDecoration', 'line-through'); + } + }, + { + tags: { + dir: null + }, + conv: function (node) { + this.convertTagTo(node, 'ul'); + } + }, + { + tags: { + center: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'div')) + .css('textAlign', 'center'); + } + }, + { + tags: { + font: { + size: null + } + }, + conv: function (node, $node) { + var size = $node.css('fontSize'), + fontSize = size; + + // IE < 8 sets a font tag with no size to +0 so + // should just skip it. + if (fontSize !== '+0') { + // IE 8 and below incorrectly returns the value of the size + // attribute instead of the px value so must convert it + if (SCEditor.ie < 9) { + fontSize = 10; + + if (size > 1) { + fontSize = 13; + } + if (size > 2) { + fontSize = 16; + } + if (size > 3) { + fontSize = 18; + } + if (size > 4) { + fontSize = 24; + } + if (size > 5) { + fontSize = 32; + } + if (size > 6) { + fontSize = 48; + } + } + + $node.css('fontSize', fontSize); + } + + $node.removeAttr('size'); + } + }, + { + tags: { + font: null + }, + conv: function (node) { + // All it's attributes will be converted + // by the attribute converters + this.convertTagTo(node, 'span'); + } + }, + { + tags: { + '*': { + type: ['_moz'] + } + }, + conv: function (node, $node) { + $node.removeAttr('type'); + } + }, + { + tags: { + '*': { + '_moz_dirty': null + } + }, + conv: function (node, $node) { + $node.removeAttr('_moz_dirty'); + } + }, + { + tags: { + '*': { + '_moz_editor_bogus_node': null + } + }, + conv: function (node, $node) { + $node.remove(); + } + } + ]; + + /** + * Allowed attributes map. + * + * To allow an attribute for all tags use * as the tag name. + * + * Leave empty or null to allow all attributes. (the disallow + * list will be used to filter them instead) + * @type {Object} + * @name jQuery.sceditor.plugins.xhtml.allowedAttribs + * @since v1.4.1 + */ + sceditorPlugins.xhtml.allowedAttribs = {}; + + /** + * Attributes that are not allowed. + * + * Only used if allowed attributes is null or empty. + * @type {Object} + * @name jQuery.sceditor.plugins.xhtml.disallowedAttribs + * @since v1.4.1 + */ + sceditorPlugins.xhtml.disallowedAttribs = {}; + + /** + * Array containing all the allowed tags. + * + * If null or empty all tags will be allowed. + * @type {Array} + * @name jQuery.sceditor.plugins.xhtml.allowedTags + * @since v1.4.1 + */ + sceditorPlugins.xhtml.allowedTags = []; + + /** + * Array containing all the disallowed tags. + * + * Only used if allowed tags is null or empty. + * @type {Array} + * @name jQuery.sceditor.plugins.xhtml.disallowedTags + * @since v1.4.1 + */ + sceditorPlugins.xhtml.disallowedTags = []; +}(jQuery)); diff --git a/js/sceditor/development/plugins/bbcode.js b/js/sceditor/development/plugins/bbcode.js new file mode 100644 index 00000000..f1c81bab --- /dev/null +++ b/js/sceditor/development/plugins/bbcode.js @@ -0,0 +1,2810 @@ +/** + * SCEditor BBCode Plugin + * http://www.sceditor.com/ + * + * Copyright (C) 2011-2014, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * @fileoverview SCEditor BBCode Plugin + * @author Sam Clarke + * @requires jQuery + */ +/*global prompt: true*/ +/*jshint maxdepth: false*/ +// TODO: Tidy this code up and consider seperating the BBCode parser into a +// standalone module that can be used with other JS/NodeJS +(function ($, window, document) { + 'use strict'; + + var SCEditor = $.sceditor; + var sceditorPlugins = SCEditor.plugins; + var escapeEntities = SCEditor.escapeEntities; + var escapeUriScheme = SCEditor.escapeUriScheme; + + var IE_VER = SCEditor.ie; + + // In IE < 11 a BR at the end of a block level element + // causes a double line break. + var IE_BR_FIX = IE_VER && IE_VER < 11; + + + + var getEditorCommand = SCEditor.command.get; + + var defaultCommandsOverrides = { + bold: { + txtExec: ['[b]', '[/b]'] + }, + italic: { + txtExec: ['[i]', '[/i]'] + }, + underline: { + txtExec: ['[u]', '[/u]'] + }, + strike: { + txtExec: ['[s]', '[/s]'] + }, + subscript: { + txtExec: ['[sub]', '[/sub]'] + }, + superscript: { + txtExec: ['[sup]', '[/sup]'] + }, + left: { + txtExec: ['[left]', '[/left]'] + }, + center: { + txtExec: ['[center]', '[/center]'] + }, + right: { + txtExec: ['[right]', '[/right]'] + }, + justify: { + txtExec: ['[justify]', '[/justify]'] + }, + font: { + txtExec: function (caller) { + var editor = this; + + getEditorCommand('font')._dropDown( + editor, + caller, + function (fontName) { + editor.insertText( + '[font=' + fontName + ']', + '[/font]' + ); + } + ); + } + }, + size: { + txtExec: function (caller) { + var editor = this; + + getEditorCommand('size')._dropDown( + editor, + caller, + function (fontSize) { + editor.insertText( + '[size=' + fontSize + ']', + '[/size]' + ); + } + ); + } + }, + color: { + txtExec: function (caller) { + var editor = this; + + getEditorCommand('color')._dropDown( + editor, + caller, + function (color) { + editor.insertText( + '[color=' + color + ']', + '[/color]' + ); + } + ); + } + }, + bulletlist: { + txtExec: function (caller, selected) { + var content = ''; + + $.each(selected.split(/\r?\n/), function () { + content += (content ? '\n' : '') + + '[li]' + this + '[/li]'; + }); + + this.insertText('[ul]\n' + content + '\n[/ul]'); + } + }, + orderedlist: { + txtExec: function (caller, selected) { + var content = ''; + + $.each(selected.split(/\r?\n/), function () { + content += (content ? '\n' : '') + + '[li]' + this + '[/li]'; + }); + + sceditorPlugins.bbcode.bbcode.get(''); + + this.insertText('[ol]\n' + content + '\n[/ol]'); + } + }, + table: { + txtExec: ['[table][tr][td]', '[/td][/tr][/table]'] + }, + horizontalrule: { + txtExec: ['[hr]'] + }, + code: { + txtExec: ['[code]', '[/code]'] + }, + image: { + txtExec: function (caller, selected) { + var editor = this, + url = prompt(editor._('Enter the image URL:'), selected); + + if (url) { + editor.insertText('[img]' + url + '[/img]'); + } + } + }, + email: { + txtExec: function (caller, selected) { + var editor = this, + display = selected && selected.indexOf('@') > -1 ? + null : selected, + email = prompt(editor._('Enter the e-mail address:'), + (display ? '' : selected)), + text = prompt(editor._('Enter the displayed text:'), + display || email) || email; + + if (email) { + editor.insertText('[email=' + email + ']' + + text + '[/email]'); + } + } + }, + link: { + txtExec: function (caller, selected) { + var editor = this, + display = /^[a-z]+:\/\//i.test($.trim(selected)) ? + null : selected, + url = prompt(editor._('Enter URL:'), + (display ? 'http://' : $.trim(selected))), + text = prompt(editor._('Enter the displayed text:'), + display || url) || url; + + if (url) { + editor.insertText('[url=' + url + ']' + text + '[/url]'); + } + } + }, + quote: { + txtExec: ['[quote]', '[/quote]'] + }, + youtube: { + txtExec: function (caller) { + var editor = this; + + getEditorCommand('youtube')._dropDown( + editor, + caller, + function (id) { + editor.insertText('[youtube]' + id + '[/youtube]'); + } + ); + } + }, + rtl: { + txtExec: ['[rtl]', '[/rtl]'] + }, + ltr: { + txtExec: ['[ltr]', '[/ltr]'] + } + }; + + /** + * Removes any leading or trailing quotes ('") + * + * @return string + * @since v1.4.0 + */ + var _stripQuotes = function (str) { + return str ? + str.replace(/\\(.)/g, '$1').replace(/^(["'])(.*?)\1$/, '$2') : str; + }; + + /** + * Formats a string replacing {0}, {1}, {2}, ect. with + * the params provided + * + * @param {String} str The string to format + * @param {string} args... The strings to replace + * @return {String} + * @since v1.4.0 + */ + var _formatString = function () { + var undef; + var args = arguments; + + return args[0].replace(/\{(\d+)\}/g, function (str, p1) { + return args[p1 - 0 + 1] !== undef ? + args[p1 - 0 + 1] : + '{' + p1 + '}'; + }); + }; + + /** + * Enum of valid token types + * @type {Object} + * @private + */ + var TokenType = { + OPEN: 'open', + CONTENT: 'content', + NEWLINE: 'newline', + CLOSE: 'close' + }; + + + /** + * Tokenize token object + * + * @param {String} type The type of token this is, + * should be one of tokenType + * @param {String} name The name of this token + * @param {String} val The originally matched string + * @param {Array} attrs Any attributes. Only set on + * TokenType.OPEN tokens + * @param {Array} children Any children of this token + * @param {TokenizeToken} closing This tokens closing tag. + * Only set on TokenType.OPEN tokens + * @class TokenizeToken + * @name TokenizeToken + * @memberOf jQuery.sceditor.BBCodeParser.prototype + */ + var TokenizeToken = function ( + /*jshint maxparams: false*/ + type, name, val, attrs, children, closing + ) { + var base = this; + + base.type = type; + base.name = name; + base.val = val; + base.attrs = attrs || {}; + base.children = children || []; + base.closing = closing || null; + }; + + TokenizeToken.prototype = { + /** @lends jQuery.sceditor.BBCodeParser.prototype.TokenizeToken */ + /** + * Clones this token + * + * @param {Bool} includeChildren If to include the children in + * the clone. Defaults to false. + * @return {TokenizeToken} + */ + clone: function (includeChildren) { + var base = this; + + return new TokenizeToken( + base.type, + base.name, + base.val, + base.attrs, + includeChildren ? base.children : [], + base.closing ? base.closing.clone() : null + ); + }, + /** + * Splits this token at the specified child + * + * @param {TokenizeToken|Int} splitAt The child to split at or the + * index of the child + * @return {TokenizeToken} The right half of the split token or + * null if failed + */ + splitAt: function (splitAt) { + var clone; + var base = this; + var splitAtLength = 0; + var childrenLen = base.children.length; + + if (typeof splitAt !== 'number') { + splitAt = $.inArray(splitAt, base.children); + } + + if (splitAt < 0 || splitAt > childrenLen) { + return null; + } + + // Work out how many items are on the right side of the split + // to pass to splice() + while (childrenLen--) { + if (childrenLen >= splitAt) { + splitAtLength++; + } else { + childrenLen = 0; + } + } + + clone = base.clone(); + clone.children = base.children.splice(splitAt, splitAtLength); + return clone; + } + }; + + + /** + * SCEditor BBCode parser class + * + * @param {Object} options + * @class BBCodeParser + * @name jQuery.sceditor.BBCodeParser + * @since v1.4.0 + */ + var BBCodeParser = function (options) { + // make sure this is not being called as a function + if (!(this instanceof BBCodeParser)) { + return new BBCodeParser(options); + } + + var base = this; + + // Private methods + var init, + tokenizeTag, + tokenizeAttrs, + parseTokens, + normaliseNewLines, + fixNesting, + isChildAllowed, + removeEmpty, + fixChildren, + convertToHTML, + convertToBBCode, + hasTag, + quote, + lower, + last; + + + init = function () { + base.bbcodes = sceditorPlugins.bbcode.bbcodes; + base.opts = $.extend( + {}, + BBCodeParser.defaults, + options + ); + }; + + /** + * Takes a BBCode string and splits it into open, + * content and close tags. + * + * It does no checking to verify a tag has a matching open + * or closing tag or if the tag is valid child of any tag + * before it. For that the tokens should be passed to the + * parse function. + * + * @param {String} str + * @return {Array} + * @memberOf jQuery.sceditor.BBCodeParser.prototype + */ + base.tokenize = function (str) { + var matches, type, i; + var toks = []; + var tokens = [ + // Close must come before open as they are + // the same except close has a / at the start. + { + type: TokenType.CLOSE, + regex: /^\[\/[^\[\]]+\]/ + }, + { + type: TokenType.OPEN, + regex: /^\[[^\[\]]+\]/ + }, + { + type: TokenType.NEWLINE, + regex: /^(\r\n|\r|\n)/ + }, + { + type: TokenType.CONTENT, + regex: /^([^\[\r\n]+|\[)/ + } + ]; + + tokens.reverse(); + + strloop: + while (str.length) { + i = tokens.length; + while (i--) { + type = tokens[i].type; + + // Check if the string matches any of the tokens + if (!(matches = str.match(tokens[i].regex)) || + !matches[0]) { + continue; + } + + // Add the match to the tokens list + toks.push(tokenizeTag(type, matches[0])); + + // Remove the match from the string + str = str.substr(matches[0].length); + + // The token has been added so start again + continue strloop; + } + + // If there is anything left in the string which doesn't match + // any of the tokens then just assume it's content and add it. + if (str.length) { + toks.push(tokenizeTag(TokenType.CONTENT, str)); + } + + str = ''; + } + + return toks; + }; + + /** + * Extracts the name an params from a tag + * + * @param {tokenType} type + * @param {string} val + * @return {Object} + * @private + */ + tokenizeTag = function (type, val) { + var matches, attrs, name, + openRegex = /\[([^\]\s=]+)(?:([^\]]+))?\]/, + closeRegex = /\[\/([^\[\]]+)\]/; + + // Extract the name and attributes from opening tags and + // just the name from closing tags. + if (type === TokenType.OPEN && (matches = val.match(openRegex))) { + name = lower(matches[1]); + + if (matches[2] && (matches[2] = $.trim(matches[2]))) { + attrs = tokenizeAttrs(matches[2]); + } + } + + if (type === TokenType.CLOSE && (matches = val.match(closeRegex))) { + name = lower(matches[1]); + } + + if (type === TokenType.NEWLINE) { + name = '#newline'; + } + + // Treat all tokens without a name and + // all unknown BBCodes as content + if (!name || + ((type === TokenType.OPEN || type === TokenType.CLOSE) && + !sceditorPlugins.bbcode.bbcodes[name])) { + type = TokenType.CONTENT; + name = '#'; + } + + return new TokenizeToken(type, name, val, attrs); + }; + + /** + * Extracts the individual attributes from a string containing + * all the attributes. + * + * @param {String} attrs + * @return {Array} Assoc array of attributes + * @private + */ + tokenizeAttrs = function (attrs) { + var matches, + /* + ([^\s=]+) Anything that's not a space or equals + = Equals sign = + (?: + (?: + (["']) The opening quote + ( + (?:\\\2|[^\2])*? Anything that isn't the + unescaped opening quote + ) + \2 The opening quote again which + will close the string + ) + | If not a quoted string then match + ( + (?:.(?!\s\S+=))*.? Anything that isn't part of + [space][non-space][=] which + would be a new attribute + ) + ) + */ + attrRegex = + /([^\s=]+)=(?:(?:(["'])((?:\\\2|[^\2])*?)\2)|((?:.(?!\s\S+=))*.))/g, + ret = {}; + + // if only one attribute then remove the = from the start and + // strip any quotes + if (attrs.charAt(0) === '=' && attrs.indexOf('=', 1) < 0) { + ret.defaultattr = _stripQuotes(attrs.substr(1)); + } else { + if (attrs.charAt(0) === '=') { + attrs = 'defaultattr' + attrs; + } + + // No need to strip quotes here, the regex will do that. + while ((matches = attrRegex.exec(attrs))) { + ret[lower(matches[1])] = + _stripQuotes(matches[3]) || matches[4]; + } + } + + return ret; + }; + + /** + * Parses a string into an array of BBCodes + * + * @param {string} str + * @param {boolean} preserveNewLines If to preserve all new lines, not + * strip any based on the passed + * formatting options + * @return {Array} Array of BBCode objects + * @memberOf jQuery.sceditor.BBCodeParser.prototype + */ + base.parse = function (str, preserveNewLines) { + var ret = parseTokens(base.tokenize(str)); + var opts = base.opts; + + if (opts.fixInvalidChildren) { + fixChildren(ret); + } + + if (opts.removeEmptyTags) { + removeEmpty(ret); + } + + if (opts.fixInvalidNesting) { + fixNesting(ret); + } + + normaliseNewLines(ret, null, preserveNewLines); + + if (opts.removeEmptyTags) { + removeEmpty(ret); + } + + return ret; + }; + + /** + * Checks if an array of TokenizeToken's contains the + * specified token. + * + * Checks the tokens name and type match another tokens + * name and type in the array. + * + * @param {string} name + * @param {tokenType} type + * @param {Array} arr + * @return {Boolean} + * @private + */ + hasTag = function (name, type, arr) { + var i = arr.length; + + while (i--) { + if (arr[i].type === type && arr[i].name === name) { + return true; + } + } + + return false; + }; + + /** + * Checks if the child tag is allowed as one + * of the parent tags children. + * + * @param {TokenizeToken} parent + * @param {TokenizeToken} child + * @return {Boolean} + * @private + */ + isChildAllowed = function (parent, child) { + var parentBBCode = parent ? base.bbcodes[parent.name] : {}, + allowedChildren = parentBBCode.allowedChildren; + + if (base.opts.fixInvalidChildren && allowedChildren) { + return $.inArray(child.name || '#', allowedChildren) > -1; + } + + return true; + }; + +// TODO: Tidy this parseTokens() function up a bit. + /** + * Parses an array of tokens created by tokenize() + * + * @param {Array} toks + * @return {Array} Parsed tokens + * @see tokenize() + * @private + */ + parseTokens = function (toks) { + var token, bbcode, curTok, clone, i, previous, next, + cloned = [], + output = [], + openTags = [], + /** + * Returns the currently open tag or undefined + * @return {TokenizeToken} + */ + currentOpenTag = function () { + return last(openTags); + }, + /** + * Adds a tag to either the current tags children + * or to the output array. + * @param {TokenizeToken} token + * @private + */ + addTag = function (token) { + if (currentOpenTag()) { + currentOpenTag().children.push(token); + } else { + output.push(token); + } + }, + /** + * Checks if this tag closes the current tag + * @param {String} name + * @return {Void} + */ + closesCurrentTag = function (name) { + return currentOpenTag() && + (bbcode = base.bbcodes[currentOpenTag().name]) && + bbcode.closedBy && + $.inArray(name, bbcode.closedBy) > -1; + }; + + while ((token = toks.shift())) { + next = toks[0]; + + /* jshint indent:false */ + switch (token.type) { + case TokenType.OPEN: + // Check it this closes a parent, + // e.g. for lists [*]one [*]two + if (closesCurrentTag(token.name)) { + openTags.pop(); + } + + addTag(token); + bbcode = base.bbcodes[token.name]; + + // If this tag is not self closing and it has a closing + // tag then it is open and has children so add it to the + // list of open tags. If has the closedBy property then + // it is closed by other tags so include everything as + // it's children until one of those tags is reached. + if ((!bbcode || !bbcode.isSelfClosing) && + (bbcode.closedBy || + hasTag(token.name, TokenType.CLOSE, toks))) { + openTags.push(token); + } else if (!bbcode || !bbcode.isSelfClosing) { + token.type = TokenType.CONTENT; + } + break; + + case TokenType.CLOSE: + // check if this closes the current tag, + // e.g. [/list] would close an open [*] + if (currentOpenTag() && + token.name !== currentOpenTag().name && + closesCurrentTag('/' + token.name)) { + openTags.pop(); + } + + // If this is closing the currently open tag just pop + // the close tag off the open tags array + if (currentOpenTag() && + token.name === currentOpenTag().name) { + currentOpenTag().closing = token; + openTags.pop(); + + // If this is closing an open tag that is the parent of + // the current tag then clone all the tags including the + // current one until reaching the parent that is being + // closed. Close the parent and then add the clones back + // in. + } else if (hasTag(token.name, TokenType.OPEN, + openTags)) { + + // Remove the tag from the open tags + while ((curTok = openTags.pop())) { + + // If it's the tag that is being closed then + // discard it and break the loop. + if (curTok.name === token.name) { + curTok.closing = token; + break; + } + + // Otherwise clone this tag and then add any + // previously cloned tags as it's children + clone = curTok.clone(); + + if (cloned.length) { + clone.children.push(last(cloned)); + } + + cloned.push(clone); + } + + // Add the last cloned child to the now current tag + // (the parent of the tag which was being closed) + addTag(last(cloned)); + + // Add all the cloned tags to the open tags list + i = cloned.length; + while (i--) { + openTags.push(cloned[i]); + } + + cloned.length = 0; + + // This tag is closing nothing so treat it as content + } else { + token.type = TokenType.CONTENT; + addTag(token); + } + break; + + case TokenType.NEWLINE: + // handle things like + // [*]list\nitem\n[*]list1 + // where it should come out as + // [*]list\nitem[/*]\n[*]list1[/*] + // instead of + // [*]list\nitem\n[/*][*]list1[/*] + if (currentOpenTag() && next && + closesCurrentTag( + (next.type === TokenType.CLOSE ? '/' : '') + + next.name + )) { + // skip if the next tag is the closing tag for + // the option tag, i.e. [/*] + if (!(next.type === TokenType.CLOSE && + next.name === currentOpenTag().name)) { + bbcode = base.bbcodes[currentOpenTag().name]; + + if (bbcode && bbcode.breakAfter) { + openTags.pop(); + } else if (bbcode && + bbcode.isInline === false && + base.opts.breakAfterBlock && + bbcode.breakAfter !== false) { + openTags.pop(); + } + } + } + + addTag(token); + break; + + default: // content + addTag(token); + break; + } + + previous = token; + } + + return output; + }; + + /** + * Normalise all new lines + * + * Removes any formatting new lines from the BBCode + * leaving only content ones. I.e. for a list: + * + * [list] + * [*] list item one + * with a line break + * [*] list item two + * [/list] + * + * would become + * + * [list] [*] list item one + * with a line break [*] list item two [/list] + * + * Which makes it easier to convert to HTML or add + * the formatting new lines back in when converting + * back to BBCode + * + * @param {Array} children + * @param {TokenizeToken} parent + * @param {Bool} onlyRemoveBreakAfter + * @return {void} + */ + normaliseNewLines = function (children, parent, onlyRemoveBreakAfter) { + var token, left, right, parentBBCode, bbcode, + removedBreakEnd, removedBreakBefore, remove; + var childrenLength = children.length; +// TODO: this function really needs tidying up + if (parent) { + parentBBCode = base.bbcodes[parent.name]; + } + + var i = childrenLength; + while (i--) { + if (!(token = children[i])) { + continue; + } + + if (token.type === TokenType.NEWLINE) { + left = i > 0 ? children[i - 1] : null; + right = i < childrenLength - 1 ? children[i + 1] : null; + remove = false; + + // Handle the start and end new lines + // e.g. [tag]\n and \n[/tag] + if (!onlyRemoveBreakAfter && parentBBCode && + parentBBCode.isSelfClosing !== true) { + // First child of parent so must be opening line break + // (breakStartBlock, breakStart) e.g. [tag]\n + if (!left) { + if (parentBBCode.isInline === false && + base.opts.breakStartBlock && + parentBBCode.breakStart !== false) { + remove = true; + } + + if (parentBBCode.breakStart) { + remove = true; + } + // Last child of parent so must be end line break + // (breakEndBlock, breakEnd) + // e.g. \n[/tag] + // remove last line break (breakEndBlock, breakEnd) + } else if (!removedBreakEnd && !right) { + if (parentBBCode.isInline === false && + base.opts.breakEndBlock && + parentBBCode.breakEnd !== false) { + remove = true; + } + + if (parentBBCode.breakEnd) { + remove = true; + } + + removedBreakEnd = remove; + } + } + + if (left && left.type === TokenType.OPEN) { + if ((bbcode = base.bbcodes[left.name])) { + if (!onlyRemoveBreakAfter) { + if (bbcode.isInline === false && + base.opts.breakAfterBlock && + bbcode.breakAfter !== false) { + remove = true; + } + + if (bbcode.breakAfter) { + remove = true; + } + } else if (bbcode.isInline === false) { + remove = true; + } + } + } + + if (!onlyRemoveBreakAfter && !removedBreakBefore && + right && right.type === TokenType.OPEN) { + + if ((bbcode = base.bbcodes[right.name])) { + if (bbcode.isInline === false && + base.opts.breakBeforeBlock && + bbcode.breakBefore !== false) { + remove = true; + } + + if (bbcode.breakBefore) { + remove = true; + } + + removedBreakBefore = remove; + + if (remove) { + children.splice(i, 1); + continue; + } + } + } + + if (remove) { + children.splice(i, 1); + } + + // reset double removedBreakBefore removal protection. + // This is needed for cases like \n\n[\tag] where + // only 1 \n should be removed but without this they both + // would be. + removedBreakBefore = false; + } else if (token.type === TokenType.OPEN) { + normaliseNewLines(token.children, token, + onlyRemoveBreakAfter); + } + } + }; + + /** + * Fixes any invalid nesting. + * + * If it is a block level element inside 1 or more inline elements + * then those inline elements will be split at the point where the + * block level is and the block level element placed between the split + * parts. i.e. + * [inline]A[blocklevel]B[/blocklevel]C[/inline] + * Will become: + * [inline]A[/inline][blocklevel]B[/blocklevel][inline]C[/inline] + * + * @param {Array} children + * @param {Array} [parents] Null if there is no parents + * @param {Array} [insideInline] Boolean, if inside an inline element + * @param {Array} [rootArr] Root array if there is one + * @return {Array} + * @private + */ + fixNesting = function (children, parents, insideInline, rootArr) { + var token, i, parent, parentIndex, parentParentChildren, right; + + var isInline = function (token) { + var bbcode = base.bbcodes[token.name]; + + return !bbcode || bbcode.isInline !== false; + }; + + parents = parents || []; + rootArr = rootArr || children; + + // This must check the length each time as it can change when + // tokens are moved to fix the nesting. + for (i = 0; i < children.length; i++) { + if (!(token = children[i]) || token.type !== TokenType.OPEN) { + continue; + } + + if (!isInline(token) && insideInline) { + // if this is a blocklevel element inside an inline one then + // split the parent at the block level element + parent = last(parents); + right = parent.splitAt(token); + + parentParentChildren = parents.length > 1 ? + parents[parents.length - 2].children : rootArr; + + parentIndex = $.inArray(parent, parentParentChildren); + if (parentIndex > -1) { + // remove the block level token from the right side of + // the split inline element + right.children.splice( + $.inArray(token, right.children), 1); + + // insert the block level token and the right side after + // the left side of the inline token + parentParentChildren.splice( + parentIndex + 1, 0, token, right + ); + + // return to parents loop as the + // children have now increased + return; + } + + } + + parents.push(token); + + fixNesting( + token.children, + parents, + insideInline || isInline(token), + rootArr + ); + + parents.pop(token); + } + }; + + /** + * Fixes any invalid children. + * + * If it is an element which isn't allowed as a child of it's parent + * then it will be converted to content of the parent element. i.e. + * [code]Code [b]only[/b] allows text.[/code] + * Will become: + * Code [b]only[/b] allows text. + * Instead of: + * Code only allows text. + * + * @param {Array} children + * @param {Array} [parent] Null if there is no parents + * @private + */ + fixChildren = function (children, parent) { + var token, args; + + var i = children.length; + while (i--) { + if (!(token = children[i])) { + continue; + } + + if (!isChildAllowed(parent, token)) { + // if it is not then convert it to text and see if it + // is allowed + token.name = null; + token.type = TokenType.CONTENT; + + if (isChildAllowed(parent, token)) { + args = [i + 1, 0].concat(token.children); + + if (token.closing) { + token.closing.name = null; + token.closing.type = TokenType.CONTENT; + args.push(token.closing); + } + + i += args.length - 1; + Array.prototype.splice.apply(children, args); + } else { + parent.children.splice(i, 1); + } + } + + if (token.type === TokenType.OPEN) { + fixChildren(token.children, token); + } + } + }; + + /** + * Removes any empty BBCodes which are not allowed to be empty. + * + * @param {Array} tokens + * @private + */ + removeEmpty = function (tokens) { + var token, bbcode; + + /** + * Checks if all children are whitespace or not + * @private + */ + var isTokenWhiteSpace = function (children) { + var j = children.length; + + while (j--) { + var type = children[j].type; + + if (type === TokenType.OPEN || type === TokenType.CLOSE) { + return false; + } + + if (type === TokenType.CONTENT && + /\S|\u00A0/.test(children[j].val)) { + return false; + } + } + + return true; + }; + + var i = tokens.length; + while (i--) { + // So skip anything that isn't a tag since only tags can be + // empty, content can't + if (!(token = tokens[i]) || token.type !== TokenType.OPEN) { + continue; + } + + bbcode = base.bbcodes[token.name]; + + // Remove any empty children of this tag first so that if they + // are all removed this one doesn't think it's not empty. + removeEmpty(token.children); + + if (isTokenWhiteSpace(token.children) && bbcode && + !bbcode.isSelfClosing && !bbcode.allowsEmpty) { + tokens.splice.apply( + tokens, + $.merge([i, 1], token.children) + ); + } + } + }; + + /** + * Converts a BBCode string to HTML + * + * @param {String} str + * @param {Bool} preserveNewLines If to preserve all new lines, not + * strip any based on the passed + * formatting options + * @return {String} + * @memberOf jQuery.sceditor.BBCodeParser.prototype + */ + base.toHTML = function (str, preserveNewLines) { + return convertToHTML(base.parse(str, preserveNewLines), true); + }; + + /** + * @private + */ + convertToHTML = function (tokens, isRoot) { + var undef, token, bbcode, content, html, needsBlockWrap, + blockWrapOpen, isInline, lastChild, + ret = []; + + isInline = function (bbcode) { + return (!bbcode || (bbcode.isHtmlInline !== undef ? + bbcode.isHtmlInline : bbcode.isInline)) !== false; + }; + + while (tokens.length > 0) { + if (!(token = tokens.shift())) { + continue; + } + + if (token.type === TokenType.OPEN) { + lastChild = + token.children[token.children.length - 1] || {}; + bbcode = base.bbcodes[token.name]; + needsBlockWrap = isRoot && isInline(bbcode); + content = convertToHTML(token.children, false); + + if (bbcode && bbcode.html) { + // Only add a line break to the end if this is + // blocklevel and the last child wasn't block-level + if (!isInline(bbcode) && + isInline(base.bbcodes[lastChild.name]) && + !bbcode.isPreFormatted && + !bbcode.skipLastLineBreak) { + // Add placeholder br to end of block level elements + // in all browsers apart from IE < 9 which handle + // new lines differently and doesn't need one. + if (!IE_BR_FIX) { + content += '
    '; + } + } + + if (!$.isFunction(bbcode.html)) { + token.attrs['0'] = content; + html = sceditorPlugins.bbcode.formatBBCodeString( + bbcode.html, + token.attrs + ); + } else { + html = bbcode.html.call( + base, + token, + token.attrs, + content + ); + } + } else { + html = token.val + content + + (token.closing ? token.closing.val : ''); + } + } else if (token.type === TokenType.NEWLINE) { + if (!isRoot) { + ret.push('
    '); + continue; + } + + // If not already in a block wrap then start a new block + if (!blockWrapOpen) { + ret.push('

    '); + + // If it's an empty DIV and compatibility mode is below + // IE8 then we must add a non-breaking space to the div + // otherwise the div will be collapsed. Adding a BR + // works but when you press enter to make a newline it + // suddenly goes back to the normal IE div behavior and + // creates two lines, one for the newline and one for + // the BR. I'm sure there must be a better fix but I've + // yet to find one. + // Cannot do zoom: 1; or set a height on the div to fix + // it as that causes resize handles to be added to the + // div when it's clicked on. + if (IE_VER < 8 || (document.documentMode && + document.documentMode < 8)) { + ret.push('\u00a0'); + } + } + + // Putting BR in a div in IE causes it + // to do a double line break. + if (!IE_BR_FIX) { + ret.push('
    '); + } + + // Normally the div acts as a line-break with by moving + // whatever comes after onto a new line. + // If this is the last token, add an extra line-break so it + // shows as there will be nothing after it. + if (!tokens.length) { + ret.push('
    '); + } + + ret.push('
    \n'); + blockWrapOpen = false; + continue; + // content + } else { + needsBlockWrap = isRoot; + html = escapeEntities(token.val, true); + } + + if (needsBlockWrap && !blockWrapOpen) { + ret.push('
    '); + blockWrapOpen = true; + } else if (!needsBlockWrap && blockWrapOpen) { + ret.push('
    \n'); + blockWrapOpen = false; + } + + ret.push(html); + } + + if (blockWrapOpen) { + ret.push('
    \n'); + } + + return ret.join(''); + }; + + /** + * Takes a BBCode string, parses it then converts it back to BBCode. + * + * This will auto fix the BBCode and format it with the specified + * options. + * + * @param {String} str + * @param {Bool} preserveNewLines If to preserve all new lines, not + * strip any based on the passed + * formatting options + * @return {String} + * @memberOf jQuery.sceditor.BBCodeParser.prototype + */ + base.toBBCode = function (str, preserveNewLines) { + return convertToBBCode(base.parse(str, preserveNewLines)); + }; + + /** + * Converts parsed tokens back into BBCode with the + * formatting specified in the options and with any + * fixes specified. + * + * @param {Array} toks Array of parsed tokens from base.parse() + * @return {String} + * @private + */ + convertToBBCode = function (toks) { + var token, attr, bbcode, isBlock, isSelfClosing, quoteType, + breakBefore, breakStart, breakEnd, breakAfter, + // Create an array of strings which are joined together + // before being returned as this is faster in slow browsers. + // (Old versions of IE). + ret = []; + + while (toks.length > 0) { + if (!(token = toks.shift())) { + continue; + } +// TODO: tidy this + bbcode = base.bbcodes[token.name]; + isBlock = !(!bbcode || bbcode.isInline !== false); + isSelfClosing = bbcode && bbcode.isSelfClosing; + + breakBefore = (isBlock && base.opts.breakBeforeBlock && + bbcode.breakBefore !== false) || + (bbcode && bbcode.breakBefore); + + breakStart = (isBlock && !isSelfClosing && + base.opts.breakStartBlock && + bbcode.breakStart !== false) || + (bbcode && bbcode.breakStart); + + breakEnd = (isBlock && base.opts.breakEndBlock && + bbcode.breakEnd !== false) || + (bbcode && bbcode.breakEnd); + + breakAfter = (isBlock && base.opts.breakAfterBlock && + bbcode.breakAfter !== false) || + (bbcode && bbcode.breakAfter); + + quoteType = (bbcode ? bbcode.quoteType : null) || + base.opts.quoteType || BBCodeParser.QuoteType.auto; + + if (!bbcode && token.type === TokenType.OPEN) { + ret.push(token.val); + + if (token.children) { + ret.push(convertToBBCode(token.children)); + } + + if (token.closing) { + ret.push(token.closing.val); + } + } else if (token.type === TokenType.OPEN) { + if (breakBefore) { + ret.push('\n'); + } + + // Convert the tag and it's attributes to BBCode + ret.push('[' + token.name); + if (token.attrs) { + if (token.attrs.defaultattr) { + ret.push('=', quote( + token.attrs.defaultattr, + quoteType, + 'defaultattr' + )); + + delete token.attrs.defaultattr; + } + + for (attr in token.attrs) { + if (token.attrs.hasOwnProperty(attr)) { + ret.push(' ', attr, '=', + quote(token.attrs[attr], quoteType, attr)); + } + } + } + ret.push(']'); + + if (breakStart) { + ret.push('\n'); + } + + // Convert the tags children to BBCode + if (token.children) { + ret.push(convertToBBCode(token.children)); + } + + // add closing tag if not self closing + if (!isSelfClosing && !bbcode.excludeClosing) { + if (breakEnd) { + ret.push('\n'); + } + + ret.push('[/' + token.name + ']'); + } + + if (breakAfter) { + ret.push('\n'); + } + + // preserve whatever was recognized as the + // closing tag if it is a self closing tag + if (token.closing && isSelfClosing) { + ret.push(token.closing.val); + } + } else { + ret.push(token.val); + } + } + + return ret.join(''); + }; + + /** + * Quotes an attribute + * + * @param {String} str + * @param {BBCodeParser.QuoteType} quoteType + * @param {String} name + * @return {String} + * @private + */ + quote = function (str, quoteType, name) { + var QuoteTypes = BBCodeParser.QuoteType, + needsQuotes = /\s|=/.test(str); + + if ($.isFunction(quoteType)) { + return quoteType(str, name); + } + + if (quoteType === QuoteTypes.never || + (quoteType === QuoteTypes.auto && !needsQuotes)) { + return str; + } + + return '"' + str.replace('\\', '\\\\').replace('"', '\\"') + '"'; + }; + + /** + * Returns the last element of an array or null + * + * @param {Array} arr + * @return {Object} Last element + * @private + */ + last = function (arr) { + if (arr.length) { + return arr[arr.length - 1]; + } + + return null; + }; + + /** + * Converts a string to lowercase. + * + * @param {String} str + * @return {String} Lowercase version of str + * @private + */ + lower = function (str) { + return str.toLowerCase(); + }; + + init(); + }; + + /** + * Quote type + * @type {Object} + * @class QuoteType + * @name jQuery.sceditor.BBCodeParser.QuoteType + * @since v1.4.0 + */ + BBCodeParser.QuoteType = { + /** @lends jQuery.sceditor.BBCodeParser.QuoteType */ + /** + * Always quote the attribute value + * @type {Number} + */ + always: 1, + + /** + * Never quote the attributes value + * @type {Number} + */ + never: 2, + + /** + * Only quote the attributes value when it contains spaces to equals + * @type {Number} + */ + auto: 3 + }; + + /** + * Default BBCode parser options + * @type {Object} + */ + BBCodeParser.defaults = { + /** + * If to add a new line before block level elements + * + * @type {Boolean} + */ + breakBeforeBlock: false, + + /** + * If to add a new line after the start of block level elements + * + * @type {Boolean} + */ + breakStartBlock: false, + + /** + * If to add a new line before the end of block level elements + * + * @type {Boolean} + */ + breakEndBlock: false, + + /** + * If to add a new line after block level elements + * + * @type {Boolean} + */ + breakAfterBlock: true, + + /** + * If to remove empty tags + * + * @type {Boolean} + */ + removeEmptyTags: true, + + /** + * If to fix invalid nesting, + * i.e. block level elements inside inline elements. + * + * @type {Boolean} + */ + fixInvalidNesting: true, + + /** + * If to fix invalid children. + * i.e. A tag which is inside a parent that doesn't + * allow that type of tag. + * + * @type {Boolean} + */ + fixInvalidChildren: true, + + /** + * Attribute quote type + * + * @type {BBCodeParser.QuoteType} + * @since 1.4.1 + */ + quoteType: BBCodeParser.QuoteType.auto + }; + + /** + * Deprecated, use sceditorPlugins.bbcode + * + * @class sceditorBBCodePlugin + * @name jQuery.sceditor.sceditorBBCodePlugin + * @deprecated + */ + $.sceditorBBCodePlugin = + /** + * BBCode plugin for SCEditor + * + * @class bbcode + * @name jQuery.sceditor.plugins.bbcode + * @since 1.4.1 + */ + sceditorPlugins.bbcode = function () { + var base = this; + + /** + * Private methods + * @private + */ + var buildBbcodeCache, + handleStyles, + handleTags, + removeFirstLastDiv; + + base.bbcodes = sceditorPlugins.bbcode.bbcodes; + base.stripQuotes = _stripQuotes; + + /** + * cache of all the tags pointing to their bbcodes to enable + * faster lookup of which bbcode a tag should have + * @private + */ + var tagsToBBCodes = {}; + + /** + * Same as tagsToBBCodes but instead of HTML tags it's styles + * @private + */ + var stylesToBBCodes = {}; + + /** + * Allowed children of specific HTML tags. Empty array if no + * children other than text nodes are allowed + * @private + */ + var validChildren = { + ul: ['li', 'ol', 'ul'], + ol: ['li', 'ol', 'ul'], + table: ['tr'], + tr: ['td', 'th'], + code: ['br', 'p', 'div'] + }; + + /** + * Initializer + * @private + */ + base.init = function () { + base.opts = this.opts; + + // build the BBCode cache + buildBbcodeCache(); + + this.commands = $.extend( + true, {}, defaultCommandsOverrides, this.commands + ); + + // Add BBCode helper methods + this.toBBCode = base.signalToSource; + this.fromBBCode = base.signalToWysiwyg; + }; + + /** + * Populates tagsToBBCodes and stylesToBBCodes to enable faster lookups + * + * @private + */ + buildBbcodeCache = function () { + $.each(base.bbcodes, function (bbcode) { + var isBlock, + tags = base.bbcodes[bbcode].tags, + styles = base.bbcodes[bbcode].styles; + + if (tags) { + $.each(tags, function (tag, values) { + isBlock = base.bbcodes[bbcode].isInline === false; + + tagsToBBCodes[tag] = tagsToBBCodes[tag] || {}; + + tagsToBBCodes[tag][isBlock] = + tagsToBBCodes[tag][isBlock] || {}; + + tagsToBBCodes[tag][isBlock][bbcode] = values; + }); + } + + if (styles) { + $.each(styles, function (style, values) { + isBlock = base.bbcodes[bbcode].isInline === false; + + stylesToBBCodes[isBlock] = + stylesToBBCodes[isBlock] || {}; + + stylesToBBCodes[isBlock][style] = + stylesToBBCodes[isBlock][style] || {}; + + stylesToBBCodes[isBlock][style][bbcode] = values; + }); + } + }); + }; + + /** + * Checks if any bbcode styles match the elements styles + * + * @return string Content with any matching + * bbcode tags wrapped around it. + * @private + */ + handleStyles = function ($element, content, blockLevel) { + var styleValue, format, + getStyle = SCEditor.dom.getStyle; + + // convert blockLevel to boolean + blockLevel = !!blockLevel; + + if (!stylesToBBCodes[blockLevel]) { + return content; + } + + $.each(stylesToBBCodes[blockLevel], function (property, bbcodes) { + styleValue = getStyle($element[0], property); + + // if the parent has the same style use that instead of this one + // so you don't end up with [i]parent[i]child[/i][/i] + if (!styleValue || + getStyle($element.parent()[0], property) === styleValue) { + return; + } + + $.each(bbcodes, function (bbcode, values) { + if (!values || + $.inArray(styleValue.toString(), values) > -1) { + format = base.bbcodes[bbcode].format; + + if ($.isFunction(format)) { + content = format.call(base, $element, content); + } else { + content = _formatString(format, content); + } + } + }); + }); + + return content; + }; + + /** + * Handles a HTML tag and finds any matching bbcodes + * + * @param {jQuery} $element The element to convert + * @param {String} content The Tags text content + * @param {Bool} blockLevel If to convert block level tags + * @return {String} Content with any matching bbcode tags + * wrapped around it. + * @private + */ + handleTags = function ($element, content, blockLevel) { + var convertBBCode, format, + element = $element[0], + tag = element.nodeName.toLowerCase(); + + // convert blockLevel to boolean + blockLevel = !!blockLevel; + + if (tagsToBBCodes[tag] && tagsToBBCodes[tag][blockLevel]) { + // loop all bbcodes for this tag + $.each(tagsToBBCodes[tag][blockLevel], function ( + bbcode, bbcodeAttribs) { + // if the bbcode requires any attributes then check this has + // all needed + if (bbcodeAttribs) { + convertBBCode = false; + + // loop all the bbcode attribs + $.each(bbcodeAttribs, function (attrib, values) { + // Skip if the element doesn't have the attibue or + // the attribute doesn't match one of the require + // values + if (!$element.attr(attrib) || (values && + $.inArray($element.attr(attrib), values) < 0)) { + return; + } + + // break this loop as we have matched this bbcode + convertBBCode = true; + return false; + }); + + if (!convertBBCode) { + return; + } + } + + format = base.bbcodes[bbcode].format; + + if ($.isFunction(format)) { + content = format.call(base, $element, content); + } else { + content = _formatString(format, content); + } + }); + } + + var isInline = SCEditor.dom.isInline; + if (blockLevel && (!isInline(element, true) || tag === 'br')) { + var isLastBlockChild, parent, parentLastChild, + previousSibling = element.previousSibling; + + // Skips selection makers and ignored elements + // Skip empty inline elements + while (previousSibling && + previousSibling.nodeType === 1 && + !$(previousSibling).is('br') && + isInline(previousSibling, true) && + !previousSibling.firstChild) { + previousSibling = previousSibling.previousSibling; + } + + // If it's the last block of an inline that is the last + // child of a block then it shouldn't cause a line break + // except in IE < 11 + //
    + do { + parent = element.parentNode; + parentLastChild = parent.lastChild; + + isLastBlockChild = parentLastChild === element; + element = parent; + } while (parent && isLastBlockChild && isInline(parent, true)); + + // If this block is: + // * Not the last child of a block level element + // * Is a
  • tag (lists are blocks) + // * Is IE < 11 and the tag is BR. IE < 11 never collapses BR + // tags. + if (!isLastBlockChild || tag === 'li' || + (tag === 'br' && IE_BR_FIX)) { + content += '\n'; + } + + // Check for: + // texttext + // + // The second opening opening tag should cause a + // line break because the previous sibing is inline. + if (tag !== 'br' && previousSibling && + !$(previousSibling).is('br') && + isInline(previousSibling, true)) { + content = '\n' + content; + } + } + + return content; + }; + + /** + * Converts HTML to BBCode + * + * @param {String} html Html string, this function ignores this, + * it works off domBody + * @param {jQuery} $body Editors dom body object to convert + * @return {String} BBCode which has been converted from HTML + * @memberOf jQuery.plugins.bbcode.prototype + */ + base.signalToSource = function (html, $body) { + var $tmpContainer, bbcode, + parser = new BBCodeParser(base.opts.parserOptions); + + if (!$body) { + if (typeof html === 'string') { + $tmpContainer = $('
    ') + .css('visibility', 'hidden') + .appendTo(document.body) + .html(html); + + $body = $tmpContainer; + } else { + $body = $(html); + } + } + + if (!$body || !$body.jquery) { + return ''; + } + + SCEditor.dom.removeWhiteSpace($body[0]); + + // Remove all the stuff that is meant to be ignored + $('.sceditor-ignore', $body).remove(); + + bbcode = base.elementToBbcode($body); + + if ($tmpContainer) { + $tmpContainer.remove(); + } + + bbcode = parser.toBBCode(bbcode, true); + + if (base.opts.bbcodeTrim) { + bbcode = $.trim(bbcode); + } + + return bbcode; + }; + + /** + * Converts a HTML dom element to BBCode starting from + * the innermost element and working backwards + * + * @private + * @param {jQuery} $element The element to convert to BBCode + * @return {string} BBCode + * @memberOf jQuery.plugins.bbcode.prototype + */ + base.elementToBbcode = function ($element) { + var toBBCode = function (node, vChildren) { + var ret = ''; +// TODO: Move to BBCode class? + SCEditor.dom.traverse(node, function (node) { + var $node = $(node), + curTag = '', + nodeType = node.nodeType, + tag = node.nodeName.toLowerCase(), + vChild = validChildren[tag], + firstChild = node.firstChild, + isValidChild = true; + + if (typeof vChildren === 'object') { + isValidChild = $.inArray(tag, vChildren) > -1; + + // Emoticons should always be converted + if ($node.is('img') && + $node.data('sceditor-emoticon')) { + isValidChild = true; + } + + // if this tag is one of the parents allowed children + // then set this tags allowed children to whatever it + // allows, otherwise set to what the parent allows + if (!isValidChild) { + vChild = vChildren; + } + } + + // 3 = text and 1 = element + if (nodeType !== 3 && nodeType !== 1) { + return; + } + + if (nodeType === 1) { + // skip empty nlf elements (new lines automatically + // added after block level elements like quotes) + if ($node.hasClass('sceditor-nlf')) { + if (!firstChild || (!IE_BR_FIX && + node.childNodes.length === 1 && + /br/i.test(firstChild.nodeName))) { + return; + } + } + + // don't loop inside iframes + if (tag !== 'iframe') { + curTag = toBBCode(node, vChild); + } + +// TODO: isValidChild is no longer needed. Should use valid children bbcodes +// instead by creating BBCode tokens like the parser. + if (isValidChild) { + // code tags should skip most styles + if (tag !== 'code') { + // handle inline bbcodes + curTag = handleStyles($node, curTag); + curTag = handleTags($node, curTag); + + // handle blocklevel bbcodes + curTag = handleStyles($node, curTag, true); + } + + ret += handleTags($node, curTag, true); + } else { + ret += curTag; + } + } else { + ret += node.nodeValue; + } + }, false, true); + + return ret; + }; + + return toBBCode($element[0]); + }; + + /** + * Converts BBCode to HTML + * + * @param {String} text + * @param {Bool} asFragment + * @return {String} HTML + * @memberOf jQuery.plugins.bbcode.prototype + */ + base.signalToWysiwyg = function (text, asFragment) { + var parser = new BBCodeParser(base.opts.parserOptions), + html = parser.toHTML(base.opts.bbcodeTrim ? + $.trim(text) : text); + + return asFragment ? removeFirstLastDiv(html) : html; + }; + + /** + * Removes the first and last divs from the HTML. + * + * This is needed for pasting + * @param {String} html + * @return {String} + * @private + */ + removeFirstLastDiv = function (html) { + var node, next, removeDiv, + $output = $('
    ').hide().appendTo(document.body), + output = $output[0]; + + removeDiv = function (node, isFirst) { + // Don't remove divs that have styling + if (SCEditor.dom.hasStyling(node)) { + return; + } + + if (IE_BR_FIX || (node.childNodes.length !== 1 || + !$(node.firstChild).is('br'))) { + while ((next = node.firstChild)) { + output.insertBefore(next, node); + } + } + + if (isFirst) { + var lastChild = output.lastChild; + + if (node !== lastChild && $(lastChild).is('div') && + node.nextSibling === lastChild) { + output.insertBefore(document.createElement('br'), node); + } + } + + output.removeChild(node); + }; + + output.innerHTML = html.replace(/<\/div>\n/g, '
    '); + + if ((node = output.firstChild) && $(node).is('div')) { + removeDiv(node, true); + } + + if ((node = output.lastChild) && $(node).is('div')) { + removeDiv(node); + } + + output = output.innerHTML; + $output.remove(); + + return output; + }; + }; + + + + /** + * Formats a string replacing {name} with the values of + * obj.name properties. + * + * If there is no property for the specified {name} then + * it will be left intact. + * + * @param {String} str + * @param {Object} obj + * @return {String} + * @since 1.4.5 + */ + sceditorPlugins.bbcode.formatBBCodeString = function (str, obj) { + return str.replace(/\{([^}]+)\}/g, function (match, group) { + var undef, + escape = true; + + if (group.charAt(0) === '!') { + escape = false; + group = group.substring(1); + } + + if (group === '0') { + escape = false; + } + + if (obj[group] === undef) { + return match; + } + + return escape ? + escapeEntities(obj[group], true) : + obj[group]; + }); + }; + + /** + * Converts a number 0-255 to hex. + * + * Will return 00 if number is not a valid number. + * + * @param {Number} number + * @return {String} + * @private + */ + var toHex = function (number) { + number = parseInt(number, 10); + + if (isNaN(number)) { + return '00'; + } + + number = Math.max(0, Math.min(number, 255)).toString(16); + + return number.length < 2 ? '0' + number : number; + }; + + var _normaliseColour = function (colorStr) { + var match; + + colorStr = colorStr || '#000'; + + // rgb(n,n,n); + if ((match = + colorStr.match(/rgb\((\d{1,3}),\s*?(\d{1,3}),\s*?(\d{1,3})\)/i))) { + return '#' + + toHex(match[1]) + + toHex(match[2] - 0) + + toHex(match[3] - 0); + } + + // expand shorthand + if ((match = colorStr.match(/#([0-f])([0-f])([0-f])\s*?$/i))) { + return '#' + + match[1] + match[1] + + match[2] + match[2] + + match[3] + match[3]; + } + + return colorStr; + }; + + var bbcodes = { + // START_COMMAND: Bold + b: { + tags: { + b: null, + strong: null + }, + styles: { + // 401 is for FF 3.5 + 'font-weight': ['bold', 'bolder', '401', '700', '800', '900'] + }, + format: '[b]{0}[/b]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Italic + i: { + tags: { + i: null, + em: null + }, + styles: { + 'font-style': ['italic', 'oblique'] + }, + format: '[i]{0}[/i]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Underline + u: { + tags: { + u: null + }, + styles: { + 'text-decoration': ['underline'] + }, + format: '[u]{0}[/u]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Strikethrough + s: { + tags: { + s: null, + strike: null + }, + styles: { + 'text-decoration': ['line-through'] + }, + format: '[s]{0}[/s]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Subscript + sub: { + tags: { + sub: null + }, + format: '[sub]{0}[/sub]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Superscript + sup: { + tags: { + sup: null + }, + format: '[sup]{0}[/sup]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Font + font: { + tags: { + font: { + face: null + } + }, + styles: { + 'font-family': null + }, + quoteType: BBCodeParser.QuoteType.never, + format: function ($element, content) { + var font; + + if (!$element.is('font') || !(font = $element.attr('face'))) { + font = $element.css('font-family'); + } + + return '[font=' + _stripQuotes(font) + ']' + + content + '[/font]'; + }, + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Size + size: { + tags: { + font: { + size: null + } + }, + styles: { + 'font-size': null + }, + format: function (element, content) { + var fontSize = element.attr('size'), + size = 2; + + if (!fontSize) { + fontSize = element.css('fontSize'); + } + + // Most browsers return px value but IE returns 1-7 + if (fontSize.indexOf('px') > -1) { + // convert size to an int + fontSize = fontSize.replace('px', '') - 0; + + if (fontSize < 12) { + size = 1; + } + if (fontSize > 15) { + size = 3; + } + if (fontSize > 17) { + size = 4; + } + if (fontSize > 23) { + size = 5; + } + if (fontSize > 31) { + size = 6; + } + if (fontSize > 47) { + size = 7; + } + } else { + size = fontSize; + } + + return '[size=' + size + ']' + content + '[/size]'; + }, + html: '{!0}' + }, + // END_COMMAND + + // START_COMMAND: Color + color: { + tags: { + font: { + color: null + } + }, + styles: { + color: null + }, + quoteType: BBCodeParser.QuoteType.never, + format: function ($element, content) { + var color; + + if (!$element.is('font') || !(color = $element.attr('color'))) { + color = $element[0].style.color || $element.css('color'); + } + + return '[color=' + _normaliseColour(color) + ']' + + content + '[/color]'; + }, + html: function (token, attrs, content) { + return '' + content + ''; + } + }, + // END_COMMAND + + // START_COMMAND: Lists + ul: { + tags: { + ul: null + }, + breakStart: true, + isInline: false, + skipLastLineBreak: true, + format: '[ul]{0}[/ul]', + html: '
      {0}
    ' + }, + list: { + breakStart: true, + isInline: false, + skipLastLineBreak: true, + html: '
      {0}
    ' + }, + ol: { + tags: { + ol: null + }, + breakStart: true, + isInline: false, + skipLastLineBreak: true, + format: '[ol]{0}[/ol]', + html: '
      {0}
    ' + }, + li: { + tags: { + li: null + }, + isInline: false, + closedBy: ['/ul', '/ol', '/list', '*', 'li'], + format: '[li]{0}[/li]', + html: '
  • {0}
  • ' + }, + '*': { + isInline: false, + closedBy: ['/ul', '/ol', '/list', '*', 'li'], + html: '
  • {0}
  • ' + }, + // END_COMMAND + + // START_COMMAND: Table + table: { + tags: { + table: null + }, + isInline: false, + isHtmlInline: true, + skipLastLineBreak: true, + format: '[table]{0}[/table]', + html: '{0}
    ' + }, + tr: { + tags: { + tr: null + }, + isInline: false, + skipLastLineBreak: true, + format: '[tr]{0}[/tr]', + html: '{0}' + }, + th: { + tags: { + th: null + }, + allowsEmpty: true, + isInline: false, + format: '[th]{0}[/th]', + html: '{0}' + }, + td: { + tags: { + td: null + }, + allowsEmpty: true, + isInline: false, + format: '[td]{0}[/td]', + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Emoticons + emoticon: { + allowsEmpty: true, + tags: { + img: { + src: null, + 'data-sceditor-emoticon': null + } + }, + format: function ($elm, content) { + return $elm.data('sceditor-emoticon') + content; + }, + html: '{0}' + }, + // END_COMMAND + + // START_COMMAND: Horizontal Rule + hr: { + tags: { + hr: null + }, + allowsEmpty: true, + isSelfClosing: true, + isInline: false, + format: '[hr]{0}', + html: '
    ' + }, + // END_COMMAND + + // START_COMMAND: Image + img: { + allowsEmpty: true, + tags: { + img: { + src: null + } + }, + allowedChildren: ['#'], + quoteType: BBCodeParser.QuoteType.never, + format: function ($element, content) { + var width, height, + attribs = '', + element = $element[0], + style = function (name) { + return element.style ? element.style[name] : null; + }; + + // check if this is an emoticon image + if ($element.attr('data-sceditor-emoticon')) { + return content; + } + + width = $element.attr('width') || style('width'); + height = $element.attr('height') || style('height'); + + // only add width and height if one is specified + if ((element.complete && (width || height)) || + (width && height)) { + attribs = '=' + $element.width() + 'x' + $element.height(); + } + + return '[img' + attribs + ']' + $element.attr('src') + '[/img]'; + }, + html: function (token, attrs, content) { + var undef, width, height, match, + attribs = ''; + + // handle [img width=340 height=240]url[/img] + width = attrs.width; + height = attrs.height; + + // handle [img=340x240]url[/img] + if (attrs.defaultattr) { + match = attrs.defaultattr.split(/x/i); + + width = match[0]; + height = (match.length === 2 ? match[1] : match[0]); + } + + if (width !== undef) { + attribs += ' width="' + escapeEntities(width, true) + '"'; + } + + if (height !== undef) { + attribs += ' height="' + escapeEntities(height, true) + '"'; + } + + return ''; + } + }, + // END_COMMAND + + // START_COMMAND: URL + url: { + allowsEmpty: true, + tags: { + a: { + href: null + } + }, + quoteType: BBCodeParser.QuoteType.never, + format: function (element, content) { + var url = element.attr('href'); + + // make sure this link is not an e-mail, + // if it is return e-mail BBCode + if (url.substr(0, 7) === 'mailto:') { + return '[email="' + url.substr(7) + '"]' + + content + '[/email]'; + } + + return '[url=' + url + ']' + content + '[/url]'; + }, + html: function (token, attrs, content) { + attrs.defaultattr = + escapeEntities(attrs.defaultattr, true) || content; + + return '' + content + ''; + } + }, + // END_COMMAND + + // START_COMMAND: E-mail + email: { + quoteType: BBCodeParser.QuoteType.never, + html: function (token, attrs, content) { + return '' + content + ''; + } + }, + // END_COMMAND + + // START_COMMAND: Quote + quote: { + tags: { + blockquote: null + }, + isInline: false, + quoteType: BBCodeParser.QuoteType.never, + format: function (element, content) { + var author = ''; + var $elm = $(element); + var $cite = $elm.children('cite').first(); + + if ($cite.length === 1 || $elm.data('author')) { + author = $cite.text() || $elm.data('author'); + + $elm.data('author', author); + $cite.remove(); + + content = this.elementToBbcode($(element)); + author = '=' + author.replace(/(^\s+|\s+$)/g, ''); + + $elm.prepend($cite); + } + + return '[quote' + author + ']' + content + '[/quote]'; + }, + html: function (token, attrs, content) { + if (attrs.defaultattr) { + content = '' + escapeEntities(attrs.defaultattr) + + '' + content; + } + + return '
    ' + content + '
    '; + } + }, + // END_COMMAND + + // START_COMMAND: Code + code: { + tags: { + code: null + }, + isInline: false, + allowedChildren: ['#', '#newline'], + format: '[code]{0}[/code]', + html: '{0}' + }, + // END_COMMAND + + + // START_COMMAND: Left + left: { + styles: { + 'text-align': [ + 'left', + '-webkit-left', + '-moz-left', + '-khtml-left' + ] + }, + isInline: false, + format: '[left]{0}[/left]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // START_COMMAND: Centre + center: { + styles: { + 'text-align': [ + 'center', + '-webkit-center', + '-moz-center', + '-khtml-center' + ] + }, + isInline: false, + format: '[center]{0}[/center]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // START_COMMAND: Right + right: { + styles: { + 'text-align': [ + 'right', + '-webkit-right', + '-moz-right', + '-khtml-right' + ] + }, + isInline: false, + format: '[right]{0}[/right]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // START_COMMAND: Justify + justify: { + styles: { + 'text-align': [ + 'justify', + '-webkit-justify', + '-moz-justify', + '-khtml-justify' + ] + }, + isInline: false, + format: '[justify]{0}[/justify]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // START_COMMAND: YouTube + youtube: { + allowsEmpty: true, + tags: { + iframe: { + 'data-youtube-id': null + } + }, + format: function (element, content) { + element = element.attr('data-youtube-id'); + + return element ? '[youtube]' + element + '[/youtube]' : content; + }, + html: '' + }, + // END_COMMAND + + + // START_COMMAND: Rtl + rtl: { + styles: { + direction: ['rtl'] + }, + format: '[rtl]{0}[/rtl]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // START_COMMAND: Ltr + ltr: { + styles: { + direction: ['ltr'] + }, + format: '[ltr]{0}[/ltr]', + html: '
    {0}
    ' + }, + // END_COMMAND + + // this is here so that commands above can be removed + // without having to remove the , after the last one. + // Needed for IE. + ignore: {} + }; + + /** + * Static BBCode helper class + * @class command + * @name jQuery.plugins.bbcode.bbcode + */ + sceditorPlugins.bbcode.bbcode = + /** @lends jQuery.plugins.bbcode.bbcode */ + { + /** + * Gets a BBCode + * + * @param {String} name + * @return {Object|null} + * @since v1.3.5 + */ + get: function (name) { + return bbcodes[name] || null; + }, + + /** + *

    Adds a BBCode to the parser or updates an existing + * BBCode if a BBCode with the specified name already exists.

    + * + * @param {String} name + * @param {Object} bbcode + * @return {this|false} Returns false if name or bbcode is false + * @since v1.3.5 + */ + set: function (name, bbcode) { + if (!name || !bbcode) { + return false; + } + + // merge any existing command properties + bbcode = $.extend(bbcodes[name] || {}, bbcode); + + bbcode.remove = function () { + delete bbcodes[name]; + }; + + bbcodes[name] = bbcode; + + return this; + }, + + /** + * Renames a BBCode + * + * This does not change the format or HTML handling, those must be + * changed manually. + * + * @param {String} name [description] + * @param {String} newName [description] + * @return {this|false} + * @since v1.4.0 + */ + rename: function (name, newName) { + if (name in bbcodes) { + bbcodes[newName] = bbcodes[name]; + + delete bbcodes[name]; + } else { + return false; + } + + return this; + }, + + /** + * Removes a BBCode + * + * @param {String} name + * @return {this} + * @since v1.3.5 + */ + remove: function (name) { + if (name in bbcodes) { + delete bbcodes[name]; + } + + return this; + } + }; + + /** + * Deprecated, use plugins: option instead. I.e.: + * + * $('textarea').sceditor({ + * plugins: 'bbcode' + * }); + * + * @deprecated + */ + $.fn.sceditorBBCodePlugin = function (options) { + options = options || {}; + + if ($.isPlainObject(options)) { + options.plugins = (options.plugins || '') + 'bbcode'; + } + + return this.sceditor(options); + }; + + /** + * Converts CSS RGB and hex shorthand into hex + * + * @since v1.4.0 + * @param {String} colorStr + * @return {String} + * @deprecated + */ + sceditorPlugins.bbcode.normaliseColour = _normaliseColour; + sceditorPlugins.bbcode.formatString = _formatString; + sceditorPlugins.bbcode.stripQuotes = _stripQuotes; + sceditorPlugins.bbcode.bbcodes = bbcodes; + SCEditor.BBCodeParser = BBCodeParser; +})(jQuery, window, document); diff --git a/js/sceditor/development/plugins/format.js b/js/sceditor/development/plugins/format.js new file mode 100644 index 00000000..15129957 --- /dev/null +++ b/js/sceditor/development/plugins/format.js @@ -0,0 +1,127 @@ +/** + * SCEditor Paragraph Formatting Plugin + * http://www.sceditor.com/ + * + * Copyright (C) 2011-2013, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * @fileoverview SCEditor Paragraph Formatting Plugin + * @author Sam Clarke + * @requires jQuery + */ +(function ($) { + 'use strict'; + + $.sceditor.plugins.format = function () { + var base = this; + + /** + * Default tags + * @type {Object} + * @private + */ + var tags = { + p: 'Paragraph', + h1: 'Heading 1', + h2: 'Heading 2', + h3: 'Heading 3', + h4: 'Heading 4', + h5: 'Heading 5', + h6: 'Heading 6', + address: 'Address', + pre: 'Preformatted Text' + }; + + /** + * Private functions + * @private + */ + var insertTag, + formatCmd; + + + base.init = function () { + var opts = this.opts, + pOpts = opts.paragraphformat; + + // Don't enable if the BBCode plugin is enabled. + if (opts.plugins && opts.plugins.indexOf('bbcode') > -1) { + return; + } + + if (pOpts) { + if (pOpts.tags) { + tags = pOpts.tags; + } + + if (pOpts.excludeTags) { + $.each(pOpts.excludeTags, function (idx, val) { + delete tags[val]; + }); + } + } + + if (!this.commands.format) { + this.commands.format = { + exec: formatCmd, + txtExec: formatCmd, + tooltip: 'Format Paragraph' + }; + } + + if (opts.toolbar === $.sceditor.defaultOptions.toolbar) { + opts.toolbar = opts.toolbar.replace(',color,', + ',color,format,'); + } + }; + + /** + * Inserts the specified tag into the editor + * + * @param {sceditor} editor + * @param {string} tag + * @private + */ + insertTag = function (editor, tag) { + if (editor.sourceMode()) { + editor.insert('<' + tag + '>', ''); + } else { + editor.execCommand('formatblock', '<' + tag + '>'); + } + + }; + + /** + * Function for the exec and txtExec properties + * + * @param {node} caller + * @private + */ + formatCmd = function (caller) { + var editor = this, + $content = $('
    '); + + $.each(tags, function (tag, val) { + $( + '' + + (val.name || val) + '' + ).click(function () { + editor.closeDropDown(true); + + if (val.exec) { + val.exec(editor); + } else { + insertTag(editor, tag); + } + + return false; + }) + .appendTo($content); + }); + + editor.createDropDown(caller, 'format', $content); + }; + }; +})(jQuery); diff --git a/js/sceditor/development/plugins/undo.js b/js/sceditor/development/plugins/undo.js new file mode 100644 index 00000000..7abedbf4 --- /dev/null +++ b/js/sceditor/development/plugins/undo.js @@ -0,0 +1,187 @@ +(function ($) { + 'use strict'; + + $.sceditor.plugins.undo = function () { + var base = this; + var editor; + var charChangedCount = 0; + var previousValue; + + var undoLimit = 50; + var redoStates = []; + var undoStates = []; + var ignoreNextValueChanged = false; + + /** + * Sets the editor to the specified state. + * + * @param {Object} state + * @private + */ + var applyState = function (state) { + ignoreNextValueChanged = true; + + previousValue = state.value; + + editor.sourceMode(state.sourceMode); + editor.val(state.value, false); + editor.focus(); + + if (state.sourceMode) { + editor.sourceEditorCaret(state.caret); + } else { + editor.getRangeHelper().restoreRange(); + } + + ignoreNextValueChanged = false; + }; + + + /** + * Caluclates the number of characters that have changed + * between two strings. + * + * @param {String} strA + * @param {String} strB + * @return {String} + * @private + */ + var simpleDiff = function (strA, strB) { + var start, end, aLenDiff, bLenDiff, + aLength = strA.length, + bLength = strB.length, + length = Math.max(aLength, bLength); + + // Calculate the start + for (start = 0; start < length; start++) { + if (strA.charAt(start) !== strB.charAt(start)) { + break; + } + } + + // Calculate the end + aLenDiff = aLength < bLength ? bLength - aLength : 0; + bLenDiff = bLength < aLength ? aLength - bLength : 0; + + for (end = length - 1; end >= 0; end--) { + if (strA.charAt(end - aLenDiff) !== + strB.charAt(end - bLenDiff)) { + break; + } + } + + return (end - start) + 1; + }; + + base.init = function () { + // The this variable will be set to the instance of the editor + // calling it, hence why the plugins "this" is saved to the base + // variable. + editor = this; + + undoLimit = editor.undoLimit || undoLimit; + + // addShortcut is the easiest way to add handlers to specific + // shortcuts + editor.addShortcut('ctrl+z', base.undo); + editor.addShortcut('ctrl+shift+z', base.redo); + editor.addShortcut('ctrl+y', base.redo); + }; + + base.undo = function () { + var state = undoStates.pop(); + var rawEditorValue = editor.val(null, false); + + if (state && !redoStates.length && rawEditorValue === state.value) { + state = undoStates.pop(); + } + + if (state) { + if (!redoStates.length) { + redoStates.push({ + 'caret': editor.sourceEditorCaret(), + 'sourceMode': editor.sourceMode(), + 'value': rawEditorValue + }); + } + + redoStates.push(state); + applyState(state); + } + + return false; + }; + + base.redo = function () { + var state = redoStates.pop(); + + if (!undoStates.length) { + undoStates.push(state); + state = redoStates.pop(); + } + + if (state) { + undoStates.push(state); + applyState(state); + } + + return false; + }; + + base.signalReady = function () { + var rawValue = editor.val(null, false); + + // Store the initial value as the last value + previousValue = rawValue; + + undoStates.push({ + 'caret': this.sourceEditorCaret(), + 'sourceMode': this.sourceMode(), + 'value': rawValue + }); + }; + + /** + * Handle the valueChanged signal. + * + * e.rawValue will either be the raw HTML from the WYSIWYG editor with + * the rangeHelper range markers inserted, or it will be the raw value + * of the source editor (BBCode or HTML depening on plugins). + * @return {void} + */ + base.signalValuechangedEvent = function (e) { + var rawValue = e.rawValue; + + if (undoLimit > 0 && undoStates.length > undoLimit) { + undoStates.shift(); + } + + // If the editor hasn't fully loaded yet, + // then the previous value won't be set. + if (ignoreNextValueChanged || !previousValue || + previousValue === rawValue) { + return; + } + + // Value has changed so remove all redo states + redoStates.length = 0; + charChangedCount += simpleDiff(previousValue, rawValue); + + if (charChangedCount < 20) { + return; + // ?? + } else if (charChangedCount < 50 && !/\s$/g.test(e.rawValue)) { + return; + } + + undoStates.push({ + 'caret': editor.sourceEditorCaret(), + 'sourceMode': editor.sourceMode(), + 'value': rawValue + }); + + charChangedCount = 0; + previousValue = rawValue; + }; + }; +}(jQuery)); diff --git a/js/sceditor/development/plugins/xhtml.js b/js/sceditor/development/plugins/xhtml.js new file mode 100644 index 00000000..7ba03e5f --- /dev/null +++ b/js/sceditor/development/plugins/xhtml.js @@ -0,0 +1,1319 @@ +/** + * SCEditor XHTML Plugin + * http://www.sceditor.com/ + * + * Copyright (C) 2011-2013, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * @author Sam Clarke + * @requires jQuery + */ +/*global prompt: true*/ +(function ($) { + 'use strict'; + + var SCEditor = $.sceditor; + var sceditorPlugins = SCEditor.plugins; + var dom = SCEditor.dom; + + var defaultCommandsOverrides = { + bold: { + txtExec: [ + '', + '' + ] + }, + italic: { + txtExec: [ + '', + '' + ] + }, + underline: { + txtExec: [ + '', + '' + ] + }, + strike: { + txtExec: [ + '', + '' + ] + }, + subscript: { + txtExec: [ + '', + '' + ] + }, + superscript: { + txtExec: [ + '', + '' + ] + }, + left: { + txtExec: [ + '
    ', + '
    ' + ] + }, + center: { + txtExec: [ + '
    ', + '
    ' + ] + }, + right: { + txtExec: [ + '
    ', + '
    ' + ] + }, + justify: { + txtExec: [ + '
    ', + '
    ' + ] + }, + font: { + txtExec: function (caller) { + var editor = this; + + SCEditor.command.get('font')._dropDown( + editor, + caller, + function (fontName) { + editor.insertText('', ''); + } + ); + } + }, + size: { + txtExec: function (caller) { + var editor = this; + + SCEditor.command.get('size')._dropDown( + editor, + caller, + function (fontSize) { + editor.insertText('', ''); + } + ); + } + }, + color: { + txtExec: function (caller) { + var editor = this; + + SCEditor.command.get('color')._dropDown( + editor, + caller, + function (color) { + editor.insertText('', ''); + } + ); + } + }, + bulletlist: { + txtExec: [ + '
    • ', + '
    ' + ] + }, + orderedlist: { + txtExec: [ + '
    1. ', + '
    ' + ] + }, + table: { + txtExec: [ + '
    ', + '
    ' + ] + }, + horizontalrule: { + txtExec: [ + '
    ' + ] + }, + code: { + txtExec: [ + '', + '' + ] + }, + image: { + txtExec: function (caller, selected) { + var url = prompt(this._('Enter the image URL:'), selected); + + if (url) { + this.insertText(''); + } + } + }, + email: { + txtExec: function (caller, sel) { + var email, text, + display = sel && sel.indexOf('@') > -1 ? null : sel; + + email = prompt( + this._('Enter the e-mail address:'), + (display ? '' : sel) + ); + + text = prompt( + this._('Enter the displayed text:'), + display || email + ) || email; + + if (email) { + this.insertText( + '' + text + '' + ); + } + } + }, + link: { + txtExec: function (caller, sel) { + var display = sel && sel.indexOf('http://') > -1 ? null : sel, + url = prompt(this._('Enter URL:'), + (display ? 'http://' : sel)), + text = prompt(this._('Enter the displayed text:'), + display || url) || url; + + if (url) { + this.insertText( + '' + text + '' + ); + } + } + }, + quote: { + txtExec: [ + '
    ', + '
    ' + ] + }, + youtube: { + txtExec: function (caller) { + var editor = this; + + SCEditor.command.get('youtube')._dropDown( + editor, + caller, + function (id) { + editor.insertText( + '' + ); + } + ); + } + }, + rtl: { + txtExec: [ + '
    ', + '
    ' + ] + }, + ltr: { + txtExec: [ + '
    ', + '
    ' + ] + } + }; + + /** + * XHTMLSerializer part of the XHTML plugin. + * + * @class XHTMLSerializer + * @name jQuery.sceditor.XHTMLSerializer + * @since v1.4.1 + */ + SCEditor.XHTMLSerializer = function () { + var base = this; + + var opts = { + indentStr: '\t' + }; + + /** + * Array containing the output, used as it's faster + * than string concatenation in slow browsers. + * @type {Array} + * @private + */ + var outputStringBuilder = []; + + /** + * Current indention level + * @type {Number} + * @private + */ + var currentIndent = 0; + + /** + * @private + */ + var escapeEntites, + trim, + serializeNode, + handleDoc, + handleElement, + handleCdata, + handleComment, + handleText, + output, + canIndent; +// TODO: use escape.entities + /** + * Escapes XHTML entities + * + * @param {String} str + * @return {String} + * @private + */ + escapeEntites = function (str) { + var entites = { + '&': '&', + '<': '<', + '>': '>', + '"': '"' + }; + + return !str ? '' : str.replace(/[&<>"]/g, function (entity) { + return entites[entity] || entity; + }); + }; + + /** + * @param {string} str + * @return {string} + * @private + */ + trim = function (str) { + return str + // New lines will be shown as spaces so just convert to spaces. + .replace(/[\r\n]/, ' ') + .replace(/[^\S|\u00A0]+/g, ' '); + }; + + /** + * Serializes a node to XHTML + * + * @param {Node} node Node to serialize + * @param {Boolean} onlyChildren If to only serialize the nodes + * children and not the node + * itself + * @return {String} The serialized node + * @name serialize + * @memberOf jQuery.sceditor.XHTMLSerializer.prototype + * @since v1.4.1 + */ + base.serialize = function (node, onlyChildren) { + outputStringBuilder = []; + + if (onlyChildren) { + node = node.firstChild; + + while (node) { + serializeNode(node); + node = node.nextSibling; + } + } else { + serializeNode(node); + } + + return outputStringBuilder.join(''); + }; + + /** + * Serializes a node to the outputStringBuilder + * + * @param {Node} node + * @return {Void} + * @private + */ + serializeNode = function (node, parentIsPre) { + switch (node.nodeType) { + case 1: // element + var tagName = node.nodeName.toLowerCase(); + + // IE comment + if (tagName === '!') { + handleComment(node); + } else { + handleElement(node, parentIsPre); + } + break; + + case 3: // text + handleText(node, parentIsPre); + break; + + case 4: // cdata section + handleCdata(node); + break; + + case 8: // comment + handleComment(node); + break; + + case 9: // document + case 11: // document fragment + handleDoc(node); + break; + + // Ignored types + case 2: // attribute + case 5: // entity ref + case 6: // entity + case 7: // processing instruction + case 10: // document type + case 12: // notation + break; + } + }; + + /** + * Handles doc node + * @param {Node} node + * @return {void} + * @private + */ + handleDoc = function (node) { + var child = node.firstChild; + + while (child) { + serializeNode(child); + child = child.nextSibling; + } + }; + + /** + * Handles element nodes + * @param {Node} node + * @return {void} + * @private + */ + handleElement = function (node, parentIsPre) { + var child, attr, attrValue, + tagName = node.nodeName.toLowerCase(), + isIframe = tagName === 'iframe', + attrIdx = node.attributes.length, + firstChild = node.firstChild, + // pre || pre-wrap with any vendor prefix + isPre = parentIsPre || + /pre(?:\-wrap)?$/i.test($(node).css('whiteSpace')), + selfClosing = !node.firstChild && !dom.canHaveChildren(node) && + !isIframe; + + if ($(node).hasClass('sceditor-ignore')) { + return; + } + + output('<' + tagName, !parentIsPre && canIndent(node)); + while (attrIdx--) { + attr = node.attributes[attrIdx]; + + // IE < 8 returns all possible attributes not just specified + // ones. IE < 8 also doesn't say value on input is specified + // so just assume it is. + if (!SCEditor.ie || attr.specified || + (tagName === 'input' && attr.name === 'value')) { + // IE < 8 doesn't return the CSS for the style attribute + if (SCEditor.ie < 8 && /style/i.test(attr.name)) { + attrValue = node.style.cssText; + } else { + attrValue = attr.value; + } + + output(' ' + attr.name.toLowerCase() + '="' + + escapeEntites(attrValue) + '"', false); + } + } + output(selfClosing ? ' />' : '>', false); + + if (!isIframe) { + child = firstChild; + } + + while (child) { + currentIndent++; + + serializeNode(child, isPre); + child = child.nextSibling; + + currentIndent--; + } + + if (!selfClosing) { + output( + '', + !isPre && !isIframe && canIndent(node) && + firstChild && canIndent(firstChild) + ); + } + }; + + /** + * Handles CDATA nodes + * @param {Node} node + * @return {void} + * @private + */ + handleCdata = function (node) { + output(''); + }; + + /** + * Handles comment nodes + * @param {Node} node + * @return {void} + * @private + */ + handleComment = function (node) { + output(''); + }; + + /** + * Handles text nodes + * @param {Node} node + * @return {void} + * @private + */ + handleText = function (node, parentIsPre) { + var text = node.nodeValue; + + if (!parentIsPre) { + text = trim(text); + } + + if (text) { + output(escapeEntites(text), !parentIsPre && canIndent(node)); + } + }; + + /** + * Adds a string to the outputStringBuilder. + * + * The string will be indented unless indent is set to boolean false. + * @param {String} str + * @param {Boolean} indent + * @return {void} + * @private + */ + output = function (str, indent) { + var i = currentIndent; + + if (indent !== false) { + // Don't add a new line if it's the first element + if (outputStringBuilder.length) { + outputStringBuilder.push('\n'); + } + + while (i--) { + outputStringBuilder.push(opts.indentStr); + } + } + + outputStringBuilder.push(str); + }; + + /** + * Checks if should indent the node or not + * @param {Node} node + * @return {boolean} + * @private + */ + canIndent = function (node) { + var prev = node.previousSibling; + + if (node.nodeType !== 1 && prev) { + return !dom.isInline(prev); + } + + // first child of a block element + if (!prev && !dom.isInline(node.parentNode)) { + return true; + } + + return !dom.isInline(node); + }; + }; + + /** + * SCEditor XHTML plugin + * @class xhtml + * @name jQuery.sceditor.plugins.xhtml + * @since v1.4.1 + */ + sceditorPlugins.xhtml = function () { + var base = this; + + /** + * Tag converstions cache + * @type {Object} + * @private + */ + var tagConvertersCache = {}; + + /** + * Attributes filter cache + * @type {Object} + * @private + */ + var attrsCache = {}; + + /** + * Private methods + * @private + */ + var convertTags, + convertNode, + isEmpty, + removeTags, + mergeAttribsFilters, + removeAttribs, + wrapInlines; + + + /** + * Init + * @return {void} + */ + base.init = function () { + if (!$.isEmptyObject(sceditorPlugins.xhtml.converters || {})) { + $.each( + sceditorPlugins.xhtml.converters, + function (idx, converter) { + $.each(converter.tags, function (tagname) { + if (!tagConvertersCache[tagname]) { + tagConvertersCache[tagname] = []; + } + + tagConvertersCache[tagname].push(converter); + }); + } + ); + } + + this.commands = $.extend(true, + {}, defaultCommandsOverrides, this.commands); + }; + + /** + * Converts the WYSIWYG content to XHTML + * @param {String} html + * @param {Node} domBody + * @return {String} + * @memberOf jQuery.sceditor.plugins.xhtml.prototype + */ + base.signalToSource = function (html, domBody) { + domBody = domBody.jquery ? domBody[0] : domBody; + + convertTags(domBody); + removeTags(domBody); + removeAttribs(domBody); + wrapInlines(domBody); + + return (new SCEditor.XHTMLSerializer()).serialize(domBody, true); + }; + + /** + * Converts the XHTML to WYSIWYG content. + * + * This doesn't currently do anything as XHTML + * is valid WYSIWYG content. + * @param {String} text + * @return {String} + * @memberOf jQuery.sceditor.plugins.xhtml.prototype + */ + base.signalToWysiwyg = function (text) { + return text; + }; + + /** + * Deprecated, use dom.convertElement() instead. + * @deprecated + */ + base.convertTagTo = dom.convertElement; + + /** + * Runs all converters for the specified tagName + * against the DOM node. + * @param {String} tagName + * @param {jQuery} $node + * @return {Node} node + * @private + */ + convertNode = function (tagName, $node, node) { + if (!tagConvertersCache[tagName]) { + return; + } + + $.each(tagConvertersCache[tagName], function (idx, converter) { + if (converter.tags[tagName]) { + $.each(converter.tags[tagName], function (attr, values) { + if (!node.getAttributeNode) { + return; + } + + attr = node.getAttributeNode(attr); + + // IE < 8 always returns an attribute regardless of if + // it has been specified so must check it. + if (!attr || (SCEditor.ie < 8 && !attr.specified)) { + return; + } + + if (values && $.inArray(attr.value, values) < 0) { + return; + } + + converter.conv.call(base, node, $node); + }); + } else if (converter.conv) { + converter.conv.call(base, node, $node); + } + }); + }; + + /** + * Converts any tags/attributes to their XHTML equivalents + * @param {Node} node + * @return {Void} + * @private + */ + convertTags = function (node) { + dom.traverse(node, function (node) { + var $node = $(node), + tagName = node.nodeName.toLowerCase(); + + convertNode('*', $node, node); + convertNode(tagName, $node, node); + }, true); + }; + + /** + * Tests if a node is empty and can be removed. + * + * @param {Node} node + * @return {Boolean} + * @private + */ + isEmpty = function (node, excludeBr) { + var childNodes = node.childNodes, + tagName = node.nodeName.toLowerCase(), + nodeValue = node.nodeValue, + childrenLength = childNodes.length; + + if (excludeBr && tagName === 'br') { + return true; + } + + if ($(node).hasClass('sceditor-ignore')) { + return true; + } + + if (!dom.canHaveChildren(node)) { + return false; + } + + // \S|\u00A0 = any non space char + if (nodeValue && /\S|\u00A0/.test(nodeValue)) { + return false; + } + + while (childrenLength--) { + if (!isEmpty(childNodes[childrenLength], + excludeBr && !node.previousSibling && !node.nextSibling)) { + return false; + } + } + + return true; + }; + + /** + * Removes any tags that are not white listed or if no + * tags are white listed it will remove any tags that + * are black listed. + * + * @param {Node} rootNode + * @return {Void} + * @private + */ + removeTags = function (rootNode) { + dom.traverse(rootNode, function (node) { + var remove, + tagName = node.nodeName.toLowerCase(), + parentNode = node.parentNode, + nodeType = node.nodeType, + isBlock = !dom.isInline(node), + previousSibling = node.previousSibling, + nextSibling = node.nextSibling, + isTopLevel = parentNode === rootNode, + noSiblings = !previousSibling && !nextSibling, + empty = tagName !== 'iframe' && isEmpty(node, + isTopLevel && noSiblings && tagName !== 'br'), + document = node.ownerDocument, + allowedtags = sceditorPlugins.xhtml.allowedTags, + disallowedTags = sceditorPlugins.xhtml.disallowedTags; + + // 3 = text node + if (nodeType === 3) { + return; + } + + if (nodeType === 4) { + tagName = '!cdata'; + } else if (tagName === '!' || nodeType === 8) { + tagName = '!comment'; + } + + if (empty) { + remove = true; + // 3 is text node which do not get filtered + } else if (allowedtags && allowedtags.length) { + remove = ($.inArray(tagName, allowedtags) < 0); + } else if (disallowedTags && disallowedTags.length) { + remove = ($.inArray(tagName, disallowedTags) > -1); + } + + if (remove) { + if (!empty) { + if (isBlock && previousSibling && + dom.isInline(previousSibling)) { + parentNode.insertBefore( + document.createTextNode(' '), node); + } + + // Insert all the childen after node + while (node.firstChild) { + parentNode.insertBefore(node.firstChild, + nextSibling); + } + + if (isBlock && nextSibling && + dom.isInline(nextSibling)) { + parentNode.insertBefore( + document.createTextNode(' '), nextSibling); + } + } + + parentNode.removeChild(node); + } + }, true); + }; + + /** + * Merges two sets of attribute filters into one + * + * @param {Object} filtersA + * @param {Object} filtersB + * @return {Object} + * @private + */ + mergeAttribsFilters = function (filtersA, filtersB) { + var ret = {}; + + if (filtersA) { + $.extend(ret, filtersA); + } + + if (!filtersB) { + return ret; + } + + $.each(filtersB, function (attrName, values) { + if ($.isArray(values)) { + ret[attrName] = $.merge(ret[attrName] || [], values); + } else if (!ret[attrName]) { + ret[attrName] = null; + } + }); + + return ret; + }; + + /** + * Wraps adjacent inline child nodes of root + * in paragraphs. + * + * @param {Node} root + * @private + */ + wrapInlines = function (root) { + var adjacentInlines = []; + var wrapAdjacents = function () { + if (adjacentInlines.length) { + $('

    ', root.ownerDocument) + .insertBefore(adjacentInlines[0]) + .append(adjacentInlines); + + adjacentInlines = []; + } + }; + + // Strip empty text nodes so they don't get wrapped. + dom.removeWhiteSpace(root); + + var node = root.firstChild; + while (node) { + if (dom.isInline(node) && !$(node).is('.sceditor-ignore')) { + adjacentInlines.push(node); + } else { + wrapAdjacents(); + } + + node = node.nextSibling; + } + + wrapAdjacents(); + }; + + /** + * Removes any attributes that are not white listed or + * if no attributes are white listed it will remove + * any attributes that are black listed. + * @param {Node} node + * @return {Void} + * @private + */ + removeAttribs = function (node) { + var tagName, attr, attrName, attrsLength, validValues, remove, + allowedAttribs = sceditorPlugins.xhtml.allowedAttribs, + isAllowed = allowedAttribs && + !$.isEmptyObject(allowedAttribs), + disallowedAttribs = sceditorPlugins.xhtml.disallowedAttribs, + isDisallowed = disallowedAttribs && + !$.isEmptyObject(disallowedAttribs); + + attrsCache = {}; + + dom.traverse(node, function (node) { + if (!node.attributes) { + return; + } + + tagName = node.nodeName.toLowerCase(); + attrsLength = node.attributes.length; + + if (attrsLength) { + if (!attrsCache[tagName]) { + if (isAllowed) { + attrsCache[tagName] = mergeAttribsFilters( + allowedAttribs['*'], + allowedAttribs[tagName] + ); + } else { + attrsCache[tagName] = mergeAttribsFilters( + disallowedAttribs['*'], + disallowedAttribs[tagName] + ); + } + } + + while (attrsLength--) { + attr = node.attributes[attrsLength]; + attrName = attr.name; + validValues = attrsCache[tagName][attrName]; + remove = false; + + if (isAllowed) { + remove = validValues !== null && + (!$.isArray(validValues) || + $.inArray(attr.value, validValues) < 0); + } else if (isDisallowed) { + remove = validValues === null || + ($.isArray(validValues) && + $.inArray(attr.value, validValues) > -1); + } + + if (remove) { + node.removeAttribute(attrName); + } + } + } + }); + }; + }; + + /** + * Tag conveters, a converter is applied to all + * tags that match the criteria. + * @type {Array} + * @name jQuery.sceditor.plugins.xhtml.converters + * @since v1.4.1 + */ + sceditorPlugins.xhtml.converters = [ + { + tags: { + '*': { + width: null + } + }, + conv: function (node, $node) { + $node.css('width', $node.attr('width')).removeAttr('width'); + } + }, + { + tags: { + '*': { + height: null + } + }, + conv: function (node, $node) { + $node.css('height', $node.attr('height')).removeAttr('height'); + } + }, + { + tags: { + 'li': { + value: null + } + }, + conv: function (node, $node) { + if (SCEditor.ie < 8) { + node.removeAttribute('value'); + } else { + $node.removeAttr('value'); + } + } + }, + { + tags: { + '*': { + text: null + } + }, + conv: function (node, $node) { + $node.css('color', $node.attr('text')).removeAttr('text'); + } + }, + { + tags: { + '*': { + color: null + } + }, + conv: function (node, $node) { + $node.css('color', $node.attr('color')).removeAttr('color'); + } + }, + { + tags: { + '*': { + face: null + } + }, + conv: function (node, $node) { + $node.css('fontFamily', $node.attr('face')).removeAttr('face'); + } + }, + { + tags: { + '*': { + align: null + } + }, + conv: function (node, $node) { + $node.css('textAlign', $node.attr('align')).removeAttr('align'); + } + }, + { + tags: { + '*': { + border: null + } + }, + conv: function (node, $node) { + $node + .css('borderWidth',$node.attr('border')) + .removeAttr('border'); + } + }, + { + tags: { + applet: { + name: null + }, + img: { + name: null + }, + layer: { + name: null + }, + map: { + name: null + }, + object: { + name: null + }, + param: { + name: null + } + }, + conv: function (node, $node) { + if (!$node.attr('id')) { + $node.attr('id', $node.attr('name')); + } + + $node.removeAttr('name'); + } + }, + { + tags: { + '*': { + vspace: null + } + }, + conv: function (node, $node) { + $node + .css('marginTop', $node.attr('vspace') - 0) + .css('marginBottom', $node.attr('vspace') - 0) + .removeAttr('vspace'); + } + }, + { + tags: { + '*': { + hspace: null + } + }, + conv: function (node, $node) { + $node + .css('marginLeft', $node.attr('hspace') - 0) + .css('marginRight', $node.attr('hspace') - 0) + .removeAttr('hspace'); + } + }, + { + tags: { + 'hr': { + noshade: null + } + }, + conv: function (node, $node) { + $node.css('borderStyle', 'solid').removeAttr('noshade'); + } + }, + { + tags: { + '*': { + nowrap: null + } + }, + conv: function (node, $node) { + $node.css('white-space', 'nowrap').removeAttr('nowrap'); + } + }, + { + tags: { + big: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'span')).css('fontSize', 'larger'); + } + }, + { + tags: { + small: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'span')).css('fontSize', 'smaller'); + } + }, + { + tags: { + b: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'strong')); + } + }, + { + tags: { + u: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'span')) + .css('textDecoration', 'underline'); + } + }, + { + tags: { + i: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'em')); + } + }, + { + tags: { + s: null, + strike: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'span')) + .css('textDecoration', 'line-through'); + } + }, + { + tags: { + dir: null + }, + conv: function (node) { + this.convertTagTo(node, 'ul'); + } + }, + { + tags: { + center: null + }, + conv: function (node) { + $(this.convertTagTo(node, 'div')) + .css('textAlign', 'center'); + } + }, + { + tags: { + font: { + size: null + } + }, + conv: function (node, $node) { + var size = $node.css('fontSize'), + fontSize = size; + + // IE < 8 sets a font tag with no size to +0 so + // should just skip it. + if (fontSize !== '+0') { + // IE 8 and below incorrectly returns the value of the size + // attribute instead of the px value so must convert it + if (SCEditor.ie < 9) { + fontSize = 10; + + if (size > 1) { + fontSize = 13; + } + if (size > 2) { + fontSize = 16; + } + if (size > 3) { + fontSize = 18; + } + if (size > 4) { + fontSize = 24; + } + if (size > 5) { + fontSize = 32; + } + if (size > 6) { + fontSize = 48; + } + } + + $node.css('fontSize', fontSize); + } + + $node.removeAttr('size'); + } + }, + { + tags: { + font: null + }, + conv: function (node) { + // All it's attributes will be converted + // by the attribute converters + this.convertTagTo(node, 'span'); + } + }, + { + tags: { + '*': { + type: ['_moz'] + } + }, + conv: function (node, $node) { + $node.removeAttr('type'); + } + }, + { + tags: { + '*': { + '_moz_dirty': null + } + }, + conv: function (node, $node) { + $node.removeAttr('_moz_dirty'); + } + }, + { + tags: { + '*': { + '_moz_editor_bogus_node': null + } + }, + conv: function (node, $node) { + $node.remove(); + } + } + ]; + + /** + * Allowed attributes map. + * + * To allow an attribute for all tags use * as the tag name. + * + * Leave empty or null to allow all attributes. (the disallow + * list will be used to filter them instead) + * @type {Object} + * @name jQuery.sceditor.plugins.xhtml.allowedAttribs + * @since v1.4.1 + */ + sceditorPlugins.xhtml.allowedAttribs = {}; + + /** + * Attributes that are not allowed. + * + * Only used if allowed attributes is null or empty. + * @type {Object} + * @name jQuery.sceditor.plugins.xhtml.disallowedAttribs + * @since v1.4.1 + */ + sceditorPlugins.xhtml.disallowedAttribs = {}; + + /** + * Array containing all the allowed tags. + * + * If null or empty all tags will be allowed. + * @type {Array} + * @name jQuery.sceditor.plugins.xhtml.allowedTags + * @since v1.4.1 + */ + sceditorPlugins.xhtml.allowedTags = []; + + /** + * Array containing all the disallowed tags. + * + * Only used if allowed tags is null or empty. + * @type {Array} + * @name jQuery.sceditor.plugins.xhtml.disallowedTags + * @since v1.4.1 + */ + sceditorPlugins.xhtml.disallowedTags = []; +}(jQuery)); diff --git a/js/sceditor/development/themes/default.css b/js/sceditor/development/themes/default.css new file mode 100644 index 00000000..b79d655d --- /dev/null +++ b/js/sceditor/development/themes/default.css @@ -0,0 +1,500 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */ +/** + * SCEditor + * http://www.ssceditor.com/ + * + * Copyright (C) 2011-12, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + */ +div.sceditor-grip, +.sceditor-button div { + background-image: url("famfamfam.png"); + background-repeat: no-repeat; + width: 16px; + height: 16px; +} +.sceditor-button-youtube div { + background-position: 0px 0px; +} +.sceditor-button-link div { + background-position: 0px -16px; +} +.sceditor-button-unlink div { + background-position: 0px -32px; +} +.sceditor-button-underline div { + background-position: 0px -48px; +} +.sceditor-button-time div { + background-position: 0px -64px; +} +.sceditor-button-table div { + background-position: 0px -80px; +} +.sceditor-button-superscript div { + background-position: 0px -96px; +} +.sceditor-button-subscript div { + background-position: 0px -112px; +} +.sceditor-button-strike div { + background-position: 0px -128px; +} +.sceditor-button-source div { + background-position: 0px -144px; +} +.sceditor-button-size div { + background-position: 0px -160px; +} +.sceditor-button-rtl div { + background-position: 0px -176px; +} +.sceditor-button-right div { + background-position: 0px -192px; +} +.sceditor-button-removeformat div { + background-position: 0px -208px; +} +.sceditor-button-quote div { + background-position: 0px -224px; +} +.sceditor-button-print div { + background-position: 0px -240px; +} +.sceditor-button-pastetext div { + background-position: 0px -256px; +} +.sceditor-button-paste div { + background-position: 0px -272px; +} +.sceditor-button-outdent div { + background-position: 0px -288px; +} +.sceditor-button-orderedlist div { + background-position: 0px -304px; +} +.sceditor-button-maximize div { + background-position: 0px -320px; +} +.sceditor-button-ltr div { + background-position: 0px -336px; +} +.sceditor-button-left div { + background-position: 0px -352px; +} +.sceditor-button-justify div { + background-position: 0px -368px; +} +.sceditor-button-italic div { + background-position: 0px -384px; +} +.sceditor-button-indent div { + background-position: 0px -400px; +} +.sceditor-button-image div { + background-position: 0px -416px; +} +.sceditor-button-horizontalrule div { + background-position: 0px -432px; +} +.sceditor-button-format div { + background-position: 0px -448px; +} +.sceditor-button-font div { + background-position: 0px -464px; +} +.sceditor-button-emoticon div { + background-position: 0px -480px; +} +.sceditor-button-email div { + background-position: 0px -496px; +} +.sceditor-button-date div { + background-position: 0px -512px; +} +.sceditor-button-cut div { + background-position: 0px -528px; +} +.sceditor-button-copy div { + background-position: 0px -544px; +} +.sceditor-button-color div { + background-position: 0px -560px; +} +.sceditor-button-code div { + background-position: 0px -576px; +} +.sceditor-button-center div { + background-position: 0px -592px; +} +.sceditor-button-bulletlist div { + background-position: 0px -608px; +} +.sceditor-button-bold div { + background-position: 0px -624px; +} +div.sceditor-grip { + background-position: 0px -640px; + width: 10px; + height: 10px; +} +.rtl div.sceditor-grip { + background-position: 0px -650px; + width: 10px; + height: 10px; +} +/** + * SCEditor + * http://www.ssceditor.com/ + * + * Copyright (C) 2011-12, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + */ +/*--------------------------------------------------- + LESS Elements 0.7 + --------------------------------------------------- + A set of useful LESS mixins + More info at: http://lesselements.com + ---------------------------------------------------*/ +.sceditor-container { + position: relative; + background: #fff; + border: 1px solid #d9d9d9; + font-size: 13px; + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + color: #222; + line-height: 1; + font-weight: bold; + border-radius: 4px; + background-clip: padding-box; +} +.sceditor-container *, +.sceditor-container *:before, +.sceditor-container *:after { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +.sceditor-container, +.sceditor-container div, +div.sceditor-dropdown, +div.sceditor-dropdown div { + padding: 0; + margin: 0; + z-index: 3; +} +.sceditor-container iframe, +.sceditor-container textarea { + line-height: 1; + border: 0; + outline: none; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 13px; + color: #111; + padding: 0; + margin: 5px; + resize: none; + background: #fff; + display: block; +} +div.sceditor-resize-cover { + position: absolute; + top: 0; + left: 0; + background: #000; + width: 100%; + height: 100%; + z-index: 10; + opacity: 0.3; +} +.ie6 div.sceditor-resize-cover, +.ie7 div.sceditor-resize-cover, +.ie8 div.sceditor-resize-cover { + background: #efefef; +} +.sceditor-container.ie6 { + overflow: hidden; +} +div.sceditor-grip { + overflow: hidden; + width: 10px; + height: 10px; + cursor: pointer; + position: absolute; + bottom: 0; + right: 0; + z-index: 3; +} +.sceditor-maximize { + position: fixed; + top: 0; + left: 0; + height: 100% !important; + width: 100% !important; + border-radius: 0; + background-clip: padding-box; + z-index: 2000; +} +html.sceditor-maximize, +body.sceditor-maximize { + height: 100%; + width: 100%; + padding: 0; + margin: 0; + overflow: hidden; +} +.ie6.sceditor-maximize { + position: absolute; +} +.sceditor-maximize div.sceditor-grip { + display: none; +} +.sceditor-maximize div.sceditor-toolbar { + border-radius: 0; + background-clip: padding-box; +} +/** + * Dropdown styleing + */ +div.sceditor-dropdown { + position: absolute; + border: 1px solid #ccc; + background: #fff; + color: #333; + z-index: 4000; + padding: 10px; + line-height: 1; + border-radius: 2px; + background-clip: padding-box; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.2); +} +div.sceditor-dropdown a, +div.sceditor-dropdown a:link { + color: #333; +} +div.sceditor-dropdown form { + margin: 0; +} +div.sceditor-dropdown label { + display: block; + font-weight: bold; + color: #3c3c3c; + padding: 4px 0; +} +div.sceditor-dropdown input, +div.sceditor-dropdown textarea { + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + outline: 0; + padding: 4px; + border: 1px solid #ccc; + border-top-color: #888; + margin: 0 0 .75em; + border-radius: 1px; + background-clip: padding-box; +} +div.sceditor-dropdown textarea { + padding: 6px; +} +div.sceditor-dropdown input:focus, +div.sceditor-dropdown textarea:focus { + border-color: #aaa; + border-top-color: #666; + box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.1); +} +div.sceditor-dropdown .button { + font-weight: bold; + color: #444; + padding: 6px 12px; + background: #ececec; + border: solid 1px #ccc; + border-radius: 2px; + background-clip: padding-box; + cursor: pointer; + margin: .3em 0 0; +} +div.sceditor-dropdown .button:hover { + background: #f3f3f3; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15); +} +div.sceditor-font-picker, +div.sceditor-fontsize-picker, +div.sceditor-format { + padding: 6px 0; +} +div.sceditor-emoticons, +div.sceditor-more-emoticons, +div.sceditor-color-picker { + padding: 0; +} +.sceditor-pastetext textarea { + border: 1px solid #bbb; + width: 20em; +} +.sceditor-emoticons img, +.sceditor-more-emoticons img { + padding: 0; + cursor: pointer; + margin: 2px; +} +.sceditor-more { + border-top: 1px solid #bbb; + display: block; + text-align: center; + cursor: pointer; + font-weight: bold; + padding: 6px 0; +} +.sceditor-dropdown a:hover { + background: #eee; +} +.sceditor-fontsize-option, +.sceditor-font-option, +.sceditor-format a { + display: block; + padding: 7px 10px; + cursor: pointer; + text-decoration: none; + color: #222; +} +.sceditor-fontsize-option { + padding: 7px 13px; +} +.sceditor-color-column { + float: left; +} +.sceditor-color-option { + display: block; + border: 1px solid #fff; + height: 10px; + width: 10px; + overflow: hidden; +} +.sceditor-color-option:hover { + border: 1px solid #333; +} +/** + * Toolbar styleing + */ +div.sceditor-toolbar { + overflow: hidden; + padding: 3px 5px 2px; + background: #f7f7f7; + border-bottom: 1px solid #c0c0c0; + line-height: 0; + text-align: left; + user-select: none; + border-radius: 3px 3px 0 0; + background-clip: padding-box; +} +div.sceditor-group { + display: inline-block; + background: #ddd; + margin: 1px 5px 1px 0; + padding: 1px; + border-bottom: 1px solid #aaa; + border-radius: 3px; + background-clip: padding-box; +} +.ie6 div.sceditor-group, +.ie7 div.sceditor-group { + display: inline; + zoom: 1; +} +.sceditor-button { + float: left; + cursor: pointer; + padding: 3px 5px; + width: 16px; + height: 20px; + border-radius: 3px; + background-clip: padding-box; + /* Needed for Safari 5? */ + text-indent: -9999px; +} +.ie .sceditor-button { + text-indent: 0; +} +.ie6 .sceditor-button, +.ie7 .sceditor-button { + float: none !important; + display: inline; + zoom: 1; +} +.ie6 .sceditor-button { + padding: 0; +} +.ie6 .sceditor-button div { + margin: 5px; +} +.ie7 .sceditor-button div { + margin: 5px 0; +} +.sceditor-button:hover, +.sceditor-button:active, +.sceditor-button.active { + background: #fff; + box-shadow: inset 1px 1px 0 rgba(0,0,0,0.3), inset -1px 0 rgba(0,0,0,0.3), inset 0 -1px 0 rgba(0,0,0,0.2); +} +.sceditor-button:active { + background: #fff; + box-shadow: inset 1px 1px 0 rgba(0,0,0,0.3), inset -1px 0 rgba(0,0,0,0.3), inset 0 -1px 0 rgba(0,0,0,0.2), inset 0 0 8px rgba(0,0,0,0.3); +} +.sceditor-button.disabled:hover { + background: inherit; + cursor: default; + box-shadow: none; +} +.sceditor-button, +.sceditor-button div { + display: block; +} +.sceditor-button div { + margin: 2px 0; + padding: 0; + overflow: hidden; + line-height: 0; + font-size: 0; + color: transparent; +} +.sceditor-button.disabled div { + filter: alpha(opacity=30); + opacity: 0.3; +} +.text .sceditor-button, +.text .sceditor-button div, +.sceditor-button.text, +.sceditor-button.text div, +.text-icon .sceditor-button, +.text-icon .sceditor-button div, +.sceditor-button.text-icon, +.sceditor-button.text-icon div { + width: auto; + overflow: visible; + line-height: 16px; + font-size: 1em; + color: inherit; + text-indent: 0; +} +.text .sceditor-button div, +.sceditor-button.text div { + padding: 0 2px; + background: none; +} +.text-icon .sceditor-button div, +.sceditor-button.text-icon div { + padding: 0 2px 0 20px; +} +.rtl div.sceditor-toolbar { + text-align: right; +} +.rtl .sceditor-button { + float: right; +} +.rtl div.sceditor-grip { + right: auto; + left: 0; +} diff --git a/js/sceditor/development/themes/famfamfam.png b/js/sceditor/development/themes/famfamfam.png new file mode 100644 index 0000000000000000000000000000000000000000..c95ef4acda121fdda34d1944ca54d973ffa80718 GIT binary patch literal 11682 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 literal 0 HcmV?d00001 diff --git a/js/sceditor/development/themes/monocons/monocons.ttf b/js/sceditor/development/themes/monocons/monocons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d100abdf72a460aa813066000555d43240e47ded GIT binary patch literal 7860 zcmds6Yiu0Xb-rg_cV}iFGy57omf|djHYQEZTJ~hm`~R9j`3OvQ<%H zBsrB`$KBZZ;RFz1IH_S6fw5H(H*qV#NDZ`bTV$Ibu8r7@iXbkUq}8@4>>}t76^>gp zXqNr%>?}>a+SET?s*L(##oFsnaq|J7eBr4$kQL4WNg!m=*``7 z^WH^v57W>-gSPvrJ7>$YfBchC#^`Remk+KSSnVAA@CS@Z4fO3la^TeJ+8QviO{;hw zIdbgrhu=4zd6qH7V$6v=a`?cZe?Rn<&*0flP->5$L$O&D@21fne`MwKnfDyS3;0zOF)oYZhUE-k4y72j#n^svFBgkTZE5P6$3xX%%t^aUi-~ZqG7+YoEW=g0V$Bhko9ma;<95O?s-s{eh{e0cwi-8f&+yC1B8pd!x}1 zI5=z2zfpq?v%0{+HLhjSPS(lppsF`FS)HuT)#qx}O0|-yq_df9Ce71Y#>-U7^;*4F zohwWhCOv;3&J~V-e4zPRNmZrK_QA&ws4);txtpg)lhHw+Bq=*F?nn~(8|#D7q!^Kk zLQ6pQe8^Cn+Ne*k&6r)u31;SGd&EJ$;9)+PGS|k$L<*A&Bxmx~21O#al}qp3mC0F_ zuG3ALrW^6dawKjTs(OH$)PBz$7*5*JNF-_}hlfYrdn=nt8m21Cs%a#x!MD0i-xsH0 ztrKV+4lZXflQAuwE!XD8%h|LxHaS<%IQ2r6PQ8Ej?E7cC=U-V_d1a-wRP?Fy(mOA` z^v=C#uDr6Z?H7wJyv$7IVoe>aiKCuiDdvFlqs(IkHp6DI#u3UdkeBCn-c~CauO61` z)m>_P-7jpSb{G5EY&KhsMz?cyjoPC(`EIk@Cg1hNwegO5$(R@B9Pm2IhA_uc29z_E zs)wzIC{^m7Qz_IvUMY~E1Tuc3;RnCqMs3$^;P1D>E5Iq%+64Xp=fp;w6Tbw`Ru5%o z9VJwX%Z7mS8|-Gx5z-pSs*uKP1v2Xh@zgva3p{A{L?w_?EG3YTf{^H1rHs*abWmi$ z^CA-e+y^96!ZcOQwkO=&a4c=`XgrZh4la(5M@T#N7m;+-FcsCZhcW}%RK^|}rf-al zR0eIu@FgCJK)|xGn6C5fnye~{Ea!5S!L*|Lvaaz6*JJ5uR8!6E1{e0rWeZrxL$Et0 zcAZ0tb`f^~Uw-PTu}0$@%Ggu%(DToat*(xV@;ulGJv_>0@!mTD29LqI60fMi3BW0+ z)apB_UfD!gTqRs>VU+4>I_m_TS;xbGopQZK&n>mOe-MukNm@2-?!lRjNUIW;WWH#o zW0q~`sS`^}-3zKjT*B#5_G5sgD;n7JyTIHl#Hfk)QIEOCMIW`^ycEx zqc%kq*;W&l6N66E(uOT_A!B>kD9&>W>#!jCIM4kJ%v5ag!}5P`b|g12u+?|nRHvWNIX2#kY zy+^-;vp&d1z}^Ve@XZjgfpL~OW;AEOM3DP;jKH_+AQrPNGctAYxixxa_fUMOn;)= z>io#)ZPXgyyk~x9hUhbDQhzL28{PwT7+=>V;(S>w%?4npU6yBCS&3EI4QzqkB)FXM z>`FBc9(z@eLoHN`fOVX1jw1h81DXw=e816Yw_Rf54n5PpMjy2sftg_q*GG+*+inFM zCeduS>8b}z57*FPHFh^U%pPH9S&OyV+w2|8TpOVoxo6gPP^M?w7HF=DU!e-|o+aF7 zz_iI3S=^uyDj2qd%C!Z;3dcNQ&x-g7K`V0L^XdU6+&rMEJ6_>3BEgH|c3qSKj&(~L z%w|Cfrc(^3Gv@Rrk?~TFcQzK2$mh@s&*_{P*GXLWOOnEiI$w}2o%{4DSLaQxyGwW^ z!6x>uX6w$aI$!Fvrl&t#$I{~ZlE8N5n_O?6jrA!=JpwJVn;`<~NO6$rw!_!|W&@r3 zWJv{1i|am$&MiNjfJCxfPL^ex{CZf#dw7TzdYgt@F*K1@&Whq{Kn z?fZW^W;OyZjiu@ZUai1TXFjgw3w5XJ!7^k>+~6oVRe!s`y@k>YVOKOnp+>*L!b+># z>DT&DT7L$cv@5WiU&nj`PoGNAiNX^O&8BMC>9%e2gMr!X!fc+K+dMhwXm1Br^Xc7d ztSQzatmVhP{vuW)wBsl6_SHCTf|mg=Sg71z%K7j9Ys^-%v1TlliZx~VzZVNMr0k$A zrH0@#d;;6w3^u+A`!56_fY-MDp9r_WcUieMZi&6lT!Lo+tBqK#=eY)9jPOmlTuIU9 zWGtGFTk*K5-|X-7sTGZ;Y%3Z|+L6fV?#~Fx7qN#H@LYmV9Yf@R{0{uk5vt@X3$mAY z@)_XL5>hP;QY?$wmeutwY8}=hs{G`)PEX}>Q#oo{Ys|N-M#pkrJ**KaPv*{}KQ|?4 zDDbaZm-$y$`Br|9k0C$dr>#3uh?x{-t^ETXp&J8S5s@`Ym59?QarmMfF1MfUwzD1l zn%O4pK%M;C(7X*zyd$%(;{AWZ`#t}T>Euv?oVqCV!(jOJ-i`>G5`!KAQI>@dS7-BV zncWMXm!L9o61WwF1MnQY0w0y?1y3%n03J!(Xh?@mpBeeO;fj3g!O9NV1MzUGeYrdE+uF8lipJ*HtZ{G}!B=uxx#&$<+mHA%8<*^2Mp9k)><(>!(b zDCPfJIOUQmNwJt5Gix<7F2!VH@c!jxv42_Uix22LRzJfQ;a9P`Cn5w70ekQZLM0Io zaILT&I*4##8&xM$qS7CaV4+s;MOM%^R}L;rcE6xTH0_R*ZCm2HMF3S%buW9fq;f@z z@W_LP$~gjuA8VRqJg!7k?bc+%&RL1XZaWsYtVA;LGWepJlCIsuIoGf>^_$T_D^=S% zTbP=d81u#_rsC1WfS36*EoMg(nN)T-p0c$pMZ0g>79Tbp+p0`&xz+PVy-~L?IbGUv zN!O!^oR+mRb}FGHRS2OP`W_KIG7|Wf4?WJw%pc;1Hty2i|z* znKz#4UTCeZwpPy$rJ$Ntg8PNU$g?AyldGp5Nhu0Z8{?jN;~<8uwk! z(~RiQkZQ^z>n3A z^aaDXkbaYv)|h4(+Ard&lI#3psKt3}=*0m488%JN(hJN(e6Sbz$276eo{dmhWK@E4 zv7Xey`Iwd*gvnSpd~8I_H7=s&e!>M$5oo`urpYq1Qf5;wcjwfUm2flBsA*<0L&JI5 z(1ypd*^J|DO(;@o>V`=t8{x5-9UG8zt|%$`ZHXkg`@4|i;atr{9BQQOp&YU@QAM3I zP5d8_==o@LlWiIhB1ytBu#Y*M=AVYSiYyz0$8dSRqURup+(iMgjt4JH6rQ*9B;R${ zspaMOhlZAO=jq+~<@0yt=que7VlMm;{BdixyFRtyIrs=11HKj4F46_M0P8;+WXaN- zB!^FWJ<$Qz>JF@^$O@s47k0{3j~ApcLDWwaHN09*pHC+9v$MNr%^f>TfZ2R9Ij`rc zi3yb`|okze!KfzZ)B*oh5vLh@Siqe zmecH3_Gxw(cKC`wg^(YcEL<~Cp=ObR^5xiuAmJK5Au%yRGg{KG3U?9F(7My88F_M>K^!5& zMlsl^CVa9fwneN|_%iradMfMk6bQ$LA@u>-=5Q20h$Z52J(V$PNNFgM$0Y;$cY88s zCeu6-8G&TaPuR?jjgC8&?IT)7GY9y99LtowO3E$+qgX_mu+e=N{G*0u zs11c*>VS2~+A*-s6(f3ABj6IoU?dc60}+;Hz#1P#i1kT)BoF`*kse%!8*F;txCgjh z_#YjdJ(0f@*-MeTWXVvA3O8K2PW@0I;6A*tFJ4`vb|ATRwd9)T1Yk zyQOVt{3oyXzD)!ha-ADaEO;!=Hk=|-2}YkHq?17=MJYycID8h_l%y1;DMMMffCDs0 zL&%EdXaw=cD7lE_#>k^_n!tCJ0!`6on&yuke{?SnNeD|JEQhcX!nqJuLs$!8J%rms zctZ$p3gPY$?g`<|A>13n#U3n$^h+WAQb@lP(l3SdOCkMINWT=)FNO3=A^lQFzZB9h zh4f1y{ZdH36w)t;^vfara!9`%(l3Yf%OQQ3_JD8Yfc_%*7wjA1%O0F*)Wx?`@l8hT aEObwBt`HleB`z_7y|Zxc`vPwKX8Ru)Dfl)3 literal 0 HcmV?d00001 diff --git a/js/sceditor/development/themes/office-toolbar.css b/js/sceditor/development/themes/office-toolbar.css new file mode 100644 index 00000000..896f96bd --- /dev/null +++ b/js/sceditor/development/themes/office-toolbar.css @@ -0,0 +1,594 @@ +/** + * Copyright (C) 2012, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Icons by Mark James (http://www.famfamfam.com/lab/icons/silk/) + * Licensed under the Creative Commons CC-BY license (http://creativecommons.org/licenses/by/3.0/) + */ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */ +/** + * SCEditor + * http://www.ssceditor.com/ + * + * Copyright (C) 2011-12, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + */ +div.sceditor-grip, +.sceditor-button div { + background-image: url("famfamfam.png"); + background-repeat: no-repeat; + width: 16px; + height: 16px; +} +.sceditor-button-youtube div { + background-position: 0px 0px; +} +.sceditor-button-link div { + background-position: 0px -16px; +} +.sceditor-button-unlink div { + background-position: 0px -32px; +} +.sceditor-button-underline div { + background-position: 0px -48px; +} +.sceditor-button-time div { + background-position: 0px -64px; +} +.sceditor-button-table div { + background-position: 0px -80px; +} +.sceditor-button-superscript div { + background-position: 0px -96px; +} +.sceditor-button-subscript div { + background-position: 0px -112px; +} +.sceditor-button-strike div { + background-position: 0px -128px; +} +.sceditor-button-source div { + background-position: 0px -144px; +} +.sceditor-button-size div { + background-position: 0px -160px; +} +.sceditor-button-rtl div { + background-position: 0px -176px; +} +.sceditor-button-right div { + background-position: 0px -192px; +} +.sceditor-button-removeformat div { + background-position: 0px -208px; +} +.sceditor-button-quote div { + background-position: 0px -224px; +} +.sceditor-button-print div { + background-position: 0px -240px; +} +.sceditor-button-pastetext div { + background-position: 0px -256px; +} +.sceditor-button-paste div { + background-position: 0px -272px; +} +.sceditor-button-outdent div { + background-position: 0px -288px; +} +.sceditor-button-orderedlist div { + background-position: 0px -304px; +} +.sceditor-button-maximize div { + background-position: 0px -320px; +} +.sceditor-button-ltr div { + background-position: 0px -336px; +} +.sceditor-button-left div { + background-position: 0px -352px; +} +.sceditor-button-justify div { + background-position: 0px -368px; +} +.sceditor-button-italic div { + background-position: 0px -384px; +} +.sceditor-button-indent div { + background-position: 0px -400px; +} +.sceditor-button-image div { + background-position: 0px -416px; +} +.sceditor-button-horizontalrule div { + background-position: 0px -432px; +} +.sceditor-button-format div { + background-position: 0px -448px; +} +.sceditor-button-font div { + background-position: 0px -464px; +} +.sceditor-button-emoticon div { + background-position: 0px -480px; +} +.sceditor-button-email div { + background-position: 0px -496px; +} +.sceditor-button-date div { + background-position: 0px -512px; +} +.sceditor-button-cut div { + background-position: 0px -528px; +} +.sceditor-button-copy div { + background-position: 0px -544px; +} +.sceditor-button-color div { + background-position: 0px -560px; +} +.sceditor-button-code div { + background-position: 0px -576px; +} +.sceditor-button-center div { + background-position: 0px -592px; +} +.sceditor-button-bulletlist div { + background-position: 0px -608px; +} +.sceditor-button-bold div { + background-position: 0px -624px; +} +div.sceditor-grip { + background-position: 0px -640px; + width: 10px; + height: 10px; +} +.rtl div.sceditor-grip { + background-position: 0px -650px; + width: 10px; + height: 10px; +} +/** + * SCEditor + * http://www.ssceditor.com/ + * + * Copyright (C) 2011-12, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + */ +/*--------------------------------------------------- + LESS Elements 0.7 + --------------------------------------------------- + A set of useful LESS mixins + More info at: http://lesselements.com + ---------------------------------------------------*/ +.sceditor-container { + position: relative; + background: #fff; + border: 1px solid #d9d9d9; + font-size: 13px; + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + color: #222; + line-height: 1; + font-weight: bold; + border-radius: 4px; + background-clip: padding-box; +} +.sceditor-container *, +.sceditor-container *:before, +.sceditor-container *:after { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +.sceditor-container, +.sceditor-container div, +div.sceditor-dropdown, +div.sceditor-dropdown div { + padding: 0; + margin: 0; + z-index: 3; +} +.sceditor-container iframe, +.sceditor-container textarea { + line-height: 1; + border: 0; + outline: none; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 13px; + color: #111; + padding: 0; + margin: 5px; + resize: none; + background: #fff; + display: block; +} +div.sceditor-resize-cover { + position: absolute; + top: 0; + left: 0; + background: #000; + width: 100%; + height: 100%; + z-index: 10; + opacity: 0.3; +} +.ie6 div.sceditor-resize-cover, +.ie7 div.sceditor-resize-cover, +.ie8 div.sceditor-resize-cover { + background: #efefef; +} +.sceditor-container.ie6 { + overflow: hidden; +} +div.sceditor-grip { + overflow: hidden; + width: 10px; + height: 10px; + cursor: pointer; + position: absolute; + bottom: 0; + right: 0; + z-index: 3; +} +.sceditor-maximize { + position: fixed; + top: 0; + left: 0; + height: 100% !important; + width: 100% !important; + border-radius: 0; + background-clip: padding-box; + z-index: 2000; +} +html.sceditor-maximize, +body.sceditor-maximize { + height: 100%; + width: 100%; + padding: 0; + margin: 0; + overflow: hidden; +} +.ie6.sceditor-maximize { + position: absolute; +} +.sceditor-maximize div.sceditor-grip { + display: none; +} +.sceditor-maximize div.sceditor-toolbar { + border-radius: 0; + background-clip: padding-box; +} +/** + * Dropdown styleing + */ +div.sceditor-dropdown { + position: absolute; + border: 1px solid #ccc; + background: #fff; + color: #333; + z-index: 4000; + padding: 10px; + line-height: 1; + border-radius: 2px; + background-clip: padding-box; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.2); +} +div.sceditor-dropdown a, +div.sceditor-dropdown a:link { + color: #333; +} +div.sceditor-dropdown form { + margin: 0; +} +div.sceditor-dropdown label { + display: block; + font-weight: bold; + color: #3c3c3c; + padding: 4px 0; +} +div.sceditor-dropdown input, +div.sceditor-dropdown textarea { + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + outline: 0; + padding: 4px; + border: 1px solid #ccc; + border-top-color: #888; + margin: 0 0 .75em; + border-radius: 1px; + background-clip: padding-box; +} +div.sceditor-dropdown textarea { + padding: 6px; +} +div.sceditor-dropdown input:focus, +div.sceditor-dropdown textarea:focus { + border-color: #aaa; + border-top-color: #666; + box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.1); +} +div.sceditor-dropdown .button { + font-weight: bold; + color: #444; + padding: 6px 12px; + background: #ececec; + border: solid 1px #ccc; + border-radius: 2px; + background-clip: padding-box; + cursor: pointer; + margin: .3em 0 0; +} +div.sceditor-dropdown .button:hover { + background: #f3f3f3; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15); +} +div.sceditor-font-picker, +div.sceditor-fontsize-picker, +div.sceditor-format { + padding: 6px 0; +} +div.sceditor-emoticons, +div.sceditor-more-emoticons, +div.sceditor-color-picker { + padding: 0; +} +.sceditor-pastetext textarea { + border: 1px solid #bbb; + width: 20em; +} +.sceditor-emoticons img, +.sceditor-more-emoticons img { + padding: 0; + cursor: pointer; + margin: 2px; +} +.sceditor-more { + border-top: 1px solid #bbb; + display: block; + text-align: center; + cursor: pointer; + font-weight: bold; + padding: 6px 0; +} +.sceditor-dropdown a:hover { + background: #eee; +} +.sceditor-fontsize-option, +.sceditor-font-option, +.sceditor-format a { + display: block; + padding: 7px 10px; + cursor: pointer; + text-decoration: none; + color: #222; +} +.sceditor-fontsize-option { + padding: 7px 13px; +} +.sceditor-color-column { + float: left; +} +.sceditor-color-option { + display: block; + border: 1px solid #fff; + height: 10px; + width: 10px; + overflow: hidden; +} +.sceditor-color-option:hover { + border: 1px solid #333; +} +/** + * Toolbar styleing + */ +div.sceditor-toolbar { + overflow: hidden; + padding: 3px 5px 2px; + background: #f7f7f7; + border-bottom: 1px solid #c0c0c0; + line-height: 0; + text-align: left; + user-select: none; + border-radius: 3px 3px 0 0; + background-clip: padding-box; +} +div.sceditor-group { + display: inline-block; + background: #ddd; + margin: 1px 5px 1px 0; + padding: 1px; + border-bottom: 1px solid #aaa; + border-radius: 3px; + background-clip: padding-box; +} +.ie6 div.sceditor-group, +.ie7 div.sceditor-group { + display: inline; + zoom: 1; +} +.sceditor-button { + float: left; + cursor: pointer; + padding: 3px 5px; + width: 16px; + height: 20px; + border-radius: 3px; + background-clip: padding-box; + /* Needed for Safari 5? */ + text-indent: -9999px; +} +.ie .sceditor-button { + text-indent: 0; +} +.ie6 .sceditor-button, +.ie7 .sceditor-button { + float: none !important; + display: inline; + zoom: 1; +} +.ie6 .sceditor-button { + padding: 0; +} +.ie6 .sceditor-button div { + margin: 5px; +} +.ie7 .sceditor-button div { + margin: 5px 0; +} +.sceditor-button:hover, +.sceditor-button:active, +.sceditor-button.active { + background: #fff; + box-shadow: inset 1px 1px 0 rgba(0,0,0,0.3), inset -1px 0 rgba(0,0,0,0.3), inset 0 -1px 0 rgba(0,0,0,0.2); +} +.sceditor-button:active { + background: #fff; + box-shadow: inset 1px 1px 0 rgba(0,0,0,0.3), inset -1px 0 rgba(0,0,0,0.3), inset 0 -1px 0 rgba(0,0,0,0.2), inset 0 0 8px rgba(0,0,0,0.3); +} +.sceditor-button.disabled:hover { + background: inherit; + cursor: default; + box-shadow: none; +} +.sceditor-button, +.sceditor-button div { + display: block; +} +.sceditor-button div { + margin: 2px 0; + padding: 0; + overflow: hidden; + line-height: 0; + font-size: 0; + color: transparent; +} +.sceditor-button.disabled div { + filter: alpha(opacity=30); + opacity: 0.3; +} +.text .sceditor-button, +.text .sceditor-button div, +.sceditor-button.text, +.sceditor-button.text div, +.text-icon .sceditor-button, +.text-icon .sceditor-button div, +.sceditor-button.text-icon, +.sceditor-button.text-icon div { + width: auto; + overflow: visible; + line-height: 16px; + font-size: 1em; + color: inherit; + text-indent: 0; +} +.text .sceditor-button div, +.sceditor-button.text div { + padding: 0 2px; + background: none; +} +.text-icon .sceditor-button div, +.sceditor-button.text-icon div { + padding: 0 2px 0 20px; +} +.rtl div.sceditor-toolbar { + text-align: right; +} +.rtl .sceditor-button { + float: right; +} +.rtl div.sceditor-grip { + right: auto; + left: 0; +} +.sceditor-container { + border: 1px solid #8db2e3; +} +.sceditor-container textarea { + font-family: Consolas, "Bitstream Vera Sans Mono", "Andale Mono", Monaco, "DejaVu Sans Mono", "Lucida Console", monospace; +} +div.sceditor-toolbar { + border-bottom: 1px solid #95a9c3; + background: #dee8f5; + background: linear-gradient(to bottom, #dee8f5 0%, #c7d8ed 29%, #ccdcee 61%, #c0d8ef 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dee8f5', endColorstr='#c0d8ef', GradientType=0); +} +.ie9 div.sceditor-toolbar { + filter: none; + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RlZThmNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjI5JSIgc3RvcC1jb2xvcj0iI2M3ZDhlZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjYxJSIgc3RvcC1jb2xvcj0iI2NjZGNlZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNjMGQ4ZWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); +} +div.sceditor-group { + border: 1px solid #7596bf; + background: transparent; + padding: 0; + background: #cadcf0; + background: linear-gradient(to bottom, #cadcf0 24%, #bcd0e9 38%, #d0e1f7 99%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cadcf0', endColorstr='#d0e1f7', GradientType=0); +} +.ie9 div.sceditor-group { + filter: none; + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIyNCUiIHN0b3AtY29sb3I9IiNjYWRjZjAiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIzOCUiIHN0b3AtY29sb3I9IiNiY2QwZTkiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNkMGUxZjciIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); +} +.sceditor-button { + height: 16px; + padding: 3px 4px; + border-radius: 0; + background-clip: padding-box; + box-shadow: inset 0 1px #d5e3f1, inset 0 -1px #e3edfb, inset 1px 0 #cddcef, inset -1px 0 #b8ceea; +} +.sceditor-button:first-child { + border-radius: 4px 0 0 4px; + background-clip: padding-box; +} +.sceditor-button:last-child { + border-radius: 0 4px 4px 0; + background-clip: padding-box; +} +.sceditor-button div { + margin: 0; +} +.ie9 .sceditor-button { + filter: none !important; +} +.sceditor-button.active { + background: #fbdbb5; + background: linear-gradient(to bottom, #fbdbb5 11%, #feb456 29%, #fdeb9f 99%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbdbb5', endColorstr='#fdeb9f', GradientType=0); + box-shadow: inset 0 1px #ebd1b4, inset 0 -1px #ffe47f, inset -1px 0 #b8ceea; +} +.ie9 .sceditor-button.active { + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIxMSUiIHN0b3AtY29sb3I9IiNmYmRiYjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIyOSUiIHN0b3AtY29sb3I9IiNmZWI0NTYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNmZGZkOWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); +} +.sceditor-button:hover { + background: #fef7d5; + background: linear-gradient(to bottom, #fef7d5 0%, #fae5a9 42%, #ffd048 42%, #ffe59f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fef7d5', endColorstr='#ffe59f', GradientType=0); + box-shadow: inset 0 1px #fffbe8, inset -1px 0 #ffefc4, inset 0 -1px #fff9cc; +} +.ie9 .sceditor-button:hover { + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZjdkNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZhZTVhOSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZmZDA0OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmU1OWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); +} +.sceditor-button:active { + background: #e7a66d; + background: linear-gradient(to bottom, #e7a66d 0%, #fcb16d 1%, #ff8d05 42%, #ffc450 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e7a66d', endColorstr='#ffc450', GradientType=0); + box-shadow: inset 0 1px 1px #7b6645, inset 0 -1px #d19c33; +} +.ie9 .sceditor-button:active { + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2U3YTY2ZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjElIiBzdG9wLWNvbG9yPSIjZmNiMTZkIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNDIlIiBzdG9wLWNvbG9yPSIjZmY4ZDA1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmYzQ1MCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=); +} +.sceditor-button.active:hover { + background: #dba368; + background: linear-gradient(to bottom, #dba368 0%, #ffbd79 4%, #fea335 34%, #ffc64c 66%, #fee069 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dba368', endColorstr='#fee069', GradientType=0); + box-shadow: inset 0 1px 1px #9e8255, inset 0 -1px #fcce6b; +} +.ie9 .sceditor-button.active:hover { + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RiYTM2OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQlIiBzdG9wLWNvbG9yPSIjZmZiZDc5IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMzQlIiBzdG9wLWNvbG9yPSIjZmVhMzM1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNjYlIiBzdG9wLWNvbG9yPSIjZmZjNjRjIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZlZTA2OSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=); +} diff --git a/js/sceditor/development/themes/office.css b/js/sceditor/development/themes/office.css new file mode 100644 index 00000000..7f2f3281 --- /dev/null +++ b/js/sceditor/development/themes/office.css @@ -0,0 +1,616 @@ +/** + * Copyright (C) 2012, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Icons by Mark James (http://www.famfamfam.com/lab/icons/silk/) + * Licensed under the Creative Commons CC-BY license (http://creativecommons.org/licenses/by/3.0/) + */ +/** + * Copyright (C) 2012, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Icons by Mark James (http://www.famfamfam.com/lab/icons/silk/) + * Licensed under the Creative Commons CC-BY license (http://creativecommons.org/licenses/by/3.0/) + */ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */ +/** + * SCEditor + * http://www.ssceditor.com/ + * + * Copyright (C) 2011-12, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + */ +div.sceditor-grip, +.sceditor-button div { + background-image: url("famfamfam.png"); + background-repeat: no-repeat; + width: 16px; + height: 16px; +} +.sceditor-button-youtube div { + background-position: 0px 0px; +} +.sceditor-button-link div { + background-position: 0px -16px; +} +.sceditor-button-unlink div { + background-position: 0px -32px; +} +.sceditor-button-underline div { + background-position: 0px -48px; +} +.sceditor-button-time div { + background-position: 0px -64px; +} +.sceditor-button-table div { + background-position: 0px -80px; +} +.sceditor-button-superscript div { + background-position: 0px -96px; +} +.sceditor-button-subscript div { + background-position: 0px -112px; +} +.sceditor-button-strike div { + background-position: 0px -128px; +} +.sceditor-button-source div { + background-position: 0px -144px; +} +.sceditor-button-size div { + background-position: 0px -160px; +} +.sceditor-button-rtl div { + background-position: 0px -176px; +} +.sceditor-button-right div { + background-position: 0px -192px; +} +.sceditor-button-removeformat div { + background-position: 0px -208px; +} +.sceditor-button-quote div { + background-position: 0px -224px; +} +.sceditor-button-print div { + background-position: 0px -240px; +} +.sceditor-button-pastetext div { + background-position: 0px -256px; +} +.sceditor-button-paste div { + background-position: 0px -272px; +} +.sceditor-button-outdent div { + background-position: 0px -288px; +} +.sceditor-button-orderedlist div { + background-position: 0px -304px; +} +.sceditor-button-maximize div { + background-position: 0px -320px; +} +.sceditor-button-ltr div { + background-position: 0px -336px; +} +.sceditor-button-left div { + background-position: 0px -352px; +} +.sceditor-button-justify div { + background-position: 0px -368px; +} +.sceditor-button-italic div { + background-position: 0px -384px; +} +.sceditor-button-indent div { + background-position: 0px -400px; +} +.sceditor-button-image div { + background-position: 0px -416px; +} +.sceditor-button-horizontalrule div { + background-position: 0px -432px; +} +.sceditor-button-format div { + background-position: 0px -448px; +} +.sceditor-button-font div { + background-position: 0px -464px; +} +.sceditor-button-emoticon div { + background-position: 0px -480px; +} +.sceditor-button-email div { + background-position: 0px -496px; +} +.sceditor-button-date div { + background-position: 0px -512px; +} +.sceditor-button-cut div { + background-position: 0px -528px; +} +.sceditor-button-copy div { + background-position: 0px -544px; +} +.sceditor-button-color div { + background-position: 0px -560px; +} +.sceditor-button-code div { + background-position: 0px -576px; +} +.sceditor-button-center div { + background-position: 0px -592px; +} +.sceditor-button-bulletlist div { + background-position: 0px -608px; +} +.sceditor-button-bold div { + background-position: 0px -624px; +} +div.sceditor-grip { + background-position: 0px -640px; + width: 10px; + height: 10px; +} +.rtl div.sceditor-grip { + background-position: 0px -650px; + width: 10px; + height: 10px; +} +/** + * SCEditor + * http://www.ssceditor.com/ + * + * Copyright (C) 2011-12, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + */ +/*--------------------------------------------------- + LESS Elements 0.7 + --------------------------------------------------- + A set of useful LESS mixins + More info at: http://lesselements.com + ---------------------------------------------------*/ +.sceditor-container { + position: relative; + background: #fff; + border: 1px solid #d9d9d9; + font-size: 13px; + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + color: #222; + line-height: 1; + font-weight: bold; + border-radius: 4px; + background-clip: padding-box; +} +.sceditor-container *, +.sceditor-container *:before, +.sceditor-container *:after { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +.sceditor-container, +.sceditor-container div, +div.sceditor-dropdown, +div.sceditor-dropdown div { + padding: 0; + margin: 0; + z-index: 3; +} +.sceditor-container iframe, +.sceditor-container textarea { + line-height: 1; + border: 0; + outline: none; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 13px; + color: #111; + padding: 0; + margin: 5px; + resize: none; + background: #fff; + display: block; +} +div.sceditor-resize-cover { + position: absolute; + top: 0; + left: 0; + background: #000; + width: 100%; + height: 100%; + z-index: 10; + opacity: 0.3; +} +.ie6 div.sceditor-resize-cover, +.ie7 div.sceditor-resize-cover, +.ie8 div.sceditor-resize-cover { + background: #efefef; +} +.sceditor-container.ie6 { + overflow: hidden; +} +div.sceditor-grip { + overflow: hidden; + width: 10px; + height: 10px; + cursor: pointer; + position: absolute; + bottom: 0; + right: 0; + z-index: 3; +} +.sceditor-maximize { + position: fixed; + top: 0; + left: 0; + height: 100% !important; + width: 100% !important; + border-radius: 0; + background-clip: padding-box; + z-index: 2000; +} +html.sceditor-maximize, +body.sceditor-maximize { + height: 100%; + width: 100%; + padding: 0; + margin: 0; + overflow: hidden; +} +.ie6.sceditor-maximize { + position: absolute; +} +.sceditor-maximize div.sceditor-grip { + display: none; +} +.sceditor-maximize div.sceditor-toolbar { + border-radius: 0; + background-clip: padding-box; +} +/** + * Dropdown styleing + */ +div.sceditor-dropdown { + position: absolute; + border: 1px solid #ccc; + background: #fff; + color: #333; + z-index: 4000; + padding: 10px; + line-height: 1; + border-radius: 2px; + background-clip: padding-box; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.2); +} +div.sceditor-dropdown a, +div.sceditor-dropdown a:link { + color: #333; +} +div.sceditor-dropdown form { + margin: 0; +} +div.sceditor-dropdown label { + display: block; + font-weight: bold; + color: #3c3c3c; + padding: 4px 0; +} +div.sceditor-dropdown input, +div.sceditor-dropdown textarea { + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + outline: 0; + padding: 4px; + border: 1px solid #ccc; + border-top-color: #888; + margin: 0 0 .75em; + border-radius: 1px; + background-clip: padding-box; +} +div.sceditor-dropdown textarea { + padding: 6px; +} +div.sceditor-dropdown input:focus, +div.sceditor-dropdown textarea:focus { + border-color: #aaa; + border-top-color: #666; + box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.1); +} +div.sceditor-dropdown .button { + font-weight: bold; + color: #444; + padding: 6px 12px; + background: #ececec; + border: solid 1px #ccc; + border-radius: 2px; + background-clip: padding-box; + cursor: pointer; + margin: .3em 0 0; +} +div.sceditor-dropdown .button:hover { + background: #f3f3f3; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15); +} +div.sceditor-font-picker, +div.sceditor-fontsize-picker, +div.sceditor-format { + padding: 6px 0; +} +div.sceditor-emoticons, +div.sceditor-more-emoticons, +div.sceditor-color-picker { + padding: 0; +} +.sceditor-pastetext textarea { + border: 1px solid #bbb; + width: 20em; +} +.sceditor-emoticons img, +.sceditor-more-emoticons img { + padding: 0; + cursor: pointer; + margin: 2px; +} +.sceditor-more { + border-top: 1px solid #bbb; + display: block; + text-align: center; + cursor: pointer; + font-weight: bold; + padding: 6px 0; +} +.sceditor-dropdown a:hover { + background: #eee; +} +.sceditor-fontsize-option, +.sceditor-font-option, +.sceditor-format a { + display: block; + padding: 7px 10px; + cursor: pointer; + text-decoration: none; + color: #222; +} +.sceditor-fontsize-option { + padding: 7px 13px; +} +.sceditor-color-column { + float: left; +} +.sceditor-color-option { + display: block; + border: 1px solid #fff; + height: 10px; + width: 10px; + overflow: hidden; +} +.sceditor-color-option:hover { + border: 1px solid #333; +} +/** + * Toolbar styleing + */ +div.sceditor-toolbar { + overflow: hidden; + padding: 3px 5px 2px; + background: #f7f7f7; + border-bottom: 1px solid #c0c0c0; + line-height: 0; + text-align: left; + user-select: none; + border-radius: 3px 3px 0 0; + background-clip: padding-box; +} +div.sceditor-group { + display: inline-block; + background: #ddd; + margin: 1px 5px 1px 0; + padding: 1px; + border-bottom: 1px solid #aaa; + border-radius: 3px; + background-clip: padding-box; +} +.ie6 div.sceditor-group, +.ie7 div.sceditor-group { + display: inline; + zoom: 1; +} +.sceditor-button { + float: left; + cursor: pointer; + padding: 3px 5px; + width: 16px; + height: 20px; + border-radius: 3px; + background-clip: padding-box; + /* Needed for Safari 5? */ + text-indent: -9999px; +} +.ie .sceditor-button { + text-indent: 0; +} +.ie6 .sceditor-button, +.ie7 .sceditor-button { + float: none !important; + display: inline; + zoom: 1; +} +.ie6 .sceditor-button { + padding: 0; +} +.ie6 .sceditor-button div { + margin: 5px; +} +.ie7 .sceditor-button div { + margin: 5px 0; +} +.sceditor-button:hover, +.sceditor-button:active, +.sceditor-button.active { + background: #fff; + box-shadow: inset 1px 1px 0 rgba(0,0,0,0.3), inset -1px 0 rgba(0,0,0,0.3), inset 0 -1px 0 rgba(0,0,0,0.2); +} +.sceditor-button:active { + background: #fff; + box-shadow: inset 1px 1px 0 rgba(0,0,0,0.3), inset -1px 0 rgba(0,0,0,0.3), inset 0 -1px 0 rgba(0,0,0,0.2), inset 0 0 8px rgba(0,0,0,0.3); +} +.sceditor-button.disabled:hover { + background: inherit; + cursor: default; + box-shadow: none; +} +.sceditor-button, +.sceditor-button div { + display: block; +} +.sceditor-button div { + margin: 2px 0; + padding: 0; + overflow: hidden; + line-height: 0; + font-size: 0; + color: transparent; +} +.sceditor-button.disabled div { + filter: alpha(opacity=30); + opacity: 0.3; +} +.text .sceditor-button, +.text .sceditor-button div, +.sceditor-button.text, +.sceditor-button.text div, +.text-icon .sceditor-button, +.text-icon .sceditor-button div, +.sceditor-button.text-icon, +.sceditor-button.text-icon div { + width: auto; + overflow: visible; + line-height: 16px; + font-size: 1em; + color: inherit; + text-indent: 0; +} +.text .sceditor-button div, +.sceditor-button.text div { + padding: 0 2px; + background: none; +} +.text-icon .sceditor-button div, +.sceditor-button.text-icon div { + padding: 0 2px 0 20px; +} +.rtl div.sceditor-toolbar { + text-align: right; +} +.rtl .sceditor-button { + float: right; +} +.rtl div.sceditor-grip { + right: auto; + left: 0; +} +.sceditor-container { + border: 1px solid #8db2e3; +} +.sceditor-container textarea { + font-family: Consolas, "Bitstream Vera Sans Mono", "Andale Mono", Monaco, "DejaVu Sans Mono", "Lucida Console", monospace; +} +div.sceditor-toolbar { + border-bottom: 1px solid #95a9c3; + background: #dee8f5; + background: linear-gradient(to bottom, #dee8f5 0%, #c7d8ed 29%, #ccdcee 61%, #c0d8ef 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dee8f5', endColorstr='#c0d8ef', GradientType=0); +} +.ie9 div.sceditor-toolbar { + filter: none; + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RlZThmNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjI5JSIgc3RvcC1jb2xvcj0iI2M3ZDhlZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjYxJSIgc3RvcC1jb2xvcj0iI2NjZGNlZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNjMGQ4ZWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); +} +div.sceditor-group { + border: 1px solid #7596bf; + background: transparent; + padding: 0; + background: #cadcf0; + background: linear-gradient(to bottom, #cadcf0 24%, #bcd0e9 38%, #d0e1f7 99%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cadcf0', endColorstr='#d0e1f7', GradientType=0); +} +.ie9 div.sceditor-group { + filter: none; + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIyNCUiIHN0b3AtY29sb3I9IiNjYWRjZjAiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIzOCUiIHN0b3AtY29sb3I9IiNiY2QwZTkiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNkMGUxZjciIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); +} +.sceditor-button { + height: 16px; + padding: 3px 4px; + border-radius: 0; + background-clip: padding-box; + box-shadow: inset 0 1px #d5e3f1, inset 0 -1px #e3edfb, inset 1px 0 #cddcef, inset -1px 0 #b8ceea; +} +.sceditor-button:first-child { + border-radius: 4px 0 0 4px; + background-clip: padding-box; +} +.sceditor-button:last-child { + border-radius: 0 4px 4px 0; + background-clip: padding-box; +} +.sceditor-button div { + margin: 0; +} +.ie9 .sceditor-button { + filter: none !important; +} +.sceditor-button.active { + background: #fbdbb5; + background: linear-gradient(to bottom, #fbdbb5 11%, #feb456 29%, #fdeb9f 99%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbdbb5', endColorstr='#fdeb9f', GradientType=0); + box-shadow: inset 0 1px #ebd1b4, inset 0 -1px #ffe47f, inset -1px 0 #b8ceea; +} +.ie9 .sceditor-button.active { + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIxMSUiIHN0b3AtY29sb3I9IiNmYmRiYjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIyOSUiIHN0b3AtY29sb3I9IiNmZWI0NTYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNmZGZkOWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); +} +.sceditor-button:hover { + background: #fef7d5; + background: linear-gradient(to bottom, #fef7d5 0%, #fae5a9 42%, #ffd048 42%, #ffe59f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fef7d5', endColorstr='#ffe59f', GradientType=0); + box-shadow: inset 0 1px #fffbe8, inset -1px 0 #ffefc4, inset 0 -1px #fff9cc; +} +.ie9 .sceditor-button:hover { + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZjdkNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZhZTVhOSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZmZDA0OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmU1OWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); +} +.sceditor-button:active { + background: #e7a66d; + background: linear-gradient(to bottom, #e7a66d 0%, #fcb16d 1%, #ff8d05 42%, #ffc450 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e7a66d', endColorstr='#ffc450', GradientType=0); + box-shadow: inset 0 1px 1px #7b6645, inset 0 -1px #d19c33; +} +.ie9 .sceditor-button:active { + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2U3YTY2ZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjElIiBzdG9wLWNvbG9yPSIjZmNiMTZkIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNDIlIiBzdG9wLWNvbG9yPSIjZmY4ZDA1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmYzQ1MCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=); +} +.sceditor-button.active:hover { + background: #dba368; + background: linear-gradient(to bottom, #dba368 0%, #ffbd79 4%, #fea335 34%, #ffc64c 66%, #fee069 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dba368', endColorstr='#fee069', GradientType=0); + box-shadow: inset 0 1px 1px #9e8255, inset 0 -1px #fcce6b; +} +.ie9 .sceditor-button.active:hover { + background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RiYTM2OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQlIiBzdG9wLWNvbG9yPSIjZmZiZDc5IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMzQlIiBzdG9wLWNvbG9yPSIjZmVhMzM1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNjYlIiBzdG9wLWNvbG9yPSIjZmZjNjRjIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZlZTA2OSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=); +} +.sceditor-container { + background: #a3c2ea; + background: linear-gradient(to bottom, #a3c2ea 0%, #6d92c1 39%, #577fb3 64%, #6591cc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#a3c2ea', endColorstr='#6591cc', GradientType=0); +} +.sceditor-container iframe, +.sceditor-container textarea { + border: 1px solid #646464; + background: #fff; + margin: 7px 40px; + padding: 20px; + box-shadow: 1px 1px 5px #293a52; +} diff --git a/js/sceditor/development/themes/square.css b/js/sceditor/development/themes/square.css new file mode 100644 index 00000000..3c644de4 --- /dev/null +++ b/js/sceditor/development/themes/square.css @@ -0,0 +1,589 @@ +/** + * Square theme + * + * This theme is best suited to short toolbars that + * don't span multiple lines. + * + * Copyright (C) 2012, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + * + * Icons by Mark James (http://www.famfamfam.com/lab/icons/silk/) + * Licensed under the Creative Commons CC-BY license (http://creativecommons.org/licenses/by/3.0/) + */ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */ +/** + * SCEditor + * http://www.ssceditor.com/ + * + * Copyright (C) 2011-12, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + */ +div.sceditor-grip, +.sceditor-button div { + background-image: url("famfamfam.png"); + background-repeat: no-repeat; + width: 16px; + height: 16px; +} +.sceditor-button-youtube div { + background-position: 0px 0px; +} +.sceditor-button-link div { + background-position: 0px -16px; +} +.sceditor-button-unlink div { + background-position: 0px -32px; +} +.sceditor-button-underline div { + background-position: 0px -48px; +} +.sceditor-button-time div { + background-position: 0px -64px; +} +.sceditor-button-table div { + background-position: 0px -80px; +} +.sceditor-button-superscript div { + background-position: 0px -96px; +} +.sceditor-button-subscript div { + background-position: 0px -112px; +} +.sceditor-button-strike div { + background-position: 0px -128px; +} +.sceditor-button-source div { + background-position: 0px -144px; +} +.sceditor-button-size div { + background-position: 0px -160px; +} +.sceditor-button-rtl div { + background-position: 0px -176px; +} +.sceditor-button-right div { + background-position: 0px -192px; +} +.sceditor-button-removeformat div { + background-position: 0px -208px; +} +.sceditor-button-quote div { + background-position: 0px -224px; +} +.sceditor-button-print div { + background-position: 0px -240px; +} +.sceditor-button-pastetext div { + background-position: 0px -256px; +} +.sceditor-button-paste div { + background-position: 0px -272px; +} +.sceditor-button-outdent div { + background-position: 0px -288px; +} +.sceditor-button-orderedlist div { + background-position: 0px -304px; +} +.sceditor-button-maximize div { + background-position: 0px -320px; +} +.sceditor-button-ltr div { + background-position: 0px -336px; +} +.sceditor-button-left div { + background-position: 0px -352px; +} +.sceditor-button-justify div { + background-position: 0px -368px; +} +.sceditor-button-italic div { + background-position: 0px -384px; +} +.sceditor-button-indent div { + background-position: 0px -400px; +} +.sceditor-button-image div { + background-position: 0px -416px; +} +.sceditor-button-horizontalrule div { + background-position: 0px -432px; +} +.sceditor-button-format div { + background-position: 0px -448px; +} +.sceditor-button-font div { + background-position: 0px -464px; +} +.sceditor-button-emoticon div { + background-position: 0px -480px; +} +.sceditor-button-email div { + background-position: 0px -496px; +} +.sceditor-button-date div { + background-position: 0px -512px; +} +.sceditor-button-cut div { + background-position: 0px -528px; +} +.sceditor-button-copy div { + background-position: 0px -544px; +} +.sceditor-button-color div { + background-position: 0px -560px; +} +.sceditor-button-code div { + background-position: 0px -576px; +} +.sceditor-button-center div { + background-position: 0px -592px; +} +.sceditor-button-bulletlist div { + background-position: 0px -608px; +} +.sceditor-button-bold div { + background-position: 0px -624px; +} +div.sceditor-grip { + background-position: 0px -640px; + width: 10px; + height: 10px; +} +.rtl div.sceditor-grip { + background-position: 0px -650px; + width: 10px; + height: 10px; +} +/** + * SCEditor + * http://www.ssceditor.com/ + * + * Copyright (C) 2011-12, Sam Clarke (samclarke.com) + * + * SCEditor is licensed under the MIT license: + * http://www.opensource.org/licenses/mit-license.php + */ +/*--------------------------------------------------- + LESS Elements 0.7 + --------------------------------------------------- + A set of useful LESS mixins + More info at: http://lesselements.com + ---------------------------------------------------*/ +.sceditor-container { + position: relative; + background: #fff; + border: 1px solid #d9d9d9; + font-size: 13px; + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + color: #222; + line-height: 1; + font-weight: bold; + border-radius: 4px; + background-clip: padding-box; +} +.sceditor-container *, +.sceditor-container *:before, +.sceditor-container *:after { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +.sceditor-container, +.sceditor-container div, +div.sceditor-dropdown, +div.sceditor-dropdown div { + padding: 0; + margin: 0; + z-index: 3; +} +.sceditor-container iframe, +.sceditor-container textarea { + line-height: 1; + border: 0; + outline: none; + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 13px; + color: #111; + padding: 0; + margin: 5px; + resize: none; + background: #fff; + display: block; +} +div.sceditor-resize-cover { + position: absolute; + top: 0; + left: 0; + background: #000; + width: 100%; + height: 100%; + z-index: 10; + opacity: 0.3; +} +.ie6 div.sceditor-resize-cover, +.ie7 div.sceditor-resize-cover, +.ie8 div.sceditor-resize-cover { + background: #efefef; +} +.sceditor-container.ie6 { + overflow: hidden; +} +div.sceditor-grip { + overflow: hidden; + width: 10px; + height: 10px; + cursor: pointer; + position: absolute; + bottom: 0; + right: 0; + z-index: 3; +} +.sceditor-maximize { + position: fixed; + top: 0; + left: 0; + height: 100% !important; + width: 100% !important; + border-radius: 0; + background-clip: padding-box; + z-index: 2000; +} +html.sceditor-maximize, +body.sceditor-maximize { + height: 100%; + width: 100%; + padding: 0; + margin: 0; + overflow: hidden; +} +.ie6.sceditor-maximize { + position: absolute; +} +.sceditor-maximize div.sceditor-grip { + display: none; +} +.sceditor-maximize div.sceditor-toolbar { + border-radius: 0; + background-clip: padding-box; +} +/** + * Dropdown styleing + */ +div.sceditor-dropdown { + position: absolute; + border: 1px solid #ccc; + background: #fff; + color: #333; + z-index: 4000; + padding: 10px; + line-height: 1; + border-radius: 2px; + background-clip: padding-box; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.2); +} +div.sceditor-dropdown a, +div.sceditor-dropdown a:link { + color: #333; +} +div.sceditor-dropdown form { + margin: 0; +} +div.sceditor-dropdown label { + display: block; + font-weight: bold; + color: #3c3c3c; + padding: 4px 0; +} +div.sceditor-dropdown input, +div.sceditor-dropdown textarea { + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + outline: 0; + padding: 4px; + border: 1px solid #ccc; + border-top-color: #888; + margin: 0 0 .75em; + border-radius: 1px; + background-clip: padding-box; +} +div.sceditor-dropdown textarea { + padding: 6px; +} +div.sceditor-dropdown input:focus, +div.sceditor-dropdown textarea:focus { + border-color: #aaa; + border-top-color: #666; + box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.1); +} +div.sceditor-dropdown .button { + font-weight: bold; + color: #444; + padding: 6px 12px; + background: #ececec; + border: solid 1px #ccc; + border-radius: 2px; + background-clip: padding-box; + cursor: pointer; + margin: .3em 0 0; +} +div.sceditor-dropdown .button:hover { + background: #f3f3f3; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15); +} +div.sceditor-font-picker, +div.sceditor-fontsize-picker, +div.sceditor-format { + padding: 6px 0; +} +div.sceditor-emoticons, +div.sceditor-more-emoticons, +div.sceditor-color-picker { + padding: 0; +} +.sceditor-pastetext textarea { + border: 1px solid #bbb; + width: 20em; +} +.sceditor-emoticons img, +.sceditor-more-emoticons img { + padding: 0; + cursor: pointer; + margin: 2px; +} +.sceditor-more { + border-top: 1px solid #bbb; + display: block; + text-align: center; + cursor: pointer; + font-weight: bold; + padding: 6px 0; +} +.sceditor-dropdown a:hover { + background: #eee; +} +.sceditor-fontsize-option, +.sceditor-font-option, +.sceditor-format a { + display: block; + padding: 7px 10px; + cursor: pointer; + text-decoration: none; + color: #222; +} +.sceditor-fontsize-option { + padding: 7px 13px; +} +.sceditor-color-column { + float: left; +} +.sceditor-color-option { + display: block; + border: 1px solid #fff; + height: 10px; + width: 10px; + overflow: hidden; +} +.sceditor-color-option:hover { + border: 1px solid #333; +} +/** + * Toolbar styleing + */ +div.sceditor-toolbar { + overflow: hidden; + padding: 3px 5px 2px; + background: #f7f7f7; + border-bottom: 1px solid #c0c0c0; + line-height: 0; + text-align: left; + user-select: none; + border-radius: 3px 3px 0 0; + background-clip: padding-box; +} +div.sceditor-group { + display: inline-block; + background: #ddd; + margin: 1px 5px 1px 0; + padding: 1px; + border-bottom: 1px solid #aaa; + border-radius: 3px; + background-clip: padding-box; +} +.ie6 div.sceditor-group, +.ie7 div.sceditor-group { + display: inline; + zoom: 1; +} +.sceditor-button { + float: left; + cursor: pointer; + padding: 3px 5px; + width: 16px; + height: 20px; + border-radius: 3px; + background-clip: padding-box; + /* Needed for Safari 5? */ + text-indent: -9999px; +} +.ie .sceditor-button { + text-indent: 0; +} +.ie6 .sceditor-button, +.ie7 .sceditor-button { + float: none !important; + display: inline; + zoom: 1; +} +.ie6 .sceditor-button { + padding: 0; +} +.ie6 .sceditor-button div { + margin: 5px; +} +.ie7 .sceditor-button div { + margin: 5px 0; +} +.sceditor-button:hover, +.sceditor-button:active, +.sceditor-button.active { + background: #fff; + box-shadow: inset 1px 1px 0 rgba(0,0,0,0.3), inset -1px 0 rgba(0,0,0,0.3), inset 0 -1px 0 rgba(0,0,0,0.2); +} +.sceditor-button:active { + background: #fff; + box-shadow: inset 1px 1px 0 rgba(0,0,0,0.3), inset -1px 0 rgba(0,0,0,0.3), inset 0 -1px 0 rgba(0,0,0,0.2), inset 0 0 8px rgba(0,0,0,0.3); +} +.sceditor-button.disabled:hover { + background: inherit; + cursor: default; + box-shadow: none; +} +.sceditor-button, +.sceditor-button div { + display: block; +} +.sceditor-button div { + margin: 2px 0; + padding: 0; + overflow: hidden; + line-height: 0; + font-size: 0; + color: transparent; +} +.sceditor-button.disabled div { + filter: alpha(opacity=30); + opacity: 0.3; +} +.text .sceditor-button, +.text .sceditor-button div, +.sceditor-button.text, +.sceditor-button.text div, +.text-icon .sceditor-button, +.text-icon .sceditor-button div, +.sceditor-button.text-icon, +.sceditor-button.text-icon div { + width: auto; + overflow: visible; + line-height: 16px; + font-size: 1em; + color: inherit; + text-indent: 0; +} +.text .sceditor-button div, +.sceditor-button.text div { + padding: 0 2px; + background: none; +} +.text-icon .sceditor-button div, +.sceditor-button.text-icon div { + padding: 0 2px 0 20px; +} +.rtl div.sceditor-toolbar { + text-align: right; +} +.rtl .sceditor-button { + float: right; +} +.rtl div.sceditor-grip { + right: auto; + left: 0; +} +.sceditor-container { + border: 1px solid #d6d6d6; + border-radius: 0; + background-clip: padding-box; +} +.sceditor-container textarea { + font-family: Consolas, "Bitstream Vera Sans Mono", "Andale Mono", Monaco, "DejaVu Sans Mono", "Lucida Console", monospace; + background: #2e3436; + color: #fff; + margin: 0; + padding: 5px; +} +div.sceditor-toolbar, +div.sceditor-group { + background: #f2f2f2; + background: linear-gradient(to bottom, #f2f2f2 0%, #dddddd 89%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f2f2f2', endColorstr='#dddddd', GradientType=0); +} +div.sceditor-toolbar { + padding: 0; + border-bottom: 1px solid #bbb; + background-size: 100% 32px; +} +div.sceditor-group { + margin: 0; + padding: 2px 4px; + border: 0; + border-right: 1px solid #ccc; + border-left: 1px solid #eaeaea; + border-radius: 0; + background-clip: padding-box; +} +div.sceditor-group:last-child { + border-right: 0; +} +div.sceditor-group:first-child { + border-left: 0; +} +.sceditor-button { + height: 16px; + padding: 5px; + margin: 1px; + border-radius: 0; + background-clip: padding-box; +} +.sceditor-button div { + margin: 0; +} +.sceditor-button.active, +.sceditor-button:hover, +.sceditor-button:active, +.sceditor-button.active:hover { + margin: 0; + box-shadow: none; +} +.sceditor-button.active { + background: #f4f4f4; + border: 1px solid #ccc; +} +.sceditor-button:hover { + background: #fefefe; + border: 1px solid #ddd; +} +.sceditor-button.disabled:hover { + margin: 1px; + border: 0; +} +.sceditor-button:active { + background: #eee; + border: 1px solid #ccc; +} +.sceditor-button.active:hover { + background: #f8f8f8; + border: 1px solid #ddd; +} diff --git a/js/sceditor/emoticons/alien.png b/js/sceditor/emoticons/alien.png new file mode 100644 index 0000000000000000000000000000000000000000..58a07677b338e60892f47c6724419d6a93b09ade GIT binary patch literal 756 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz4!3-n|x$R~#Ffhgk_=LDdL`3}m{~t)wA0#9s zz%2#3DmpqkCMG5}Ha0FUE;%_lB_$;_H8m|QEi*GSD=RBIJ3BWwH!m-*prD|rsHnKO zxTK_{yu7@orlz*Gwz09XrKP2#qob>AH7^yxEZ%$PlU_MAC$=FgwMV8Mb# zixw?evSit^Wy_Z@U$tu0>eZ{)tXZ>m?b>zg)~#Q^e#3?h8#iv;x^?TeZQHhQ-@aqV zj-5Mq?%ut7&z?O84jedm@ZjOYhmRaNa`foYW5|ETu{DMNl zB4V6DH4`wRHcjr_W!$?|qzn9~ejCo-U3d6^yy(n~QQB zMI0^~Z_B-X&3Vnn+}Z!*U+y#vs}`3o*w4T-Pkp<^Tro?2{`W70&gWJdor>SB`epku z)4y-mna#dh6Vf?*M?>Q5_tSSD{#bECSADOxv9v(fucWQ^^Cmp5Gky0bI5mXU?nTVzV#-Na~})l-aWNAyg?~YBx~O5!uLgAvtBmL;NWom zxZFB2Z~F`TuQ5KJtUSU0_Z!bT>vlKFEHUArcAwtG0>zmt`k3EKtnyeG=F=L&^P@$L u+s5`ss>zQgrL8xYi2P_f^Kin$tHx(Sy$tnEC%OT{mci52&t;ucLK6U`!(Rme literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/angel.png b/js/sceditor/emoticons/angel.png new file mode 100644 index 0000000000000000000000000000000000000000..4792225c2749989ddb78a3804dcd5bb9617fae0e GIT binary patch literal 1182 zcmeAS@N?(olHy`uVBq!ia0vp^B0wy`!3-qNPStf`U|?zr@Ck7Zci{N{|38q#L~h#5 zKtTuzk%fx@8JKKbCcyPVbU`#CD|XifSp*@0ve8Z;#{kJ_7fuKp(*(Ft&L#ptcD5I1 zjt^IEAa|Z0SH2Hteh5!t5O;An@057%=~;X;3kB!Zi!ILJS(3rKB#U=xKHt(p{^ezY ztDD8v)C#TZm0aHUlC42`uMGo|eooEm^)h={uxx(od!E@arS60bg+oW`N zvhdxhqIcKJ-Q8+*uTSXScBO|Cg`Z3nemYI$=?sylizJ@U5q&;S?8QpyS4$*bEtPn+ zO!C!o$=53+-|SX;yH@J$dg-?tW#4U(ez#Hj-DcT$o8{hblzzWi=KU6#_uCcT?~?zx zL-ylNxsSW#KJHWccvSh*N!8DL*raOpXXJ6URM8k zP3!k%)!&!ZeqUApeNE%{4b9)Tw13~y`F&ga&sEhw*VX^r(D-vp>kp87SLg3d^}n|? z{@&I6cU$A%9U#*DcUR-zJHmGr|M#{2KL8@_ z{|~kQKLR41|BrP4KXUp1Sm*y^-TzPY|3B6H|5X3~Gq?ZG-TuD-BKQ9<-GON@B&WO| zm?#}eg8YIR7#KOZxMkGT^$pC-EUc`pZS3q5D{JeTnp@jDI=g1go;QE>rtN!=pE!By z?D_K-uRMMJ^5x4{?>~I{{N>xv-+%wT{=fYw(2Q)}xpMZ*6;&6%*lol**W7t(;Kyqt7T-)&AA3A*nqln4tI|ZM%G#~C1 zJ}xWMw{CXi>?{@$llKujr8SD)+}Nn>UZy)gXeN`;72oJRUo`?)IQViRuLRFpz$!9@ zd;Zp>;}4bH`DCp&*jM@T&b3K8=5`YvPj$MTrc+c9 zvAg8qmT8-0>RrPom|OZRmfofAKih2O>U|pOr)J2CDcq|RHN7f&^rvLp28P6hgvq6R zJ*Ut1eJ!4p%3P$_#B;`G(kwBtS(9we@CZ2SFfe>rJ8`GnuXEbP0l+XkK D{&Ew< literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/angry.png b/js/sceditor/emoticons/angry.png new file mode 100644 index 0000000000000000000000000000000000000000..7bec8e4bab65d39fa8be3bcd58ba833d3f2154be GIT binary patch literal 781 zcmV+o1M>WdP)+}4Jch)?7lhN}T&oKa2 zHTt>X-011Wuuf(@&njhkD4M2ad|k}+adUzBtk)jAHXdu<%0bHp34&EB1j?0Y`n?c; zypW0euZjcThPIstJeFl*HGTa|CISr_jCbfTVW!x$7Nad1gsYSo+$q6l52t`{OJiv4 zOi*#lg)w~7_{-&(=+KAf0V(&J~8O^9hPFeO-&n44|c+46gpIbp|yE1e~>lC+$VZ~lBL6}}yX2$xFel=zW|ui0p|4B^8i@NFx=z^^%Q zf1HjV@1mponj2z}r(~~D|GwAK;n|pv!0sYK7(j&%7Sp_EeIELM%qDF6V~Jp6`smf0 z@8j^vJ&ACCpN*lvaxu(+;dOa5-TzZIdcMqn!UQ3J)4Xl?uy5~7so98`I_Sc`vR++<)>(xmd*cxUCsUmJ*Iy3VWQbJ00000 LNkvXXu0mjfU{`#- literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/blink.png b/js/sceditor/emoticons/blink.png new file mode 100644 index 0000000000000000000000000000000000000000..ff529f1216550e49223946ee805750560cee6141 GIT binary patch literal 972 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqMyzV3G;&32_Z~;Q0UlKaivaigp4S z3nZgmI3a9^EzTwa*f&-02u zFRT2#ruO@?;_u5!zppC)zNYf~hU)K|>c4LRk;d;^n!j&r{JE<1=c@9bTk3y+?7Kju z`S+&E-&;VW`uDE--v^q1A8P))t@7^<5UKsUtMc!G`o9O7{~l@md#v^EiPryns{ik) z{lBmJ|GwJ)2SB9$|DpQ-$6Eh^Qctx1Kh^sGR2!Ho?l}Z{1Cxt-NswPK0|O%`7q^U> zx`CO6m332dYkNm$*X()okDoYs>g@R|&tJZL`Re_LPmDJ|X#ka4c)B=-R4^td9AT1> zkZfp}+3oM->e|%bEqSDwV-x4=TNTr$RzzfSZgymyY4NnjTis{=wfpx3l2wkMWD!dV zFPdvmesdYG_wz4i&#g{wZf1!*`bJ$ZFg*PJj>5Z-?)~EN4isCU&|i02=Ihzn=BwAU zpV}hYo>|Py+WO{KLy`l-w3R*^1Q@tZ{qPNK?^wy)xl5$nbHM_ye3e}!|{`DF^ zep6ueJc{CJX3va(YRZv!I}zm;$C^aTv*!n_3+4l>V-_wx1al9xLX a!N9R`TtBz_)LH-f@2?$_T|NN$ zkNo$~gee5+1efOYiRR-OD~_wFaNZEyOoiiGO6(V{*p8ccwN=aXc45eWzs02ZJ)yB? zA;0G*=BaR;x8f2a_wCehFO48A?z?GlN%2JsNym)5-=bmP&}eEF@O>&{y@dgSIqQcj za2&VbzK|NOrlDY_P$b+*{o~$!RY*@;u=sDTVZnZJztxCqnI8Kj6(4)W@uG1QC#!s!!xNsu5o;TUW9uw>Ianilse?rZ zSZ_r3i2dSvKwS44ac>m8o3F(-GJ&_9Vt86NoJHjVrEsXHFlYNx0laOiAgOO6j`12? z3v^;=df4?<<`z=dP9a;PC23|N?*}P)(K?FzH9~1y#1Fakyf^mTRSiOU-&28YbOQD{ zY82L__8%56+tB?!yvUfC(n}xARmJI&hJmy!?)T^A r>rV>oK*4drhi@F0@BXU5{;&KBuZV}c&5;fV00000NkvXXu0mjf6a%Ls literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/cheerful.png b/js/sceditor/emoticons/cheerful.png new file mode 100644 index 0000000000000000000000000000000000000000..c7c5cb8499f07ff2a47573f5cb8f6b054c96688a GIT binary patch literal 753 zcmVRvCV6*Z3k;x@!E*iw(Vz+ZQHhO>*9M=^Ex*@W|GscQ|RvhEC74T(&nM- z?N(w>TuOXM6d3;T{XTLITJz)^>#mo0QA@mzx)J94$U97@XffCingK^>`FT8k< zBlsC2Xd|HwaXwM~?|a^us#L?+sDr76(bBON3$<#@7ArBFB*7oAx`Ce+Vrn(81EJ2YL)Zw*i(eJ5T^5e{PEm9IbKgt;m;S0TvsxandyI@Sva z=bco2E45#x#8jpP{m16Qz+>AdR#WJx##}c4ZD^y6w9a@;`RhTW1VKgcbrC)ilFkdVj zo1~j2s*qX|Bvt_-5_V_+s?bzN!h9(S1JLq|CkqF}!tse58H|*b+Yw7xV5OZ=!_umP zu||QJYzaof{L%80$0}i2OIQ#O8s-)uaD~K5E4{czB^JtLm`V-C;1ORGeeA}V z%oR#`R$F55un#(ZaL3EH+q3Y>l^^zhC*N_$L}DOj^CX+fhK~B6=T{FLe8!Pw|FT0Y zWHj^}4W@tLfiZe>Qz=2#V8~=(td$+~2FnuOa0bN;@UOSw;_%yZ&gj|igOO8yt19dJ z+Y_zdy5Z-i95-GZRxV#J&|D6^?2N+C+|cv82fBZ8NB;XRI6y5vf2;k*%hv`A>_l$5M}W!&F5WSCa}6$WKFH$x?b`1Eg~ByNbD@(JlV7QO7_|&`MZ;a?oJiHyI$sApTNEC@((8pKA9@`beho98A4ANi9Meq{Cu9sisN$!Sil6sLf8Hzed7td(L-L@3g6GGe7~&r^St8E%PK#wsr|mJ`1`Wb@2kqc zuc`dLq5Au#`tMsBzi(;&zOC`+s?wjU%71RD{{gb^0+Ht5n<{^A0g>w8yXt=*X#Rbu z`R}&MzdJyr_V2FBzk90x9;p9&p!x5S*1yME|DI_5zo+{Dp4$KWs{ik+{eJ*N>i-|A z|9_LYcR#bQuaDoJ_jOO-D--WPu>}hKb$hKi)-XU6gsFF!QM=;zH1y?Ei$ZRRa%%323}dPJZ2@};&<`E%*hr%QXD zY+$H%EsJQ7U_GjK oscargruno@mac.com +Andy Fedosjeenko, aka Nightwolf -> bobo@animevanguard.com + +Copyright (C) 2001-Infinity, Oscar Gruno & Andy Fedosjeenko + +You can redistribute these files as much as you like, as long as you keep this file with them and give us the proper credit. You may even rape them if you please, just give us credit for our work. \ No newline at end of file diff --git a/js/sceditor/emoticons/cwy.png b/js/sceditor/emoticons/cwy.png new file mode 100644 index 0000000000000000000000000000000000000000..58ee08f80b3b5d8b0528bb2ddcf784b9f3e54e9d GIT binary patch literal 877 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqMyzV7wCG6XF`~!14e8e;`Q<6zv2u z7Dz_Ba6;G+TkKDKaW)ai_TtR(;mQr<&hz8S_uET4-CsT!=P7`@LL*(fq ziRW`fpU)F}u~Pcg5{Xw!C0;F)e6?Ki&2FW)Yo*?Kt z>Gzvu-fxk4zg^+|F8Pl;WIyhd`?yQ)<36R2N0mRFRQ}wCsn?kQTujA{rf4E@8{LOU)K70UghUy z_1~A(eqUApeNE%{4b9)Tw13~${&P#~&u#6$H`V{%()fE<^WSZae|LaL^WOvQ|MxWi z-v=VC{||sj`~O32U~KOEE}svKX7!RFzhGcIb8>OZsHq#6Sy)*&HMh2Rbau_2H~;vF zlc&y}zw-R$%a^a-fB3|B^OFWpsiLQgV@L&K?uF*6&5ixB&8sWZ;vMa+dN}X6H(ix92~X myjSin)tm13$L^E9Eo0W*fa-mcM_&TNm%-E3&t;ucLK6Twvy<8Y literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/devil.png b/js/sceditor/emoticons/devil.png new file mode 100644 index 0000000000000000000000000000000000000000..7d8226a277a6df575c5396daa51a4e24f348befd GIT binary patch literal 1012 zcmYjP4NOy46h800()WfIhBo|(mR6<1F@_s6)G1UbQQXAJPZ>65Zo+g*F&k_+nA9I| zDk!4qSY#^>Qzl_ZK!-zw8DaoMtZUhzB2a;q6q&8%&rs>zZOx*|cfWh`o$sD=bMHAJ zjo-*|_jd;XPTVF*0^S$l<-<^zR}WbJ1|WIT50hdMLMa|hir57lyc)j{F~2JE|2Mm` zvS21T(xn8rSmfmRa5mB`%Tlr^XDs6~G9PBEh@B#2 z_BSf}+YK4b zYx=)Fr;ryt%sr2;ne0X@6`Uu`lO}5}w2NaE98!~=TkHpYvG?_=CHAYCO098pwC~XM z@N`{$Q(essW!}Y$RkgR5ra45C=?wM2pt@pWnky+s6pR#neb?XjGC5}=-d-s#!kJc5Gs0B7R!PymVCC4ZK z{n@y!sf4>~TZDX^Y!r2Es(zHz$nl+%{aTs(?v9CF%+B*Y;tP8d%lD9g-VzjjCe3UJ z(+x*;`ZlGTN{Sawo6>*xJA78H;VBNBG3~CVw;y5W9u=1zl%8p6P{EtQ**ktqEj@() O2I6AlC6}Xj9{CSQAEAZ- literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/dizzy.png b/js/sceditor/emoticons/dizzy.png new file mode 100644 index 0000000000000000000000000000000000000000..82184642f9284288a0eb154fa17cbb0a37f53f29 GIT binary patch literal 991 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqMyzVA2Ti32_Z~;Q0UlKaivaigp4S z3nZgmI3a9^EzTwa*f&$9|Y z&ny1Ctn%}k+V9IszppC)zNYf~y6W#6s=sfl|Gou88ozI8{=Tj8=c>}5tIB__tNyv6 z`sbGVAE3xxAkzGMOXcrf^}i1^|31|GcU$G(9UxNscUR@#J=K2?)c-xw`uAA#-(#(R zPqhBuQ~iHW?f-q%|M%7YKL8^2{}0vwKhpUBNb~<=AkzB(MEn0!t^ZH8fhi>F`U@3c z(oru7@(X5QVC3ZDmQhnTFtf0-Zfb6A@96BBJ#YT;6DLodJ%8o-%a<=-z5nou@#ZHD zpi+BJ7srqa#^i(}OcD~34GlB9{heH0oBF#Yk2G^^;(UFpV%pS-h)mASj;u2+p7waF zpPOa5aIxYskG{#AIw#gWu`0aRl^Z?n{M+nvrIXUxIX89P^p9G#Zrwi7j^D40bzCDG znrwdQ7GK?-f1mHz+oOrM?l?Fq?*5nh%3+^X$BUId8w41*PW?E0gGYQ$*z`wwoFXA7 z=kF^N4#;2@SU)>z_M5c~A|YpA$8JhI-1hbL_4U!acdS;r$E~9A`m$ZRtVhb*TcMk8 zcP+ZJq_Ih9Tj^cy>nm2TkK9{SmtI=6Vx~gCgmC@ME4^zkdVOVm^{V&g#D7*c3dg&n zpI_Nh>Nj)Ey{M_8vKd;(xIU@1Z%U3ztPBmUbj+$)(5z&wf&$9|Y z&ny1Ctn%}k+V9JXzb`BOzN-BDn#%7Rs=sfl|Gou88ozI8{=Tj8=c>}5>#Bclss918 z?*ftL-wqERmi@(X5Q zVC3ZDmQhnTFtf0-Zfb6A@96BBJ#YT;6DLodJ%8o-%a<=-z5nou@#ZHDpi)~;7srqa z#^i(}OcD~34GlB9{heH0oBF#Yk2G^^;(UFpV%pS-h)mASj;u2+p7waFpPON~aIxYs zkG{#AIw#gWu`0axNq6?Nvv0G{l}<`$=iJnF(?4p}x_zmi(@MYY`^DoOD7HYMzwUI* z*R|1C&6_&DJu=A6Td-h4?EYO=0SrzdY7ra^tf_yNDRN$0y2G1^HT2W+Jch#S%^jLs zPu}BlaJ;(bp6ctXSFf*)UcPSMj@?T4xK%V>U$#qsyQ?(&`kKhiMPbo_Q)Zh41RUA6 zF8$#v)9kSIQHJ|hTiIUm5zsiXdiu>Pw$&HAM7h(-%+lO{z5dW3qn|f7n0ZT8QF?Z0 zSjmEw651zb%be=VY<(K~>M85WhmCw)Z#FO(^7MIo_4IOlG-Y7puz6u}Hnxdrj<3l9 nM|S>{I!#kk&AJMOWJU({^u#v7H8Y!mVb9>{>gTe~DWM4f#N@^6 literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/face.png b/js/sceditor/emoticons/face.png new file mode 100644 index 0000000000000000000000000000000000000000..04ad4b7a2aaf344fb64c6d11d5d4269311cc4128 GIT binary patch literal 793 zcmV+!1LpjRP)u_2(=mzY|^9m zcNzY8p&0jHl>xC1ue%C(B2`cIe*H`_g54&>hN}^`aP-}b`F;~3t$NJtR^hXU^B~sc z8J=AV>TbC(ZL;|n1rH}2HAuQ^0Z$#^u0zsQi-euvArqnExR_lG zW>8;me77925i^p`T1E(?YL7=~(q1D_+EX38+ZFib3EtB$sB|fK`lB~wA=+a?f(GE0 zAmTe$!@*gDgq04zM~~nk6()YGzyp`33-nYe`09qY%lJ@}u9~HY>%XeGq}`0zfDz#a z4Q4l1;irdl1o)B^Y_o1xAx?)2*YXIQk{o8l2MvfcX)w20hW0lK1=uJBy@4hz;=?8y zSO($D3~_b>2lR+EstK%u<)b12PD(+a|ELVCBRpt;295JodNGIIik%PaX7peNsECIhDHrY z4Cx8eBHE;af2RynKbOJrUI8AwG);h~FTSzA`SYoK_;<+=X;6tn;ysD?X*mJSw`mYL zs)T<>6{deJgXiNy{CF4d-Pgj9f+9UVMpFk~D};A*C4zh92p?7wz|nUFf_r4}Zmhu6 zkEM+5d@LI@Gs%zMYA=UR?#YJd`%=vQRgO6V<~CID_o<&sG5%!{tZ(Pz!#groe>p6E zecg9yI(~XE8_loe!}Dn&+#eO7@!4Gba91Yoy*O?4*Vig9*cYfKD!}n~{%`dc>{|9W X#NehlfXChQ00000NkvXXu0mjftdMl% literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/getlost.png b/js/sceditor/emoticons/getlost.png new file mode 100644 index 0000000000000000000000000000000000000000..ac87dcea2511cb5276398989cb23c5f434c3e462 GIT binary patch literal 792 zcmV+z1LypSP)eTtlbqs(* zg?rp`VQesQ#OcJ#L0o7iEG{S~qEJk{_2`X>IQm`=#*1Ze^lD)5Qe*UQ3I2H{ z6AxdP09J<(M-v_)P9#RZe<2I@VJ$q<26*QfdivJmU|b7VuNu2GGJN%TDp*}U=SVoA z_Kr*Awz~h2a3bH50sd7Zux0{QP4KT6;afDoGo^!jKn-iX42|z);f{-AH&|}4FoF2K z=)+uiX7unc8<~X3c$k16P*<`z0duzmv{{okF46MnNz25X%7x zeFw2bamJz!-U$+R%1M}yxz93~a7!q(SlblvP^*5b94rxt2rc~c8hFN3aJI^@SCEIf zPtrq#19JspZlZm2d}5F!z&tJ7v>FEk3fSu<*#092J+G!RVYg8DcEPKe+?;sE)$q?! z;(|c3z|fG4Mlhp>XG95CyA0;iJZyZQiC-T`WWqOu!gC(KJ^|)xG2Gp9HXP~&CC{lz z!i#39_ft%!fV)cuYn2Gwzh`6Vqcl8vWgHWp9lWuB`1iRqSgS>Fb;ttS!#k!Tl$_|G zPYzd`6xK=+cK*!9+UM!`^}Ylq`<^+3LWYix(RSlo=`hpE+3Un`wnzeE_HC~f!CaJ! z?O(GvS=CcXpqwps^rBu4Up$b6wV$)G_g^mdi-^Kp`p&`jZ`s)RHUsnTr{dFl5~5!Y z!PnPAG%vqBnuP8*QnB`BI#xeRL+6Xh_=Se};N@{quCM49>?=eUVdLrI%c5Vfhspnm Wr;i>N%`IgB0000w3l4w}@=$6W=&NVrL2Ofli?Vy`m=?_)fJ8oLVk> zx<%kzx6qYUve!1r-<>RUcdGE+^)mPR1nzB@e>hR_$yC9o(}bSR5PG^u?D-tw=kr8f ztdxAUMD*2Cu~*B)UM&}Yy+Z8GZuz%s#ow-#c)MQm?MCT$8zkOslz6vU>fL7P_nW2O zZ5u#5KOR;5bW-v2UYXB_kU4b|T_)qmdtB8}g-G=JaL_;W+`&n@*oK*n7l(){~C z^Y25=e-G6EJ<|I3So7awt$$Cn{y$Lv{}6~Y{yzdD&Hs-z{yzqiTK}JD{s+oF(f;F@2U~D=#C$9oVvwBI8UobG9Ik~uH)YJ{kEUc`Xnp@jDI=g1in}7Vo$x~;~UwQuW z<;z#^KYU`m`AGw)RNT|WF{FYq_X2Y{6N8Au!<^ge%x`bInsa;G**E{*#GT!7{QgH( zf&ZNjDhVlK{)rnkDs+q(tDR?AY+X`VyLF+4r%$!JQ1JA5V3TdM#!`i%OW)r!sB$p!%dGjLwpq|Mb-Dk+ z1cL{kf9~OTmwwF3a9O=H))Y|)8jJaXi1i50`LS-c(BjwW{;st%OM z?pnC*DZ`@q2NUK>1qSWlOoJFh$P)<vrd=TL4e zq4DMmQWl$jRfs6r>rbt8DnKY((vC>TB#QH-3t8tIIr|`B2_9p?UC!#;qNx`DunF(6S5i5 zD*xr*w$K=DzgrJ?l?n^Lmf-%&Qib#ssqmF8Zxzv2O|&)3AtH{sjsFv7jsyJ$cE;aUEGi!>+Kr2%M@7pxd_cK@J%;Kg|BUXA)n7A(5FXu zgc8Rkl5v57WVC}}Jp$cY`07-!?mJp{vqh-zSH^NiDX+HyIw) zvxG$>wE96I)4<=Tf^)A7OFtE2^4%Ofa7l^~o)-DT{`!w6bKu-3gRfr2TOuhF?A5Yp zy;TigtrE^XGA#d6h}n;F@xz_`uD=qF$fswbXS7uDYA)<_bMAw3c&imGAUJj(kiovS z7)w7Cux#(68K9g+etL literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/heart.png b/js/sceditor/emoticons/heart.png new file mode 100644 index 0000000000000000000000000000000000000000..451058d6d02646eb1b0fac70cde05c02c9864d28 GIT binary patch literal 572 zcmV-C0>k}@P)xZEyy?R`y=9^UeZv$sUe$-T>!cM1 zkZs(pGk#hUyl8@t?1I~_6oe^S&+{gww`K}`Pun2e|5ghJq1?$-bU1ip+5b#-9XiM417EWeG zqHAlLugifCw6Ze^;286VCy0w(P~asa`g?;X3WA@if~=>o=$g+;gLevmTf)I^9#*Wk zxC`uqMlLBQ_t!)!QpR{(6ug-R&JVOgm!+6w7dQ@nD^NB}2>`F8fakTv@qSiptpo@R z$3Z(DvUIvaGkmSsO7jf(yP)CM&JFdYf!)gfJZNM#fZqxJS6={J%R+Dw5WwsJ0000< KMNUMnLSTaAWev6f literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/kissing.png b/js/sceditor/emoticons/kissing.png new file mode 100644 index 0000000000000000000000000000000000000000..28d775242312a519611bcf2b29752c4765abb2cb GIT binary patch literal 793 zcmV+!1LpjRP)0YJwXLyT+YM@4acxAkZQJg(eec?~?H$i#GkE*`U-j=O+9c2Md5+I90M-=_ zu0JO^k`&@3;yI$0urr+IvXi(?M89~#a^lqou1UwnH%rj7RRK?v4(@s_x_*=3_vZ_7 z-<4?)+Hl(h!VQFt==$pELby8&2n?7I9A+qO#A=TLz9ub}_9^h`Lpc!I{?lheETQJ+ z3sUAAewK0P(6|}lDGM-d1*WVBPg)QfBXPe0{#GrV2NgK{W+84qFL_qz8!1d9zS{Cm zDFTB=geNR4AsJ!$ACiX0%q;aaX<*+a!_SZNOg|@5#lq7bxjqB_P6N%tOfnYW{1dV{ z4aUrQOqdZGq2+gK;XbOs+^=Q0|FTp;dWu;1%I3F9c&Xt@77{FE5hfYVW70&kG$PQe zhqqRRiCH@>D zzpr~QNyU#3WTN5aTugtGkEsvyQ1?tWzP~da_gs{c`1?xm!9Gva6E23+T$b>IU041B XKE9Q6@a!0~00000NkvXXu0mjf6^?Pr literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/laughing.png b/js/sceditor/emoticons/laughing.png new file mode 100644 index 0000000000000000000000000000000000000000..d65f35ec82967bee26777dbc0deb39f2af387807 GIT binary patch literal 912 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 T^SL{P00000NkvXXu0mjf0kd`( literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/shocked.png b/js/sceditor/emoticons/shocked.png new file mode 100644 index 0000000000000000000000000000000000000000..f3dfb11f8d22ddb7d678befd190322f0df7d330b GIT binary patch literal 780 zcmV+n1M~ceP)%Z-~r5!eHV=V(9x9l3*TC!ZD$NbDBd<*J|vJC}Hc8W2;hxuO5#D_w8OxurHzV zj!VPVJO0RGqDxMVWnftcEa~80)E+#u_sU_c5uxtAB;0Xv=qeZMDU2Y#&;KwLj!88y zA_+STyI;`2HABN6 zl*8O0!rEVHc;xDEPI{(L_-5YwDKu0S4UL3C!4lms^050wHD#%SV^jfas|4Hm8Tjq- zXioT=P}n_FDuR=Si$zW*6lj@JNMN@HYbh|Iowke zILicV-h{X(#`H$l8=#^od@NCbG{lmY{#lcvS0b8qx4T&;g5*!o6U>mwQ8^*E> zZ2p;y<wT=QzvmpDrKh4Y+NgUg9(r0ib9E-Hjagn9>hn{v@oN&3l|K~)idpAM zFJN={;(;hE|D25N|5CA&PvoW2bqY3qOUCNA37C057N6b|;n^Glx37n2UVeKt3LS66 zV)@H>EPWP-wil!E3k~tX%fkYY&p&wKVeTF3jdDiX^EVMA<@NM@BxVUd&vS9TUq&SzICW!9`=)~;pNuV*u8 zW;SSJG-+is>tMB>%w#i_(QXpE(^L+pSEGI`JE@?OsDyO7IwC9~fmuAsH7LF-t8dxavmvPErYi{8c-vz;ww2V2}O_V^uK zi92|b4{)R(RpW!Ju!&PvWyW|3Q=|!H3t9+H$ zc&o1SR^Q;QxxrU^o3HLRU;Q1vhI{(y#B92i3khQeSdTV~X&i04;&7C&f;rFqut`+9$Q(+~4G{fByb_@!x!VUWZn4 z&MwypDi>GA|L>9vt-Z3mk8_qd%RIGN<=lmPd!p{M9ptLC)Ct`G=j~Mn-BvT@C#s%t zGw(fq7jArEt6Kqsg4v_5OI|U!WP)sma(ylZQFMKv2EM7(e57hms>Y_qh8J8yjQxXT!#TTQ22BG zIsQ8dAWkBlBWei?!)Y!%iQDXm+fSHGy!ya3!8r700(vr3a5fp>sMn+GHyM6^J{I>~ z83fUW+xie5P8>sYef4xK933WX3><;YVTRIXto4}SZqj3^P=!w)ihyX#F&w*FsJr=s zfcb`>6&$=Zek8n8M*-7E15-!CJ9!kg#z@?6f~QpvTZsx~Z^q*0^ZaK;>`q}2@m2ae ziP#u4!#i;lOGri>#V{m2|AcS>jZ_Cqt^z+l&LjPt2$Tv>d*u2McsflqiX%xTk%%;N zB$$aKS-94zhoeG;xnGlT|7C$fdWux|O4?fqJXP-`2kZiqM-oRcBEQjVgsWDA<@6N% z_)wS-z9RmKawHEg6H9*IOEVZ_M7wN?!rB?>J3oPfp`c&8hr!q-w?h~YKa=rO=MMAA`- zWYowAnRn2@LU)Z4maJsVeie%!?hX;cm!-nfAG#_CmI66E4H}-#)&Plz4J={NkO5o$ zdX@=n`7$j0lz{Pfqwv5b0YZ4%&V&8+A5TWYRv?4BR>f1==+t4eTPvWn7HiEKxT}@0 z<)vWpmjq0I6pbJ5Zrx$*V$Ltp|7; literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/silly.png b/js/sceditor/emoticons/silly.png new file mode 100644 index 0000000000000000000000000000000000000000..d4497d9aee01396181aea5545c6fe0dca0109df9 GIT binary patch literal 930 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqMyzVEi566XF`~!14e8e;`Q<6zv2u z7Dz_Ba6;G+TbxYw3l4w}@=$6W=&NVrL2Ofli?Vy`m=?_)fJ8oLVk> zx<%kzx6qYUve!1r-<>RUcdGE+^)mPR1nzB@e>hR_$yC9o(}bSR5PG^u?D-tw=kr8f ztdxAUMD*2Cu~*B)UM&}Yy+Z8GZuz%s#ow-#c)MQm?MCT$8zkOslz6vU>fL7P_ZubN zZRu6+iEh{=8S_^FGRQY^K?aLX}uZLy7 z9+CfgT=Cmcxo^kiznxI{c2e=%8KrM$RKA~5_kYYQTz8m z{of<4e~&f)J<axjH`bc<@hWMQr@qlfRFtst7oT{fXaQUAxoP`o;g{3duU9-ViwP z^JoiGH_s64NKH?|Qx-DngyP!LpG#4!_pVJlrkv&E)?A#z(C`H(RTJcxRbY zd(4MXPQdljG(WxEocw$pzYuCw-AHKZ*8hBkwztDnm{r-UW|D6p}* literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/sleeping.png b/js/sceditor/emoticons/sleeping.png new file mode 100644 index 0000000000000000000000000000000000000000..2b97a8033ee0907a0600015f7d1c576b6cafb9f3 GIT binary patch literal 1039 zcmeAS@N?(olHy`uVBq!ia0vp^B0wy~!3-oDVtf1<7?|_|d_r8q9XS5~{|_W-fufy2 z#sbM`7fuKpVvDnhK(-fWjt^IEAa|Z0SH2Hteh5!t5O;An@057%=~;X;3kB!Zi!ILJ zS(3rKB#U=xKHt(p{^ezYtDD8v)C#TZm0aHUlC42`uMGo|eooEm^)h={u zxx(od!E@arS60bg+oW`NvhdxhqIcKJ-Rl#&w_WMsMByh>g`Z9nc{)Sn=^}~eb3~ud z6ML~z`qdJNS4$;cEt7n;T=Mk_$v3-|-maB;yI%V3M%i~8q~C3nez#fn-DbJ>n`Pc_ zk$Jye;r%Z8k2~c)?vnesPwC@PvTidzMWC~c1HdCNu}?nRKA~A|9)BP=UJ7X=T&}Q zR{wcT>-S~V-XUseBoP2=}<&EGdPf8W&leM|fIEuG)Dwf|gI{c~OY&kc<~x3vBM zxp#H`-c|MxWi-v=VC{||sj`~O4j|Brx3=l>(!|BrS4KL(O||DWjo2daFc|Np7p z|EKyJJ56r^6OejIkY6wZ10yFFw~U&)ftiJsbyIU|dq-#2?0NH#pE!By?D;FtU%q_# z>ivgLj5j}N0F`EXx;TbZFy>xho-Q3A(DpDPSNYr8+}mDjuWUPPv@LLV@7en8#mRe* zpFeZaT|r2&FG60SWvyi3%e{<&m(3LzA98dA@G7sX$aIVmp7gsdtzys2g?2@}yN`+I z-}?XOeDllHYjXO_8mxIvYt>zik9w$*$UFZypk`~Lmg2j3jKVY&6{ zH}mil&p*Gke|CNQHUBaOKApcGRA--0-#pXj(d1tzU$*{jNRHO|A7IuTq%qUQ?c>u@ z<%TWF??Tubj|g^IiC+JHj_H%!4k3k)6*^MA7EiA8ZDRQO-FJVt5N~_^%lKHUhKY3^ ze+`+KSZh`tfBrpyQQb_N$KL5-fq}%2Ws~pOY)um>C^-4Hyz2gWhX=dEe}6l-b8$Bt zgY|OrdsA1IlhBw>zi+Dlz6C@Yzi(;&zOC`+y6T@Bs()^&{{gb^0+Ht5n<{^Asrr%D;Q6{~oCSd!YI6k=DP*n*Sba{d=PI|DNjqdusphtNy>Q z_WuD8ssDcnL>m7e0g>ka#~S}114*s_Pc;7n6+hAb|5WS$Q|t;0FJHcT|KStk%}*LYrM8|fjv*C{ zsS`{WU2_m|+dsSK&&LPvEy;hhSz;wA>BX5k#0e<=<8)2dtA*dM*xxpBj_O?P$vm-NJi9X9PTp5}XZ z(c4>b)3U!_zJAQ;c3$?=?`zApHu%?VaF6|8cKGq4h+l>ITW7`Rbsjl)IegN=e2aJM zL?2^L3ucVkf3az_4fVboFyt=akR{0C-T%{{R30 literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/tongue.png b/js/sceditor/emoticons/tongue.png new file mode 100644 index 0000000000000000000000000000000000000000..73da3e34ba3840435b21ef55c80188ea3841f60c GIT binary patch literal 981 zcmeAS@N?(olHy`uVBq!ia0vp^A|TAc3?z4jzqMyzV3H5;32_Z~;Q0UlKaivaigp4S z3nZgmI3a9^EzTwa*yCeLJJ_{iOW&QwrbDt9-w#_Vc{r&&w)5 zuc`gMtn~Y;^6zUZzptzQzM=a2ruy$&K&0{emgeu<8h@@T|GBRE=Z5N^Tk3y++`B-e z`S+IU-@EF6A87u4sQK@X+P}Lh|L&>&d!YXBk=DP*n*Sba{d=PIpNZjrZu44EyIT4g8&ya+rN5k9l3~ z61ORL-psu5sp8<^h1Tuem0gj;7;_=; z=h?bIH&+#dGv(gWx2&ud?0Yi#Z{Ngu`cK~Mo?rj}&yPRo{+)c?|er4V(VBj-&y85}Sb4q9e03`9*5&!@I literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/unsure.png b/js/sceditor/emoticons/unsure.png new file mode 100644 index 0000000000000000000000000000000000000000..87c7599719d6be5d1766b657921f69e45cedf2aa GIT binary patch literal 763 zcmVwym<)wl`SYiq}T8w#~6UZQHhOt6Y^%;h+1?=%qA#$@g+~zUzAdfb$Cd zp1du#-1|{hWxtED204Di|A;=s6(3!7t2tj+E7~`LO;f3jGir@#=+R7foEHe1k7`>uEJo(mdxLhU>m*= z&Z$c%_}J%~CaI-G0d2krdq1R+Ze#@Ug*UwSWGJlN8aO6sWZ-|E^6TA77^@^$*q@9y z9|+>4*YSnlW&DyzQ*}-s6M_N>PkCFv8s>T#Rx?wv`<-x3_%&bHI+ibiolO^~DYOr$ zU}=V(U}EIl`plJjuA4;AGBW6>QxKSn9;k=A>YL zOB{B+8p;X3gv$N}w+kU};YxCV!8{ zTlWQW!W&!<_SQomM?qgCfTdnSi_eY3-YX~go1!mB#qz#H%>EODT`$w002ovPDHLkV1lV$WP<7?rClj>j2XnZ}Q`0a%9x05PAFRTB)s{Z?i=I>kD zf3B<{v+C^3>V$SDwFo`SR8K51$xse$oI% zlBbJfNCji=1?J*rM+ue(-MP0bvu|&EYnJ-vzy00!NpF76l-3pg$|-E<=F+pgPIQB2 z>GKYcD^=+xudb|Ct+*1HCmDOMy83Rc%%&5sHNt*&YE1og(C%q?r=`}RkhNhe4}I@# zaB`R_tG{HQ{*5ILZ+CpiS+_co_rjiAA3vAfi+IBm3U+`=Mk83Ml8`0XfZQHhL+jhq@X$Ie(bLOTQWGCuPe%IeG|3e=D zg9bDgnoGm95?7(ZMF`D4SSutjWeU)DCk1(1qNwnrvrw(e z6vA31V@-mV3Z0H7h3hjFmWyHf$S1;N)b5L>!cJ$QM*EHrONEp+hYF~au#bh&D0f^r z>~&IDO2sg~O-JvIMAYty^bqFP-bi5`ZL5_6RNBbVAajMtY*iBU=L?{Jo`$Xq@yK4w zMmoz`xcSD~Xx1l|G70Q8L|X48sh3ii%w8>lrC0>h`*f)9CZYX!49?C7ros)*!XM@j z4}|)0D$H2|)*M=ey;edboTx?uTcw!DgfM6Fpna5ruJiF|+!cwr|N2wm_wEz>#MNaH z&^}Iq=>v~7iB@7Q6*8!(KUVDM$ oHrO?UOoEOhlY8fVgB?sh0XTn_nkWgd9RL6T07*qoM6N<$f_mL}CIA2c literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/whistling.png b/js/sceditor/emoticons/whistling.png new file mode 100644 index 0000000000000000000000000000000000000000..3940f0d8215e74f6fb86126b8005e3f95c2eea28 GIT binary patch literal 1072 zcmeAS@N?(olHy`uVBq!ia0vp^;y^6I!3-n=6T)m57?^?rd_r8q9XS5~{|_YTiK3lA z)3%2G7!bzNLly%gY3pcgwDB7F$y*w60fjeT(RZKFN&}qz-h79OxB0 z(I9YQg2<_Mp;OBh&b11j>lV4xCwyg<+_i}!*ET8LSSWROz1+R+N{{v{J)SB0c&X&$ z)iO_}3O}78@^q2J(_IQL7E8QXDg9!V#N@P4Pl`(5%McgTL+CHHZk(#HexACD@3+9UVrr0VCr@}Eztf4-#k<)Gr1 zLrP!HXnZ}a`1QE**Rv|$jw*gTru6N&(zlZ;-_EFiJFE8nl*;#Ws^2ebeZQgcR z{C}+b{|ON3|9`3nOiNj_OPhg-%%CL5FPMRWk&}y?S6oI`P2IrE!pb@zv8<`NwWG6Z z_PqHkw;eft;^gVG=dV0}`SR8K51)Sh3aaus0n`)g>Eakt!I+$Igik_3vY}ySxQkSZEI&{(v*_bC(hb$74vq@nPxyi0{>r<1c;=3#BVmACgz{uQOTWu~a;i7)D zHPhip>8bSGd)xEh&$C@E_WjG(GLg27&5cJxmDShW*qeTSU2J!_-t7&kFPG%hI&Rpp zB>nc6UhDF=w>D-Ro0ZERzFW%mMB`Cboo=h;y7#x#{(iHrb90*CMzfw!w(iZRc1+*$ z&3~@_{*_zTZCtv|;&PmXP~M#=yPu)FXV0dJT1sZF{Aadljzgixj+<&}PoAZy9A}yN z@+9|0<<`xe!46J)<}Wrhm~)UpPJfZtu3cV>PJC>VWngH2RKk-Owr3wOk{CQ){an^L HB{Ts5%ZKa> literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/wink.png b/js/sceditor/emoticons/wink.png new file mode 100644 index 0000000000000000000000000000000000000000..3d1a9cc0725bef494cd960fcff0ad294e44444c0 GIT binary patch literal 791 zcmV+y1L*vTP)*z?q>i6$z6;)!IZ!Aj-g@-LFr>bhh~7*Y9L*Zo8`S9jTY`UHiNnL! zg@V5!#D@t3h!ctK?_Y?Ay;BR%paI?yMo-szto3T)YF1;pNQSQ-j{<+YnF-iWsJ-LT z;DyFNBrJk&!T|rY5tuOn(7YiD6;AP-wQ%OYfkL zLc1jbCg?pwE%f%0uwG8W6pVZp%fbbr&|F9 z$R{y-gl!{fVjk!X;rL$3Hls9ggKDg`DPS*^VDXPcG`$+d!bYL+?X*|pcue5w-IR_A zBx8(*WE%K~)bMmE;i{FvoSlrh@8j_617R$DLnu7w@#{ljE)>JvDCh356#fx4Nj62p zYWN0NrhvOa25W%`i@zse;-hFhdSx&R&)&VTfB5&gXjltHaMj7UODtvJ?NPD_Yb|oP zYNW8{i?H-(0%kss!LRp)vg~_y2!)J}w$WnwTQM-x%-KuCa8^lJ!0A_qAMOAE002ovPDHLkV1k#Le$W5_ literal 0 HcmV?d00001 diff --git a/js/sceditor/emoticons/wub.png b/js/sceditor/emoticons/wub.png new file mode 100644 index 0000000000000000000000000000000000000000..d5faa2b605b5d4890adb314da8754dd360d5c8f4 GIT binary patch literal 1010 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz5!3-qlM(p{{z`!IK;1l8+uE6pC|9>D!3ly!u z1vEBFfiqf(J6aLMh9GAFg=_`BY$btQCBa-Zkvs+dJZq%I_Z6M^85I-53#8q;!{6l=6y^^|Cp5dF}v_%PQj=0iqEN8pHs6xXXJj) z%KuzY@+B+(OMc1Mto*Mz1z&RtzvdQx%`5umlkg2l7M6aisQyu0_M^P&M@7|-%IaSg zRlh2#e*qblHNUEAe$~|es;T=`TlcH3{#QK^HT-G-qQ>9VHNR_Wf7jOi2C^HQem6D! zt*`&v(D1jR@o!_(Um&-+`EOg>-;VZwP0jzBfvDwQOUu8uwtpQR|2jMVb#?u3ZTa8Y z`o9f`+Wxn<{qJc1-`VlMs}qE^Zk$bptaCE9<7_*7lCh zuG#bEA3t&O)Y}a<<`Q^X{z3V#8tKV;^zI*8DYq15BCW_8~exJ>DgF92RBg4McxwqqUZ*K#l zZF$$X^~T>=a_z|b!)NXrZZH1S+3}%plktBO?e8s3v(`R+b;qK7wYkw|Uax3X+;aei5s`ykzeTk@1Jb^;>%g4TJKDI%F}i!mH5oD+4r<#sgPhd z!)4pvk9-`udq1abJHJjtgy}#?e0JM()qj(GD^A|{^XuKaTX!(;E(mlhY6&R4bm?dtl|a{u%{|NCv2Gos23oiZL50^^6l)78&q Iol`;+01z+H<^TWy literal 0 HcmV?d00001 diff --git a/js/sceditor/example.html b/js/sceditor/example.html new file mode 100644 index 00000000..c6dcca5f --- /dev/null +++ b/js/sceditor/example.html @@ -0,0 +1,117 @@ + + + + + + SCEditor Demo + + + + + + + + + + + + +

    +
    + + +

    If you are using IE9+ or any other browser then it should automatically replace + :) and other emoticon codes with theit emoticon images.

    +
    + +
    + + +
    + + +

    SCEditor is licensed under the MIT

    + + diff --git a/js/sceditor/languages/ar.js b/js/sceditor/languages/ar.js new file mode 100644 index 00000000..ac7b0e52 --- /dev/null +++ b/js/sceditor/languages/ar.js @@ -0,0 +1,68 @@ +/** + * @author Atramez_Zeton http://onyx-sy.net + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['ar'] = { + 'Bold': 'عريض', + 'Italic': 'مائل', + 'Underline': 'خط من الأسفل', + 'Strikethrough': 'خط في المنتصف', + 'Subscript': 'حرف منخفض', + 'Superscript': 'حرف مرتفع', + 'Align left': 'انحياز إلى اليسار', + 'Center': 'توسط', + 'Align right': 'انحياز إالى اليمين', + 'Justify': 'ملأ السطر', + 'Font Name': 'نوع الخط', + 'Font Size': 'حجم الخط', + 'Font Color': 'لون الخط', + 'Remove Formatting': 'ازالة التعديلات', + 'Cut': 'قص', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Ctrl/Cmd-X متصفحك لا يدعم اوامر القص الرجاء استخدام اختصارات لوحة التحكم', + 'Copy': 'نسخ', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Ctrl/Cmd-C متصفحك لا يدعم اوامر النسخ الرجاء استخدام اختصارات لوحة التحكم', + 'Paste': 'لصق', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Ctrl/Cmd-V متصفحك لا يدعم اوامر اللصق الرجاء استخدام اختصارات لوحة التحكم', + 'Paste your text inside the following box:': 'قم بلصق نصّك في المربع', + 'Paste Text': 'الصق النص', + 'Bullet list': 'قائمة نقطية', + 'Numbered list': 'قائمة مرقمة', + 'Undo': 'تراجع', + 'Redo': 'تقدم', + 'Rows:': 'اسطر', + 'Cols:': 'اعمدة', + 'Insert a table': 'ادرج جدول', + 'Insert a horizontal rule': 'ادرج مسطرة افقية', + 'Code': 'كود', + 'Width (optional):': 'عرض (اختياري)', + 'Height (optional):': 'ارتفاع (اختياري)', + 'Insert an image': 'ادرج صورة', + 'E-mail:': 'بريد الكتروني', + 'Insert an email': 'ادرج بريدا الكترونيا', + 'URL:': 'وصلة موقع', + 'Insert a link': 'ادرج وصلة لموقع', + 'Unlink': 'ازالة الوصلة', + 'More': 'المزيد', + 'Insert an emoticon': 'ادرج وجها', + 'Video URL:': 'وصلة فيديو', + 'Insert': 'ادرج', + 'Insert a YouTube video': 'ادرج وصلة فيديو يوتيوب', + 'Insert current date': 'ادرج التاريخ الحالي', + 'Insert current time': 'ادرج الوقت الحالي', + 'Print': 'اطبع', + 'View source': 'اظهر المصدر', + 'Description (optional):': 'الوصف (اختياري)', + 'Enter the image URL:': 'ضع وصلة الصورة', + 'Enter the e-mail address:': 'ضع عنوان البريد الإلكتروني', + 'Enter the displayed text:': 'ضع النص الذي تريد اظهاره', + 'Enter URL:': 'ضع وصلة موقع', + 'Enter the YouTube video URL or ID:': 'ضع وصلة فيديو يوتيوب او رقم الفيديو', + 'Insert a Quote': 'ادرج اقتباسا', + 'Invalid YouTube video': 'هذا الفيديو غير صالح', + + dateFormat: 'day-month-year' + }; +})(jQuery); diff --git a/js/sceditor/languages/ca.js b/js/sceditor/languages/ca.js new file mode 100644 index 00000000..ad26f5f6 --- /dev/null +++ b/js/sceditor/languages/ca.js @@ -0,0 +1,68 @@ +/** + * @author Fran Sobrino + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['ca'] = { + 'Bold': 'Negrita', + 'Italic': 'Cursiva', + 'Underline': 'Subratlla', + 'Strikethrough': 'Ratllar', + 'Subscript': 'Sub\u00edndice', + 'Superscript': 'Super\u00edndice', + 'Align left': 'Alinear a l\'Esquerra', + 'Center': 'Centrar', + 'Align right': 'Alinear a la dreta', + 'Justify': 'Justificar', + 'Font Name': 'Tipus de Lletra', + 'Font Size': 'Mida de Lletra', + 'Font Color': 'Color de Font', + 'Remove Formatting': 'Treure Formats', + 'Cut': 'Tallar', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'O seu navegador non acepta o comando cortar. Por favor, empregue a combinaci\u00f3n Ctrl/Cmd-X', + 'Copy': 'Copiar', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'O seu navegador non acepta o comando cortar. Por favor, empregue a combinaci\u00f3n Ctrl/Cmd-C', + 'Paste': 'Pegar', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'O seu navegador non acepta o comando cortar. Por favor, empregue a combinaci\u00f3n Ctrl/Cmd-V', + 'Paste your text inside the following box:': 'Pega o texto dentro do seguinte recadro', + 'Paste Text': 'Pegar Texto', + 'Bullet list': 'Llista d\'Vinyetes', + 'Numbered list': 'Llista numerada', + 'Undo': 'Desfer', + 'Redo': 'Refer', + 'Rows:': 'Files', + 'Cols:': 'Columnes', + 'Insert a table': 'Inserir una taula', + 'Insert a horizontal rule': 'Insereix una Regla horitzontal', + 'Code': 'C\u00f3digo', + 'Width (optional):': 'Ample (Opcional)', + 'Height (optional):': 'Alçada (Opcional)', + 'Insert an image': 'Insereix una imatge', + 'E-mail:': 'Correu electrònic', + 'Insert an email': 'Insereix un Email', + 'URL:': 'URL', + 'Insert a link': 'Inserir un enllaç', + 'Unlink': 'Treure un enllaç', + 'More': 'Més', + 'Insert an emoticon': 'Inserir un emoticon', + 'Video URL:': 'URL del V\u00eddeo', + 'Insert': 'Insereix', + 'Insert a YouTube video': 'Insereix un v\u00eddeo de YouTube', + 'Insert current date': 'Insereix data actual', + 'Insert current time': 'Insereix hora actual', + 'Print': 'Imprimir', + 'View source': 'Veure C\u00f3digo', + 'Description (optional):': 'Descripci\u00f3 (Opcional):', + 'Enter the image URL:': 'Ingressar la URL de la imatge:', + 'Enter the e-mail address:': 'Ingressar el correu electr\u00f3nico:', + 'Enter the displayed text:': 'Ingressar el texto mostrat:', + 'Enter URL:': 'Entrada URL:', + 'Enter the YouTube video URL or ID:': 'Entrada URL ou ID de YouTube', + 'Insert a Quote': 'v Insereix', + 'Invalid YouTube video': 'V\u00eddeo de YouTube Inv\u00e1lido', + + dateFormat: 'day-month-year' + }; +})(jQuery); diff --git a/js/sceditor/languages/cn.js b/js/sceditor/languages/cn.js new file mode 100644 index 00000000..b5a4c01b --- /dev/null +++ b/js/sceditor/languages/cn.js @@ -0,0 +1,68 @@ +/** + * @author + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['cn'] = { + 'Bold': '粗体', + 'Italic': '斜体', + 'Underline': '下划线', + 'Strikethrough': '删除线', + 'Subscript': '下标', + 'Superscript': '上标', + 'Align left': '靠左对齐', + 'Center': '置中', + 'Align right': '靠右对齐', + 'Justify': '两端对齐', + 'Font Name': '字体', + 'Font Size': '字号', + 'Font Color': '字色', + 'Remove Formatting': '格式清除', + 'Cut': '剪切', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': '您的浏览器不支持剪切命令,请使用快捷键 Ctrl/Cmd-X', + 'Copy': '拷贝', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': '您的浏览器不支持拷贝命令,请使用快捷键 Ctrl/Cmd-C', + 'Paste': '粘贴', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': '您的浏览器不支持粘贴命令,请使用快捷键 Ctrl/Cmd-V', + 'Paste your text inside the following box:': '请在下面贴入您的文本', + 'Paste Text': '粘贴纯文本', + 'Bullet list': '符号列表', + 'Numbered list': '编号列表', + 'Undo': '恢复', + 'Redo': '撤消', + 'Rows:': '行数', + 'Cols:': '列数', + 'Insert a table': '插入表格', + 'Insert a horizontal rule': '插入分隔符', + 'Code': '代码', + 'Width (optional):': '宽度(选填)', + 'Height (optional):': '高度(选填)', + 'Insert an image': '插入图片', + 'E-mail:': 'Email地址', + 'Insert an email': '插入Email地址', + 'URL:': '网址', + 'Insert a link': '插入链接', + 'Unlink': '取消链接', + 'More': '更多', + 'Insert an emoticon': '插入表情符号', + 'Video URL:': '视频地址', + 'Insert': '插入', + 'Insert a YouTube video': '插入YouTube视频', + 'Insert current date': '插入当前日期', + 'Insert current time': '插入当前时间', + 'Print': '打印', + 'View source': '查看代码', + 'Description (optional):': '描述(选填)', + 'Enter the image URL:': '输入图片地址', + 'Enter the e-mail address:': '输入email地址', + 'Enter the displayed text:': '输入显示文字', + 'Enter URL:': '输入网址', + 'Enter the YouTube video URL or ID:': '输入YouTube地址或编号', + 'Insert a Quote': '插入引用', + 'Invalid YouTube video': '无效的YouTube视频', + + dateFormat: 'year-month-day' + }; +})(jQuery); diff --git a/js/sceditor/languages/cs.js b/js/sceditor/languages/cs.js new file mode 100644 index 00000000..acc65771 --- /dev/null +++ b/js/sceditor/languages/cs.js @@ -0,0 +1,71 @@ +/** + * @author Daniel Vítek danielvitek1@gmail.com danvitek.cz + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['cs'] = { + 'Bold': 'Tučné', + 'Italic': 'Kurzíva', + 'Underline': 'Podtržené', + 'Strikethrough': 'Přeškrtnuté', + 'Subscript': 'Dolní index', + 'Superscript': 'Horní index', + 'Align left': 'Zarovnat vlevo', + 'Center': 'Zarovnat na střed', + 'Align right': 'Zarovnat vpravo', + 'Justify': 'Zarovnat do bloku', + 'Font Name': 'Výběr písma', + 'Font Size': 'Velikost písma', + 'Font Color': 'Barva písma', + 'Remove Formatting': 'Vymazat formátování', + 'Cut': 'Vyjmout', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Váš prohlížeč nepodporuje tento příkaz, použijte CTRL+X', + 'Copy': 'Kopírovat', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Váš prohlížeč nepodporuje tento příkaz, použijte CTRL+C', + 'Paste': 'Vložit', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Váš prohlížeč nepodporuje tento příkaz, použijte CTRL+V', + 'Paste your text inside the following box:': 'Vložte Váš text do následujícího pole', + 'Paste Text': 'Vložit text', + 'Bullet list': 'Seznam', + 'Numbered list': 'Číslovaný seznam', + 'Undo': 'Zpět', + 'Redo': 'Vpřed', + 'Rows:': 'Řádků', + 'Cols:': 'Buněk', + 'Insert a table': 'Vložit tabulku', + 'Insert a horizontal rule': 'Vložit vodorovnou čáru', + 'Code': 'Vložit kód', + 'Width (optional):': 'Šířka (volitelné)', + 'Height (optional):': 'Výška (volitelné)', + 'Insert an image': 'Vložit obrázek', + 'E-mail:': 'E-mailová adresa', + 'Insert an email': 'Vložit e-mail', + 'URL:': 'Adresa', + 'Insert a link': 'Vložit odkaz', + 'Unlink': 'Zrušit odkaz', + 'More': 'Více', + 'Insert an emoticon': 'Vložit smajlíka', + 'Video URL:': 'Adresa videa', + 'Insert': 'Vložit', + 'Insert a YouTube video': 'Vložte video z YouTube', + 'Insert current date': 'Vložte aktuální datum', + 'Insert current time': 'Vložte aktuální čas', + 'Print': 'Vytisknout', + 'View source': 'Zobrazit zdroj', + 'Description (optional):': 'Popis (volitelné)', + 'Enter the image URL:': 'Vložte adresu obrázku', + 'Enter the e-mail address:': 'Vložte e-mailovou adresu', + 'Enter the displayed text:': 'Vložte zobrazovaný text', + 'Enter URL:': 'Vložte adresu', + 'Enter the YouTube video URL or ID:': 'Vložte adresu YouTube videa nebo ID videa', + 'Insert a Quote':'Vložit citát', + 'Invalid YouTube video': 'Neplatné YouTube video', + 'Add indent': 'Posunout na další úroveň', + 'Remove one indent': 'Posunout na předchozí úroveň', + 'Maximize': 'Zobrazit přes celou obrazovku', + + dateFormat: 'day-month-year' + }; +})(jQuery); diff --git a/js/sceditor/languages/de.js b/js/sceditor/languages/de.js new file mode 100644 index 00000000..f9df1146 --- /dev/null +++ b/js/sceditor/languages/de.js @@ -0,0 +1,59 @@ +(function ($) { + 'use strict'; + + $.sceditor.locale['de'] = { + 'Bold': 'Fett', + 'Italic': 'Kursiv', + 'Underline': 'Unterstrichen', + 'Strikethrough': 'Durchgestrichen', + 'Subscript': 'Tiefgestellt', + 'Superscript': 'Hochgestellt', + 'Align left': 'Linksbündig ausrichten', + 'Center': 'Zentrieren', + 'Align right': 'Rechtsbündig ausrichten', + 'Justify': 'Blocksatz', + 'Font Name': 'Schriftname', + 'Font Size': 'Schriftgröße', + 'Font Color': 'Schriftfarbe', + 'Remove Formatting': 'Formatierung entfernen', + 'Cut': 'Ausschneiden', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Ihr Browser erlaubt das Ausschneiden von Text nicht, bitte Nutzen Sie das Tastenkürzel Strg / Cmd-X', + 'Copy': 'Kopieren', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Ihr Browser erlaubt das Kopieren von Text nicht, bitte Nutzen Sie das Tastenkürzel Strg / Cmd-C', + 'Paste': 'Einfügen', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Ihr Browser erlaubt das Einfügen von Text nicht, bitte Nutzen Sie das Tastenkürzel Strg / Cmd-V', + 'Paste your text inside the following box:': 'Fügen Sie Ihren Text in die folgende Box ein', + 'Paste Text': 'Text einfügen', + 'Bullet list': 'Aufzählungsliste', + 'Numbered list': 'Nummerierte Liste', + 'Undo': 'Rückgängig machen', + 'Redo': 'Wiederherstellen', + 'Rows:': 'Zeilen', + 'Cols:': 'Spalten', + 'Insert a table': 'Tabelle einfügen', + 'Insert a horizontal rule': 'Horizontale Linie einfügen', + 'Code': 'Code', + 'Insert a Quote': 'Zitat einfügen', + 'Width (optional):': 'Breite (Optional)', + 'Height (optional):': 'Höhe (Optional)', + 'Insert an image': 'Ein Bild einfügen', + 'E-mail:': 'E-Mail', + 'Insert an email': 'E-Mail einfügen', + 'URL:': 'URL', + 'Insert a link': 'Link einfügen', + 'Unlink': 'Link entfernen', + 'More': 'Mehr', + 'Left-to-Right': 'Links nach rechts', + 'Right-to-Left': 'Rechts nach links', + 'Insert an emoticon': 'Emoticon einfügen', + 'Video URL:': 'Video URL', + 'Insert': 'Einfügen', + 'Insert a YouTube video': 'YouTube Video einfügen', + 'Insert current date': 'Aktuelles Datum einfügen', + 'Insert current time': 'Aktuelle Uhrzeit einfügen', + 'Print': 'Drucken', + 'Maximize': 'Maximieren', + 'View source': 'Quelltext ansehen', + dateFormat: 'day.month.year' + }; +})(jQuery); diff --git a/js/sceditor/languages/el.js b/js/sceditor/languages/el.js new file mode 100644 index 00000000..5be096f5 --- /dev/null +++ b/js/sceditor/languages/el.js @@ -0,0 +1,68 @@ +/** + * @author Nikos Aggelis nikosaggelis@hotmail.gr + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['el'] = { + 'Bold': 'Έντονα', + 'Italic': 'Πλάγια', + 'Underline': 'Υπογραμμισμένα', + 'Strikethrough': 'Διαγραμμισμένα', + 'Subscript': 'Δείκτης', + 'Superscript': 'Εκθέτης', + 'Align left': 'Αριστερή στοίχιση', + 'Center': 'Κεντραρισμένα', + 'Align right': 'Δεξιά στοίχιση', + 'Justify': 'Πλήρης στοίχιση', + 'Font Name': 'Γραμματοσειρά', + 'Font Size': 'Μέγεθος', + 'Font Color': 'Χρώμα', + 'Remove Formatting': 'Αφαίρεση μορφοποίησης', + 'Cut': 'Αποκοπή', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Ο περιηγητής σας δεν επιτρέπει την εντολή αποκοπής. Παρακαλούμε χρησιμοποιήστε τη συντόμευση πληκτρολογίου Ctrl/Cmd-X', + 'Copy': 'Αντιγραφή', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Ο περιηγητής σας δεν επιτρέπει την εντολή αντιγραφής. Παρακαλούμε χρησιμοποιήστε τη συντόμευση πληκτρολογίου Ctrl/Cmd-C', + 'Paste': 'Επικόλληση', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Ο περιηγητής σας δεν επιτρέπει την εντολή επικόλλησης. Παρακαλούμε χρησιμοποιήστε τη συντόμευση πληκτρολογίου Ctrl/Cmd-V', + 'Paste your text inside the following box:': 'Επικολλήστε το κείμενό σας μέσα στο ακόλουθο πλαίσιο:', + 'Paste Text': 'Επικόλληση κειμένου', + 'Bullet list': 'Λίστα με κουκίδες', + 'Numbered list': 'Λίστα με αρίθμηση', + 'Undo': 'Αναίρεση', + 'Redo': 'Επανάληψη', + 'Rows:': 'Γραμμές', + 'Cols:': 'Στήλες', + 'Insert a table': 'Εισαγωγή πίνακα', + 'Insert a horizontal rule': 'Εισαγωγή οριζόντιας γραμμής', + 'Code': 'Κώδικας', + 'Width (optional):': 'Πλάτος (Προαιρετικό)', + 'Height (optional):': 'Ύψος (Προαιρετικό)', + 'Insert an image': 'Εισαγωγή εικόνας', + 'E-mail:': 'Ηλεκτρονικό ταχυδρομείο', + 'Insert an email': 'Εισαγωγή email', + 'URL:': 'Ηλεκτρονική διεύθυνση', + 'Insert a link': 'Εισαγωγή συνδέσμου', + 'Unlink': 'Κατάργηση σύνδεσης', + 'More': 'Περισσότερα', + 'Insert an emoticon': 'Εισαγωγή φατσούλας', + 'Video URL:': 'Διεύθυνση βίντεο', + 'Insert': 'Εισαγωγή', + 'Insert a YouTube video': 'Εισαγωγή βίντεο YouTube', + 'Insert current date': 'Εισαγωγή τρέχουσας ημερομηνίας', + 'Insert current time': 'Εισαγωγή τρέχουσας ώρας', + 'Print': 'Εκτύπωση', + 'Maximize': 'Μεγιστοποίηση', + 'View source': 'Προβολή πηγαίου κώδικα', + 'Description (optional):': 'Περιγραφή (προαιρετικό)', + 'Enter the image URL:': 'Εισάγετε τη διεύθυνση εικόνας', + 'Enter the e-mail address:': 'Εισάγετε τη διεύθυνση e-mail', + 'Enter the displayed text:': 'Εισάγετε το εμφανιζόμενο κείμενο', + 'Enter URL:': 'Εισάγετε διεύθυνση', + 'Enter the YouTube video URL or ID:': 'Εισάγετε τη διεύθυνση του βίντεο YouTube ή το ID', + 'Insert a Quote': 'Εισαγωγή παράθεσης', + 'Invalid YouTube video': 'Μη έγκυρο βίντεο YouTube', + + dateFormat: 'day-month-year' + }; +})(jQuery); diff --git a/js/sceditor/languages/en-US.js b/js/sceditor/languages/en-US.js new file mode 100644 index 00000000..412b5a6b --- /dev/null +++ b/js/sceditor/languages/en-US.js @@ -0,0 +1,7 @@ +(function ($) { + 'use strict'; + + $.sceditor.locale['en-US'] = { + dateFormat: 'month/day/year' + }; +})(jQuery); diff --git a/js/sceditor/languages/en.js b/js/sceditor/languages/en.js new file mode 100644 index 00000000..1cb73d4c --- /dev/null +++ b/js/sceditor/languages/en.js @@ -0,0 +1,12 @@ +(function ($) { + 'use strict'; + + $.sceditor.locale['en-GB'] = { + 'Font Color': 'Font Colour', + 'Center': 'Centre', + dateFormat: 'day/month/year' + }; + + // set this as the default English locale + $.sceditor.locale['en'] = $.sceditor.locale['en-GB']; +})(jQuery); diff --git a/js/sceditor/languages/es.js b/js/sceditor/languages/es.js new file mode 100644 index 00000000..5a1e7e71 --- /dev/null +++ b/js/sceditor/languages/es.js @@ -0,0 +1,68 @@ +/** + * @author + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['es'] = { + 'Bold': 'Negrita', + 'Italic': 'Cursiva', + 'Underline': 'Subrayar', + 'Strikethrough': 'Tachar', + 'Subscript': 'Sub\u00edndice', + 'Superscript': 'Super\u00edndice', + 'Align left': 'Alinear a la Izquierda', + 'Center': 'Centrar', + 'Align right': 'Alinear a la Derecha', + 'Justify': 'Justificar', + 'Font Name': 'Tipo de Letra', + 'Font Size': 'Tama\u00f1o de Letra', + 'Font Color': 'Color de Fuente', + 'Remove Formatting': 'Quitar Formatos', + 'Cut': 'Cortar', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Su navegador no acepta el comando cortar. Por favor, use la combinaci\u00f3n Ctrl/Cmd-X', + 'Copy': 'Copiar', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Su navegador no acepta el comando copiar. Por favor, use la combinaci\u00f3n Ctrl/Cmd-C', + 'Paste': 'Pegar', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Su navegador no acepta el comando pegar. Por favor, use la combinaci\u00f3n Ctrl/Cmd-V', + 'Paste your text inside the following box:': 'Pega el texto dentro del siguiente recuadro', + 'Paste Text': 'Pegar Texto', + 'Bullet list': 'Lista de Vi\u00f1etas', + 'Numbered list': 'Lista Numerada', + 'Undo': 'Deshacer', + 'Redo': 'Rehacer', + 'Rows:': 'Filas', + 'Cols:': 'Columnas', + 'Insert a table': 'Insertar una Tabla', + 'Insert a horizontal rule': 'Insertar una Regla Horizontal', + 'Code': 'C\u00f3digo', + 'Width (optional):': 'Ancho (Opcional)', + 'Height (optional):': 'Altura (Opcional)', + 'Insert an image': 'Insertar una Imagen', + 'E-mail:': 'E-mail', + 'Insert an email': 'Insertar un Email', + 'URL:': 'URL', + 'Insert a link': 'Insertar un V\u00ednculo', + 'Unlink': 'Quitar V\u00ednculo', + 'More': 'M\u00e1s', + 'Insert an emoticon': 'Insertar un emoticon', + 'Video URL:': 'URL del V\u00eddeo', + 'Insert': 'Insertar', + 'Insert a YouTube video': 'Insertar un v\u00eddeo de YouTube', + 'Insert current date': 'Insertar fecha actual', + 'Insert current time': 'Insertar hora actual', + 'Print': 'Imprimir', + 'View source': 'Ver C\u00f3digo', + 'Description (optional):': 'Descripci\u00f3n (Opcional):', + 'Enter the image URL:': 'Ingresar la URL de la imagen:', + 'Enter the e-mail address:': 'Ingresar el correo electr\u00f3nico:', + 'Enter the displayed text:': 'Ingresar el texto mostrado:', + 'Enter URL:': 'Ingresar URL:', + 'Enter the YouTube video URL or ID:': 'Ingresar URL o ID de YouTube', + 'Insert a Quote': 'Insertar Cita', + 'Invalid YouTube video': 'Video de YouTube Inv\u00e1lido', + + dateFormat: 'day-month-year' + }; +})(jQuery); diff --git a/js/sceditor/languages/et.js b/js/sceditor/languages/et.js new file mode 100644 index 00000000..e513cad3 --- /dev/null +++ b/js/sceditor/languages/et.js @@ -0,0 +1,57 @@ +(function ($) { + 'use strict'; + + $.sceditor.locale['et'] = { + 'Bold': 'Rasvane', + 'Italic': 'Kaldkiri', + 'Underline': 'Allajoonitud', + 'Strikethrough': 'Läbijoonitud', + 'Subscript': 'Allindeks', + 'Superscript': 'Ülaindeks', + 'Align left': 'Joonad vasakule', + 'Center': 'Joonda keskele', + 'Align right': 'Joonda paremale', + 'Justify': 'Joondus mõlemale poole', + 'Font Name': 'Fondi nimi', + 'Font Size': 'Fondi suurus', + 'Font Color': 'Fondi värv', + 'Remove Formatting': 'Eemalda vormindus', + 'Cut': 'Lõika', + 'Sinu veebilehitseja ei luba lõikamise käsu kasutamist. Palun kasuta kiirklahvi Ctrl/Cmd-X': '... Ctrl / Cmd-X', + 'Copy': 'Kopeeri', + 'Sinu veebilehitseja ei luba kopeerimise käsu kasutamist. Palun kasuta kiirklahvi Ctrl/Cmd-C': '... Ctrl / Cmd-C', + 'Paste': 'Aseta', + 'Sinu veebilehitseja ei luba asetamise käsu kasutamist. Palun kasuta kiirklahvi Ctrl/Cmd-V': '... Ctrl / Cmd-V', + 'Paste your text inside the following box:': 'Aseta oma tekst järgneva tekstikasti sisse', + 'Paste Text': 'Aseta tekstina', + 'Bullet list': 'Nimekiri', + 'Numbered list': 'Nummerdatud nimekiri', + 'Undo': 'Samm tagasi', + 'Redo': 'Samm edasi', + 'Rows:': 'Read', + 'Cols:': 'Veerud', + 'Insert a table': 'Sisesta tabel', + 'Insert a horizontal rule': 'Sisesta horisontaalne joon', + 'Code': 'Kood', + 'Insert a Quote': 'Sisesta tsitaat', + 'Width (optional):': 'Laius (Valikuline)', + 'Height (optional):': 'Kõrgus (Valikuline)', + 'Insert an image': 'Sisesta pilt', + 'E-mail:': 'E-post', + 'Insert an email': 'Sisesta e-posti aadress', + 'URL:': 'Link', + 'Insert a link': 'Sisesta link', + 'Unlink': 'Eemalda link', + 'More': 'Veel', + 'Insert an emoticon': 'Sisesta emotikon', + 'Video URL:': 'Video link', + 'Insert': 'Sisesta', + 'Insert a YouTube video': 'Sisesta YouTube video', + 'Insert current date': 'Sisesta praegune kuupäev', + 'Insert current time': 'Sisesta praegune kellaaeg', + 'Print': 'Prindi', + 'View source': 'Vaata lähtekoodi', + + dateFormat: 'day.month.year' + }; +})(jQuery); diff --git a/js/sceditor/languages/fa.js b/js/sceditor/languages/fa.js new file mode 100644 index 00000000..a80824ce --- /dev/null +++ b/js/sceditor/languages/fa.js @@ -0,0 +1,69 @@ +// add locale:'fa', to your config options. +// Translated By Ebad Ghafoory [info@ghafoory.com] +// 2013/05/01 +(function ($) { + 'use strict'; + + $.sceditor.locale['fa'] = { + 'Bold': 'تیره', + 'Italic': 'مورب', + 'Underline': 'زیرخط', + 'Strikethrough': 'خط خورده', + 'Subscript': 'زیرنویس', + 'Superscript': 'بالانویس', + 'Align left': 'چپ چین', + 'Center': 'وسط چین', + 'Align right': 'راست چین', + 'Justify': 'همخط', + 'Font Name': 'نام قلم', + 'Font Size': 'اندازه\u200cی نوشته', + 'Font Color': 'رنگ نوشته', + 'Remove Formatting': 'پاکسازی فرمت نوشته', + 'Cut': 'برش', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'مرورگر شما اجازه برش توسط نرم\u200cافزار را نمی\u200cدهد. لطفا از دکمه\u200cهای ترکیبی Ctrl / Cmd-X استفاده کنید', + 'Copy': 'کپی', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'مرورگر شما اجازه کپی کردن توسط نرم\u200cافزار را نمی\u200cدهد. لطفا از دکمه\u200cهای ترکیبی Ctrl / Cmd-C استفاده کنید', + 'Paste': 'چسباندن', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'مرورگر شما اجازه چسباندن توسط نرم\u200cافزار را نمی\u200cدهد. لطفا از دکمه\u200cهای ترکیبی Ctrl / Cmd-V استفاده کنید', + 'Paste your text inside the following box:': 'متن خود را در داخل کادر زیر بچسبانید', + 'Paste Text': 'چسباندن متن', + 'Bullet list': 'لیست', + 'Numbered list': 'لیست عددی', + 'Undo': 'حرکت قبل', + 'Redo': 'حرکت بعد', + 'Rows:': 'تعداد ردیف', + 'Cols:': 'تعداد ستون', + 'Insert a table': 'افزودن جدول', + 'Insert a horizontal rule': 'افزودن خط افقی', + 'Code': 'کد', + 'Insert a Quote': 'افزودن نقل قول', + 'Width (optional):': 'پهنا (دلخواه):', + 'Height (optional):': 'ارتفاع (دلخواه):', + 'Insert an image': 'افزودن عکس', + 'E-mail:': 'ایمیل', + 'Insert an email': 'افزودن ایمیل', + 'URL:': 'آدرس اینترنتی', + 'Insert a link': 'افزودن لینک', + 'Unlink': 'حذف لینک', + 'More': 'بیشتر', + 'Insert an emoticon': 'افزودن شکلک', + 'Video URL:': 'آدرس اینترنتی ویدیو', + 'Insert': 'افزودن', + 'Insert a YouTube video': 'افزودن فیلم از یوتوب', + 'Insert current date': 'افزودن تاریخ اکنون', + 'Insert current time': 'افزودن زمان اکنون', + 'Print': 'چاپ', + 'View source': 'مشاهده سورس', + 'Description (optional):': 'توضیحات (دلخواه):', + 'Enter the image URL:': 'آدرس اینترنتی عکس را وارد کنید:', + 'Enter the e-mail address:': 'آدرس ایمیل را وارد کنید:', + 'Enter the displayed text:': 'متن نمایش\u200cدهنده را وارد کنید:', + 'Enter URL:': 'آدرس اینترنتی را وارد کنید:', + 'Enter the YouTube video URL or ID:': 'آدرس اینترنتی فیلم یوتوب یا شناسه ویدیو را وارد کنید:', + 'Invalid YouTube video': 'فیلم یوتوب غیر معتبر است', + 'Right-to-Left': 'راست به چپ', + 'Left-to-Right': 'چپ به راست', + + dateFormat: 'year.month.day' + }; +})(jQuery); diff --git a/js/sceditor/languages/fr.js b/js/sceditor/languages/fr.js new file mode 100644 index 00000000..418ecc04 --- /dev/null +++ b/js/sceditor/languages/fr.js @@ -0,0 +1,70 @@ + +// add locale:'fr', to your config options. + +(function ($) { + 'use strict'; + + $.sceditor.locale['fr-FR'] = { + 'Bold': 'Gras', + 'Italic': 'Italique', + 'Underline': 'Souligné', + 'Strikethrough': 'Barré', + 'Subscript': 'Indice', + 'Superscript': 'Exposant', + 'Align left': 'Aligner à gauche', + 'Center': 'Centrer', + 'Align right': 'Aligner à droite', + 'Justify': 'Justifier', + 'Font Name': 'Police', + 'Font Size': 'Taille de police', + 'Font Color': 'Couleur de police', + 'Remove Formatting': 'Enlever le formatage', + 'Cut': 'Couper', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Votre navigateur n\'autorise pas la commande \'Couper\'. Merci d\'utiliser le raccourcis clavier Ctrl/Cmd+X', + 'Copy': 'Copier', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Votre navigateur n\'autorise pas la commande \'Copier\'. Merci d\'utiliser le raccourcis clavier Ctrl/Cmd+C', + 'Paste': 'Coller', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Votre navigateur n\'autorise pas la commande \'Coller\'. Merci d\'utiliser le raccourcis clavier Ctrl/Cmd+V', + 'Paste your text inside the following box:': 'Collez votre texte à l\'intérieur de ce bloc', + 'Paste Text': 'Texte collé', + 'Bullet list': 'Liste à puce', + 'Numbered list': 'Liste numérotée', + 'Undo': 'Annuler', + 'Redo': 'Rétablir', + 'Rows:': 'Lignes', + 'Cols:': 'Colonnes', + 'Insert a table': 'Insérer un tableau', + 'Insert a horizontal rule': 'Insérer une ligne horizontale', + 'Code': 'Code', + 'Insert a Quote': 'Insérer une citation', + 'Width (optional):': 'Largeur (Optionelle)', + 'Height (optional):': 'Hauteur (Optionelle)', + 'Insert an image': 'Insérer une image', + 'E-mail:': 'Courriel', + 'Insert an email': 'Insérer un courriel', + 'URL:': 'URL', + 'Insert a link': 'Insérer un lien', + 'Unlink': 'Supprimer un lien', + 'More': 'Plus', + 'Insert an emoticon': 'Insérer une émoticône', + 'Video URL:': 'URL Vidéo', + 'Insert': 'Insérer', + 'Insert a YouTube video': 'Insérer une vidéo YouTube', + 'Insert current date': 'Insérer la date actuelle', + 'Insert current time': 'Insérer l\'heure actuelle', + 'Print': 'Imprimer', + 'View source': 'Afficher le texte brut', + 'Description (optional):': 'Description (Optionelle)', + 'Enter the image URL:': 'Entrez l\'URL de l\'image:', + 'Enter the e-mail address:': 'Entrez le courriel:', + 'Enter the displayed text:': 'Entrez le texte affiché:', + 'Enter URL:': 'Entrez une URL:', + 'Enter the YouTube video URL or ID:': 'Entrez l\'URL ou l\'ID de la vidéo YouTube:', + 'Invalid YouTube video': 'Vidéo YouTube invalide', + 'Right-to-Left': 'De droite à gauche', + 'Left-to-Right': 'De gauche à droite', + + dateFormat: 'day/month/year' + }; + $.sceditor.locale['fr'] = $.sceditor.locale['fr-FR']; +})(jQuery); diff --git a/js/sceditor/languages/gl.js b/js/sceditor/languages/gl.js new file mode 100644 index 00000000..90ce2350 --- /dev/null +++ b/js/sceditor/languages/gl.js @@ -0,0 +1,68 @@ +/** + * @author Fran Sobrino + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['gl'] = { + 'Bold': 'Negrita', + 'Italic': 'Cursiva', + 'Underline': 'Subrayar', + 'Strikethrough': 'Riscar', + 'Subscript': 'Sub\u00edndice', + 'Superscript': 'Super\u00edndice', + 'Align left': 'Alinear á Esquerda', + 'Center': 'Centrar', + 'Align right': 'Alinear á Dereita', + 'Justify': 'Xustificar', + 'Font Name': 'Tipo de Letra', + 'Font Size': 'Tama\u00f1o de Letra', + 'Font Color': 'Cor de Fonte', + 'Remove Formatting': 'Quitar Formatos', + 'Cut': 'Cortar', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'O seu navegador non acepta o comando cortar. Por favor, empregue a combinaci\u00f3n Ctrl/Cmd-X', + 'Copy': 'Copiar', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'O seu navegador non acepta o comando cortar. Por favor, empregue a combinaci\u00f3n Ctrl/Cmd-C', + 'Paste': 'Pegar', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'O seu navegador non acepta o comando cortar. Por favor, empregue a combinaci\u00f3n Ctrl/Cmd-V', + 'Paste your text inside the following box:': 'Pega o texto dentro do seguinte recadro', + 'Paste Text': 'Pegar Texto', + 'Bullet list': 'Lista de Vi\u00f1etas', + 'Numbered list': 'Lista Numerada', + 'Undo': 'Desfacer', + 'Redo': 'Refacer', + 'Rows:': 'Ringleiras', + 'Cols:': 'Columnas', + 'Insert a table': 'Engadir unha Tabla', + 'Insert a horizontal rule': 'Engadir unha Regla Horizontal', + 'Code': 'C\u00f3digo', + 'Width (optional):': 'Ancho (Opcional)', + 'Height (optional):': 'Altura (Opcional)', + 'Insert an image': 'Engadir unha Imaxen', + 'E-mail:': 'E-mail', + 'Insert an email': 'Engadir un Email', + 'URL:': 'URL', + 'Insert a link': 'Engadir un V\u00ednculo', + 'Unlink': 'Quitar V\u00ednculo', + 'More': 'M\u00e1is', + 'Insert an emoticon': 'Engadir un emoticon', + 'Video URL:': 'URL do V\u00eddeo', + 'Insert': 'Engadir', + 'Insert a YouTube video': 'Engadir un v\u00eddeo de YouTube', + 'Insert current date': 'Engadir data actual', + 'Insert current time': 'Engadir hora actual', + 'Print': 'Imprimir', + 'View source': 'Ver C\u00f3digo', + 'Description (optional):': 'Descripci\u00f3n (Opcional):', + 'Enter the image URL:': 'Ingresar a URL da imaxen:', + 'Enter the e-mail address:': 'Ingresar o correo electr\u00f3nico:', + 'Enter the displayed text:': 'Ingresar o texto mostrado:', + 'Enter URL:': 'Ingresar URL:', + 'Enter the YouTube video URL or ID:': 'Ingresar URL ou ID de YouTube', + 'Insert a Quote': 'Engadir Cita', + 'Invalid YouTube video': 'V\u00eddeo de YouTube Inv\u00e1lido', + + dateFormat: 'day-month-year' + }; +})(jQuery); diff --git a/js/sceditor/languages/hu.js b/js/sceditor/languages/hu.js new file mode 100644 index 00000000..ae9f7298 --- /dev/null +++ b/js/sceditor/languages/hu.js @@ -0,0 +1,69 @@ +/** + * @author Ángyán László + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + * @date 2013-08-11 + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['hu'] = { + 'Bold': 'Félkövér', + 'Italic': 'Dőlt', + 'Underline': 'Aláhúzva', + 'Strikethrough': 'Áthúzva', + 'Subscript': 'Alsó index', + 'Superscript': 'Felső index', + 'Align left': 'Balra zárt', + 'Center': 'Középre zárt', + 'Align right': 'Jobbra zárt', + 'Justify': 'Sorkizárt', + 'Font Name': 'Betűtípus', + 'Font Size': 'Betű méret', + 'Font Color': 'Betű szín', + 'Remove Formatting': 'Formázás törlése', + 'Cut': 'Kivágás', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'A böngésző biztonsági beállításai nem engedik a kivágást. Használd a Ctrl/Cmd+X billetyűket.', + 'Copy': 'Másolás', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'A böngésző biztonsági beállításai nem engedik a másolást. Használd a Ctrl/Cmd+C billetyűket.', + 'Paste': 'Beillesztés', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'A böngésző biztonsági beállításai nem engedik a beillesztést. Használd a Ctrl/Cmd+V billetyűket.', + 'Paste your text inside the following box:': 'Illeszd be a szöveget a dobozba:', + 'Paste Text': 'Szöveg beszúrása', + 'Bullet list': 'Felsorolás', + 'Numbered list': 'Sorszámozott felsorolás', + 'Undo': 'Vissza', + 'Redo': 'Mégis', + 'Rows:': 'Sorok', + 'Cols:': 'Oszlopok', + 'Insert a table': 'Táblázat beszúrása', + 'Insert a horizontal rule': 'Vízszintes vonal beszúrása', + 'Code': 'Kód', + 'Width (optional):': 'Szélesség (nem kötelező):', + 'Height (optional):': 'Magasság (nem kötelező):', + 'Insert an image': 'Illessz be egy képet', + 'E-mail:': 'Email:', + 'Insert an email': 'Illessz be egy email címet.', + 'URL:': 'Honlap', + 'Insert a link': 'Hivatkozás létrehozása', + 'Unlink': 'Hivatkozás megszüntetése', + 'More': 'Több', + 'Insert an emoticon': 'Smiley beszúrása', + 'Video URL:': 'Video link:', + 'Insert': 'Beszúrás', + 'Insert a YouTube video': 'Youtube video beszúrása', + 'Insert current date': 'Szúrd be az aktuális dátumot', + 'Insert current time': 'Szúrd be a jelenlegi időt', + 'Print': 'Nyomtatás', + 'View source': 'Forrás', + 'Description (optional):': 'Hivatkozás szövege (nem kötelező)', + 'Enter the image URL:': 'Kép URL beillesztése:', + 'Enter the e-mail address:': 'Írd be az email címet:', + 'Enter the displayed text:': 'Írd be a megjelenítendő szöveget:', + 'Enter URL:': 'Írd be a linket:', + 'Enter the YouTube video URL or ID:': 'Írd be a Youtube video URL-jét vagy azonosítóját', + 'Insert a Quote': 'Idézet beszúrása', + 'Invalid YouTube video': 'Érvénytelen Youtube link', + + dateFormat: 'year.month.day.' + }; +})(jQuery); diff --git a/js/sceditor/languages/it.js b/js/sceditor/languages/it.js new file mode 100644 index 00000000..fcdc7364 --- /dev/null +++ b/js/sceditor/languages/it.js @@ -0,0 +1,72 @@ +/** + * @author + * @author Gianluca Guazzo + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['it-IT'] = { + 'Bold': 'Grassetto', + 'Italic': 'Corsivo', + 'Underline': 'Sottolineato', + 'Strikethrough': 'Barrato', + 'Subscript': 'Pedice', + 'Superscript': 'Apice', + 'Align left': 'Allinea a sinistra', + 'Center': 'Centrato', + 'Align right': 'Allinea a destra', + 'Justify': 'Giustificato', + 'Font Name': 'Nome carattere', + 'Font Size': 'Dimensione carattere', + 'Font Color': 'Colore carattere', + 'Remove Formatting': 'Rimuovi formattazione', + 'Cut': 'Taglia', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Il tuo browser non permette il comando Taglia. Usa per favore la scorciatoia da tastiera Ctrl/Cmd-X', + 'Copy': 'Copia', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Il tuo browser non permette il comando Copia. Usa per favore la scorciatoia da tastiera Ctrl/Cmd-C', + 'Paste': 'Incolla', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Il tuo browser non permette il comando Incolla. Usa per favore la scorciatoia da tastiera Ctrl/Cmd-V', + 'Paste your text inside the following box:': 'Incolla il tuo testo dentro il seguente riquadro', + 'Paste Text': 'Incolla Testo', + 'Bullet list': 'Elenco puntato', + 'Numbered list': 'Elenco numerato', + 'Undo': 'Annulla', + 'Redo': 'Ripeti', + 'Rows:': 'Righe:', + 'Cols:': 'Colonne:', + 'Insert a table': 'Inserisci una tabella', + 'Insert a horizontal rule': 'Inserisci riga orizzontale', + 'Code': 'Codice', + 'Width (optional):': 'Larghezza(opzionale):', + 'Height (optional):': 'Altezza(opzionale):', + 'Insert an image': 'Inserisci un\'immagine', + 'E-mail:': 'E-mail:', + 'Insert an email': 'Inserisci una email', + 'URL:': 'URL:', + 'Insert a link': 'Inserisci collegamento(link):', + 'Unlink': 'Togli collegamento(link):', + 'More': 'Di più', + 'Insert an emoticon': 'Inserisci una emoticon', + 'Video URL:': 'URL del video', + 'Insert': 'Inserisci', + 'Insert a YouTube video': 'Inserisci un video YouTube', + 'Insert current date': 'Inserisci data corrente', + 'Insert current time': 'Inserisci ora corrente', + 'Print': 'Stampa', + 'View source': 'Vedi codice sorgente', + 'Description (optional):': 'Descrizione (opzionale):', + 'Enter the image URL:': 'Inserisci URL dell\'immagine', + 'Enter the e-mail address:': 'Inserisci indirizzo email', + 'Enter the displayed text:': 'Inserisci testo visualizzato', + 'Enter URL:': 'Inserisci URL', + 'Enter the YouTube video URL or ID:': 'Inserisci URL o ID video di YouTube', + 'Insert a Quote': 'Inserisci una citazione', + 'Invalid YouTube video': 'Video YouTube invalido', + + dateFormat: 'day-month-year' + }; + + // Set as the default Italian locale + $.sceditor.locale['it'] = $.sceditor.locale['it-IT']; +})(jQuery); diff --git a/js/sceditor/languages/ja.js b/js/sceditor/languages/ja.js new file mode 100644 index 00000000..2cc8ca0f --- /dev/null +++ b/js/sceditor/languages/ja.js @@ -0,0 +1,71 @@ +/** + * @author + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['ja'] = { + 'Bold': '太字', + 'Italic': '斜字', + 'Underline': '下線', + 'Strikethrough': '取り消し線', + 'Subscript': '下付き文字', + 'Superscript': '上付き文字', + 'Align left': '左揃え', + 'Center': '中央揃え', + 'Align right': '右揃え', + 'Justify': '均等揃え', + 'Font Name': 'フォント名', + 'Font Size': 'フォントサイズ', + 'Font Color': 'フォントの色', + 'Remove Formatting': '書式解除', + 'Cut': '切り取り', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'お使いのブラウザではカットコマンドを許可されていません。 キーボードショートカットの Ctrl/Cmd-X をお使いください。', + 'Copy': 'コピー', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'お使いのブラウザではコピーコマンドを許可されていません。 キーボードショートカットの Ctrl/Cmd-C をお使いください。', + 'Paste': '貼り付け', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'お使いのブラウザでは貼り付けコマンドを許可されていません。 キーボードショートカットの Ctrl/Cmd-V をお使いください。', + 'Paste your text inside the following box:': '以下にテキストを貼り付けてください。', + 'Paste Text': 'テキストを貼り付け', + 'Bullet list': '箇条書き', + 'Numbered list': '段落番号', + 'Undo': '元に戻す', + 'Redo': 'やり直す', + 'Rows:': '行数', + 'Cols:': '列数', + 'Insert a table': '表を挿入', + 'Insert a horizontal rule': '水平線を挿入', + 'Code': 'コード', + 'Width (optional):': '幅 (オプション)', + 'Height (optional):': '高さ (オプション)', + 'Insert an image': '画像を挿入', + 'E-mail:': 'メールアドレス', + 'Insert an email': 'メールアドレスを挿入', + //'URL:': ', + 'Insert a link': 'リンクを挿入', + 'Unlink': 'リンクを解除', + //'More': ', + 'Insert an emoticon': '顔文字を挿入', + 'Video URL:': '動画URL', + 'Insert': '挿入', + 'Insert a YouTube video': 'Youtubeを挿入', + 'Insert current date': '現在の日付を挿入', + 'Insert current time': '現在の時間を挿入', + 'Print': '印刷', + 'View source': 'ソースを表示', + 'Description (optional):': '説明 (オプション)', + 'Enter the image URL:': '画像URLを入力してください。', + 'Enter the e-mail address:': 'メールアドレスを入力してください。', + 'Enter the displayed text:': '表示テキストを入力してください。', + 'Enter URL:': 'URLを入力してください。', + 'Enter the YouTube video URL or ID:': 'Youtubeの動画URLまたはIDを入力してください。', + 'Insert a Quote': '引用を挿入', + 'Invalid YouTube video': '不正なYoutube動画', + 'Left-to-Right': '左から右へ', + 'Right-to-Left': '右から左へ', + 'Maximize': '最大化', + + dateFormat: 'year-month-day' + }; +})(jQuery); diff --git a/js/sceditor/languages/lt.js b/js/sceditor/languages/lt.js new file mode 100644 index 00000000..91a24897 --- /dev/null +++ b/js/sceditor/languages/lt.js @@ -0,0 +1,68 @@ +/** + * @author Team from www.klaustukai.lt + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['lt'] = { + 'Bold': 'Paryškintas', + 'Italic': 'Pasvirasis', + 'Underline': 'Pabraukti', + 'Strikethrough': 'Perbraukti', + 'Subscript': 'Parašyti sumažintas raides po žodžio', + 'Superscript': 'Parašyti sumažintas raides virš žodžio', + 'Align left': 'Kairysis lygiavimas', + 'Center': 'Centrinis lygiavimas', + 'Align right': 'Dešinysis lygiavimas', + 'Justify': 'Išlygintas tekstas', + 'Font Name': 'Šrifto pavadinimas', + 'Font Size': 'Šrifto dydis', + 'Font Color': 'Šrifto spalva', + 'Remove Formatting': 'Panaikinti teksto formatavimą', + 'Cut': 'Iškirpti', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Jūsų paieškos sistema neleidžia atlikti šios funkcijos. Norėdami iškirpti spauskite Ctrl/Cmd-x', + 'Copy': 'Kopijuoti', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Jūsų paieškos sistema neleidžia atlikti šios komandos. Norėdami nukopijuoti spauskite Ctrl/Cmd - C', + 'Paste': 'Įklijuoti', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Jūsų paieškos sistema neleidžia atlikti šios komandos. Norėdami įklijuoti spauskite Ctrl/Cmd - V', + 'Paste your text inside the following box:': 'Įklijuokite tekstą nurodytoje vietoje', + 'Paste Text': 'Įklijuoti tekstą', + 'Bullet list': 'Sugrupuotas sąrašas', + 'Numbered list': 'Sunumeruotas sąrašas', + 'Undo': 'panaikinti', + 'Redo': 'atitaisyti', + 'Rows:': 'Eilutės', + 'Cols:': 'Stulpeliai', + 'Insert a table': 'Įterpti lentelę', + 'Insert a horizontal rule': 'Įterpti horizontalią liniją', + 'Code': 'Šalies kodas', + 'Width (optional):': 'plotis (laisvai pasirenkamas)', + 'Height (optional):': 'aukštis (laisvai pasirenkamas)', + 'Insert an image': 'Įterpti nuotrauką', + 'E-mail:': 'Elektroninis paštas', + 'Insert an email': 'Įterpti elktroninio pašto nuorodą', + 'URL:': 'Internetinės svetainės adresas:', + 'Insert a link': 'Įterpti nuorodą', + 'Unlink': 'Atjungti', + 'More': 'Daugiau', + 'Insert an emoticon': 'Įterpti šypsenėlę', + 'Video URL:': 'Vaizdo klipo nuoroda', + 'Insert': 'Įterpti', + 'Insert a YouTube video': 'Įterpti Youtube vaizdo klipą', + 'Insert current date': 'Įterpti esamą datą (diena-mėnuo-metai)', + 'Insert current time': 'Įterpti esamą laiką', + 'Print': 'Atspausdinti', + 'View source': 'Peržiūrėti šaltinį', + 'Description (optional):': 'Aprašymas (laisvai pasirenkamas)', + 'Enter the image URL:': 'Įterpti nuotraukos adresą', + 'Enter the e-mail address:': 'Įterpti elektroninio pašto adresą', + 'Enter the displayed text:': 'Įvesti pavaizduotą tekstą', + 'Enter URL:': 'Įvesti internetinį adresą', + 'Enter the YouTube video URL or ID:': 'Įrašykite Youtube vaizdo klipo nuorodą ar ID', + 'Insert a Quote': 'Įterpti citatą', + 'Invalid YouTube video': 'YouTube vaizdo įrašas neveikia', + + dateFormat: 'year-month-day' + }; +})(jQuery); diff --git a/js/sceditor/languages/nb.js b/js/sceditor/languages/nb.js new file mode 100644 index 00000000..455ee0f2 --- /dev/null +++ b/js/sceditor/languages/nb.js @@ -0,0 +1,70 @@ +/** + * @author Katrine + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['nb-NO'] = { + 'Bold': 'Fet', + 'Italic': 'Kursiv', + 'Underline': 'Understrek', + 'Strikethrough': 'Gjennomstrek', + 'Subscript': 'Senket', + 'Superscript': 'Hevet', + 'Align left': 'Sidestill til venstre', + 'Center': 'Midstill', + 'Align right': 'Sidestill til høyre', + 'Justify': 'Normalt oppstilt', + 'Font Name': 'Skriftype', + 'Font Size': 'Skriftstørrelse', + 'Font Color': 'skriftfarge', + 'Remove Formatting': 'Fjern formatering', + 'Cut': 'Klipp', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Nettleseren din kan ikke utføre klippe kommandoen. Vennligst bruk hurtigtasten Ctrl / Cmd-X', + 'Copy': 'Kopier', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Nettleseren din kan ikke utføre kopier kommandoen. Vennligst bruk hurtigtasten Ctrl / Cmd-C', + 'Paste': 'Lim', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Nettleseren din kan ikke utføre lime kommandoen. Vennligst bruk hurtigtasten Ctrl / Cmd-V', + 'Paste your text inside the following box:': 'Lim inn teksten i den følgende boksen:', + 'Paste Text': 'Lim inn tekst', + 'Bullet list': 'Bullet liste', + 'Numbered list': 'Nummerert liste', + 'Undo': 'Angre', + 'Redo': 'Gjør på nytt', + 'Rows:': 'Rader', + 'Cols:': 'Kolonner', + 'Insert a table': 'Sett inn en tabell', + 'Insert a horizontal rule': 'Sett en horisontal regel', + 'Code': 'Kode', + 'Width (optional):': 'Bredde (valgfritt):', + 'Height (optional):': 'Høyde (valgfritt):', + 'Insert an image': 'Sett inn et bilde', + 'E-mail:': 'E-post', + 'Insert an email': 'Sett inn en e-post', + 'URL:': 'URL:', + 'Insert a link': 'Sett inn en lenke', + 'Unlink': 'Oppheve tilknytningen', + 'More': 'Mer', + 'Insert an emoticon': 'Sett inn et uttrykksikon', + 'Video URL:': 'Video URL', + 'Insert': 'Sett inn', + 'Insert a YouTube video': 'Sett inn en YouTube-video', + 'Insert current date': 'Sett inn gjeldende dato', + 'Insert current time': 'Sett inn gjeldende klokkeslett', + 'Print': 'Skriv ut', + 'View source': 'Vis kildekode', + 'Description (optional):': 'Beskrivelse (valgfritt):', + 'Enter the image URL:': 'Skriv inn bildet\'s URL:', + 'Enter the e-mail address:': 'Skriv inn e-postadresse:', + 'Enter the displayed text:': 'Skriv inn teksten som vises:', + 'Enter URL:': 'Skriv inn URL adresse:', + 'Enter the YouTube video URL or ID:': 'Angi YouTube video link eller ID:', + 'Insert a Quote': 'Sett inn sitat', + 'Invalid YouTube video': 'Ugyldig Youtube video', + + dateFormat: 'day.month.year' + }; + + $.sceditor.locale['nb'] = $.sceditor.locale['nb-NO']; +})(jQuery); diff --git a/js/sceditor/languages/nl.js b/js/sceditor/languages/nl.js new file mode 100644 index 00000000..48c89bb4 --- /dev/null +++ b/js/sceditor/languages/nl.js @@ -0,0 +1,57 @@ +(function ($) { + 'use strict'; + + $.sceditor.locale['nl'] = { + 'Bold': 'Vet', + 'Italic': 'Schuingedrukt', + 'Underline': 'Onderstreept', + 'Strikethrough': 'Doorhalen', + 'Subscript': 'Subscript', + 'Superscript': 'Superscript', + 'Align left': 'Links uitlijnen', + 'Center': 'Centreren', + 'Align right': 'Rechts uitlijnen', + 'Justify': 'Uitvullen', + 'Font Name': 'Fontnaam', + 'Font Size': 'Fontgrootte', + 'Font Color': 'Fontkleur', + 'Remove Formatting': 'Verwijder opmaak', + 'Cut': 'Knippen', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Je browser staat het knippen commando niet toe. Gebruik de toetsenbord sneltoets Ctrl / Cmd-X', + 'Copy': 'Kopiëren', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Je browser staat het kopieer commando niet toe. Gebruik de toetsenbord sneltoets Ctrl / Cmd-C', + 'Paste': 'Plakken', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Je browser staat het plakken commando niet toe. Gebruik de toetsenbord sneltoets Ctrl / Cmd-V', + 'Paste your text inside the following box:': 'Plak je tekst in de volgende locatie:', + 'Paste Text': 'Tekst plakken', + 'Bullet list': 'Opsomming', + 'Numbered list': 'Genummerde lijst', + 'Undo': 'Ongedaan maken', + 'Redo': 'Opnieuw uitvoeren', + 'Rows:': 'Rijen', + 'Cols:': 'Kolommen', + 'Insert a table': 'Tabel', + 'Insert a horizontal rule': 'Horizontale regel', + 'Code': 'Code', + 'Insert a Quote': 'Citeren', + 'Width (optional):': 'Breedte (optioneel):', + 'Height (optional):': 'Hoogte (optioneel):', + 'Insert an image': 'Afbeelding', + 'E-mail:': 'E-mail', + 'Insert an email': 'E-mail', + 'URL:': 'URL:', + 'Insert a link': 'Link', + 'Unlink': 'Link verwijderen', + 'More': 'Meer', + 'Insert an emoticon': 'Emoticon', + 'Video URL:': 'Video URL', + 'Insert': 'Invoegen', + 'Insert a YouTube video': 'YouTube-video', + 'Insert current date': 'Huidige datum', + 'Insert current time': 'Huidige tijd', + 'Print': 'Print', + 'View source': 'Bron bekijken', + + dateFormat: 'day.month.year' + }; +})(jQuery); diff --git a/js/sceditor/languages/pl.js b/js/sceditor/languages/pl.js new file mode 100644 index 00000000..09a4c06a --- /dev/null +++ b/js/sceditor/languages/pl.js @@ -0,0 +1,68 @@ +/** + * @author + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['pl'] = { + 'Bold': 'Pogrubienie', + 'Italic': 'Kursywa', + 'Underline': 'Podkreślenie', + 'Strikethrough': 'Przekreślenie', + 'Subscript': 'Indeks dolny', + 'Superscript': 'Indeks górny', + 'Align left': 'Do lewej', + 'Center': 'Do środka', + 'Align right': 'Do prawej', + 'Justify': 'Wyjustowanie', + 'Font Name': 'Krój czcionki', + 'Font Size': 'Rozmiar czcionki', + 'Font Color': 'Kolor czcionki', + 'Remove Formatting': 'Usuń formatowanie', + 'Cut': 'Wytnij', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Twoja przeglądarka nie obsługuje opcji wycinania. Użyj skrótu klawiszowego Cmd/Ctrl + X', + 'Copy': 'Skopiuj', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Twoja przeglądarka nie obsługuje opcji kopiowania. Użyj skrótu klawiszowego Cmd/Ctrl + C', + 'Paste': 'Wklej', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Twoja przeglądarka nie obsługuje opcji wklejania. Użyj skrótu klawiszowego Cmd/Ctrl + V', + 'Paste your text inside the following box:': 'Wklej swój tekst do tego pola:', + 'Paste Text': 'Wklej tekst', + 'Bullet list': 'Wypunktowanie', + 'Numbered list': 'Lista numerowana', + 'Undo': 'Cofnij', + 'Redo': 'Powtórz', + 'Rows:': 'Wiersze:', + 'Cols:': 'Kolumny:', + 'Insert a table': 'Wstaw tabelę', + 'Insert a horizontal rule': 'Wstaw linię poziomą', + 'Code': 'Kod', + 'Width (optional):': 'Szerokość (opcjonalnie)', + 'Height (optional):': 'Wysokość (opcjonalnie)', + 'Insert an image': 'Wstaw obrazek', + 'E-mail:': 'E-mail', + 'Insert an email': 'Wstaw e-mail', + 'URL:': 'URL', + 'Insert a link': 'Wstaw odnośnik', + 'Unlink': 'Usuń odnośnik', + 'More': 'Więcej', + 'Insert an emoticon': 'Wstaw emotikonę', + 'Video URL:': 'URL do filmu', + 'Insert': 'Wstaw', + 'Insert a YouTube video': 'Wstaw film YouTube', + 'Insert current date': 'Wstaw aktualną datę', + 'Insert current time': 'Wstaw aktualny czas', + 'Print': 'Drukuj', + 'View source': 'Pokaż źródło', + 'Description (optional):': 'Opis (opcjonalny)', + 'Enter the image URL:': 'Wstaw URL do obrazka', + 'Enter the e-mail address:': 'Wpisz adres e-mail', + 'Enter the displayed text:': 'Wpisz wyświetlony tekst', + 'Enter URL:': 'Wpisz adres URL', + 'Enter the YouTube video URL or ID:': 'Wpisz adres URL lub ID filmu na YouTube', + 'Insert a Quote': 'Wstaw cytat', + 'Invalid YouTube video': 'Nieprawidłowy film YouTube', + + dateFormat: 'day-month-year' + }; +})(jQuery); diff --git a/js/sceditor/languages/pt-BR.js b/js/sceditor/languages/pt-BR.js new file mode 100644 index 00000000..a279a1d5 --- /dev/null +++ b/js/sceditor/languages/pt-BR.js @@ -0,0 +1,67 @@ +/** +* @author martec +* @license [MIT](http://www.opensource.org/licenses/mit-license.php) +*/ +(function ($) { + 'use strict'; + + $.sceditor.locale['pt-BR'] = { + 'Bold': 'Negrito', + 'Italic': 'Itálico', + 'Underline': 'Sublinhado', + 'Strikethrough': 'Rasurado', + 'Subscript': 'Subscrito', + 'Superscript': 'Sobrescrito ', + 'Align left': 'Alinhar à esquerda', + 'Center': 'Centralizar', + 'Align right': 'Alinhar à direita', + 'Justify': 'Justificar', + 'Font Name': 'Nome da fonte', + 'Font Size': 'Tamanho da fonte', + 'Font Color': 'Cor da fonte', + 'Remove Formatting': 'Remover a formatação', + 'Cut': 'Recortar', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Seu navegador não permite o comando recortar. Favor use o atalho Ctrl/Cmd-X', + 'Copy': 'Copiar', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Seu navegador não permite o comando copiar. Favor use o atalho Ctrl/Cmd-C', + 'Paste': 'Colar', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Seu navegador não permite o comando colar. Favor use o atalho Ctrl/Cmd-V', + 'Paste your text inside the following box:': 'Cole o seu texto dentro da caixa de texto a seguir:', + 'Paste Text': 'Colar o texto', + 'Bullet list': 'Lista com marcadores', + 'Numbered list': 'Lista numérica', + 'Undo': 'Desfazer', + 'Redo': 'Refazer', + 'Rows:': 'Linhas:', + 'Cols:': 'Colunas:', + 'Insert a table': 'Inserir uma tabela', + 'Insert a horizontal rule': 'Inserir uma linha horizontal', + 'Code': 'Código', + 'Width (optional):': 'Largura (opcional):', + 'Height (optional):': 'Altura (opcional):', + 'Insert an image': 'Inserir uma imagem', + 'E-mail:': 'E-mail:', + 'Insert an email': 'Inserir um e-mail', + 'URL:': 'URL:', + 'Insert a link': 'Inserir um hiperlink', + 'Unlink': 'Remover o hiperlink', + 'More': 'Mais', + 'Insert an emoticon': 'Inserir um emoticon', + 'Video URL:': 'Video URL:', + 'Insert': 'Inserir', + 'Insert a YouTube video': 'Inserir YouTube video', + 'Insert current date': 'Inserir a data atual', + 'Insert current time': 'Inserir a hora atual', + 'Print': 'Imprimir', + 'View source': 'Fonte', + 'Description (optional):': 'Descrição (opcional):', + 'Enter the image URL:': 'Informe o endereço URL da imagem:', + 'Enter the e-mail address:': 'Informe o endereço de e-mail:', + 'Enter the displayed text:': 'Digite o texto exibido:', + 'Enter URL:': 'Informe o endereço URL:', + 'Enter the YouTube video URL or ID:': 'Informe o endereço URL ou ID do YouTube:', + 'Insert a Quote': 'Inserir uma citação', + 'Invalid YouTube video': 'Vídeo do YouTube inválido', + dateFormat: 'day-month-year' + }; +})(jQuery); diff --git a/js/sceditor/languages/pt.js b/js/sceditor/languages/pt.js new file mode 100644 index 00000000..1d3c2f8f --- /dev/null +++ b/js/sceditor/languages/pt.js @@ -0,0 +1,69 @@ +/** +* @author brunoais +* @license [MIT](http://www.opensource.org/licenses/mit-license.php) +*/ +(function ($) { + 'use strict'; + + $.sceditor.locale['pt-PT'] = { + 'Bold': 'Negrito', + 'Italic': 'Itálico', + 'Underline': 'Sublinhado', + 'Strikethrough': 'Rasurado', + 'Subscript': 'Subscrito', + 'Superscript': 'Sobrescrito ', + 'Align left': 'Alinhar à esquerda', + 'Center': 'Centrar', + 'Align right': 'Alinhar à direita', + 'Justify': 'Justificar', + 'Font Name': 'Nome da fonte', + 'Font Size': 'Tamanho da fonte', + 'Font Color': 'Cor da fonte', + 'Remove Formatting': 'Remover a formatação', + 'Cut': 'Cortar', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Seu navegador não permite o comando cortar. Por favor use o atalho Ctrl/Cmd-X', + 'Copy': 'Copiar', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Seu navegador não permite o comando copiar. Por favor use o atalho Ctrl/Cmd-C', + 'Paste': 'Colar', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Seu navegador não permite o comando colar. Por favor use o atalho Ctrl/Cmd-V', + 'Paste your text inside the following box:': 'Cole o seu texto dentro da caixa de texto a seguir:', + 'Paste Text': 'Colar o texto', + 'Bullet list': 'Lista com marcadores', + 'Numbered list': 'Lista numérica', + 'Undo': 'Desfazer', + 'Redo': 'Refazer', + 'Rows:': 'Linhas:', + 'Cols:': 'Colunas:', + 'Insert a table': 'Inserir uma tabela', + 'Insert a horizontal rule': 'Inserir uma linha horizontal', + 'Code': 'Código', + 'Width (optional):': 'Largura (opcional):', + 'Height (optional):': 'Altura (opcional):', + 'Insert an image': 'Inserir uma imagem', + 'E-mail:': 'E-mail:', + 'Insert an email': 'Inserir um e-mail', + 'URL:': 'URL:', + 'Insert a link': 'Inserir um hiperlink', + 'Unlink': 'Remover o hiperlink', + 'More': 'Mais', + 'Insert an emoticon': 'Inserir um emoticon', + 'Video URL:': 'Video URL:', + 'Insert': 'Inserir', + 'Insert a YouTube video': 'Inserir YouTube video', + 'Insert current date': 'Inserir a data atual', + 'Insert current time': 'Inserir a hora atual', + 'Print': 'Imprimir', + 'View source': 'Código fonte', + 'Description (optional):': 'Descrição (opcional):', + 'Enter the image URL:': 'Introduza o endereço URL da imagem:', + 'Enter the e-mail address:': 'Introduza o endereço de e-mail:', + 'Enter the displayed text:': 'Indique o texto exibido:', + 'Enter URL:': 'Introduza o endereço URL:', + 'Enter the YouTube video URL or ID:': 'Introduza o endereço URL ou o ID do video do YouTube:', + 'Insert a Quote': 'Inserir uma citação', + dateFormat: 'day/month/year' + }; + + // Set as the default Portuguese locale + $.sceditor.locale['pt'] = $.sceditor.locale['pt-PT']; +})(jQuery); diff --git a/js/sceditor/languages/ru.js b/js/sceditor/languages/ru.js new file mode 100644 index 00000000..32e0ed1f --- /dev/null +++ b/js/sceditor/languages/ru.js @@ -0,0 +1,57 @@ +(function ($) { + 'use strict'; + + $.sceditor.locale['ru'] = { + 'Bold': 'Жирный', + 'Italic': 'Курсив', + 'Underline': 'Подчёркнутый', + 'Strikethrough': 'Зачёркнутый', + 'Subscript': 'Нижний индекс', + 'Superscript': 'Верхний индекс', + 'Align left': 'Выравнивание по левому краю', + 'Center': 'Выравнивание по центру', + 'Align right': 'Выравнивание по правому краю', + 'Justify': 'Выравнивание по обоим краям', + 'Font Name': 'Шрифт', + 'Font Size': 'Размер шрифта', + 'Font Color': 'Цвет шрифта', + 'Remove Formatting': 'Удалить форматирование', + 'Cut': 'Вырезать', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Ваш браузер не позволяет выполнять эту команду. Пожалуйста, используйте сочетание клавиш Ctrl / Cmd-X', + 'Copy': 'Копировать', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Ваш браузер не позволяет выполнять эту команду. Пожалуйста, используйте сочетание клавиш Ctrl / Cmd-C', + 'Paste': 'Выставить', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Ваш браузер не позволяет выполнять эту команду. Пожалуйста, используйте сочетание клавиш Ctrl / Cmd-V', + 'Paste your text inside the following box:': 'Вставьте текст в следующее окно:', + 'Paste Text': 'Вставить текст', + 'Bullet list': 'Маркированный список', + 'Numbered list': 'Нумерованный список', + 'Undo': 'Отменить', + 'Redo': 'Повторить', + 'Rows:': 'Строки', + 'Cols:': 'Столбцы', + 'Insert a table': 'Таблица', + 'Insert a horizontal rule': 'Горизонтальная линия', + 'Code': 'Код', + 'Insert a Quote': 'Цитата', + 'Width (optional):': 'Ширина (необязательно):', + 'Height (optional):': 'Высота (необязательно):', + 'Insert an image': 'Изображение', + 'E-mail:': 'E-mail', + 'Insert an email': 'E-mail', + 'URL:': 'URL:', + 'Insert a link': 'Ссылка', + 'Unlink': 'Удалить ссылку', + 'More': 'Больше', + 'Insert an emoticon': 'Смайлы', + 'Video URL:': 'Видео URL', + 'Insert': 'Вставить', + 'Insert a YouTube video': 'YouTube-видео', + 'Insert current date': 'Текущая дата', + 'Insert current time': 'Текущее время', + 'Print': 'Распечатать', + 'View source': 'Показать код', + 'Maximize': 'Развернуть', + dateFormat: 'day.month.year' + }; +})(jQuery); diff --git a/js/sceditor/languages/sv.js b/js/sceditor/languages/sv.js new file mode 100644 index 00000000..cd4a9f73 --- /dev/null +++ b/js/sceditor/languages/sv.js @@ -0,0 +1,58 @@ +(function ($) { + 'use strict'; + + $.sceditor.locale['sv-SE'] = { + 'Bold': 'Fet', + 'Italic': 'Kursiv', + 'Underline': 'Understruken', + 'Strikethrough': 'Genomstruken', + 'Subscript': 'Nersänkt', + 'Superscript': 'Upphöjt', + 'Align left': 'Vänsterställ', + 'Center': 'Centrera', + 'Align right': 'Högerställ', + 'Justify': 'Normalt oppstilt', + 'Font Name': 'Teckensnitt', + 'Font Size': 'Teckenstorlek', + 'Font Color': 'Teckenfärg', + 'Remove Formatting': 'Ta bort formatering', + 'Cut': 'Klipp ut', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Din webbläsare kan inte utföra kommandot. Vänligen använd kortkommando Ctrl / Cmd-X', + 'Copy': 'Kopiera', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Din webbläsare kan inte utföra kommandot. Vänligen använd kortkommando Ctrl / Cmd-C', + 'Paste': 'Klista in', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Din webbläsare kan inte utföra kommandot. Vänligen använd kortkommando Ctrl / Cmd-V', + 'Paste your text inside the following box:': 'Klistra in din text i rutan:', + 'Paste Text': 'Klistra in text', + 'Bullet list': 'Lista', + 'Numbered list': 'Numrerad lista', + 'Undo': 'Ångra', + 'Redo': 'Gör om', + 'Rows:': 'Rader', + 'Cols:': 'Kolumner', + 'Insert a table': 'Infoga tabell', + 'Insert a horizontal rule': 'Infoga skiljestreck', + 'Code': 'Kod', + 'Width (optional):': 'Bredd (valfritt):', + 'Height (optional):': 'Höjd (valfritt):', + 'Insert an image': 'Infoga bild', + 'E-mail:': 'E-post', + 'Insert an email': 'Infoga e-post', + 'URL:': 'URL:', + 'Insert a link': 'Infoga länk', + 'Unlink': 'Ta bort länk', + 'More': 'Mer', + 'Insert an emoticon': 'Infoga smiley', + 'Video URL:': 'Video URL', + 'Insert': 'Infoga', + 'Insert a YouTube video': 'Infoga YouTube-video', + 'Insert current date': 'Infoga dagens datum', + 'Insert current time': 'Infoga nuvarande tid', + 'Print': 'Skriv ut', + 'View source': 'Visa källkod', + 'Description (optional):': 'Beskrivning (valfritt):', + dateFormat: 'year-month-day' + }; + + $.sceditor.locale['sv'] = $.sceditor.locale['sv-SE']; +})(jQuery); diff --git a/js/sceditor/languages/template.js b/js/sceditor/languages/template.js new file mode 100644 index 00000000..6f3cf0bd --- /dev/null +++ b/js/sceditor/languages/template.js @@ -0,0 +1,74 @@ +/** + * @author + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + // Replace with the language code, e.g. no, fr, en, ect. + $.sceditor.locale[''] = { + + // Original string is on the left, place the translation between + // the quotes on the right + 'Bold': '', + 'Italic': '', + 'Underline': '', + 'Strikethrough': '', + 'Subscript': '', + 'Superscript': '', + 'Align left': '', + 'Center': '', + 'Align right': '', + 'Justify': '', + 'Font Name': '', + 'Font Size': '', + 'Font Color': '', + 'Remove Formatting': '', + 'Cut': '', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': '', + 'Copy': '', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': '', + 'Paste': '', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': '', + 'Paste your text inside the following box:': '', + 'Paste Text': '', + 'Bullet list': '', + 'Numbered list': '', + 'Undo': '', + 'Redo': '', + 'Rows:': '', + 'Cols:': '', + 'Insert a table': '', + 'Insert a horizontal rule': '', + 'Code': '', + 'Width (optional):': '', + 'Height (optional):': '', + 'Insert an image': '', + 'E-mail:': '', + 'Insert an email': '', + 'URL:': '', + 'Insert a link': '', + 'Unlink': '', + 'More': '', + 'Insert an emoticon': '', + 'Video URL:': '', + 'Insert': '', + 'Insert a YouTube video': '', + 'Insert current date': '', + 'Insert current time': '', + 'Print': '', + 'View source': '', + 'Description (optional):': '', + 'Enter the image URL:': '', + 'Enter the e-mail address:': '', + 'Enter the displayed text:': '', + 'Enter URL:': '', + 'Enter the YouTube video URL or ID:': '', + 'Insert a Quote': '', + 'Invalid YouTube video': '', + + // month format, replace - with the date format seperator and order in the + // order used + dateFormat: 'day-month-year' + }; +})(jQuery); diff --git a/js/sceditor/languages/tr.js b/js/sceditor/languages/tr.js new file mode 100644 index 00000000..9f58c121 --- /dev/null +++ b/js/sceditor/languages/tr.js @@ -0,0 +1,66 @@ +/** + * @author Mahmut Yaman - iletisim@/m-yaman.com + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + $.sceditor.locale['tr'] = { + 'Bold': 'Kalın', + 'Italic': 'İtalik', + 'Underline': 'Altı çizgili', + 'Strikethrough': 'Üstü çizgili', + 'Subscript': 'Simge', + 'Superscript': 'Üstsimge', + 'Align left': 'Sola yasla', + 'Center': 'Ortala', + 'Align right': 'Sağa yasla', + 'Justify': 'Satır uzunluğuna ayarla', + 'Font Name': 'Yazı tipi', + 'Font Size': 'Yazı boyutu', + 'Font Color': 'Yazı rengi', + 'Remove Formatting': 'Biçimlendirmeyi temizle', + 'Cut': 'Kes', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Tarayıcınız kesme komutuna izin vermiyor. Lütfen Ctrl/Cmd-X klavye kısayolunu kullanın.', + 'Copy': 'Kopyala', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Tarayıcınız kopyalama komutuna izin vermiyor. Lütfen Ctrl/Cmd-C klavye kısayolunu kullanın.', + 'Paste': 'Yapıştır', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Tarayıcınız yapıştırma komutuna izin vermiyor. Lütfen Ctrl/Cmd-V klavye kısayolunu kullanın.', + 'Paste your text inside the following box:': 'Yazınızı bu kutucuğa yapıştırın:', + 'Paste Text': 'Metin Yapıştır', + 'Bullet list': 'Madde işaretli liste', + 'Numbered list': 'Numaralı liste', + 'Undo': 'Geri al', + 'Redo': 'Yinele', + 'Rows:': 'Sütun:', + 'Cols:': 'Kolon:', + 'Insert a table': 'Tablo ekle', + 'Insert a horizontal rule': 'Yatay ayraç ekle', + 'Code': 'Kod', + 'Width (optional):': 'Genişlik (opsiyonel):', + 'Height (optional):': 'Yükseklik (opsiyonel):', + 'Insert an image': 'Resim ekle', + 'E-mail:': 'E-posta:', + 'Insert an email': 'E-posta ekle', + 'URL:': 'URL:', + 'Insert a link': 'Bağlantı ekle', + 'Unlink': 'Bağlantıyı kaldır', + 'More': 'Daha fazla', + 'Insert an emoticon': 'Yüz ifadesi ekle', + 'Video URL:': 'Video URL:', + 'Insert': 'Ekle', + 'Insert a YouTube video': 'YouTube videosu ekle', + 'Insert current date': 'Şuanki tarihi ekle', + 'Insert current time': 'Şuanki saati ekle', + 'Print': 'Yazdır', + 'View source': 'Kaynağı görüntüle', + 'Description (optional):': 'Açıklama (opsiyonel):', + 'Enter the image URL:': 'Resim URL\'sini girin:', + 'Enter the e-mail address:': 'E-posta adresini girin:', + 'Enter the displayed text:': 'Görünecek yazıyı girin:', + 'Enter URL:': 'URL\'yi girin:', + 'Enter the YouTube video URL or ID:': 'YouTube video URL\'sini yada ID\'sini girin:', + 'Insert a Quote': 'Alıntı ekle', + 'Invalid YouTube video': 'Geçersiz YouTube videosu', + dateFormat: 'day-month-year' + }; +})(jQuery); diff --git a/js/sceditor/languages/tw.js b/js/sceditor/languages/tw.js new file mode 100644 index 00000000..19305bb7 --- /dev/null +++ b/js/sceditor/languages/tw.js @@ -0,0 +1,68 @@ +/** + * @author + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['tw'] = { + 'Bold': '粗體', + 'Italic': '斜體', + 'Underline': '底線', + 'Strikethrough': '删除線', + 'Subscript': '下標', + 'Superscript': '上標', + 'Align left': '靠左對齊', + 'Center': '置中', + 'Align right': '靠右對齊', + 'Justify': '兩端對齊', + 'Font Name': '字形', + 'Font Size': '字體大小', + 'Font Color': '文字顏色', + 'Remove Formatting': '清除格式', + 'Cut': '剪下', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': '您的瀏覽器不支持剪下命令,請使用快速键 Ctrl/Cmd-X', + 'Copy': '拷貝', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': '您的瀏覽器不支持拷貝命令,請使用快速键 Ctrl/Cmd-C', + 'Paste': '貼上', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': '您的瀏覽器不支持貼上命令,請使用快速键 Ctrl/Cmd-V', + 'Paste your text inside the following box:': '請在下面貼上您的文字', + 'Paste Text': '貼上纯文字', + 'Bullet list': '符號列表', + 'Numbered list': '编號列表', + 'Undo': '復原', + 'Redo': '重做', + 'Rows:': '行數', + 'Cols:': '列數', + 'Insert a table': '插入表格', + 'Insert a horizontal rule': '插入分隔線', + 'Code': '原始碼', + 'Width (optional):': '寬度(選填)', + 'Height (optional):': '高度(選填)', + 'Insert an image': '插入圖片', + 'E-mail:': 'Email', + 'Insert an email': '插入Email', + 'URL:': '網址', + 'Insert a link': '插入超鏈結', + 'Unlink': '取消超鏈結', + 'More': '更多', + 'Insert an emoticon': '插入表情符號', + 'Video URL:': '影片網址', + 'Insert': '插入', + 'Insert a YouTube video': '插入 YouTube 影片', + 'Insert current date': '插入目前日期', + 'Insert current time': '插入目前時間', + 'Print': '列印', + 'View source': '查看原始碼', + 'Description (optional):': '描述(選填)', + 'Enter the image URL:': '輸入圖片網址', + 'Enter the e-mail address:': '輸入 Email', + 'Enter the displayed text:': '輸入顯示文字', + 'Enter URL:': '輸入網址', + 'Enter the YouTube video URL or ID:': '輸入 YouTube 網址或影片编號', + 'Insert a Quote': '插入引用', + 'Invalid YouTube video': '無效的YouTube影片', + + dateFormat: 'year-month-day' + }; +})(jQuery); diff --git a/js/sceditor/languages/uk.js b/js/sceditor/languages/uk.js new file mode 100644 index 00000000..829ef235 --- /dev/null +++ b/js/sceditor/languages/uk.js @@ -0,0 +1,57 @@ +(function ($) { + 'use strict'; + + $.sceditor.locale['uk'] = { + 'Bold': 'Жирний', + 'Italic': 'Курсив', + 'Underline': 'Підкреслений', + 'Strikethrough': 'Закреслений', + 'Subscript': 'Нижній індекс', + 'Superscript': 'Верхній індекс', + 'Align left': 'Вирівняти по лівому краю', + 'Center': 'Вирівняти по центру', + 'Align right': 'Вирівняти по правому краю', + 'Justify': 'Вирівняти по ширині', + 'Font Name': 'Шрифт', + 'Font Size': 'Розмір шрифту', + 'Font Color': 'Колір шрифту', + 'Remove Formatting': 'Видалити форматування', + 'Cut': 'Вирізати', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Ваш браузер не дозволяє виконати цю команду. Будь ласка, використовуйте комбінацію клавіш Ctrl/Cmd-X', + 'Copy': 'Копіювати', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Ваш браузер не дозволяє виконати цю команду. Будь ласка, використовуйте комбінацію клавіш Ctrl/Cmd-C', + 'Paste': 'Вставити', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Ваш браузер не дозволяє виконати цю команду. Будь ласка, використовуйте комбінацію клавіш Ctrl/Cmd-V', + 'Paste your text inside the following box:': 'Вставте текст у наступне вікно:', + 'Paste Text': 'Вставити текст', + 'Bullet list': 'Маркований список', + 'Numbered list': 'Нумерований список', + 'Undo': 'Відмінити', + 'Redo': 'Повторити', + 'Rows:': 'Рядків:', + 'Cols:': 'Cтовпців:', + 'Insert a table': 'Додати таблицю', + 'Insert a horizontal rule': 'Додати горизонтальну лінію', + 'Code': 'Код', + 'Insert a Quote': 'Додати цитату', + 'Width (optional):': 'Ширина (необов\'язково):', + 'Height (optional):': 'Висота (необов\'язково):', + 'Insert an image': 'Додати зображення', + 'E-mail:': 'E-mail:', + 'Insert an email': 'Додати E-mail', + 'URL:': 'URL:', + 'Insert a link': 'Додати посилання', + 'Unlink': 'Видалити посилання', + 'More': 'Більше', + 'Insert an emoticon': 'Додати смайлик', + 'Video URL:': 'URL відео:', + 'Insert': 'Вставити', + 'Insert a YouTube video': 'Додати відео з YouTube', + 'Insert current date': 'Додати дату', + 'Insert current time': 'Додати час', + 'Print': 'Надрукувати', + 'View source': 'Показати код', + 'Maximize': 'Розгорнути редактор', + dateFormat: 'day.month.year' + }; +})(jQuery); diff --git a/js/sceditor/languages/vi.js b/js/sceditor/languages/vi.js new file mode 100644 index 00000000..d554202d --- /dev/null +++ b/js/sceditor/languages/vi.js @@ -0,0 +1,68 @@ +/** + * @author Chien + * @license [MIT](http://www.opensource.org/licenses/mit-license.php) + */ +(function ($) { + 'use strict'; + + $.sceditor.locale['vi'] = { + 'Bold': 'Đậm', + 'Italic': 'Nghiêng', + 'Underline': 'Gạch chân', + 'Strikethrough': 'Gạch giữa', + 'Subscript': 'Hệ số', + 'Superscript': 'Mũ', + 'Align left': 'Căn trái', + 'Center': 'Căn giữa', + 'Align right': 'Căn phải', + 'Justify': 'Căn đều', + 'Font Name': 'Phông chữ', + 'Font Size': 'Cỡ chữ', + 'Font Color': 'Màu chữ', + 'Remove Formatting': 'Xóa định dạng', + 'Cut': 'Cắt', + 'Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X': 'Trình duyệt không cho phép sử dụng lệnh Cut. Vui lòng sử dụng phím tắt Ctrl/Cmd-X', + 'Copy': 'Sao chép', + 'Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C': 'Trình duyệt không cho phép sử dụng lệnh Copy. Vui lòng sử dụng phím tắt Ctrl/Cmd-C', + 'Paste': 'Chép vào', + 'Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V': 'Trình duyệt không cho phép sử dụng lệnh Paste. Vui lòng sử dụng phím tắt Ctrl/Cmd-V', + 'Paste your text inside the following box:': 'Chép nội dung text vào khung sau', + 'Paste Text': 'Chép nội dung text', + 'Bullet list': 'Danh sách kiểu nốt', + 'Numbered list': 'Danh sách kiểu số', + 'Undo': 'Hủy bỏ', + 'Redo': 'Trở lại bước trước', + 'Rows:': 'Số dòng', + 'Cols:': 'Số cột', + 'Insert a table': 'Thêm bảng', + 'Insert a horizontal rule': 'Thêm thước ngang', + 'Code': 'Mã code', + 'Width (optional):': 'Dài (không bắt buộc)', + 'Height (optional):': 'Rộng (không bắt buộc)', + 'Insert an image': 'Chèn hình ảnh', + 'E-mail:': 'E-mail', + 'Insert an email': 'Chèn email', + 'URL:': 'Liên kết', + 'Insert a link': 'Chèn liên kết', + 'Unlink': 'Bỏ liên kết', + 'More': 'Xem thêm', + 'Insert an emoticon': 'Chèn biểu tượng', + 'Video URL:': 'Đường dẫn của Video', + 'Insert': 'Thêm vào', + 'Insert a YouTube video': 'Chèn Youtube', + 'Insert current date': 'Chèn ngày hiện tại', + 'Insert current time': 'Chèn thời gian hiện tại', + 'Print': 'In ấn', + 'View source': 'Xem mã nguồn', + 'Description (optional):': 'Mô tả (không bắt buộc)', + 'Enter the image URL:': 'Nhập vào đường dẫn của hình ảnh', + 'Enter the e-mail address:': 'Nhập vào địa chỉ email', + 'Enter the displayed text:': 'Nhập vào nội dung hiển thị', + 'Enter URL:': 'Nhập vào liên kết', + 'Enter the YouTube video URL or ID:': 'Nhập vào liên kết của video hoặc ID trên Youtube', + 'Insert a Quote': 'Chèn trích dẫn', + 'Invalid YouTube video': 'Video Youtube không chính xác', + + dateFormat: 'day/month/year' + }; +})(jQuery); diff --git a/js/sceditor/minified/jquery.sceditor.bbcode.min.js b/js/sceditor/minified/jquery.sceditor.bbcode.min.js new file mode 100644 index 00000000..dc89156d --- /dev/null +++ b/js/sceditor/minified/jquery.sceditor.bbcode.min.js @@ -0,0 +1,4 @@ +/* SCEditor v1.5.2 | (C) 2016, Sam Clarke | sceditor.com/license */ +!function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(2),e=c(3),f=c(6),g=c(7);b.sceditor=d,d.commands=c(9),d.defaultOptions=c(10),d.RangeHelper=c(4),d.dom=c(5),d.ie=f.ie,d.ios=f.ios,d.isWysiwygSupported=f.isWysiwygSupported,d.regexEscape=g.regex,d.escapeEntities=g.entities,d.escapeUriScheme=g.uriScheme,d.PluginManager=e,d.plugins=e.plugins,b.fn.sceditor=function(a){var c,e,g=[];if(a=a||{},a.runWithoutWysiwygSupport||f.isWysiwygSupported)return this.each(function(){c=this.jquery?this:b(this),e=c.data("sceditor"),c.parents(".sceditor-container").length>0||("state"===a?g.push(!!e):"instance"===a?g.push(e):e||new d(this,a))}),g.length?1===g.length?g[0]:b(g):this}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b){a.exports=jQuery},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(3),e=c(4),f=c(5),g=c(7),h=c(6),i=c(8),j=window,k=document,l=b(j),m=b(k),n=h.ie,o=n&&n<11,p=function(a,c){var q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba,ca,da,ea,fa,ga,ha,ia,ja,ka,la,ma,na,oa,pa,qa,ra,sa,ta,ua=this,va=a.get?a.get(0):a,wa=b(va),xa=[],ya=[],za=[],Aa={},Ba=[],Ca={};ua.commands=b.extend(!0,{},c.commands||p.commands),ua.opts=c=b.extend({},p.defaultOptions,c),K=function(){wa.data("sceditor",ua),b.each(c,function(a,d){b.isPlainObject(d)&&(c[a]=b.extend(!0,{},d))}),c.locale&&"en"!==c.locale&&Q(),q=b('
    ').insertAfter(wa).css("z-index",c.zIndex),n&&q.addClass("ie ie"+n),H=!!wa.attr("required"),wa.removeAttr("required"),P(),W(),R(),O(!!c.startInSourceMode),U(),S(),T(),h.isWysiwygSupported||ua.toggleSourceMode(),ha();var a=function(){l.off("load",a),c.autofocus&&ma(),c.autoExpand&&ua.expandToContent(),fa(),C.call("ready")};l.on("load",a),k.readyState&&"complete"===k.readyState&&a()},P=function(){var a=c.plugins;a=a?a.toString().split(","):[],C=new d(ua),b.each(a,function(a,c){C.register(b.trim(c))})},Q=function(){var a;A=p.locale[c.locale],A||(a=c.locale.split("-"),A=p.locale[a[0]]),A&&A.dateFormat&&(c.dateFormat=A.dateFormat)},O=function(a){var d,f;w=b(""),s=b(''),a?(q.addClass("sourceMode"),s.hide()):(q.addClass("wysiwygMode"),w.hide()),c.spellcheck||w.attr("spellcheck","false"),"https:"===j.location.protocol&&s.attr("src","javascript:false"),q.append(s).append(w),t=s[0],x=w[0],ua.dimensions(c.width||wa.width(),c.height||wa.height()),d=X(),d.open(),d.write(i("html",{attrs:n?' class="ie ie'+n+'"':"",spellcheck:c.spellcheck?"":'spellcheck="false"',charset:c.charset,style:c.style})),d.close(),v=b(d),u=b(d.body),ua.readOnly(!!c.readOnly),(h.ios||n)&&(u.height("100%"),n||u.on("touchend",ua.focus)),f=wa.attr("tabindex"),w.attr("tabindex",f),s.attr("tabindex",f),B=new e(t.contentWindow),ua.val(wa.hide().val())},S=function(){c.autoUpdate&&(u.on("blur",ta),w.on("blur",ta)),null===c.rtl&&(c.rtl="rtl"===w.css("direction")),ua.rtl(!!c.rtl),c.autoExpand&&v.on("keyup",ua.expandToContent),c.resizeEnabled&&V(),q.attr("id",c.id),ua.emoticons(c.emoticonsEnabled)},T=function(){var a=n?"selectionchange":"keyup focus blur contextmenu mouseup touchend click",d="keydown keyup keypress focus blur contextmenu";m.click(ea),b(va.form).on("reset",ba).submit(ua.updateOriginal),l.on("resize orientationChanged",fa),u.keypress(aa).keydown($).keydown(_).keyup(ja).blur(ra).keyup(sa).on("paste",Y).on(a,ka).on(d,da),c.emoticonsCompat&&j.getSelection&&u.keyup(oa),w.blur(ra).keyup(sa).keydown($).on(d,da),v.mousedown(ca).blur(ra).on(a,ka).on("beforedeactivate keyup mouseup",N).keyup(ja).focus(function(){z=null}),q.on("selectionchanged",la).on("selectionchanged",ha).on("selectionchanged valuechanged nodechanged",da)},R=function(){var a,d=ua.commands,e=(c.toolbarExclude||"").split(","),f=c.toolbar.split("|");r=b('
    '),b.each(f,function(c,f){a=b('
    '),b.each(f.split(","),function(c,f){var g,h,j=d[f];!j||b.inArray(f,e)>-1||(h=j.shortcut,g=i("toolbarButton",{name:f,dispName:ua._(j.name||j.tooltip||f)},!0),g.data("sceditor-txtmode",!!j.txtExec).data("sceditor-wysiwygmode",!!j.exec).toggleClass("disabled",!j.exec).mousedown(function(){(!n||n<9)&&(J=!0)}).click(function(){var a=b(this);return a.hasClass("disabled")||M(a,j),ha(),!1}),j.tooltip&&g.attr("title",ua._(j.tooltip)+(h?" ("+h+")":"")),h&&ua.addShortcut(h,f),j.state?za.push({name:f,state:j.state}):"string"==typeof j.exec&&za.push({name:f,state:j.exec}),a.append(g),Ca[f]=g)}),a[0].firstChild&&r.append(a)}),b(c.toolbarContainer||q).append(r)},U=function(){b.each(ua.commands,function(a,c){c.forceNewLineAfter&&b.isArray(c.forceNewLineAfter)&&(ya=b.merge(ya,c.forceNewLineAfter))}),ja()},V=function(){var a,d,e,f,g,h,i=b('
    '),k=b('
    '),l="touchmove mousemove",o="touchcancel touchend mouseup",p=0,r=0,s=0,t=0,u=0,v=0,w=q.width(),x=q.height(),y=!1,z=ua.rtl();a=c.resizeMinHeight||x/1.5,d=c.resizeMaxHeight||2.5*x,e=c.resizeMinWidth||w/1.25,f=c.resizeMaxWidth||1.25*w,g=function(b){"touchmove"===b.type?(b=j.event,s=b.changedTouches[0].pageX,t=b.changedTouches[0].pageY):(s=b.pageX,t=b.pageY);var g=v+(t-r),h=z?u-(s-p):u+(s-p);f>0&&h>f&&(h=f),e>0&&h0&&g>d&&(g=d),a>0&&g-1&&(a=q.width()),s.width(a-s.data("outerWidthOffset")),w.width(a-w.data("outerWidthOffset")),h.ios&&u&&u.width(a-s.data("outerWidthOffset")-(u.outerWidth(!0)-u.width()))),b!==!1&&(d!==!1&&(c.height=b),b&&b.toString().indexOf("%")>-1&&(b=q.height(b).height(),q.height("auto")),b-=c.toolbarContainer?0:r.outerHeight(!0),s.height(b-s.data("outerHeightOffset")),w.height(b-f-w.data("outerHeightOffset"))),ua)},ua.updateStyleCache=function(){s.data("outerWidthOffset",s.outerWidth(!0)-s.width()),w.data("outerWidthOffset",w.outerWidth(!0)-w.width()),s.data("outerHeightOffset",s.outerHeight(!0)-s.height()),w.data("outerHeightOffset",w.outerHeight(!0)-w.height())},ua.height=function(a,b){return a||0===a?(ua.dimensions(null,a,b),ua):q.height()},ua.maximize=function(a){return"undefined"==typeof a?q.is(".sceditor-maximize"):(a=!!a,n<7&&b("html, body").toggleClass("sceditor-maximize",a),q.toggleClass("sceditor-maximize",a),ua.width(a?"100%":c.width,!1),ua.height(a?"100%":c.height,!1),ua)},ua.expandToContent=function(a){var b=q.height(),d=b-s.height(),e=u[0].scrollHeight||v[0].documentElement.scrollHeight,f=c.resizeMaxHeight||2*(c.height||wa.height());e+=d,(a===!0||e<=f)&&e>b&&ua.height(e)},ua.destroy=function(){C&&(C.destroy(),B=null,z=null,C=null,y&&y.off().remove(),m.off("click",ea),l.off("resize orientationChanged",fa),b(va.form).off("reset",ba).off("submit",ua.updateOriginal),u.off(),v.off().find("*").remove(),w.off().remove(),r.remove(),q.off().find("*").off().remove(),q.remove(),wa.removeData("sceditor").removeData("sceditorbbcode").show(),H&&wa.attr("required","required"))},ua.createDropDown=function(a,d,e,f){var g,h="sceditor-"+d,i=y&&y.is("."+h);ua.closeDropDown(!0),i||(f!==!1&&b(e).find(":not(input,textarea)").filter(function(){return 1===this.nodeType}).attr("unselectable","on"),g={top:a.offset().top,left:a.offset().left,marginTop:a.outerHeight()},b.extend(g,c.dropDownCss),y=b('
    ').css(g).append(e).appendTo(b("body")).on("click focusin",function(a){a.stopPropagation()}),setTimeout(function(){y&&y.find("input,textarea").first().focus()}))},ea=function(a){3!==a.which&&y&&(ta(),ua.closeDropDown())},Y=function(a){var b,d,e,f=u[0],g=v[0],h=0,i=k.createElement("div"),j=g.createDocumentFragment(),l=!!a&&a.clipboardData;if(c.disablePasting)return!1;if(c.enablePasteFiltering){if(B.saveRange(),k.body.appendChild(i),l&&l.getData&&((b=l.getData("text/html"))||(b=l.getData("text/plain"))))return i.innerHTML=b,Z(f,i),!1;for(e=u.scrollTop()||v.scrollTop();f.firstChild;)j.appendChild(f.firstChild);return d=function(a,b){if(a.childNodes.length>0||h>25){for(;a.firstChild;)b.appendChild(a.firstChild);for(;j.firstChild;)a.appendChild(j.firstChild);u.scrollTop(e),v.scrollTop(e),b.childNodes.length>0?Z(a,b):B.restoreRange()}else h++,setTimeout(function(){d(a,b)},20)},d(f,i),ua.focus(),!0}},Z=function(a,c){f.fixNesting(c);var d=c.innerHTML;C.hasHandler("toSource")&&(d=C.callOnlyFirst("toSource",d,b(c))),c.parentNode.removeChild(c),C.hasHandler("toWysiwyg")&&(d=C.callOnlyFirst("toWysiwyg",d,!0)),B.restoreRange(),ua.wysiwygEditorInsertHtml(d,null,!0)},ua.closeDropDown=function(a){y&&(y.off().remove(),y=null),a===!0&&ua.focus()},X=function(){return t.contentDocument?t.contentDocument:t.contentWindow&&t.contentWindow.document?t.contentWindow.document:t.document},ua.wysiwygEditorInsertHtml=function(a,c,d){var e,g,h,i=s.height();ua.focus(),(d||!b(E).is("code")&&0===b(E).parents("code").length)&&(B.insertHTML(a,c),B.saveRange(),L(u[0]),e=u.find("#sceditor-end-marker").show(),g=u.scrollTop()||v.scrollTop(),h=f.getOffset(e[0]).top+1.5*e.outerHeight(!0)-i,e.hide(),(h>g||h+i").appendTo(b("body")).hide().html(g);d!==!1&&C.hasHandler("toSource")&&(g=C.callOnlyFirst("toSource",g,h)),h.remove(),a+=g+c}return d!==!1&&C.hasHandler("toWysiwyg")&&(a=C.callOnlyFirst("toWysiwyg",a,!0)),d!==!1&&f===!0&&(a=a.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&")),ua.wysiwygEditorInsertHtml(a),ua},ua.getWysiwygEditorValue=function(a){var c,d=b("
    ").appendTo(document.body).append(b(u[0].childNodes).clone());return f.fixNesting(d[0]),c=d.html(),a!==!1&&C.hasHandler("toSource")&&(c=C.callOnlyFirst("toSource",c,d)),d.remove(),c},ua.getBody=function(){return u},ua.getContentAreaContainer=function(){return s},ua.getSourceEditorValue=function(a){var b=w.val();return a!==!1&&C.hasHandler("toWysiwyg")&&(b=C.callOnlyFirst("toWysiwyg",b)),b},ua.setWysiwygEditorValue=function(a){a||(a="

    "+(n?"":"
    ")+"

    "),u[0].innerHTML=a,L(u[0]),ja(),qa()},ua.setSourceEditorValue=function(a){w.val(a),qa()},ua.updateOriginal=function(){wa.val(ua.val())},L=function(a){if(c.emoticonsEnabled&&!b(a).parents("code").length){var d=a.ownerDocument,e="\\s| | | | | ",h=[],j=[],k=b.extend({},c.emoticons.more,c.emoticons.dropdown,c.emoticons.hidden);b.each(k,function(a){c.emoticonsCompat&&(j[a]=new RegExp("(>|^|"+e+")"+g.regex(a)+"($|<|"+e+")")),h.push(a)});var l=function(a){for(a=a.firstChild;a;){var e,g,m,n,o,p,q,r=a.parentNode,s=a.nodeValue;if(3!==a.nodeType)b(a).is("code")||l(a);else if(s)for(o=h.length;o--;)g=h[o],q=c.emoticonsCompat?s.search(j[g]):s.indexOf(g),q>-1&&(p=a.nextSibling,m=k[g],e=s.substr(q).split(g),s=s.substr(0,q)+e.shift(),a.nodeValue=s,n=f.parseHTML(i("emoticon",{key:g,url:m.url||m,tooltip:m.tooltip||g}),d),r.insertBefore(n[0],p),r.insertBefore(d.createTextNode(e.join(g)),p));a=a.nextSibling}};l(a),c.emoticonsCompat&&(Ba=u.find("img[data-sceditor-emoticon]"))}},ua.inSourceMode=function(){return q.hasClass("sourceMode")},ua.sourceMode=function(a){var b=ua.inSourceMode();return"boolean"!=typeof a?b:((b&&!a||!b&&a)&&ua.toggleSourceMode(),ua)},ua.toggleSourceMode=function(){var a=ua.inSourceMode();!h.isWysiwygSupported&&a||(a||(B.saveRange(),B.clear()),ua.blur(),a?ua.setWysiwygEditorValue(ua.getSourceEditorValue()):ua.setSourceEditorValue(ua.getWysiwygEditorValue()),z=null,w.toggle(),s.toggle(),q.toggleClass("wysiwygMode",a).toggleClass("sourceMode",!a),ga(),ha())},ia=function(){return x.focus(),"undefined"!=typeof x.selectionStart?x.value.substring(x.selectionStart,x.selectionEnd):k.selection.createRange().text},M=function(a,c){ua.inSourceMode()?c.txtExec&&(b.isArray(c.txtExec)?ua.sourceEditorInsertText.apply(ua,c.txtExec):c.txtExec.call(ua,a,ia())):c.exec&&(b.isFunction(c.exec)?c.exec.call(ua,a):ua.execCommand(c.exec,c.hasOwnProperty("execParam")?c.execParam:null))},N=function(){n&&(z=B.selectedRange())},ua.execCommand=function(a,c){var d=!1,e=ua.commands[a],f=b(B.parentNode());if(ua.focus(),!f.is("code")&&0===f.parents("code").length){try{d=v[0].execCommand(a,!1,c)}catch(a){}!d&&e&&e.errorMessage&&alert(ua._(e.errorMessage)),ha()}},ka=function(){function a(){B&&!B.compare(F)&&(F=B.cloneSelected(),q.trigger(b.Event("selectionchanged"))),G=!1}G||(G=!0,n?a():setTimeout(a,100))},la=function(){var a,c=B.parentNode();D!==c&&(a=D,D=c,E=B.getFirstBlockParent(c),q.trigger(b.Event("nodechanged",{oldNode:a,newNode:D})))},ua.currentNode=function(){return D},ua.currentBlockNode=function(){return E},ha=function(a){var b,c,d="active",e=v[0],f=ua.sourceMode();if(ua.readOnly())return void r.find(d).removeClass(d);f||(c=a?a.newNode:B.parentNode(),b=B.getFirstBlockParent(c));for(var g=0;g-1&&(h=e.queryCommandState(j)?1:0)}catch(a){}}else k||(h=j.call(ua,c,b));i.toggleClass("disabled",k||h<0).toggleClass(d,h>0)}},aa=function(a){var c,d,e,g,h="code,blockquote,pre",i="li,ul,ol";if(!a.originalEvent.defaultPrevented)return ua.closeDropDown(),c=b(E).closest(h+","+i).first(),13===a.which&&c.length&&!c.is(i)?(z=null,d=v[0].createElement("br"),B.insertNode(d),o||(e=d.parentNode,g=e.lastChild,g&&3===g.nodeType&&""===g.nodeValue&&(e.removeChild(g),g=e.lastChild),!f.isInline(e,!0)&&g===d&&f.isInline(d.previousSibling)&&B.insertHTML("
    ")),!1):void 0},ja=function(){var a,c,d,e=u[0];f.rTraverse(e,function(g){if(a=g.nodeName.toLowerCase(),b.inArray(a,ya)>-1&&(c=!0),3===g.nodeType&&!/^\s*$/.test(g.nodeValue)||"br"===a||o&&!g.firstChild&&!f.isInline(g,!1))return c&&(d=v[0].createElement("p"),d.className="sceditor-nlf",d.innerHTML=o?"":"
    ",e.appendChild(d)),!1})},ba=function(){ua.val(wa.val())},ca=function(){ua.closeDropDown(),z=null},fa=function(){var a=c.height,b=c.width;ua.maximize()?ua.dimensions("100%","100%",!1):(a&&a.toString().indexOf("%")>-1||b&&b.toString().indexOf("%")>-1)&&ua.dimensions(b,a)},ua._=function(){var a,b=arguments;return A&&A[b[0]]&&(b[0]=A[b[0]]),b[0].replace(/\{(\d+)\}/g,function(c,d){return b[d-0+1]!==a?b[d-0+1]:"{"+d+"}"})},da=function(a){C.call(a.type+"Event",a,ua);var c=a.target===x?"scesrc":"scewys",d=b.Event(a);d.type=c+a.type,q.trigger(d,ua)},ua.bind=function(a,c,d,e){a=a.split(" ");for(var f=a.length;f--;)b.isFunction(c)&&(d||q.on("scewys"+a[f],c),e||q.on("scesrc"+a[f],c),"valuechanged"===a[f]&&(qa.hasHandler=!0));return ua},ua.unbind=function(a,c,d,e){a=a.split(" ");for(var f=a.length;f--;)b.isFunction(c)&&(d||q.off("scewys"+a[f],c),e||q.off("scesrc"+a[f],c));return ua},ua.blur=function(a,c,d){return b.isFunction(a)?ua.bind("blur",a,c,d):ua.sourceMode()?w.blur():u.blur(),ua},ua.focus=function(a,c,d){if(b.isFunction(a))ua.bind("focus",a,c,d);else if(ua.inSourceMode())x.focus();else{var e,f=B.selectedRange();F||B.hasSelection()||ma(),!o&&f&&1===f.endOffset&&f.collapsed&&(e=f.endContainer,e&&1===e.childNodes.length&&b(e.firstChild).is("br")&&(f.setStartBefore(e.firstChild),f.collapse(!0),B.selectRange(f))),t.contentWindow.focus(),u[0].focus(),z&&(B.selectRange(z),z=null)}return ha(),ua},ua.keyDown=function(a,b,c){return ua.bind("keydown",a,b,c)},ua.keyPress=function(a,b,c){return ua.bind("keypress",a,b,c)},ua.keyUp=function(a,b,c){return ua.bind("keyup",a,b,c)},ua.nodeChanged=function(a){return ua.bind("nodechanged",a,!1,!0)},ua.selectionChanged=function(a){return ua.bind("selectionchanged",a,!1,!0)},ua.valueChanged=function(a,b,c){return ua.bind("valuechanged",a,b,c)},na=function(a){var d,e=0,f=ua.emoticonsCache,g=String.fromCharCode(a.which);if(!b(E).is("code")&&!b(E).parents("code").length)return f||(f=[],b.each(b.extend({},c.emoticons.more,c.emoticons.dropdown,c.emoticons.hidden),function(a,b){f[e++]=[a,i("emoticon",{key:a,url:b.url||b,tooltip:b.tooltip||a})]}),f.sort(function(a,b){return a[0].length-b[0].length}),ua.emoticonsCache=f,ua.longestEmoticonCode=f[f.length-1][0].length),d=B.replaceKeyword(ua.emoticonsCache,!0,!0,ua.longestEmoticonCode,c.emoticonsCompat,g),d&&c.emoticonsCompat?(Ba=u.find("img[data-sceditor-emoticon]"),/^\s$/.test(g)):!d},oa=function(){if(Ba.length){var a,c,d,e,f,g,h=ua.currentBlockNode(),i=!1,j=/[^\s\xA0\u2002\u2003\u2009\u00a0]+/;Ba=b.map(Ba,function(k){return k&&k.parentNode?b.contains(h,k)?(a=k.previousSibling,c=k.nextSibling,f=a.nodeValue,null===f&&(f=a.innerText||""),a&&j.test(a.nodeValue.slice(-1))||c&&j.test((c.nodeValue||"")[0])?(d=k.parentNode,e=B.cloneSelected(),g=e.startContainer,f+=b(k).data("sceditor-emoticon"),g===c?i=f.length+e.startOffset:g===h&&h.childNodes[e.startOffset]===c?i=f.length:g===a&&(i=e.startOffset),c&&3===c.nodeType||(c=d.insertBefore(d.ownerDocument.createTextNode(""),c)),c.insertData(0,f),d.removeChild(a),d.removeChild(k),i!==!1&&(e.setStart(c,i),e.collapse(!0),B.selectRange(e)),null):k):k:null})}},ua.emoticons=function(a){return a||a===!1?(c.emoticonsEnabled=a,a?(u.keypress(na),ua.sourceMode()||(B.saveRange(),L(u[0]),Ba=u.find("img[data-sceditor-emoticon]"),qa(!1),B.restoreRange())):(u.find("img[data-sceditor-emoticon]").replaceWith(function(){return b(this).data("sceditor-emoticon")}),Ba=[],u.off("keypress",na),qa()),ua):c.emoticonsEnabled},ua.css=function(a){return I||(I=b('

    ',toolbarButton:'
    {dispName}
    ',emoticon:'{key}',fontOpt:'{font}',sizeOpt:'{size}',pastetext:'
    ',table:'
    ',image:'
    ',email:'
    ',link:'
    ',youtubeMenu:'
    ',youtube:''};return function(b,c,d){var e=a[b];return $.each(c,function(a,b){e=e.replace(new RegExp("\\{"+a+"\\}","g"),b)}),d&&(e=$(e)),e}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(6).ie,e=c(8),f=d&&d<11,g={bold:{exec:"bold",tooltip:"Bold",shortcut:"Ctrl+B"},italic:{exec:"italic",tooltip:"Italic",shortcut:"Ctrl+I"},underline:{exec:"underline",tooltip:"Underline",shortcut:"Ctrl+U"},strike:{exec:"strikethrough",tooltip:"Strikethrough"},subscript:{exec:"subscript",tooltip:"Subscript"},superscript:{exec:"superscript",tooltip:"Superscript"},left:{exec:"justifyleft",tooltip:"Align left"},center:{exec:"justifycenter",tooltip:"Center"},right:{exec:"justifyright",tooltip:"Align right"},justify:{exec:"justifyfull",tooltip:"Justify"},font:{_dropDown:function(a,c,d){for(var f=0,g=a.opts.fonts.split(","),h=b("
    "),i=function(){return d(b(this).data("font")),a.closeDropDown(!0),!1};f"),g=function(c){d(b(this).data("size")),a.closeDropDown(!0),c.preventDefault()},h=1;h<=7;h++)f.append(e("sizeOpt",{size:h},!0).click(g));a.createDropDown(c,"fontsize-picker",f)},exec:function(a){var b=this;g.size._dropDown(b,a,function(a){b.execCommand("fontsize",a)})},tooltip:"Font Size"},color:{_dropDown:function(a,c,d){var e,f,h,i,j={r:255,g:255,b:255},k=b("
    "),l=a.opts.colors?a.opts.colors.split("|"):new Array(21),m=[],n=g.color;if(!n._htmlCache){for(e=0;e'),f=0;f'),f%5===0?(j.g-=51,j.b=255):j.b-=51;m.push("
    "),e%5===0?(j.r-=51,j.g=255,j.b=255):(j.g=255,j.b=255)}n._htmlCache=m.join("")}k.append(n._htmlCache).find("a").click(function(c){d(b(this).attr("data-color")),a.closeDropDown(!0),c.preventDefault()}),a.createDropDown(c,"color-picker",k)},exec:function(a){var b=this;g.color._dropDown(b,a,function(a){b.execCommand("forecolor",a)})},tooltip:"Font Color"},removeformat:{exec:"removeformat",tooltip:"Remove Formatting"},cut:{exec:"cut",tooltip:"Cut",errorMessage:"Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X"},copy:{exec:"copy",tooltip:"Copy",errorMessage:"Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C"},paste:{exec:"paste",tooltip:"Paste",errorMessage:"Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V"},pastetext:{exec:function(a){var b,c,d=this;c=e("pastetext",{label:d._("Paste your text inside the following box:"),insert:d._("Insert")},!0),c.find(".button").click(function(a){b=c.find("#txt").val(),b&&d.wysiwygEditorInsertText(b),d.closeDropDown(!0),a.preventDefault()}),d.createDropDown(a,"pastetext",c)},tooltip:"Paste Text"},bulletlist:{exec:"insertunorderedlist",tooltip:"Bullet list"},orderedlist:{exec:"insertorderedlist",tooltip:"Numbered list"},indent:{state:function(a,c){var d,e,f,g=b(c),h=g.parents("ul,ol,menu"),i=h.first();if(h.length>1||i.children().length>1)return 0;if(g.is("ul,ol,menu")){if(d=this.getRangeHelper().selectedRange(),!(window.Range&&d instanceof Range))return g.is("li,ul,ol,menu")?0:-1;if(e=d.startContainer.parentNode,f=d.endContainer.parentNode,e!==e.parentNode.firstElementChild||b(f).is("li")&&f!==f.parentNode.lastElementChild)return 0}return-1},exec:function(){var a=this,c=b(a.getRangeHelper().getFirstBlockParent());a.focus(),c.parents("ul,ol,menu")&&a.execCommand("indent")},tooltip:"Add indent"},outdent:{state:function(a,c){return b(c).is("ul,ol,menu")||b(c).parents("ul,ol,menu").length>0?0:-1},exec:function(){var a=this,c=b(a.getRangeHelper().getFirstBlockParent());c.parents("ul,ol,menu")&&a.execCommand("outdent")},tooltip:"Remove one indent"},table:{forceNewLineAfter:["table"],exec:function(a){var b=this,c=e("table",{rows:b._("Rows:"),cols:b._("Cols:"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d,e,g=c.find("#rows").val()-0,h=c.find("#cols").val()-0,i="";if(!(g<1||h<1)){for(d=0;d",e=0;e"+(f?"":"
    ")+"";i+=""}i+="
    ",b.wysiwygEditorInsertHtml(i),b.closeDropDown(!0),a.preventDefault()}}),b.createDropDown(a,"inserttable",c)},tooltip:"Insert a table"},horizontalrule:{exec:"inserthorizontalrule",tooltip:"Insert a horizontal rule"},code:{forceNewLineAfter:["code"],exec:function(){this.wysiwygEditorInsertHtml("",(f?"":"
    ")+"
    ")},tooltip:"Code"},image:{exec:function(a){var b=this,c=e("image",{url:b._("URL:"),width:b._("Width (optional):"),height:b._("Height (optional):"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#image").val(),e=c.find("#width").val(),f=c.find("#height").val(),g="";e&&(g+=' width="'+e+'"'),f&&(g+=' height="'+f+'"'),d&&b.wysiwygEditorInsertHtml("'),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertimage",c)},tooltip:"Insert an image"},email:{exec:function(a){var b=this,c=e("email",{label:b._("E-mail:"),desc:b._("Description (optional):"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#email").val(),e=c.find("#des").val();d&&(b.focus(),!b.getRangeHelper().selectedHtml()||e?(e=e||d,b.wysiwygEditorInsertHtml(''+e+"")):b.execCommand("createlink","mailto:"+d)),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertemail",c)},tooltip:"Insert an email"},link:{exec:function(a){var b=this,c=e("link",{url:b._("URL:"),desc:b._("Description (optional):"),ins:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#link").val(),e=c.find("#des").val();d&&(b.focus(),!b.getRangeHelper().selectedHtml()||e?(e=e||d,b.wysiwygEditorInsertHtml(''+e+"")):b.execCommand("createlink",d)),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertlink",c)},tooltip:"Insert a link"},unlink:{state:function(){var a=b(this.currentNode());return a.is("a")||a.parents("a").length>0?0:-1},exec:function(){var a=b(this.currentNode()),c=a.is("a")?a:a.parents("a").first();c.length&&c.replaceWith(c.contents())},tooltip:"Unlink"},quote:{forceNewLineAfter:["blockquote"],exec:function(a,b,c){var d="
    ",e="
    ";b?(c=c?""+c+"":"",d=d+c+b+e,e=null):""===this.getRangeHelper().selectedHtml()&&(e=(f?"":"
    ")+e),this.wysiwygEditorInsertHtml(d,e)},tooltip:"Insert a Quote"},emoticon:{exec:function(a){var c=this,d=function(e){var f,g=c.opts.emoticonsCompat,h=c.getRangeHelper(),i=g&&" "!==h.getOuterText(!0,1)?" ":"",j=g&&" "!==h.getOuterText(!1,1)?" ":"",k=b("
    "),l=b("
    ").appendTo(k),m=0,n=b.extend({},c.opts.emoticons.dropdown,e?c.opts.emoticons.more:{});return b.each(n,function(){m++}),m=Math.sqrt(m),b.each(n,function(a,d){l.append(b("").attr({src:d.url||d,alt:a,title:d.tooltip||a}).click(function(){return c.insert(i+b(this).attr("alt")+j,null,!1).closeDropDown(!0),!1})),l.children().length>=m&&(l=b("
    ").appendTo(k))}),!e&&c.opts.emoticons.more&&(f=b(''+c._("More")+"").click(function(){return c.createDropDown(a,"more-emoticons",d(!0)),!1}),k.append(f)),k};c.createDropDown(a,"emoticons",d(!1))},txtExec:function(a){g.emoticon.exec.call(this,a)},tooltip:"Insert an emoticon"},youtube:{_dropDown:function(a,b,c){var d,f=e("youtubeMenu",{label:a._("Video URL:"),insert:a._("Insert")},!0);f.find(".button").click(function(b){var e=f.find("#link").val();e&&(d=e.match(/(?:v=|v\/|embed\/|youtu.be\/)(.{11})/),d&&(e=d[1]),/^[a-zA-Z0-9_\-]{11}$/.test(e)?c(e):alert("Invalid YouTube video")),a.closeDropDown(!0),b.preventDefault()}),a.createDropDown(b,"insertlink",f)},exec:function(a){var b=this;g.youtube._dropDown(b,a,function(a){b.wysiwygEditorInsertHtml(e("youtube",{id:a}))})},tooltip:"Insert a YouTube video"},date:{_date:function(a){var b=new Date,c=b.getYear(),d=b.getMonth()+1,e=b.getDate();return c<2e3&&(c=1900+c),d<10&&(d="0"+d),e<10&&(e="0"+e),a.opts.dateFormat.replace(/year/i,c).replace(/month/i,d).replace(/day/i,e)},exec:function(){this.insertText(g.date._date(this))},txtExec:function(){this.insertText(g.date._date(this))},tooltip:"Insert current date"},time:{_time:function(){var a=new Date,b=a.getHours(),c=a.getMinutes(),d=a.getSeconds();return b<10&&(b="0"+b),c<10&&(c="0"+c),d<10&&(d="0"+d),b+":"+c+":"+d},exec:function(){this.insertText(g.time._time())},txtExec:function(){this.insertText(g.time._time())},tooltip:"Insert current time"},ltr:{state:function(a,b){return b&&"ltr"===b.style.direction},exec:function(){var a=this,c=a.getRangeHelper().getFirstBlockParent(),d=b(c);a.focus(),(c&&!d.is("body")||(a.execCommand("formatBlock","p"),c=a.getRangeHelper().getFirstBlockParent(),d=b(c),c&&!d.is("body")))&&("ltr"===d.css("direction")?d.css("direction",""):d.css("direction","ltr"))},tooltip:"Left-to-Right"},rtl:{state:function(a,b){return b&&"rtl"===b.style.direction},exec:function(){var a=this,c=a.getRangeHelper().getFirstBlockParent(),d=b(c);a.focus(),(c&&!d.is("body")||(a.execCommand("formatBlock","p"),c=a.getRangeHelper().getFirstBlockParent(),d=b(c),c&&!d.is("body")))&&("rtl"===d.css("direction")?d.css("direction",""):d.css("direction","rtl"))},tooltip:"Right-to-Left"},print:{exec:"print",tooltip:"Print"},maximize:{state:function(){return this.maximize()},exec:function(){this.maximize(!this.maximize())},txtExec:function(){this.maximize(!this.maximize())},tooltip:"Maximize",shortcut:"Ctrl+Shift+M"},source:{state:function(){return this.sourceMode()},exec:function(){this.toggleSourceMode()},txtExec:function(){this.toggleSourceMode()},tooltip:"View source",shortcut:"Ctrl+Shift+S"},ignore:{}};return g}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1);return{toolbar:"bold,italic,underline,strike,subscript,superscript|left,center,right,justify|font,size,color,removeformat|cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|table|code,quote|horizontalrule,image,email,link,unlink|emoticon,youtube,date,time|ltr,rtl|print,maximize,source",toolbarExclude:null,style:"jquery.sceditor.default.css",fonts:"Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana",colors:null,locale:b("html").attr("lang")||"en",charset:"utf-8",emoticonsCompat:!1,emoticonsEnabled:!0,emoticonsRoot:"",emoticons:{dropdown:{":)":"emoticons/smile.png",":angel:":"emoticons/angel.png",":angry:":"emoticons/angry.png","8-)":"emoticons/cool.png",":'(":"emoticons/cwy.png",":ermm:":"emoticons/ermm.png",":D":"emoticons/grin.png","<3":"emoticons/heart.png",":(":"emoticons/sad.png",":O":"emoticons/shocked.png",":P":"emoticons/tongue.png",";)":"emoticons/wink.png"},more:{":alien:":"emoticons/alien.png",":blink:":"emoticons/blink.png",":blush:":"emoticons/blush.png",":cheerful:":"emoticons/cheerful.png",":devil:":"emoticons/devil.png",":dizzy:":"emoticons/dizzy.png",":getlost:":"emoticons/getlost.png",":happy:":"emoticons/happy.png",":kissing:":"emoticons/kissing.png",":ninja:":"emoticons/ninja.png",":pinch:":"emoticons/pinch.png",":pouty:":"emoticons/pouty.png",":sick:":"emoticons/sick.png",":sideways:":"emoticons/sideways.png",":silly:":"emoticons/silly.png",":sleeping:":"emoticons/sleeping.png",":unsure:":"emoticons/unsure.png",":woot:":"emoticons/w00t.png",":wassat:":"emoticons/wassat.png"},hidden:{":whistling:":"emoticons/whistling.png",":love:":"emoticons/wub.png"}},width:null,height:null,resizeEnabled:!0,resizeMinWidth:null,resizeMinHeight:null,resizeMaxHeight:null,resizeMaxWidth:null,resizeHeight:!0,resizeWidth:!0,dateFormat:"year-month-day",toolbarContainer:null,enablePasteFiltering:!1,disablePasting:!1,readOnly:!1,rtl:!1,autofocus:!1,autofocusEnd:!0,autoExpand:!1,autoUpdate:!1,spellcheck:!0,runWithoutWysiwygSupport:!1,startInSourceMode:!1,id:null,plugins:"",zIndex:null,bbcodeTrim:!1,disableBlockRemove:!1,parserOptions:{},dropDownCss:{}}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))}]),function(a,b,c){"use strict";var d=a.sceditor,e=d.plugins,f=d.escapeEntities,g=d.escapeUriScheme,h=d.ie,i=h&&h<11,j=d.command.get,k={bold:{txtExec:["[b]","[/b]"]},italic:{txtExec:["[i]","[/i]"]},underline:{txtExec:["[u]","[/u]"]},strike:{txtExec:["[s]","[/s]"]},subscript:{txtExec:["[sub]","[/sub]"]},superscript:{txtExec:["[sup]","[/sup]"]},left:{txtExec:["[left]","[/left]"]},center:{txtExec:["[center]","[/center]"]},right:{txtExec:["[right]","[/right]"]},justify:{txtExec:["[justify]","[/justify]"]},font:{txtExec:function(a){var b=this;j("font")._dropDown(b,a,function(a){b.insertText("[font="+a+"]","[/font]")})}},size:{txtExec:function(a){var b=this;j("size")._dropDown(b,a,function(a){b.insertText("[size="+a+"]","[/size]")})}},color:{txtExec:function(a){var b=this;j("color")._dropDown(b,a,function(a){b.insertText("[color="+a+"]","[/color]")})}},bulletlist:{txtExec:function(b,c){var d="";a.each(c.split(/\r?\n/),function(){d+=(d?"\n":"")+"[li]"+this+"[/li]"}),this.insertText("[ul]\n"+d+"\n[/ul]")}},orderedlist:{txtExec:function(b,c){var d="";a.each(c.split(/\r?\n/),function(){d+=(d?"\n":"")+"[li]"+this+"[/li]"}),e.bbcode.bbcode.get(""),this.insertText("[ol]\n"+d+"\n[/ol]")}},table:{txtExec:["[table][tr][td]","[/td][/tr][/table]"]},horizontalrule:{txtExec:["[hr]"]},code:{txtExec:["[code]","[/code]"]},image:{txtExec:function(a,b){var c=this,d=prompt(c._("Enter the image URL:"),b);d&&c.insertText("[img]"+d+"[/img]")}},email:{txtExec:function(a,b){var c=this,d=b&&b.indexOf("@")>-1?null:b,e=prompt(c._("Enter the e-mail address:"),d?"":b),f=prompt(c._("Enter the displayed text:"),d||e)||e;e&&c.insertText("[email="+e+"]"+f+"[/email]")}},link:{txtExec:function(b,c){var d=this,e=/^[a-z]+:\/\//i.test(a.trim(c))?null:c,f=prompt(d._("Enter URL:"),e?"http://":a.trim(c)),g=prompt(d._("Enter the displayed text:"),e||f)||f;f&&d.insertText("[url="+f+"]"+g+"[/url]")}},quote:{txtExec:["[quote]","[/quote]"]},youtube:{txtExec:function(a){var b=this;j("youtube")._dropDown(b,a,function(a){b.insertText("[youtube]"+a+"[/youtube]")})}},rtl:{txtExec:["[rtl]","[/rtl]"]},ltr:{txtExec:["[ltr]","[/ltr]"]}},l=function(a){return a?a.replace(/\\(.)/g,"$1").replace(/^(["'])(.*?)\1$/,"$2"):a},m=function(){var a,b=arguments;return b[0].replace(/\{(\d+)\}/g,function(c,d){return b[d-0+1]!==a?b[d-0+1]:"{"+d+"}"})},n={OPEN:"open",CONTENT:"content",NEWLINE:"newline",CLOSE:"close"},o=function(a,b,c,d,e,f){var g=this;g.type=a,g.name=b,g.val=c,g.attrs=d||{},g.children=e||[],g.closing=f||null};o.prototype={clone:function(a){var b=this;return new o(b.type,b.name,b.val,b.attrs,a?b.children:[],b.closing?b.closing.clone():null)},splitAt:function(b){var c,d=this,e=0,f=d.children.length;if("number"!=typeof b&&(b=a.inArray(b,d.children)),b<0||b>f)return null;for(;f--;)f>=b?e++:f=0;return c=d.clone(),c.children=d.children.splice(b,e),c}};var p=function(b){if(!(this instanceof p))return new p(b);var d,g,j,k,m,q,r,s,t,u,v,w,x,y,z,A=this;d=function(){A.bbcodes=e.bbcode.bbcodes,A.opts=a.extend({},p.defaults,b)},A.tokenize=function(a){var b,c,d,e=[],f=[{type:n.CLOSE,regex:/^\[\/[^\[\]]+\]/},{type:n.OPEN,regex:/^\[[^\[\]]+\]/},{type:n.NEWLINE,regex:/^(\r\n|\r|\n)/},{type:n.CONTENT,regex:/^([^\[\r\n]+|\[)/}];f.reverse();a:for(;a.length;){for(d=f.length;d--;)if(c=f[d].type,(b=a.match(f[d].regex))&&b[0]){e.push(g(c,b[0])),a=a.substr(b[0].length);continue a}a.length&&e.push(g(n.CONTENT,a)),a=""}return e},g=function(b,c){var d,f,g,h=/\[([^\]\s=]+)(?:([^\]]+))?\]/,i=/\[\/([^\[\]]+)\]/;return b===n.OPEN&&(d=c.match(h))&&(g=y(d[1]),d[2]&&(d[2]=a.trim(d[2]))&&(f=j(d[2]))),b===n.CLOSE&&(d=c.match(i))&&(g=y(d[1])),b===n.NEWLINE&&(g="#newline"),g&&(b!==n.OPEN&&b!==n.CLOSE||e.bbcode.bbcodes[g])||(b=n.CONTENT,g="#"),new o(b,g,c,f)},j=function(a){var b,c=/([^\s=]+)=(?:(?:(["'])((?:\\\2|[^\2])*?)\2)|((?:.(?!\s\S+=))*.))/g,d={};if("="===a.charAt(0)&&a.indexOf("=",1)<0)d.defaultattr=l(a.substr(1));else for("="===a.charAt(0)&&(a="defaultattr"+a);b=c.exec(a);)d[y(b[1])]=l(b[3])||b[4];return d},A.parse=function(a,b){var c=k(A.tokenize(a)),d=A.opts;return d.fixInvalidChildren&&t(c),d.removeEmptyTags&&s(c),d.fixInvalidNesting&&q(c),m(c,null,b),d.removeEmptyTags&&s(c),c},w=function(a,b,c){for(var d=c.length;d--;)if(c[d].type===b&&c[d].name===a)return!0;return!1},r=function(b,c){var d=b?A.bbcodes[b.name]:{},e=d.allowedChildren;return!A.opts.fixInvalidChildren||!e||a.inArray(c.name||"#",e)>-1},k=function(b){for(var c,d,e,f,g,h,i,j=[],k=[],l=[],m=function(){return z(l)},o=function(a){m()?m().children.push(a):k.push(a)},p=function(b){return m()&&(d=A.bbcodes[m().name])&&d.closedBy&&a.inArray(b,d.closedBy)>-1};c=b.shift();){switch(i=b[0],c.type){case n.OPEN:p(c.name)&&l.pop(),o(c),d=A.bbcodes[c.name],d&&d.isSelfClosing||!d.closedBy&&!w(c.name,n.CLOSE,b)?d&&d.isSelfClosing||(c.type=n.CONTENT):l.push(c);break;case n.CLOSE:if(m()&&c.name!==m().name&&p("/"+c.name)&&l.pop(),m()&&c.name===m().name)m().closing=c,l.pop();else if(w(c.name,n.OPEN,l)){for(;e=l.pop();){if(e.name===c.name){e.closing=c;break}f=e.clone(),j.length&&f.children.push(z(j)),j.push(f)}for(o(z(j)),g=j.length;g--;)l.push(j[g]);j.length=0}else c.type=n.CONTENT,o(c);break;case n.NEWLINE:m()&&i&&p((i.type===n.CLOSE?"/":"")+i.name)&&(i.type===n.CLOSE&&i.name===m().name||(d=A.bbcodes[m().name],d&&d.breakAfter?l.pop():d&&d.isInline===!1&&A.opts.breakAfterBlock&&d.breakAfter!==!1&&l.pop())),o(c);break;default:o(c)}h=c}return k},m=function(a,b,c){var d,e,f,g,h,i,j,k,l=a.length;b&&(g=A.bbcodes[b.name]);for(var o=l;o--;)if(d=a[o])if(d.type===n.NEWLINE){if(e=o>0?a[o-1]:null,f=o1?c[c.length-2].children:e,i=a.inArray(h,j),i>-1))return k.children.splice(a.inArray(f,k.children),1),void j.splice(i+1,0,f,k);c.push(f),q(f.children,c,d||l(f),e),c.pop(f)}},t=function(a,b){for(var c,d,e=a.length;e--;)(c=a[e])&&(r(b,c)||(c.name=null,c.type=n.CONTENT,r(b,c)?(d=[e+1,0].concat(c.children),c.closing&&(c.closing.name=null,c.closing.type=n.CONTENT,d.push(c.closing)),e+=d.length-1,Array.prototype.splice.apply(a,d)):b.children.splice(e,1)),c.type===n.OPEN&&t(c.children,c))},s=function(b){for(var c,d,e=function(a){for(var b=a.length;b--;){var c=a[b].type;if(c===n.OPEN||c===n.CLOSE)return!1;if(c===n.CONTENT&&/\S|\u00A0/.test(a[b].val))return!1}return!0},f=b.length;f--;)(c=b[f])&&c.type===n.OPEN&&(d=A.bbcodes[c.name],s(c.children),e(c.children)&&d&&!d.isSelfClosing&&!d.allowsEmpty&&b.splice.apply(b,a.merge([f,1],c.children)))},A.toHTML=function(a,b){return u(A.parse(a,b),!0)},u=function(b,d){var g,j,k,l,m,o,p,q,r,s=[];for(q=function(a){return(!a||(a.isHtmlInline!==g?a.isHtmlInline:a.isInline))!==!1};b.length>0;)if(j=b.shift()){if(j.type===n.OPEN)r=j.children[j.children.length-1]||{},k=A.bbcodes[j.name],o=d&&q(k),l=u(j.children,!1),k&&k.html?(q(k)||!q(A.bbcodes[r.name])||k.isPreFormatted||k.skipLastLineBreak||i||(l+="
    "),a.isFunction(k.html)?m=k.html.call(A,j,j.attrs,l):(j.attrs[0]=l,m=e.bbcode.formatBBCodeString(k.html,j.attrs))):m=j.val+l+(j.closing?j.closing.val:"");else{if(j.type===n.NEWLINE){if(!d){s.push("
    ");continue}p||(s.push("
    "),(h<8||c.documentMode&&c.documentMode<8)&&s.push(" ")),i||s.push("
    "),b.length||s.push("
    "),s.push("
    \n"),p=!1;continue}o=d,m=f(j.val,!0)}o&&!p?(s.push("
    "),p=!0):!o&&p&&(s.push("
    \n"),p=!1),s.push(m)}return p&&s.push("
    \n"),s.join("")},A.toBBCode=function(a,b){return v(A.parse(a,b))},v=function(a){for(var b,c,d,e,f,g,h,i,j,k,l=[];a.length>0;)if(b=a.shift())if(d=A.bbcodes[b.name],e=!(!d||d.isInline!==!1),f=d&&d.isSelfClosing,h=e&&A.opts.breakBeforeBlock&&d.breakBefore!==!1||d&&d.breakBefore,i=e&&!f&&A.opts.breakStartBlock&&d.breakStart!==!1||d&&d.breakStart,j=e&&A.opts.breakEndBlock&&d.breakEnd!==!1||d&&d.breakEnd,k=e&&A.opts.breakAfterBlock&&d.breakAfter!==!1||d&&d.breakAfter,g=(d?d.quoteType:null)||A.opts.quoteType||p.QuoteType.auto,d||b.type!==n.OPEN)if(b.type===n.OPEN){if(h&&l.push("\n"),l.push("["+b.name),b.attrs){b.attrs.defaultattr&&(l.push("=",x(b.attrs.defaultattr,g,"defaultattr")),delete b.attrs.defaultattr);for(c in b.attrs)b.attrs.hasOwnProperty(c)&&l.push(" ",c,"=",x(b.attrs[c],g,c))}l.push("]"),i&&l.push("\n"),b.children&&l.push(v(b.children)),f||d.excludeClosing||(j&&l.push("\n"),l.push("[/"+b.name+"]")),k&&l.push("\n"),b.closing&&f&&l.push(b.closing.val)}else l.push(b.val);else l.push(b.val),b.children&&l.push(v(b.children)),b.closing&&l.push(b.closing.val);return l.join("")},x=function(b,c,d){var e=p.QuoteType,f=/\s|=/.test(b);return a.isFunction(c)?c(b,d):c===e.never||c===e.auto&&!f?b:'"'+b.replace("\\","\\\\").replace('"','\\"')+'"'},z=function(a){return a.length?a[a.length-1]:null},y=function(a){return a.toLowerCase()},d()};p.QuoteType={always:1,never:2,auto:3},p.defaults={breakBeforeBlock:!1,breakStartBlock:!1,breakEndBlock:!1,breakAfterBlock:!0,removeEmptyTags:!0,fixInvalidNesting:!0,fixInvalidChildren:!0,quoteType:p.QuoteType.auto},a.sceditorBBCodePlugin=e.bbcode=function(){var b,f,g,h,j=this;j.bbcodes=e.bbcode.bbcodes,j.stripQuotes=l;var n={},o={},q={ul:["li","ol","ul"],ol:["li","ol","ul"],table:["tr"],tr:["td","th"],code:["br","p","div"]};j.init=function(){j.opts=this.opts,b(),this.commands=a.extend(!0,{},k,this.commands),this.toBBCode=j.signalToSource,this.fromBBCode=j.signalToWysiwyg},b=function(){a.each(j.bbcodes,function(b){var c,d=j.bbcodes[b].tags,e=j.bbcodes[b].styles;d&&a.each(d,function(a,d){c=j.bbcodes[b].isInline===!1,n[a]=n[a]||{},n[a][c]=n[a][c]||{},n[a][c][b]=d}),e&&a.each(e,function(a,d){c=j.bbcodes[b].isInline===!1,o[c]=o[c]||{},o[c][a]=o[c][a]||{},o[c][a][b]=d})})},f=function(b,c,e){var f,g,h=d.dom.getStyle;return e=!!e,o[e]?(a.each(o[e],function(d,e){f=h(b[0],d),f&&h(b.parent()[0],d)!==f&&a.each(e,function(d,e){(!e||a.inArray(f.toString(),e)>-1)&&(g=j.bbcodes[d].format,c=a.isFunction(g)?g.call(j,b,c):m(g,c))})}),c):c},g=function(b,c,e){var f,g,h=b[0],k=h.nodeName.toLowerCase();e=!!e,n[k]&&n[k][e]&&a.each(n[k][e],function(d,e){e&&(f=!1,a.each(e,function(c,d){if(b.attr(c)&&!(d&&a.inArray(b.attr(c),d)<0))return f=!0,!1}),!f)||(g=j.bbcodes[d].format,c=a.isFunction(g)?g.call(j,b,c):m(g,c))});var l=d.dom.isInline;if(e&&(!l(h,!0)||"br"===k)){for(var o,p,q,r=h.previousSibling;r&&1===r.nodeType&&!a(r).is("br")&&l(r,!0)&&!r.firstChild;)r=r.previousSibling;do p=h.parentNode,q=p.lastChild,o=q===h,h=p;while(p&&o&&l(p,!0));(!o||"li"===k||"br"===k&&i)&&(c+="\n"),"br"!==k&&r&&!a(r).is("br")&&l(r,!0)&&(c="\n"+c)}return c},j.signalToSource=function(b,e){var f,g,h=new p(j.opts.parserOptions);return e||("string"==typeof b?(f=a("
    ").css("visibility","hidden").appendTo(c.body).html(b),e=f):e=a(b)),e&&e.jquery?(d.dom.removeWhiteSpace(e[0]),a(".sceditor-ignore",e).remove(),g=j.elementToBbcode(e),f&&f.remove(),g=h.toBBCode(g,!0),j.opts.bbcodeTrim&&(g=a.trim(g)),g):""},j.elementToBbcode=function(b){var c=function(b,e){var h="";return d.dom.traverse(b,function(b){var d=a(b),j="",k=b.nodeType,l=b.nodeName.toLowerCase(),m=q[l],n=b.firstChild,o=!0;if("object"==typeof e&&(o=a.inArray(l,e)>-1,d.is("img")&&d.data("sceditor-emoticon")&&(o=!0),o||(m=e)),3===k||1===k)if(1===k){if(d.hasClass("sceditor-nlf")&&(!n||!i&&1===b.childNodes.length&&/br/i.test(n.nodeName)))return;"iframe"!==l&&(j=c(b,m)),o?("code"!==l&&(j=f(d,j),j=g(d,j),j=f(d,j,!0)),h+=g(d,j,!0)):h+=j}else h+=b.nodeValue},!1,!0),h};return c(b[0])},j.signalToWysiwyg=function(b,c){var d=new p(j.opts.parserOptions),e=d.toHTML(j.opts.bbcodeTrim?a.trim(b):b);return c?h(e):e},h=function(b){var e,f,g,h=a("
    ").hide().appendTo(c.body),j=h[0];return g=function(b,e){if(!d.dom.hasStyling(b)){if(i||1!==b.childNodes.length||!a(b.firstChild).is("br"))for(;f=b.firstChild;)j.insertBefore(f,b);if(e){var g=j.lastChild;b!==g&&a(g).is("div")&&b.nextSibling===g&&j.insertBefore(c.createElement("br"),b)}j.removeChild(b)}},j.innerHTML=b.replace(/<\/div>\n/g,"
    "),(e=j.firstChild)&&a(e).is("div")&&g(e,!0),(e=j.lastChild)&&a(e).is("div")&&g(e),j=j.innerHTML,h.remove(),j}},e.bbcode.formatBBCodeString=function(a,b){return a.replace(/\{([^}]+)\}/g,function(a,c){ +var d,e=!0;return"!"===c.charAt(0)&&(e=!1,c=c.substring(1)),"0"===c&&(e=!1),b[c]===d?a:e?f(b[c],!0):b[c]})};var q=function(a){return a=parseInt(a,10),isNaN(a)?"00":(a=Math.max(0,Math.min(a,255)).toString(16),a.length<2?"0"+a:a)},r=function(a){var b;return a=a||"#000",(b=a.match(/rgb\((\d{1,3}),\s*?(\d{1,3}),\s*?(\d{1,3})\)/i))?"#"+q(b[1])+q(b[2]-0)+q(b[3]-0):(b=a.match(/#([0-f])([0-f])([0-f])\s*?$/i))?"#"+b[1]+b[1]+b[2]+b[2]+b[3]+b[3]:a},s={b:{tags:{b:null,strong:null},styles:{"font-weight":["bold","bolder","401","700","800","900"]},format:"[b]{0}[/b]",html:"{0}"},i:{tags:{i:null,em:null},styles:{"font-style":["italic","oblique"]},format:"[i]{0}[/i]",html:"{0}"},u:{tags:{u:null},styles:{"text-decoration":["underline"]},format:"[u]{0}[/u]",html:"{0}"},s:{tags:{s:null,strike:null},styles:{"text-decoration":["line-through"]},format:"[s]{0}[/s]",html:"{0}"},sub:{tags:{sub:null},format:"[sub]{0}[/sub]",html:"{0}"},sup:{tags:{sup:null},format:"[sup]{0}[/sup]",html:"{0}"},font:{tags:{font:{face:null}},styles:{"font-family":null},quoteType:p.QuoteType.never,format:function(a,b){var c;return a.is("font")&&(c=a.attr("face"))||(c=a.css("font-family")),"[font="+l(c)+"]"+b+"[/font]"},html:'{0}'},size:{tags:{font:{size:null}},styles:{"font-size":null},format:function(a,b){var c=a.attr("size"),d=2;return c||(c=a.css("fontSize")),c.indexOf("px")>-1?(c=c.replace("px","")-0,c<12&&(d=1),c>15&&(d=3),c>17&&(d=4),c>23&&(d=5),c>31&&(d=6),c>47&&(d=7)):d=c,"[size="+d+"]"+b+"[/size]"},html:'{!0}'},color:{tags:{font:{color:null}},styles:{color:null},quoteType:p.QuoteType.never,format:function(a,b){var c;return a.is("font")&&(c=a.attr("color"))||(c=a[0].style.color||a.css("color")),"[color="+r(c)+"]"+b+"[/color]"},html:function(a,b,c){return''+c+""}},ul:{tags:{ul:null},breakStart:!0,isInline:!1,skipLastLineBreak:!0,format:"[ul]{0}[/ul]",html:"
      {0}
    "},list:{breakStart:!0,isInline:!1,skipLastLineBreak:!0,html:"
      {0}
    "},ol:{tags:{ol:null},breakStart:!0,isInline:!1,skipLastLineBreak:!0,format:"[ol]{0}[/ol]",html:"
      {0}
    "},li:{tags:{li:null},isInline:!1,closedBy:["/ul","/ol","/list","*","li"],format:"[li]{0}[/li]",html:"
  • {0}
  • "},"*":{isInline:!1,closedBy:["/ul","/ol","/list","*","li"],html:"
  • {0}
  • "},table:{tags:{table:null},isInline:!1,isHtmlInline:!0,skipLastLineBreak:!0,format:"[table]{0}[/table]",html:"{0}
    "},tr:{tags:{tr:null},isInline:!1,skipLastLineBreak:!0,format:"[tr]{0}[/tr]",html:"{0}"},th:{tags:{th:null},allowsEmpty:!0,isInline:!1,format:"[th]{0}[/th]",html:"{0}"},td:{tags:{td:null},allowsEmpty:!0,isInline:!1,format:"[td]{0}[/td]",html:"{0}"},emoticon:{allowsEmpty:!0,tags:{img:{src:null,"data-sceditor-emoticon":null}},format:function(a,b){return a.data("sceditor-emoticon")+b},html:"{0}"},hr:{tags:{hr:null},allowsEmpty:!0,isSelfClosing:!0,isInline:!1,format:"[hr]{0}",html:"
    "},img:{allowsEmpty:!0,tags:{img:{src:null}},allowedChildren:["#"],quoteType:p.QuoteType.never,format:function(a,b){var c,d,e="",f=a[0],g=function(a){return f.style?f.style[a]:null};return a.attr("data-sceditor-emoticon")?b:(c=a.attr("width")||g("width"),d=a.attr("height")||g("height"),(f.complete&&(c||d)||c&&d)&&(e="="+a.width()+"x"+a.height()),"[img"+e+"]"+a.attr("src")+"[/img]")},html:function(a,b,c){var d,e,h,i,j="";return e=b.width,h=b.height,b.defaultattr&&(i=b.defaultattr.split(/x/i),e=i[0],h=2===i.length?i[1]:i[0]),e!==d&&(j+=' width="'+f(e,!0)+'"'),h!==d&&(j+=' height="'+f(h,!0)+'"'),"'}},url:{allowsEmpty:!0,tags:{a:{href:null}},quoteType:p.QuoteType.never,format:function(a,b){var c=a.attr("href");return"mailto:"===c.substr(0,7)?'[email="'+c.substr(7)+'"]'+b+"[/email]":"[url="+c+"]"+b+"[/url]"},html:function(a,b,c){return b.defaultattr=f(b.defaultattr,!0)||c,''+c+""}},email:{quoteType:p.QuoteType.never,html:function(a,b,c){return''+c+""}},quote:{tags:{blockquote:null},isInline:!1,quoteType:p.QuoteType.never,format:function(b,c){var d="",e=a(b),f=e.children("cite").first();return(1===f.length||e.data("author"))&&(d=f.text()||e.data("author"),e.data("author",d),f.remove(),c=this.elementToBbcode(a(b)),d="="+d.replace(/(^\s+|\s+$)/g,""),e.prepend(f)),"[quote"+d+"]"+c+"[/quote]"},html:function(a,b,c){return b.defaultattr&&(c=""+f(b.defaultattr)+""+c),"
    "+c+"
    "}},code:{tags:{code:null},isInline:!1,allowedChildren:["#","#newline"],format:"[code]{0}[/code]",html:"{0}"},left:{styles:{"text-align":["left","-webkit-left","-moz-left","-khtml-left"]},isInline:!1,format:"[left]{0}[/left]",html:'
    {0}
    '},center:{styles:{"text-align":["center","-webkit-center","-moz-center","-khtml-center"]},isInline:!1,format:"[center]{0}[/center]",html:'
    {0}
    '},right:{styles:{"text-align":["right","-webkit-right","-moz-right","-khtml-right"]},isInline:!1,format:"[right]{0}[/right]",html:'
    {0}
    '},justify:{styles:{"text-align":["justify","-webkit-justify","-moz-justify","-khtml-justify"]},isInline:!1,format:"[justify]{0}[/justify]",html:'
    {0}
    '},youtube:{allowsEmpty:!0,tags:{iframe:{"data-youtube-id":null}},format:function(a,b){return a=a.attr("data-youtube-id"),a?"[youtube]"+a+"[/youtube]":b},html:''},rtl:{styles:{direction:["rtl"]},format:"[rtl]{0}[/rtl]",html:'
    {0}
    '},ltr:{styles:{direction:["ltr"]},format:"[ltr]{0}[/ltr]",html:'
    {0}
    '},ignore:{}};e.bbcode.bbcode={get:function(a){return s[a]||null},set:function(b,c){return!(!b||!c)&&(c=a.extend(s[b]||{},c),c.remove=function(){delete s[b]},s[b]=c,this)},rename:function(a,b){return a in s&&(s[b]=s[a],delete s[a],this)},remove:function(a){return a in s&&delete s[a],this}},a.fn.sceditorBBCodePlugin=function(b){return b=b||{},a.isPlainObject(b)&&(b.plugins=(b.plugins||"")+"bbcode"),this.sceditor(b)},e.bbcode.normaliseColour=r,e.bbcode.formatString=m,e.bbcode.stripQuotes=l,e.bbcode.bbcodes=s,d.BBCodeParser=p}(jQuery,window,document); \ No newline at end of file diff --git a/js/sceditor/minified/jquery.sceditor.min.js b/js/sceditor/minified/jquery.sceditor.min.js new file mode 100644 index 00000000..321abd34 --- /dev/null +++ b/js/sceditor/minified/jquery.sceditor.min.js @@ -0,0 +1,3 @@ +/* SCEditor v1.5.2 | (C) 2016, Sam Clarke | sceditor.com/license */ +!function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(2),e=c(3),f=c(6),g=c(7);b.sceditor=d,d.commands=c(9),d.defaultOptions=c(10),d.RangeHelper=c(4),d.dom=c(5),d.ie=f.ie,d.ios=f.ios,d.isWysiwygSupported=f.isWysiwygSupported,d.regexEscape=g.regex,d.escapeEntities=g.entities,d.escapeUriScheme=g.uriScheme,d.PluginManager=e,d.plugins=e.plugins,b.fn.sceditor=function(a){var c,e,g=[];if(a=a||{},a.runWithoutWysiwygSupport||f.isWysiwygSupported)return this.each(function(){c=this.jquery?this:b(this),e=c.data("sceditor"),c.parents(".sceditor-container").length>0||("state"===a?g.push(!!e):"instance"===a?g.push(e):e||new d(this,a))}),g.length?1===g.length?g[0]:b(g):this}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b){a.exports=jQuery},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(3),e=c(4),f=c(5),g=c(7),h=c(6),i=c(8),j=window,k=document,l=b(j),m=b(k),n=h.ie,o=n&&n<11,p=function(a,c){var q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba,ca,da,ea,fa,ga,ha,ia,ja,ka,la,ma,na,oa,pa,qa,ra,sa,ta,ua=this,va=a.get?a.get(0):a,wa=b(va),xa=[],ya=[],za=[],Aa={},Ba=[],Ca={};ua.commands=b.extend(!0,{},c.commands||p.commands),ua.opts=c=b.extend({},p.defaultOptions,c),K=function(){wa.data("sceditor",ua),b.each(c,function(a,d){b.isPlainObject(d)&&(c[a]=b.extend(!0,{},d))}),c.locale&&"en"!==c.locale&&Q(),q=b('
    ').insertAfter(wa).css("z-index",c.zIndex),n&&q.addClass("ie ie"+n),H=!!wa.attr("required"),wa.removeAttr("required"),P(),W(),R(),O(!!c.startInSourceMode),U(),S(),T(),h.isWysiwygSupported||ua.toggleSourceMode(),ha();var a=function(){l.off("load",a),c.autofocus&&ma(),c.autoExpand&&ua.expandToContent(),fa(),C.call("ready")};l.on("load",a),k.readyState&&"complete"===k.readyState&&a()},P=function(){var a=c.plugins;a=a?a.toString().split(","):[],C=new d(ua),b.each(a,function(a,c){C.register(b.trim(c))})},Q=function(){var a;A=p.locale[c.locale],A||(a=c.locale.split("-"),A=p.locale[a[0]]),A&&A.dateFormat&&(c.dateFormat=A.dateFormat)},O=function(a){var d,f;w=b(""),s=b(''),a?(q.addClass("sourceMode"),s.hide()):(q.addClass("wysiwygMode"),w.hide()),c.spellcheck||w.attr("spellcheck","false"),"https:"===j.location.protocol&&s.attr("src","javascript:false"),q.append(s).append(w),t=s[0],x=w[0],ua.dimensions(c.width||wa.width(),c.height||wa.height()),d=X(),d.open(),d.write(i("html",{attrs:n?' class="ie ie'+n+'"':"",spellcheck:c.spellcheck?"":'spellcheck="false"',charset:c.charset,style:c.style})),d.close(),v=b(d),u=b(d.body),ua.readOnly(!!c.readOnly),(h.ios||n)&&(u.height("100%"),n||u.on("touchend",ua.focus)),f=wa.attr("tabindex"),w.attr("tabindex",f),s.attr("tabindex",f),B=new e(t.contentWindow),ua.val(wa.hide().val())},S=function(){c.autoUpdate&&(u.on("blur",ta),w.on("blur",ta)),null===c.rtl&&(c.rtl="rtl"===w.css("direction")),ua.rtl(!!c.rtl),c.autoExpand&&v.on("keyup",ua.expandToContent),c.resizeEnabled&&V(),q.attr("id",c.id),ua.emoticons(c.emoticonsEnabled)},T=function(){var a=n?"selectionchange":"keyup focus blur contextmenu mouseup touchend click",d="keydown keyup keypress focus blur contextmenu";m.click(ea),b(va.form).on("reset",ba).submit(ua.updateOriginal),l.on("resize orientationChanged",fa),u.keypress(aa).keydown($).keydown(_).keyup(ja).blur(ra).keyup(sa).on("paste",Y).on(a,ka).on(d,da),c.emoticonsCompat&&j.getSelection&&u.keyup(oa),w.blur(ra).keyup(sa).keydown($).on(d,da),v.mousedown(ca).blur(ra).on(a,ka).on("beforedeactivate keyup mouseup",N).keyup(ja).focus(function(){z=null}),q.on("selectionchanged",la).on("selectionchanged",ha).on("selectionchanged valuechanged nodechanged",da)},R=function(){var a,d=ua.commands,e=(c.toolbarExclude||"").split(","),f=c.toolbar.split("|");r=b('
    '),b.each(f,function(c,f){a=b('
    '),b.each(f.split(","),function(c,f){var g,h,j=d[f];!j||b.inArray(f,e)>-1||(h=j.shortcut,g=i("toolbarButton",{name:f,dispName:ua._(j.name||j.tooltip||f)},!0),g.data("sceditor-txtmode",!!j.txtExec).data("sceditor-wysiwygmode",!!j.exec).toggleClass("disabled",!j.exec).mousedown(function(){(!n||n<9)&&(J=!0)}).click(function(){var a=b(this);return a.hasClass("disabled")||M(a,j),ha(),!1}),j.tooltip&&g.attr("title",ua._(j.tooltip)+(h?" ("+h+")":"")),h&&ua.addShortcut(h,f),j.state?za.push({name:f,state:j.state}):"string"==typeof j.exec&&za.push({name:f,state:j.exec}),a.append(g),Ca[f]=g)}),a[0].firstChild&&r.append(a)}),b(c.toolbarContainer||q).append(r)},U=function(){b.each(ua.commands,function(a,c){c.forceNewLineAfter&&b.isArray(c.forceNewLineAfter)&&(ya=b.merge(ya,c.forceNewLineAfter))}),ja()},V=function(){var a,d,e,f,g,h,i=b('
    '),k=b('
    '),l="touchmove mousemove",o="touchcancel touchend mouseup",p=0,r=0,s=0,t=0,u=0,v=0,w=q.width(),x=q.height(),y=!1,z=ua.rtl();a=c.resizeMinHeight||x/1.5,d=c.resizeMaxHeight||2.5*x,e=c.resizeMinWidth||w/1.25,f=c.resizeMaxWidth||1.25*w,g=function(b){"touchmove"===b.type?(b=j.event,s=b.changedTouches[0].pageX,t=b.changedTouches[0].pageY):(s=b.pageX,t=b.pageY);var g=v+(t-r),h=z?u-(s-p):u+(s-p);f>0&&h>f&&(h=f),e>0&&h0&&g>d&&(g=d),a>0&&g-1&&(a=q.width()),s.width(a-s.data("outerWidthOffset")),w.width(a-w.data("outerWidthOffset")),h.ios&&u&&u.width(a-s.data("outerWidthOffset")-(u.outerWidth(!0)-u.width()))),b!==!1&&(d!==!1&&(c.height=b),b&&b.toString().indexOf("%")>-1&&(b=q.height(b).height(),q.height("auto")),b-=c.toolbarContainer?0:r.outerHeight(!0),s.height(b-s.data("outerHeightOffset")),w.height(b-f-w.data("outerHeightOffset"))),ua)},ua.updateStyleCache=function(){s.data("outerWidthOffset",s.outerWidth(!0)-s.width()),w.data("outerWidthOffset",w.outerWidth(!0)-w.width()),s.data("outerHeightOffset",s.outerHeight(!0)-s.height()),w.data("outerHeightOffset",w.outerHeight(!0)-w.height())},ua.height=function(a,b){return a||0===a?(ua.dimensions(null,a,b),ua):q.height()},ua.maximize=function(a){return"undefined"==typeof a?q.is(".sceditor-maximize"):(a=!!a,n<7&&b("html, body").toggleClass("sceditor-maximize",a),q.toggleClass("sceditor-maximize",a),ua.width(a?"100%":c.width,!1),ua.height(a?"100%":c.height,!1),ua)},ua.expandToContent=function(a){var b=q.height(),d=b-s.height(),e=u[0].scrollHeight||v[0].documentElement.scrollHeight,f=c.resizeMaxHeight||2*(c.height||wa.height());e+=d,(a===!0||e<=f)&&e>b&&ua.height(e)},ua.destroy=function(){C&&(C.destroy(),B=null,z=null,C=null,y&&y.off().remove(),m.off("click",ea),l.off("resize orientationChanged",fa),b(va.form).off("reset",ba).off("submit",ua.updateOriginal),u.off(),v.off().find("*").remove(),w.off().remove(),r.remove(),q.off().find("*").off().remove(),q.remove(),wa.removeData("sceditor").removeData("sceditorbbcode").show(),H&&wa.attr("required","required"))},ua.createDropDown=function(a,d,e,f){var g,h="sceditor-"+d,i=y&&y.is("."+h);ua.closeDropDown(!0),i||(f!==!1&&b(e).find(":not(input,textarea)").filter(function(){return 1===this.nodeType}).attr("unselectable","on"),g={top:a.offset().top,left:a.offset().left,marginTop:a.outerHeight()},b.extend(g,c.dropDownCss),y=b('
    ').css(g).append(e).appendTo(b("body")).on("click focusin",function(a){a.stopPropagation()}),setTimeout(function(){y&&y.find("input,textarea").first().focus()}))},ea=function(a){3!==a.which&&y&&(ta(),ua.closeDropDown())},Y=function(a){var b,d,e,f=u[0],g=v[0],h=0,i=k.createElement("div"),j=g.createDocumentFragment(),l=!!a&&a.clipboardData;if(c.disablePasting)return!1;if(c.enablePasteFiltering){if(B.saveRange(),k.body.appendChild(i),l&&l.getData&&((b=l.getData("text/html"))||(b=l.getData("text/plain"))))return i.innerHTML=b,Z(f,i),!1;for(e=u.scrollTop()||v.scrollTop();f.firstChild;)j.appendChild(f.firstChild);return d=function(a,b){if(a.childNodes.length>0||h>25){for(;a.firstChild;)b.appendChild(a.firstChild);for(;j.firstChild;)a.appendChild(j.firstChild);u.scrollTop(e),v.scrollTop(e),b.childNodes.length>0?Z(a,b):B.restoreRange()}else h++,setTimeout(function(){d(a,b)},20)},d(f,i),ua.focus(),!0}},Z=function(a,c){f.fixNesting(c);var d=c.innerHTML;C.hasHandler("toSource")&&(d=C.callOnlyFirst("toSource",d,b(c))),c.parentNode.removeChild(c),C.hasHandler("toWysiwyg")&&(d=C.callOnlyFirst("toWysiwyg",d,!0)),B.restoreRange(),ua.wysiwygEditorInsertHtml(d,null,!0)},ua.closeDropDown=function(a){y&&(y.off().remove(),y=null),a===!0&&ua.focus()},X=function(){return t.contentDocument?t.contentDocument:t.contentWindow&&t.contentWindow.document?t.contentWindow.document:t.document},ua.wysiwygEditorInsertHtml=function(a,c,d){var e,g,h,i=s.height();ua.focus(),(d||!b(E).is("code")&&0===b(E).parents("code").length)&&(B.insertHTML(a,c),B.saveRange(),L(u[0]),e=u.find("#sceditor-end-marker").show(),g=u.scrollTop()||v.scrollTop(),h=f.getOffset(e[0]).top+1.5*e.outerHeight(!0)-i,e.hide(),(h>g||h+i").appendTo(b("body")).hide().html(g);d!==!1&&C.hasHandler("toSource")&&(g=C.callOnlyFirst("toSource",g,h)),h.remove(),a+=g+c}return d!==!1&&C.hasHandler("toWysiwyg")&&(a=C.callOnlyFirst("toWysiwyg",a,!0)),d!==!1&&f===!0&&(a=a.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&")),ua.wysiwygEditorInsertHtml(a),ua},ua.getWysiwygEditorValue=function(a){var c,d=b("
    ").appendTo(document.body).append(b(u[0].childNodes).clone());return f.fixNesting(d[0]),c=d.html(),a!==!1&&C.hasHandler("toSource")&&(c=C.callOnlyFirst("toSource",c,d)),d.remove(),c},ua.getBody=function(){return u},ua.getContentAreaContainer=function(){return s},ua.getSourceEditorValue=function(a){var b=w.val();return a!==!1&&C.hasHandler("toWysiwyg")&&(b=C.callOnlyFirst("toWysiwyg",b)),b},ua.setWysiwygEditorValue=function(a){a||(a="

    "+(n?"":"
    ")+"

    "),u[0].innerHTML=a,L(u[0]),ja(),qa()},ua.setSourceEditorValue=function(a){w.val(a),qa()},ua.updateOriginal=function(){wa.val(ua.val())},L=function(a){if(c.emoticonsEnabled&&!b(a).parents("code").length){var d=a.ownerDocument,e="\\s| | | | | ",h=[],j=[],k=b.extend({},c.emoticons.more,c.emoticons.dropdown,c.emoticons.hidden);b.each(k,function(a){c.emoticonsCompat&&(j[a]=new RegExp("(>|^|"+e+")"+g.regex(a)+"($|<|"+e+")")),h.push(a)});var l=function(a){for(a=a.firstChild;a;){var e,g,m,n,o,p,q,r=a.parentNode,s=a.nodeValue;if(3!==a.nodeType)b(a).is("code")||l(a);else if(s)for(o=h.length;o--;)g=h[o],q=c.emoticonsCompat?s.search(j[g]):s.indexOf(g),q>-1&&(p=a.nextSibling,m=k[g],e=s.substr(q).split(g),s=s.substr(0,q)+e.shift(),a.nodeValue=s,n=f.parseHTML(i("emoticon",{key:g,url:m.url||m,tooltip:m.tooltip||g}),d),r.insertBefore(n[0],p),r.insertBefore(d.createTextNode(e.join(g)),p));a=a.nextSibling}};l(a),c.emoticonsCompat&&(Ba=u.find("img[data-sceditor-emoticon]"))}},ua.inSourceMode=function(){return q.hasClass("sourceMode")},ua.sourceMode=function(a){var b=ua.inSourceMode();return"boolean"!=typeof a?b:((b&&!a||!b&&a)&&ua.toggleSourceMode(),ua)},ua.toggleSourceMode=function(){var a=ua.inSourceMode();!h.isWysiwygSupported&&a||(a||(B.saveRange(),B.clear()),ua.blur(),a?ua.setWysiwygEditorValue(ua.getSourceEditorValue()):ua.setSourceEditorValue(ua.getWysiwygEditorValue()),z=null,w.toggle(),s.toggle(),q.toggleClass("wysiwygMode",a).toggleClass("sourceMode",!a),ga(),ha())},ia=function(){return x.focus(),"undefined"!=typeof x.selectionStart?x.value.substring(x.selectionStart,x.selectionEnd):k.selection.createRange().text},M=function(a,c){ua.inSourceMode()?c.txtExec&&(b.isArray(c.txtExec)?ua.sourceEditorInsertText.apply(ua,c.txtExec):c.txtExec.call(ua,a,ia())):c.exec&&(b.isFunction(c.exec)?c.exec.call(ua,a):ua.execCommand(c.exec,c.hasOwnProperty("execParam")?c.execParam:null))},N=function(){n&&(z=B.selectedRange())},ua.execCommand=function(a,c){var d=!1,e=ua.commands[a],f=b(B.parentNode());if(ua.focus(),!f.is("code")&&0===f.parents("code").length){try{d=v[0].execCommand(a,!1,c)}catch(a){}!d&&e&&e.errorMessage&&alert(ua._(e.errorMessage)),ha()}},ka=function(){function a(){B&&!B.compare(F)&&(F=B.cloneSelected(),q.trigger(b.Event("selectionchanged"))),G=!1}G||(G=!0,n?a():setTimeout(a,100))},la=function(){var a,c=B.parentNode();D!==c&&(a=D,D=c,E=B.getFirstBlockParent(c),q.trigger(b.Event("nodechanged",{oldNode:a,newNode:D})))},ua.currentNode=function(){return D},ua.currentBlockNode=function(){return E},ha=function(a){var b,c,d="active",e=v[0],f=ua.sourceMode();if(ua.readOnly())return void r.find(d).removeClass(d);f||(c=a?a.newNode:B.parentNode(),b=B.getFirstBlockParent(c));for(var g=0;g-1&&(h=e.queryCommandState(j)?1:0)}catch(a){}}else k||(h=j.call(ua,c,b));i.toggleClass("disabled",k||h<0).toggleClass(d,h>0)}},aa=function(a){var c,d,e,g,h="code,blockquote,pre",i="li,ul,ol";if(!a.originalEvent.defaultPrevented)return ua.closeDropDown(),c=b(E).closest(h+","+i).first(),13===a.which&&c.length&&!c.is(i)?(z=null,d=v[0].createElement("br"),B.insertNode(d),o||(e=d.parentNode,g=e.lastChild,g&&3===g.nodeType&&""===g.nodeValue&&(e.removeChild(g),g=e.lastChild),!f.isInline(e,!0)&&g===d&&f.isInline(d.previousSibling)&&B.insertHTML("
    ")),!1):void 0},ja=function(){var a,c,d,e=u[0];f.rTraverse(e,function(g){if(a=g.nodeName.toLowerCase(),b.inArray(a,ya)>-1&&(c=!0),3===g.nodeType&&!/^\s*$/.test(g.nodeValue)||"br"===a||o&&!g.firstChild&&!f.isInline(g,!1))return c&&(d=v[0].createElement("p"),d.className="sceditor-nlf",d.innerHTML=o?"":"
    ",e.appendChild(d)),!1})},ba=function(){ua.val(wa.val())},ca=function(){ua.closeDropDown(),z=null},fa=function(){var a=c.height,b=c.width;ua.maximize()?ua.dimensions("100%","100%",!1):(a&&a.toString().indexOf("%")>-1||b&&b.toString().indexOf("%")>-1)&&ua.dimensions(b,a)},ua._=function(){var a,b=arguments;return A&&A[b[0]]&&(b[0]=A[b[0]]),b[0].replace(/\{(\d+)\}/g,function(c,d){return b[d-0+1]!==a?b[d-0+1]:"{"+d+"}"})},da=function(a){C.call(a.type+"Event",a,ua);var c=a.target===x?"scesrc":"scewys",d=b.Event(a);d.type=c+a.type,q.trigger(d,ua)},ua.bind=function(a,c,d,e){a=a.split(" ");for(var f=a.length;f--;)b.isFunction(c)&&(d||q.on("scewys"+a[f],c),e||q.on("scesrc"+a[f],c),"valuechanged"===a[f]&&(qa.hasHandler=!0));return ua},ua.unbind=function(a,c,d,e){a=a.split(" ");for(var f=a.length;f--;)b.isFunction(c)&&(d||q.off("scewys"+a[f],c),e||q.off("scesrc"+a[f],c));return ua},ua.blur=function(a,c,d){return b.isFunction(a)?ua.bind("blur",a,c,d):ua.sourceMode()?w.blur():u.blur(),ua},ua.focus=function(a,c,d){if(b.isFunction(a))ua.bind("focus",a,c,d);else if(ua.inSourceMode())x.focus();else{var e,f=B.selectedRange();F||B.hasSelection()||ma(),!o&&f&&1===f.endOffset&&f.collapsed&&(e=f.endContainer,e&&1===e.childNodes.length&&b(e.firstChild).is("br")&&(f.setStartBefore(e.firstChild),f.collapse(!0),B.selectRange(f))),t.contentWindow.focus(),u[0].focus(),z&&(B.selectRange(z),z=null)}return ha(),ua},ua.keyDown=function(a,b,c){return ua.bind("keydown",a,b,c)},ua.keyPress=function(a,b,c){return ua.bind("keypress",a,b,c)},ua.keyUp=function(a,b,c){return ua.bind("keyup",a,b,c)},ua.nodeChanged=function(a){return ua.bind("nodechanged",a,!1,!0)},ua.selectionChanged=function(a){return ua.bind("selectionchanged",a,!1,!0)},ua.valueChanged=function(a,b,c){return ua.bind("valuechanged",a,b,c)},na=function(a){var d,e=0,f=ua.emoticonsCache,g=String.fromCharCode(a.which);if(!b(E).is("code")&&!b(E).parents("code").length)return f||(f=[],b.each(b.extend({},c.emoticons.more,c.emoticons.dropdown,c.emoticons.hidden),function(a,b){f[e++]=[a,i("emoticon",{key:a,url:b.url||b,tooltip:b.tooltip||a})]}),f.sort(function(a,b){return a[0].length-b[0].length}),ua.emoticonsCache=f,ua.longestEmoticonCode=f[f.length-1][0].length),d=B.replaceKeyword(ua.emoticonsCache,!0,!0,ua.longestEmoticonCode,c.emoticonsCompat,g),d&&c.emoticonsCompat?(Ba=u.find("img[data-sceditor-emoticon]"),/^\s$/.test(g)):!d},oa=function(){if(Ba.length){var a,c,d,e,f,g,h=ua.currentBlockNode(),i=!1,j=/[^\s\xA0\u2002\u2003\u2009\u00a0]+/;Ba=b.map(Ba,function(k){return k&&k.parentNode?b.contains(h,k)?(a=k.previousSibling,c=k.nextSibling,f=a.nodeValue,null===f&&(f=a.innerText||""),a&&j.test(a.nodeValue.slice(-1))||c&&j.test((c.nodeValue||"")[0])?(d=k.parentNode,e=B.cloneSelected(),g=e.startContainer,f+=b(k).data("sceditor-emoticon"),g===c?i=f.length+e.startOffset:g===h&&h.childNodes[e.startOffset]===c?i=f.length:g===a&&(i=e.startOffset),c&&3===c.nodeType||(c=d.insertBefore(d.ownerDocument.createTextNode(""),c)),c.insertData(0,f),d.removeChild(a),d.removeChild(k),i!==!1&&(e.setStart(c,i),e.collapse(!0),B.selectRange(e)),null):k):k:null})}},ua.emoticons=function(a){return a||a===!1?(c.emoticonsEnabled=a,a?(u.keypress(na),ua.sourceMode()||(B.saveRange(),L(u[0]),Ba=u.find("img[data-sceditor-emoticon]"),qa(!1),B.restoreRange())):(u.find("img[data-sceditor-emoticon]").replaceWith(function(){return b(this).data("sceditor-emoticon")}),Ba=[],u.off("keypress",na),qa()),ua):c.emoticonsEnabled},ua.css=function(a){return I||(I=b('

    ',toolbarButton:'
    {dispName}
    ',emoticon:'{key}',fontOpt:'{font}',sizeOpt:'{size}',pastetext:'
    ',table:'
    ',image:'
    ',email:'
    ',link:'
    ',youtubeMenu:'
    ',youtube:''};return function(b,c,d){var e=a[b];return $.each(c,function(a,b){e=e.replace(new RegExp("\\{"+a+"\\}","g"),b)}),d&&(e=$(e)),e}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(6).ie,e=c(8),f=d&&d<11,g={bold:{exec:"bold",tooltip:"Bold",shortcut:"Ctrl+B"},italic:{exec:"italic",tooltip:"Italic",shortcut:"Ctrl+I"},underline:{exec:"underline",tooltip:"Underline",shortcut:"Ctrl+U"},strike:{exec:"strikethrough",tooltip:"Strikethrough"},subscript:{exec:"subscript",tooltip:"Subscript"},superscript:{exec:"superscript",tooltip:"Superscript"},left:{exec:"justifyleft",tooltip:"Align left"},center:{exec:"justifycenter",tooltip:"Center"},right:{exec:"justifyright",tooltip:"Align right"},justify:{exec:"justifyfull",tooltip:"Justify"},font:{_dropDown:function(a,c,d){for(var f=0,g=a.opts.fonts.split(","),h=b("
    "),i=function(){return d(b(this).data("font")),a.closeDropDown(!0),!1};f"),g=function(c){d(b(this).data("size")),a.closeDropDown(!0),c.preventDefault()},h=1;h<=7;h++)f.append(e("sizeOpt",{size:h},!0).click(g));a.createDropDown(c,"fontsize-picker",f)},exec:function(a){var b=this;g.size._dropDown(b,a,function(a){b.execCommand("fontsize",a)})},tooltip:"Font Size"},color:{_dropDown:function(a,c,d){var e,f,h,i,j={r:255,g:255,b:255},k=b("
    "),l=a.opts.colors?a.opts.colors.split("|"):new Array(21),m=[],n=g.color;if(!n._htmlCache){for(e=0;e'),f=0;f'),f%5===0?(j.g-=51,j.b=255):j.b-=51;m.push("
    "),e%5===0?(j.r-=51,j.g=255,j.b=255):(j.g=255,j.b=255)}n._htmlCache=m.join("")}k.append(n._htmlCache).find("a").click(function(c){d(b(this).attr("data-color")),a.closeDropDown(!0),c.preventDefault()}),a.createDropDown(c,"color-picker",k)},exec:function(a){var b=this;g.color._dropDown(b,a,function(a){b.execCommand("forecolor",a)})},tooltip:"Font Color"},removeformat:{exec:"removeformat",tooltip:"Remove Formatting"},cut:{exec:"cut",tooltip:"Cut",errorMessage:"Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X"},copy:{exec:"copy",tooltip:"Copy",errorMessage:"Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C"},paste:{exec:"paste",tooltip:"Paste",errorMessage:"Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V"},pastetext:{exec:function(a){var b,c,d=this;c=e("pastetext",{label:d._("Paste your text inside the following box:"),insert:d._("Insert")},!0),c.find(".button").click(function(a){b=c.find("#txt").val(),b&&d.wysiwygEditorInsertText(b),d.closeDropDown(!0),a.preventDefault()}),d.createDropDown(a,"pastetext",c)},tooltip:"Paste Text"},bulletlist:{exec:"insertunorderedlist",tooltip:"Bullet list"},orderedlist:{exec:"insertorderedlist",tooltip:"Numbered list"},indent:{state:function(a,c){var d,e,f,g=b(c),h=g.parents("ul,ol,menu"),i=h.first();if(h.length>1||i.children().length>1)return 0;if(g.is("ul,ol,menu")){if(d=this.getRangeHelper().selectedRange(),!(window.Range&&d instanceof Range))return g.is("li,ul,ol,menu")?0:-1;if(e=d.startContainer.parentNode,f=d.endContainer.parentNode,e!==e.parentNode.firstElementChild||b(f).is("li")&&f!==f.parentNode.lastElementChild)return 0}return-1},exec:function(){var a=this,c=b(a.getRangeHelper().getFirstBlockParent());a.focus(),c.parents("ul,ol,menu")&&a.execCommand("indent")},tooltip:"Add indent"},outdent:{state:function(a,c){return b(c).is("ul,ol,menu")||b(c).parents("ul,ol,menu").length>0?0:-1},exec:function(){var a=this,c=b(a.getRangeHelper().getFirstBlockParent());c.parents("ul,ol,menu")&&a.execCommand("outdent")},tooltip:"Remove one indent"},table:{forceNewLineAfter:["table"],exec:function(a){var b=this,c=e("table",{rows:b._("Rows:"),cols:b._("Cols:"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d,e,g=c.find("#rows").val()-0,h=c.find("#cols").val()-0,i="";if(!(g<1||h<1)){for(d=0;d",e=0;e"+(f?"":"
    ")+"";i+=""}i+="
    ",b.wysiwygEditorInsertHtml(i),b.closeDropDown(!0),a.preventDefault()}}),b.createDropDown(a,"inserttable",c)},tooltip:"Insert a table"},horizontalrule:{exec:"inserthorizontalrule",tooltip:"Insert a horizontal rule"},code:{forceNewLineAfter:["code"],exec:function(){this.wysiwygEditorInsertHtml("",(f?"":"
    ")+"
    ")},tooltip:"Code"},image:{exec:function(a){var b=this,c=e("image",{url:b._("URL:"),width:b._("Width (optional):"),height:b._("Height (optional):"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#image").val(),e=c.find("#width").val(),f=c.find("#height").val(),g="";e&&(g+=' width="'+e+'"'),f&&(g+=' height="'+f+'"'),d&&b.wysiwygEditorInsertHtml("'),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertimage",c)},tooltip:"Insert an image"},email:{exec:function(a){var b=this,c=e("email",{label:b._("E-mail:"),desc:b._("Description (optional):"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#email").val(),e=c.find("#des").val();d&&(b.focus(),!b.getRangeHelper().selectedHtml()||e?(e=e||d,b.wysiwygEditorInsertHtml(''+e+"")):b.execCommand("createlink","mailto:"+d)),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertemail",c)},tooltip:"Insert an email"},link:{exec:function(a){var b=this,c=e("link",{url:b._("URL:"),desc:b._("Description (optional):"),ins:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#link").val(),e=c.find("#des").val();d&&(b.focus(),!b.getRangeHelper().selectedHtml()||e?(e=e||d,b.wysiwygEditorInsertHtml(''+e+"")):b.execCommand("createlink",d)),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertlink",c)},tooltip:"Insert a link"},unlink:{state:function(){var a=b(this.currentNode());return a.is("a")||a.parents("a").length>0?0:-1},exec:function(){var a=b(this.currentNode()),c=a.is("a")?a:a.parents("a").first();c.length&&c.replaceWith(c.contents())},tooltip:"Unlink"},quote:{forceNewLineAfter:["blockquote"],exec:function(a,b,c){var d="
    ",e="
    ";b?(c=c?""+c+"":"",d=d+c+b+e,e=null):""===this.getRangeHelper().selectedHtml()&&(e=(f?"":"
    ")+e),this.wysiwygEditorInsertHtml(d,e)},tooltip:"Insert a Quote"},emoticon:{exec:function(a){var c=this,d=function(e){var f,g=c.opts.emoticonsCompat,h=c.getRangeHelper(),i=g&&" "!==h.getOuterText(!0,1)?" ":"",j=g&&" "!==h.getOuterText(!1,1)?" ":"",k=b("
    "),l=b("
    ").appendTo(k),m=0,n=b.extend({},c.opts.emoticons.dropdown,e?c.opts.emoticons.more:{});return b.each(n,function(){m++}),m=Math.sqrt(m),b.each(n,function(a,d){l.append(b("").attr({src:d.url||d,alt:a,title:d.tooltip||a}).click(function(){return c.insert(i+b(this).attr("alt")+j,null,!1).closeDropDown(!0),!1})),l.children().length>=m&&(l=b("
    ").appendTo(k))}),!e&&c.opts.emoticons.more&&(f=b(''+c._("More")+"").click(function(){return c.createDropDown(a,"more-emoticons",d(!0)),!1}),k.append(f)),k};c.createDropDown(a,"emoticons",d(!1))},txtExec:function(a){g.emoticon.exec.call(this,a)},tooltip:"Insert an emoticon"},youtube:{_dropDown:function(a,b,c){var d,f=e("youtubeMenu",{label:a._("Video URL:"),insert:a._("Insert")},!0);f.find(".button").click(function(b){var e=f.find("#link").val();e&&(d=e.match(/(?:v=|v\/|embed\/|youtu.be\/)(.{11})/),d&&(e=d[1]),/^[a-zA-Z0-9_\-]{11}$/.test(e)?c(e):alert("Invalid YouTube video")),a.closeDropDown(!0),b.preventDefault()}),a.createDropDown(b,"insertlink",f)},exec:function(a){var b=this;g.youtube._dropDown(b,a,function(a){b.wysiwygEditorInsertHtml(e("youtube",{id:a}))})},tooltip:"Insert a YouTube video"},date:{_date:function(a){var b=new Date,c=b.getYear(),d=b.getMonth()+1,e=b.getDate();return c<2e3&&(c=1900+c),d<10&&(d="0"+d),e<10&&(e="0"+e),a.opts.dateFormat.replace(/year/i,c).replace(/month/i,d).replace(/day/i,e)},exec:function(){this.insertText(g.date._date(this))},txtExec:function(){this.insertText(g.date._date(this))},tooltip:"Insert current date"},time:{_time:function(){var a=new Date,b=a.getHours(),c=a.getMinutes(),d=a.getSeconds();return b<10&&(b="0"+b),c<10&&(c="0"+c),d<10&&(d="0"+d),b+":"+c+":"+d},exec:function(){this.insertText(g.time._time())},txtExec:function(){this.insertText(g.time._time())},tooltip:"Insert current time"},ltr:{state:function(a,b){return b&&"ltr"===b.style.direction},exec:function(){var a=this,c=a.getRangeHelper().getFirstBlockParent(),d=b(c);a.focus(),(c&&!d.is("body")||(a.execCommand("formatBlock","p"),c=a.getRangeHelper().getFirstBlockParent(),d=b(c),c&&!d.is("body")))&&("ltr"===d.css("direction")?d.css("direction",""):d.css("direction","ltr"))},tooltip:"Left-to-Right"},rtl:{state:function(a,b){return b&&"rtl"===b.style.direction},exec:function(){var a=this,c=a.getRangeHelper().getFirstBlockParent(),d=b(c);a.focus(),(c&&!d.is("body")||(a.execCommand("formatBlock","p"),c=a.getRangeHelper().getFirstBlockParent(),d=b(c),c&&!d.is("body")))&&("rtl"===d.css("direction")?d.css("direction",""):d.css("direction","rtl"))},tooltip:"Right-to-Left"},print:{exec:"print",tooltip:"Print"},maximize:{state:function(){return this.maximize()},exec:function(){this.maximize(!this.maximize())},txtExec:function(){this.maximize(!this.maximize())},tooltip:"Maximize",shortcut:"Ctrl+Shift+M"},source:{state:function(){return this.sourceMode()},exec:function(){this.toggleSourceMode()},txtExec:function(){this.toggleSourceMode()},tooltip:"View source",shortcut:"Ctrl+Shift+S"},ignore:{}};return g}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1);return{toolbar:"bold,italic,underline,strike,subscript,superscript|left,center,right,justify|font,size,color,removeformat|cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|table|code,quote|horizontalrule,image,email,link,unlink|emoticon,youtube,date,time|ltr,rtl|print,maximize,source",toolbarExclude:null,style:"jquery.sceditor.default.css",fonts:"Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana",colors:null,locale:b("html").attr("lang")||"en",charset:"utf-8",emoticonsCompat:!1,emoticonsEnabled:!0,emoticonsRoot:"",emoticons:{dropdown:{":)":"emoticons/smile.png",":angel:":"emoticons/angel.png",":angry:":"emoticons/angry.png","8-)":"emoticons/cool.png",":'(":"emoticons/cwy.png",":ermm:":"emoticons/ermm.png",":D":"emoticons/grin.png","<3":"emoticons/heart.png",":(":"emoticons/sad.png",":O":"emoticons/shocked.png",":P":"emoticons/tongue.png",";)":"emoticons/wink.png"},more:{":alien:":"emoticons/alien.png",":blink:":"emoticons/blink.png",":blush:":"emoticons/blush.png",":cheerful:":"emoticons/cheerful.png",":devil:":"emoticons/devil.png",":dizzy:":"emoticons/dizzy.png",":getlost:":"emoticons/getlost.png",":happy:":"emoticons/happy.png",":kissing:":"emoticons/kissing.png",":ninja:":"emoticons/ninja.png",":pinch:":"emoticons/pinch.png",":pouty:":"emoticons/pouty.png",":sick:":"emoticons/sick.png",":sideways:":"emoticons/sideways.png",":silly:":"emoticons/silly.png",":sleeping:":"emoticons/sleeping.png",":unsure:":"emoticons/unsure.png",":woot:":"emoticons/w00t.png",":wassat:":"emoticons/wassat.png"},hidden:{":whistling:":"emoticons/whistling.png",":love:":"emoticons/wub.png"}},width:null,height:null,resizeEnabled:!0,resizeMinWidth:null,resizeMinHeight:null,resizeMaxHeight:null,resizeMaxWidth:null,resizeHeight:!0,resizeWidth:!0,dateFormat:"year-month-day",toolbarContainer:null,enablePasteFiltering:!1,disablePasting:!1,readOnly:!1,rtl:!1,autofocus:!1,autofocusEnd:!0,autoExpand:!1,autoUpdate:!1,spellcheck:!0,runWithoutWysiwygSupport:!1,startInSourceMode:!1,id:null,plugins:"",zIndex:null,bbcodeTrim:!1,disableBlockRemove:!1,parserOptions:{},dropDownCss:{}}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))}]); \ No newline at end of file diff --git a/js/sceditor/minified/jquery.sceditor.xhtml.min.js b/js/sceditor/minified/jquery.sceditor.xhtml.min.js new file mode 100644 index 00000000..f8a96985 --- /dev/null +++ b/js/sceditor/minified/jquery.sceditor.xhtml.min.js @@ -0,0 +1,3 @@ +/* SCEditor v1.5.2 | (C) 2016, Sam Clarke | sceditor.com/license */ +!function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(2),e=c(3),f=c(6),g=c(7);b.sceditor=d,d.commands=c(9),d.defaultOptions=c(10),d.RangeHelper=c(4),d.dom=c(5),d.ie=f.ie,d.ios=f.ios,d.isWysiwygSupported=f.isWysiwygSupported,d.regexEscape=g.regex,d.escapeEntities=g.entities,d.escapeUriScheme=g.uriScheme,d.PluginManager=e,d.plugins=e.plugins,b.fn.sceditor=function(a){var c,e,g=[];if(a=a||{},a.runWithoutWysiwygSupport||f.isWysiwygSupported)return this.each(function(){c=this.jquery?this:b(this),e=c.data("sceditor"),c.parents(".sceditor-container").length>0||("state"===a?g.push(!!e):"instance"===a?g.push(e):e||new d(this,a))}),g.length?1===g.length?g[0]:b(g):this}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b){a.exports=jQuery},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(3),e=c(4),f=c(5),g=c(7),h=c(6),i=c(8),j=window,k=document,l=b(j),m=b(k),n=h.ie,o=n&&n<11,p=function(a,c){var q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,$,_,aa,ba,ca,da,ea,fa,ga,ha,ia,ja,ka,la,ma,na,oa,pa,qa,ra,sa,ta,ua=this,va=a.get?a.get(0):a,wa=b(va),xa=[],ya=[],za=[],Aa={},Ba=[],Ca={};ua.commands=b.extend(!0,{},c.commands||p.commands),ua.opts=c=b.extend({},p.defaultOptions,c),K=function(){wa.data("sceditor",ua),b.each(c,function(a,d){b.isPlainObject(d)&&(c[a]=b.extend(!0,{},d))}),c.locale&&"en"!==c.locale&&Q(),q=b('
    ').insertAfter(wa).css("z-index",c.zIndex),n&&q.addClass("ie ie"+n),H=!!wa.attr("required"),wa.removeAttr("required"),P(),W(),R(),O(!!c.startInSourceMode),U(),S(),T(),h.isWysiwygSupported||ua.toggleSourceMode(),ha();var a=function(){l.off("load",a),c.autofocus&&ma(),c.autoExpand&&ua.expandToContent(),fa(),C.call("ready")};l.on("load",a),k.readyState&&"complete"===k.readyState&&a()},P=function(){var a=c.plugins;a=a?a.toString().split(","):[],C=new d(ua),b.each(a,function(a,c){C.register(b.trim(c))})},Q=function(){var a;A=p.locale[c.locale],A||(a=c.locale.split("-"),A=p.locale[a[0]]),A&&A.dateFormat&&(c.dateFormat=A.dateFormat)},O=function(a){var d,f;w=b(""),s=b(''),a?(q.addClass("sourceMode"),s.hide()):(q.addClass("wysiwygMode"),w.hide()),c.spellcheck||w.attr("spellcheck","false"),"https:"===j.location.protocol&&s.attr("src","javascript:false"),q.append(s).append(w),t=s[0],x=w[0],ua.dimensions(c.width||wa.width(),c.height||wa.height()),d=X(),d.open(),d.write(i("html",{attrs:n?' class="ie ie'+n+'"':"",spellcheck:c.spellcheck?"":'spellcheck="false"',charset:c.charset,style:c.style})),d.close(),v=b(d),u=b(d.body),ua.readOnly(!!c.readOnly),(h.ios||n)&&(u.height("100%"),n||u.on("touchend",ua.focus)),f=wa.attr("tabindex"),w.attr("tabindex",f),s.attr("tabindex",f),B=new e(t.contentWindow),ua.val(wa.hide().val())},S=function(){c.autoUpdate&&(u.on("blur",ta),w.on("blur",ta)),null===c.rtl&&(c.rtl="rtl"===w.css("direction")),ua.rtl(!!c.rtl),c.autoExpand&&v.on("keyup",ua.expandToContent),c.resizeEnabled&&V(),q.attr("id",c.id),ua.emoticons(c.emoticonsEnabled)},T=function(){var a=n?"selectionchange":"keyup focus blur contextmenu mouseup touchend click",d="keydown keyup keypress focus blur contextmenu";m.click(ea),b(va.form).on("reset",ba).submit(ua.updateOriginal),l.on("resize orientationChanged",fa),u.keypress(aa).keydown($).keydown(_).keyup(ja).blur(ra).keyup(sa).on("paste",Y).on(a,ka).on(d,da),c.emoticonsCompat&&j.getSelection&&u.keyup(oa),w.blur(ra).keyup(sa).keydown($).on(d,da),v.mousedown(ca).blur(ra).on(a,ka).on("beforedeactivate keyup mouseup",N).keyup(ja).focus(function(){z=null}),q.on("selectionchanged",la).on("selectionchanged",ha).on("selectionchanged valuechanged nodechanged",da)},R=function(){var a,d=ua.commands,e=(c.toolbarExclude||"").split(","),f=c.toolbar.split("|");r=b('
    '),b.each(f,function(c,f){a=b('
    '),b.each(f.split(","),function(c,f){var g,h,j=d[f];!j||b.inArray(f,e)>-1||(h=j.shortcut,g=i("toolbarButton",{name:f,dispName:ua._(j.name||j.tooltip||f)},!0),g.data("sceditor-txtmode",!!j.txtExec).data("sceditor-wysiwygmode",!!j.exec).toggleClass("disabled",!j.exec).mousedown(function(){(!n||n<9)&&(J=!0)}).click(function(){var a=b(this);return a.hasClass("disabled")||M(a,j),ha(),!1}),j.tooltip&&g.attr("title",ua._(j.tooltip)+(h?" ("+h+")":"")),h&&ua.addShortcut(h,f),j.state?za.push({name:f,state:j.state}):"string"==typeof j.exec&&za.push({name:f,state:j.exec}),a.append(g),Ca[f]=g)}),a[0].firstChild&&r.append(a)}),b(c.toolbarContainer||q).append(r)},U=function(){b.each(ua.commands,function(a,c){c.forceNewLineAfter&&b.isArray(c.forceNewLineAfter)&&(ya=b.merge(ya,c.forceNewLineAfter))}),ja()},V=function(){var a,d,e,f,g,h,i=b('
    '),k=b('
    '),l="touchmove mousemove",o="touchcancel touchend mouseup",p=0,r=0,s=0,t=0,u=0,v=0,w=q.width(),x=q.height(),y=!1,z=ua.rtl();a=c.resizeMinHeight||x/1.5,d=c.resizeMaxHeight||2.5*x,e=c.resizeMinWidth||w/1.25,f=c.resizeMaxWidth||1.25*w,g=function(b){"touchmove"===b.type?(b=j.event,s=b.changedTouches[0].pageX,t=b.changedTouches[0].pageY):(s=b.pageX,t=b.pageY);var g=v+(t-r),h=z?u-(s-p):u+(s-p);f>0&&h>f&&(h=f),e>0&&h0&&g>d&&(g=d),a>0&&g-1&&(a=q.width()),s.width(a-s.data("outerWidthOffset")),w.width(a-w.data("outerWidthOffset")),h.ios&&u&&u.width(a-s.data("outerWidthOffset")-(u.outerWidth(!0)-u.width()))),b!==!1&&(d!==!1&&(c.height=b),b&&b.toString().indexOf("%")>-1&&(b=q.height(b).height(),q.height("auto")),b-=c.toolbarContainer?0:r.outerHeight(!0),s.height(b-s.data("outerHeightOffset")),w.height(b-f-w.data("outerHeightOffset"))),ua)},ua.updateStyleCache=function(){s.data("outerWidthOffset",s.outerWidth(!0)-s.width()),w.data("outerWidthOffset",w.outerWidth(!0)-w.width()),s.data("outerHeightOffset",s.outerHeight(!0)-s.height()),w.data("outerHeightOffset",w.outerHeight(!0)-w.height())},ua.height=function(a,b){return a||0===a?(ua.dimensions(null,a,b),ua):q.height()},ua.maximize=function(a){return"undefined"==typeof a?q.is(".sceditor-maximize"):(a=!!a,n<7&&b("html, body").toggleClass("sceditor-maximize",a),q.toggleClass("sceditor-maximize",a),ua.width(a?"100%":c.width,!1),ua.height(a?"100%":c.height,!1),ua)},ua.expandToContent=function(a){var b=q.height(),d=b-s.height(),e=u[0].scrollHeight||v[0].documentElement.scrollHeight,f=c.resizeMaxHeight||2*(c.height||wa.height());e+=d,(a===!0||e<=f)&&e>b&&ua.height(e)},ua.destroy=function(){C&&(C.destroy(),B=null,z=null,C=null,y&&y.off().remove(),m.off("click",ea),l.off("resize orientationChanged",fa),b(va.form).off("reset",ba).off("submit",ua.updateOriginal),u.off(),v.off().find("*").remove(),w.off().remove(),r.remove(),q.off().find("*").off().remove(),q.remove(),wa.removeData("sceditor").removeData("sceditorbbcode").show(),H&&wa.attr("required","required"))},ua.createDropDown=function(a,d,e,f){var g,h="sceditor-"+d,i=y&&y.is("."+h);ua.closeDropDown(!0),i||(f!==!1&&b(e).find(":not(input,textarea)").filter(function(){return 1===this.nodeType}).attr("unselectable","on"),g={top:a.offset().top,left:a.offset().left,marginTop:a.outerHeight()},b.extend(g,c.dropDownCss),y=b('
    ').css(g).append(e).appendTo(b("body")).on("click focusin",function(a){a.stopPropagation()}),setTimeout(function(){y&&y.find("input,textarea").first().focus()}))},ea=function(a){3!==a.which&&y&&(ta(),ua.closeDropDown())},Y=function(a){var b,d,e,f=u[0],g=v[0],h=0,i=k.createElement("div"),j=g.createDocumentFragment(),l=!!a&&a.clipboardData;if(c.disablePasting)return!1;if(c.enablePasteFiltering){if(B.saveRange(),k.body.appendChild(i),l&&l.getData&&((b=l.getData("text/html"))||(b=l.getData("text/plain"))))return i.innerHTML=b,Z(f,i),!1;for(e=u.scrollTop()||v.scrollTop();f.firstChild;)j.appendChild(f.firstChild);return d=function(a,b){if(a.childNodes.length>0||h>25){for(;a.firstChild;)b.appendChild(a.firstChild);for(;j.firstChild;)a.appendChild(j.firstChild);u.scrollTop(e),v.scrollTop(e),b.childNodes.length>0?Z(a,b):B.restoreRange()}else h++,setTimeout(function(){d(a,b)},20)},d(f,i),ua.focus(),!0}},Z=function(a,c){f.fixNesting(c);var d=c.innerHTML;C.hasHandler("toSource")&&(d=C.callOnlyFirst("toSource",d,b(c))),c.parentNode.removeChild(c),C.hasHandler("toWysiwyg")&&(d=C.callOnlyFirst("toWysiwyg",d,!0)),B.restoreRange(),ua.wysiwygEditorInsertHtml(d,null,!0)},ua.closeDropDown=function(a){y&&(y.off().remove(),y=null),a===!0&&ua.focus()},X=function(){return t.contentDocument?t.contentDocument:t.contentWindow&&t.contentWindow.document?t.contentWindow.document:t.document},ua.wysiwygEditorInsertHtml=function(a,c,d){var e,g,h,i=s.height();ua.focus(),(d||!b(E).is("code")&&0===b(E).parents("code").length)&&(B.insertHTML(a,c),B.saveRange(),L(u[0]),e=u.find("#sceditor-end-marker").show(),g=u.scrollTop()||v.scrollTop(),h=f.getOffset(e[0]).top+1.5*e.outerHeight(!0)-i,e.hide(),(h>g||h+i").appendTo(b("body")).hide().html(g);d!==!1&&C.hasHandler("toSource")&&(g=C.callOnlyFirst("toSource",g,h)),h.remove(),a+=g+c}return d!==!1&&C.hasHandler("toWysiwyg")&&(a=C.callOnlyFirst("toWysiwyg",a,!0)),d!==!1&&f===!0&&(a=a.replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&")),ua.wysiwygEditorInsertHtml(a),ua},ua.getWysiwygEditorValue=function(a){var c,d=b("
    ").appendTo(document.body).append(b(u[0].childNodes).clone());return f.fixNesting(d[0]),c=d.html(),a!==!1&&C.hasHandler("toSource")&&(c=C.callOnlyFirst("toSource",c,d)),d.remove(),c},ua.getBody=function(){return u},ua.getContentAreaContainer=function(){return s},ua.getSourceEditorValue=function(a){var b=w.val();return a!==!1&&C.hasHandler("toWysiwyg")&&(b=C.callOnlyFirst("toWysiwyg",b)),b},ua.setWysiwygEditorValue=function(a){a||(a="

    "+(n?"":"
    ")+"

    "),u[0].innerHTML=a,L(u[0]),ja(),qa()},ua.setSourceEditorValue=function(a){w.val(a),qa()},ua.updateOriginal=function(){wa.val(ua.val())},L=function(a){if(c.emoticonsEnabled&&!b(a).parents("code").length){var d=a.ownerDocument,e="\\s| | | | | ",h=[],j=[],k=b.extend({},c.emoticons.more,c.emoticons.dropdown,c.emoticons.hidden);b.each(k,function(a){c.emoticonsCompat&&(j[a]=new RegExp("(>|^|"+e+")"+g.regex(a)+"($|<|"+e+")")),h.push(a)});var l=function(a){for(a=a.firstChild;a;){var e,g,m,n,o,p,q,r=a.parentNode,s=a.nodeValue;if(3!==a.nodeType)b(a).is("code")||l(a);else if(s)for(o=h.length;o--;)g=h[o],q=c.emoticonsCompat?s.search(j[g]):s.indexOf(g),q>-1&&(p=a.nextSibling,m=k[g],e=s.substr(q).split(g),s=s.substr(0,q)+e.shift(),a.nodeValue=s,n=f.parseHTML(i("emoticon",{key:g,url:m.url||m,tooltip:m.tooltip||g}),d),r.insertBefore(n[0],p),r.insertBefore(d.createTextNode(e.join(g)),p));a=a.nextSibling}};l(a),c.emoticonsCompat&&(Ba=u.find("img[data-sceditor-emoticon]"))}},ua.inSourceMode=function(){return q.hasClass("sourceMode")},ua.sourceMode=function(a){var b=ua.inSourceMode();return"boolean"!=typeof a?b:((b&&!a||!b&&a)&&ua.toggleSourceMode(),ua)},ua.toggleSourceMode=function(){var a=ua.inSourceMode();!h.isWysiwygSupported&&a||(a||(B.saveRange(),B.clear()),ua.blur(),a?ua.setWysiwygEditorValue(ua.getSourceEditorValue()):ua.setSourceEditorValue(ua.getWysiwygEditorValue()),z=null,w.toggle(),s.toggle(),q.toggleClass("wysiwygMode",a).toggleClass("sourceMode",!a),ga(),ha())},ia=function(){return x.focus(),"undefined"!=typeof x.selectionStart?x.value.substring(x.selectionStart,x.selectionEnd):k.selection.createRange().text},M=function(a,c){ua.inSourceMode()?c.txtExec&&(b.isArray(c.txtExec)?ua.sourceEditorInsertText.apply(ua,c.txtExec):c.txtExec.call(ua,a,ia())):c.exec&&(b.isFunction(c.exec)?c.exec.call(ua,a):ua.execCommand(c.exec,c.hasOwnProperty("execParam")?c.execParam:null))},N=function(){n&&(z=B.selectedRange())},ua.execCommand=function(a,c){var d=!1,e=ua.commands[a],f=b(B.parentNode());if(ua.focus(),!f.is("code")&&0===f.parents("code").length){try{d=v[0].execCommand(a,!1,c)}catch(a){}!d&&e&&e.errorMessage&&alert(ua._(e.errorMessage)),ha()}},ka=function(){function a(){B&&!B.compare(F)&&(F=B.cloneSelected(),q.trigger(b.Event("selectionchanged"))),G=!1}G||(G=!0,n?a():setTimeout(a,100))},la=function(){var a,c=B.parentNode();D!==c&&(a=D,D=c,E=B.getFirstBlockParent(c),q.trigger(b.Event("nodechanged",{oldNode:a,newNode:D})))},ua.currentNode=function(){return D},ua.currentBlockNode=function(){return E},ha=function(a){var b,c,d="active",e=v[0],f=ua.sourceMode();if(ua.readOnly())return void r.find(d).removeClass(d);f||(c=a?a.newNode:B.parentNode(),b=B.getFirstBlockParent(c));for(var g=0;g-1&&(h=e.queryCommandState(j)?1:0)}catch(a){}}else k||(h=j.call(ua,c,b));i.toggleClass("disabled",k||h<0).toggleClass(d,h>0)}},aa=function(a){var c,d,e,g,h="code,blockquote,pre",i="li,ul,ol";if(!a.originalEvent.defaultPrevented)return ua.closeDropDown(),c=b(E).closest(h+","+i).first(),13===a.which&&c.length&&!c.is(i)?(z=null,d=v[0].createElement("br"),B.insertNode(d),o||(e=d.parentNode,g=e.lastChild,g&&3===g.nodeType&&""===g.nodeValue&&(e.removeChild(g),g=e.lastChild),!f.isInline(e,!0)&&g===d&&f.isInline(d.previousSibling)&&B.insertHTML("
    ")),!1):void 0},ja=function(){var a,c,d,e=u[0];f.rTraverse(e,function(g){if(a=g.nodeName.toLowerCase(),b.inArray(a,ya)>-1&&(c=!0),3===g.nodeType&&!/^\s*$/.test(g.nodeValue)||"br"===a||o&&!g.firstChild&&!f.isInline(g,!1))return c&&(d=v[0].createElement("p"),d.className="sceditor-nlf",d.innerHTML=o?"":"
    ",e.appendChild(d)),!1})},ba=function(){ua.val(wa.val())},ca=function(){ua.closeDropDown(),z=null},fa=function(){var a=c.height,b=c.width;ua.maximize()?ua.dimensions("100%","100%",!1):(a&&a.toString().indexOf("%")>-1||b&&b.toString().indexOf("%")>-1)&&ua.dimensions(b,a)},ua._=function(){var a,b=arguments;return A&&A[b[0]]&&(b[0]=A[b[0]]),b[0].replace(/\{(\d+)\}/g,function(c,d){return b[d-0+1]!==a?b[d-0+1]:"{"+d+"}"})},da=function(a){C.call(a.type+"Event",a,ua);var c=a.target===x?"scesrc":"scewys",d=b.Event(a);d.type=c+a.type,q.trigger(d,ua)},ua.bind=function(a,c,d,e){a=a.split(" ");for(var f=a.length;f--;)b.isFunction(c)&&(d||q.on("scewys"+a[f],c),e||q.on("scesrc"+a[f],c),"valuechanged"===a[f]&&(qa.hasHandler=!0));return ua},ua.unbind=function(a,c,d,e){a=a.split(" ");for(var f=a.length;f--;)b.isFunction(c)&&(d||q.off("scewys"+a[f],c),e||q.off("scesrc"+a[f],c));return ua},ua.blur=function(a,c,d){return b.isFunction(a)?ua.bind("blur",a,c,d):ua.sourceMode()?w.blur():u.blur(),ua},ua.focus=function(a,c,d){if(b.isFunction(a))ua.bind("focus",a,c,d);else if(ua.inSourceMode())x.focus();else{var e,f=B.selectedRange();F||B.hasSelection()||ma(),!o&&f&&1===f.endOffset&&f.collapsed&&(e=f.endContainer,e&&1===e.childNodes.length&&b(e.firstChild).is("br")&&(f.setStartBefore(e.firstChild),f.collapse(!0),B.selectRange(f))),t.contentWindow.focus(),u[0].focus(),z&&(B.selectRange(z),z=null)}return ha(),ua},ua.keyDown=function(a,b,c){return ua.bind("keydown",a,b,c)},ua.keyPress=function(a,b,c){return ua.bind("keypress",a,b,c)},ua.keyUp=function(a,b,c){return ua.bind("keyup",a,b,c)},ua.nodeChanged=function(a){return ua.bind("nodechanged",a,!1,!0)},ua.selectionChanged=function(a){return ua.bind("selectionchanged",a,!1,!0)},ua.valueChanged=function(a,b,c){return ua.bind("valuechanged",a,b,c)},na=function(a){var d,e=0,f=ua.emoticonsCache,g=String.fromCharCode(a.which);if(!b(E).is("code")&&!b(E).parents("code").length)return f||(f=[],b.each(b.extend({},c.emoticons.more,c.emoticons.dropdown,c.emoticons.hidden),function(a,b){f[e++]=[a,i("emoticon",{key:a,url:b.url||b,tooltip:b.tooltip||a})]}),f.sort(function(a,b){return a[0].length-b[0].length}),ua.emoticonsCache=f,ua.longestEmoticonCode=f[f.length-1][0].length),d=B.replaceKeyword(ua.emoticonsCache,!0,!0,ua.longestEmoticonCode,c.emoticonsCompat,g),d&&c.emoticonsCompat?(Ba=u.find("img[data-sceditor-emoticon]"),/^\s$/.test(g)):!d},oa=function(){if(Ba.length){var a,c,d,e,f,g,h=ua.currentBlockNode(),i=!1,j=/[^\s\xA0\u2002\u2003\u2009\u00a0]+/;Ba=b.map(Ba,function(k){return k&&k.parentNode?b.contains(h,k)?(a=k.previousSibling,c=k.nextSibling,f=a.nodeValue,null===f&&(f=a.innerText||""),a&&j.test(a.nodeValue.slice(-1))||c&&j.test((c.nodeValue||"")[0])?(d=k.parentNode,e=B.cloneSelected(),g=e.startContainer,f+=b(k).data("sceditor-emoticon"),g===c?i=f.length+e.startOffset:g===h&&h.childNodes[e.startOffset]===c?i=f.length:g===a&&(i=e.startOffset),c&&3===c.nodeType||(c=d.insertBefore(d.ownerDocument.createTextNode(""),c)),c.insertData(0,f),d.removeChild(a),d.removeChild(k),i!==!1&&(e.setStart(c,i),e.collapse(!0),B.selectRange(e)),null):k):k:null})}},ua.emoticons=function(a){return a||a===!1?(c.emoticonsEnabled=a,a?(u.keypress(na),ua.sourceMode()||(B.saveRange(),L(u[0]),Ba=u.find("img[data-sceditor-emoticon]"),qa(!1),B.restoreRange())):(u.find("img[data-sceditor-emoticon]").replaceWith(function(){return b(this).data("sceditor-emoticon")}),Ba=[],u.off("keypress",na),qa()),ua):c.emoticonsEnabled},ua.css=function(a){return I||(I=b('

    ',toolbarButton:'
    {dispName}
    ',emoticon:'{key}',fontOpt:'{font}',sizeOpt:'{size}',pastetext:'
    ',table:'
    ',image:'
    ',email:'
    ',link:'
    ',youtubeMenu:'
    ',youtube:''};return function(b,c,d){var e=a[b];return $.each(c,function(a,b){e=e.replace(new RegExp("\\{"+a+"\\}","g"),b)}),d&&(e=$(e)),e}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1),d=c(6).ie,e=c(8),f=d&&d<11,g={bold:{exec:"bold",tooltip:"Bold",shortcut:"Ctrl+B"},italic:{exec:"italic",tooltip:"Italic",shortcut:"Ctrl+I"},underline:{exec:"underline",tooltip:"Underline",shortcut:"Ctrl+U"},strike:{exec:"strikethrough",tooltip:"Strikethrough"},subscript:{exec:"subscript",tooltip:"Subscript"},superscript:{exec:"superscript",tooltip:"Superscript"},left:{exec:"justifyleft",tooltip:"Align left"},center:{exec:"justifycenter",tooltip:"Center"},right:{exec:"justifyright",tooltip:"Align right"},justify:{exec:"justifyfull",tooltip:"Justify"},font:{_dropDown:function(a,c,d){for(var f=0,g=a.opts.fonts.split(","),h=b("
    "),i=function(){return d(b(this).data("font")),a.closeDropDown(!0),!1};f"),g=function(c){d(b(this).data("size")),a.closeDropDown(!0),c.preventDefault()},h=1;h<=7;h++)f.append(e("sizeOpt",{size:h},!0).click(g));a.createDropDown(c,"fontsize-picker",f)},exec:function(a){var b=this;g.size._dropDown(b,a,function(a){b.execCommand("fontsize",a)})},tooltip:"Font Size"},color:{_dropDown:function(a,c,d){var e,f,h,i,j={r:255,g:255,b:255},k=b("
    "),l=a.opts.colors?a.opts.colors.split("|"):new Array(21),m=[],n=g.color;if(!n._htmlCache){for(e=0;e'),f=0;f'),f%5===0?(j.g-=51,j.b=255):j.b-=51;m.push("
    "),e%5===0?(j.r-=51,j.g=255,j.b=255):(j.g=255,j.b=255)}n._htmlCache=m.join("")}k.append(n._htmlCache).find("a").click(function(c){d(b(this).attr("data-color")),a.closeDropDown(!0),c.preventDefault()}),a.createDropDown(c,"color-picker",k)},exec:function(a){var b=this;g.color._dropDown(b,a,function(a){b.execCommand("forecolor",a)})},tooltip:"Font Color"},removeformat:{exec:"removeformat",tooltip:"Remove Formatting"},cut:{exec:"cut",tooltip:"Cut",errorMessage:"Your browser does not allow the cut command. Please use the keyboard shortcut Ctrl/Cmd-X"},copy:{exec:"copy",tooltip:"Copy",errorMessage:"Your browser does not allow the copy command. Please use the keyboard shortcut Ctrl/Cmd-C"},paste:{exec:"paste",tooltip:"Paste",errorMessage:"Your browser does not allow the paste command. Please use the keyboard shortcut Ctrl/Cmd-V"},pastetext:{exec:function(a){var b,c,d=this;c=e("pastetext",{label:d._("Paste your text inside the following box:"),insert:d._("Insert")},!0),c.find(".button").click(function(a){b=c.find("#txt").val(),b&&d.wysiwygEditorInsertText(b),d.closeDropDown(!0),a.preventDefault()}),d.createDropDown(a,"pastetext",c)},tooltip:"Paste Text"},bulletlist:{exec:"insertunorderedlist",tooltip:"Bullet list"},orderedlist:{exec:"insertorderedlist",tooltip:"Numbered list"},indent:{state:function(a,c){var d,e,f,g=b(c),h=g.parents("ul,ol,menu"),i=h.first();if(h.length>1||i.children().length>1)return 0;if(g.is("ul,ol,menu")){if(d=this.getRangeHelper().selectedRange(),!(window.Range&&d instanceof Range))return g.is("li,ul,ol,menu")?0:-1;if(e=d.startContainer.parentNode,f=d.endContainer.parentNode,e!==e.parentNode.firstElementChild||b(f).is("li")&&f!==f.parentNode.lastElementChild)return 0}return-1},exec:function(){var a=this,c=b(a.getRangeHelper().getFirstBlockParent());a.focus(),c.parents("ul,ol,menu")&&a.execCommand("indent")},tooltip:"Add indent"},outdent:{state:function(a,c){return b(c).is("ul,ol,menu")||b(c).parents("ul,ol,menu").length>0?0:-1},exec:function(){var a=this,c=b(a.getRangeHelper().getFirstBlockParent());c.parents("ul,ol,menu")&&a.execCommand("outdent")},tooltip:"Remove one indent"},table:{forceNewLineAfter:["table"],exec:function(a){var b=this,c=e("table",{rows:b._("Rows:"),cols:b._("Cols:"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d,e,g=c.find("#rows").val()-0,h=c.find("#cols").val()-0,i="";if(!(g<1||h<1)){for(d=0;d",e=0;e"+(f?"":"
    ")+"";i+=""}i+="
    ",b.wysiwygEditorInsertHtml(i),b.closeDropDown(!0),a.preventDefault()}}),b.createDropDown(a,"inserttable",c)},tooltip:"Insert a table"},horizontalrule:{exec:"inserthorizontalrule",tooltip:"Insert a horizontal rule"},code:{forceNewLineAfter:["code"],exec:function(){this.wysiwygEditorInsertHtml("",(f?"":"
    ")+"
    ")},tooltip:"Code"},image:{exec:function(a){var b=this,c=e("image",{url:b._("URL:"),width:b._("Width (optional):"),height:b._("Height (optional):"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#image").val(),e=c.find("#width").val(),f=c.find("#height").val(),g="";e&&(g+=' width="'+e+'"'),f&&(g+=' height="'+f+'"'),d&&b.wysiwygEditorInsertHtml("'),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertimage",c)},tooltip:"Insert an image"},email:{exec:function(a){var b=this,c=e("email",{label:b._("E-mail:"),desc:b._("Description (optional):"),insert:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#email").val(),e=c.find("#des").val();d&&(b.focus(),!b.getRangeHelper().selectedHtml()||e?(e=e||d,b.wysiwygEditorInsertHtml(''+e+"")):b.execCommand("createlink","mailto:"+d)),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertemail",c)},tooltip:"Insert an email"},link:{exec:function(a){var b=this,c=e("link",{url:b._("URL:"),desc:b._("Description (optional):"),ins:b._("Insert")},!0);c.find(".button").click(function(a){var d=c.find("#link").val(),e=c.find("#des").val();d&&(b.focus(),!b.getRangeHelper().selectedHtml()||e?(e=e||d,b.wysiwygEditorInsertHtml(''+e+"")):b.execCommand("createlink",d)),b.closeDropDown(!0),a.preventDefault()}),b.createDropDown(a,"insertlink",c)},tooltip:"Insert a link"},unlink:{state:function(){var a=b(this.currentNode());return a.is("a")||a.parents("a").length>0?0:-1},exec:function(){var a=b(this.currentNode()),c=a.is("a")?a:a.parents("a").first();c.length&&c.replaceWith(c.contents())},tooltip:"Unlink"},quote:{forceNewLineAfter:["blockquote"],exec:function(a,b,c){var d="
    ",e="
    ";b?(c=c?""+c+"":"",d=d+c+b+e,e=null):""===this.getRangeHelper().selectedHtml()&&(e=(f?"":"
    ")+e),this.wysiwygEditorInsertHtml(d,e)},tooltip:"Insert a Quote"},emoticon:{exec:function(a){var c=this,d=function(e){var f,g=c.opts.emoticonsCompat,h=c.getRangeHelper(),i=g&&" "!==h.getOuterText(!0,1)?" ":"",j=g&&" "!==h.getOuterText(!1,1)?" ":"",k=b("
    "),l=b("
    ").appendTo(k),m=0,n=b.extend({},c.opts.emoticons.dropdown,e?c.opts.emoticons.more:{});return b.each(n,function(){m++}),m=Math.sqrt(m),b.each(n,function(a,d){l.append(b("").attr({src:d.url||d,alt:a,title:d.tooltip||a}).click(function(){return c.insert(i+b(this).attr("alt")+j,null,!1).closeDropDown(!0),!1})),l.children().length>=m&&(l=b("
    ").appendTo(k))}),!e&&c.opts.emoticons.more&&(f=b(''+c._("More")+"").click(function(){return c.createDropDown(a,"more-emoticons",d(!0)),!1}),k.append(f)),k};c.createDropDown(a,"emoticons",d(!1))},txtExec:function(a){g.emoticon.exec.call(this,a)},tooltip:"Insert an emoticon"},youtube:{_dropDown:function(a,b,c){var d,f=e("youtubeMenu",{label:a._("Video URL:"),insert:a._("Insert")},!0);f.find(".button").click(function(b){var e=f.find("#link").val();e&&(d=e.match(/(?:v=|v\/|embed\/|youtu.be\/)(.{11})/),d&&(e=d[1]),/^[a-zA-Z0-9_\-]{11}$/.test(e)?c(e):alert("Invalid YouTube video")),a.closeDropDown(!0),b.preventDefault()}),a.createDropDown(b,"insertlink",f)},exec:function(a){var b=this;g.youtube._dropDown(b,a,function(a){b.wysiwygEditorInsertHtml(e("youtube",{id:a}))})},tooltip:"Insert a YouTube video"},date:{_date:function(a){var b=new Date,c=b.getYear(),d=b.getMonth()+1,e=b.getDate();return c<2e3&&(c=1900+c),d<10&&(d="0"+d),e<10&&(e="0"+e),a.opts.dateFormat.replace(/year/i,c).replace(/month/i,d).replace(/day/i,e)},exec:function(){this.insertText(g.date._date(this))},txtExec:function(){this.insertText(g.date._date(this))},tooltip:"Insert current date"},time:{_time:function(){var a=new Date,b=a.getHours(),c=a.getMinutes(),d=a.getSeconds();return b<10&&(b="0"+b),c<10&&(c="0"+c),d<10&&(d="0"+d),b+":"+c+":"+d},exec:function(){this.insertText(g.time._time())},txtExec:function(){this.insertText(g.time._time())},tooltip:"Insert current time"},ltr:{state:function(a,b){return b&&"ltr"===b.style.direction},exec:function(){var a=this,c=a.getRangeHelper().getFirstBlockParent(),d=b(c);a.focus(),(c&&!d.is("body")||(a.execCommand("formatBlock","p"),c=a.getRangeHelper().getFirstBlockParent(),d=b(c),c&&!d.is("body")))&&("ltr"===d.css("direction")?d.css("direction",""):d.css("direction","ltr"))},tooltip:"Left-to-Right"},rtl:{state:function(a,b){return b&&"rtl"===b.style.direction},exec:function(){var a=this,c=a.getRangeHelper().getFirstBlockParent(),d=b(c);a.focus(),(c&&!d.is("body")||(a.execCommand("formatBlock","p"),c=a.getRangeHelper().getFirstBlockParent(),d=b(c),c&&!d.is("body")))&&("rtl"===d.css("direction")?d.css("direction",""):d.css("direction","rtl"))},tooltip:"Right-to-Left"},print:{exec:"print",tooltip:"Print"},maximize:{state:function(){return this.maximize()},exec:function(){this.maximize(!this.maximize())},txtExec:function(){this.maximize(!this.maximize())},tooltip:"Maximize",shortcut:"Ctrl+Shift+M"},source:{state:function(){return this.sourceMode()},exec:function(){this.toggleSourceMode()},txtExec:function(){this.toggleSourceMode()},tooltip:"View source",shortcut:"Ctrl+Shift+S"},ignore:{}};return g}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a){"use strict";var b=c(1);return{toolbar:"bold,italic,underline,strike,subscript,superscript|left,center,right,justify|font,size,color,removeformat|cut,copy,paste,pastetext|bulletlist,orderedlist,indent,outdent|table|code,quote|horizontalrule,image,email,link,unlink|emoticon,youtube,date,time|ltr,rtl|print,maximize,source",toolbarExclude:null,style:"jquery.sceditor.default.css",fonts:"Arial,Arial Black,Comic Sans MS,Courier New,Georgia,Impact,Sans-serif,Serif,Times New Roman,Trebuchet MS,Verdana",colors:null,locale:b("html").attr("lang")||"en",charset:"utf-8",emoticonsCompat:!1,emoticonsEnabled:!0,emoticonsRoot:"",emoticons:{dropdown:{":)":"emoticons/smile.png",":angel:":"emoticons/angel.png",":angry:":"emoticons/angry.png","8-)":"emoticons/cool.png",":'(":"emoticons/cwy.png",":ermm:":"emoticons/ermm.png",":D":"emoticons/grin.png","<3":"emoticons/heart.png",":(":"emoticons/sad.png",":O":"emoticons/shocked.png",":P":"emoticons/tongue.png",";)":"emoticons/wink.png"},more:{":alien:":"emoticons/alien.png",":blink:":"emoticons/blink.png",":blush:":"emoticons/blush.png",":cheerful:":"emoticons/cheerful.png",":devil:":"emoticons/devil.png",":dizzy:":"emoticons/dizzy.png",":getlost:":"emoticons/getlost.png",":happy:":"emoticons/happy.png",":kissing:":"emoticons/kissing.png",":ninja:":"emoticons/ninja.png",":pinch:":"emoticons/pinch.png",":pouty:":"emoticons/pouty.png",":sick:":"emoticons/sick.png",":sideways:":"emoticons/sideways.png",":silly:":"emoticons/silly.png",":sleeping:":"emoticons/sleeping.png",":unsure:":"emoticons/unsure.png",":woot:":"emoticons/w00t.png",":wassat:":"emoticons/wassat.png"},hidden:{":whistling:":"emoticons/whistling.png",":love:":"emoticons/wub.png"}},width:null,height:null,resizeEnabled:!0,resizeMinWidth:null,resizeMinHeight:null,resizeMaxHeight:null,resizeMaxWidth:null,resizeHeight:!0,resizeWidth:!0,dateFormat:"year-month-day",toolbarContainer:null,enablePasteFiltering:!1,disablePasting:!1,readOnly:!1,rtl:!1,autofocus:!1,autofocusEnd:!0,autoExpand:!1,autoUpdate:!1,spellcheck:!0,runWithoutWysiwygSupport:!1,startInSourceMode:!1,id:null,plugins:"",zIndex:null,bbcodeTrim:!1,disableBlockRemove:!1,parserOptions:{},dropDownCss:{}}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))}]),function(a){"use strict";var b=a.sceditor,c=b.plugins,d=b.dom,e={bold:{txtExec:["",""]},italic:{txtExec:["",""]},underline:{txtExec:['',""]},strike:{txtExec:['',""]},subscript:{txtExec:["",""]},superscript:{txtExec:["",""]},left:{txtExec:['
    ',"
    "]},center:{txtExec:['
    ',"
    "]},right:{txtExec:['
    ',"
    "]},justify:{txtExec:['
    ',"
    "]},font:{txtExec:function(a){var c=this;b.command.get("font")._dropDown(c,a,function(a){c.insertText('',"")})}},size:{txtExec:function(a){var c=this;b.command.get("size")._dropDown(c,a,function(a){c.insertText('',"")})}},color:{txtExec:function(a){var c=this;b.command.get("color")._dropDown(c,a,function(a){c.insertText('',"")})}},bulletlist:{txtExec:["
    • ","
    "]},orderedlist:{txtExec:["
    1. ","
    "]},table:{txtExec:["
    ","
    "]},horizontalrule:{txtExec:["
    "]},code:{txtExec:["",""]},image:{txtExec:function(a,b){var c=prompt(this._("Enter the image URL:"),b);c&&this.insertText('')}},email:{txtExec:function(a,b){var c,d,e=b&&b.indexOf("@")>-1?null:b;c=prompt(this._("Enter the e-mail address:"),e?"":b),d=prompt(this._("Enter the displayed text:"),e||c)||c,c&&this.insertText(''+d+"")}},link:{txtExec:function(a,b){var c=b&&b.indexOf("http://")>-1?null:b,d=prompt(this._("Enter URL:"),c?"http://":b),e=prompt(this._("Enter the displayed text:"),c||d)||d;d&&this.insertText(''+e+"")}},quote:{txtExec:["
    ","
    "]},youtube:{txtExec:function(a){var c=this;b.command.get("youtube")._dropDown(c,a,function(a){c.insertText('')})}},rtl:{txtExec:['
    ',"
    "]},ltr:{txtExec:['
    ',"
    "]}};b.XHTMLSerializer=function(){var c,e,f,g,h,i,j,k,l,m,n=this,o={indentStr:"\t"},p=[],q=0;c=function(a){var b={"&":"&","<":"<",">":">",'"':"""};return a?a.replace(/[&<>"]/g,function(a){return b[a]||a}):""},e=function(a){return a.replace(/[\r\n]/," ").replace(/[^\S|\u00A0]+/g," ")},n.serialize=function(a,b){if(p=[],b)for(a=a.firstChild;a;)f(a),a=a.nextSibling;else f(a);return p.join("")},f=function(a,b){switch(a.nodeType){case 1:var c=a.nodeName.toLowerCase();"!"===c?j(a):h(a,b);break;case 3:k(a,b);break;case 4:i(a);break;case 8:j(a);break;case 9:case 11:g(a);break;case 2:case 5:case 6:case 7:case 10:case 12:}},g=function(a){for(var b=a.firstChild;b;)f(b),b=b.nextSibling},h=function(e,g){var h,i,j,k=e.nodeName.toLowerCase(),n="iframe"===k,o=e.attributes.length,p=e.firstChild,r=g||/pre(?:\-wrap)?$/i.test(a(e).css("whiteSpace")),s=!e.firstChild&&!d.canHaveChildren(e)&&!n;if(!a(e).hasClass("sceditor-ignore")){for(l("<"+k,!g&&m(e));o--;)i=e.attributes[o],(!b.ie||i.specified||"input"===k&&"value"===i.name)&&(j=b.ie<8&&/style/i.test(i.name)?e.style.cssText:i.value,l(" "+i.name.toLowerCase()+'="'+c(j)+'"',!1));for(l(s?" />":">",!1),n||(h=p);h;)q++,f(h,r),h=h.nextSibling,q--;s||l("",!r&&!n&&m(e)&&p&&m(p))}},i=function(a){l("")},j=function(a){l("")},k=function(a,b){var d=a.nodeValue;b||(d=e(d)),d&&l(c(d),!b&&m(a))},l=function(a,b){var c=q;if(b!==!1)for(p.length&&p.push("\n");c--;)p.push(o.indentStr);p.push(a)},m=function(a){var b=a.previousSibling;return 1!==a.nodeType&&b?!d.isInline(b):!b&&!d.isInline(a.parentNode)||!d.isInline(a)}},c.xhtml=function(){var f,g,h,i,j,k,l,m=this,n={},o={};m.init=function(){a.isEmptyObject(c.xhtml.converters||{})||a.each(c.xhtml.converters,function(b,c){a.each(c.tags,function(a){n[a]||(n[a]=[]),n[a].push(c)})}),this.commands=a.extend(!0,{},e,this.commands)},m.signalToSource=function(a,c){return c=c.jquery?c[0]:c,f(c),i(c),k(c),l(c),(new b.XHTMLSerializer).serialize(c,!0)},m.signalToWysiwyg=function(a){return a},m.convertTagTo=d.convertElement,g=function(c,d,e){n[c]&&a.each(n[c],function(f,g){g.tags[c]?a.each(g.tags[c],function(c,f){e.getAttributeNode&&(c=e.getAttributeNode(c),!c||b.ie<8&&!c.specified||f&&a.inArray(c.value,f)<0||g.conv.call(m,e,d))}):g.conv&&g.conv.call(m,e,d)})},f=function(b){d.traverse(b,function(b){var c=a(b),d=b.nodeName.toLowerCase();g("*",c,b),g(d,c,b)},!0)},h=function(b,c){var e=b.childNodes,f=b.nodeName.toLowerCase(),g=b.nodeValue,i=e.length;if(c&&"br"===f)return!0;if(a(b).hasClass("sceditor-ignore"))return!0;if(!d.canHaveChildren(b))return!1;if(g&&/\S|\u00A0/.test(g))return!1;for(;i--;)if(!h(e[i],c&&!b.previousSibling&&!b.nextSibling))return!1;return!0},i=function(b){d.traverse(b,function(e){var f,g=e.nodeName.toLowerCase(),i=e.parentNode,j=e.nodeType,k=!d.isInline(e),l=e.previousSibling,m=e.nextSibling,n=i===b,o=!l&&!m,p="iframe"!==g&&h(e,n&&o&&"br"!==g),q=e.ownerDocument,r=c.xhtml.allowedTags,s=c.xhtml.disallowedTags;if(3!==j&&(4===j?g="!cdata":"!"!==g&&8!==j||(g="!comment"),p?f=!0:r&&r.length?f=a.inArray(g,r)<0:s&&s.length&&(f=a.inArray(g,s)>-1),f)){if(!p){for(k&&l&&d.isInline(l)&&i.insertBefore(q.createTextNode(" "),e);e.firstChild;)i.insertBefore(e.firstChild,m);k&&m&&d.isInline(m)&&i.insertBefore(q.createTextNode(" "),m)}i.removeChild(e)}},!0)},j=function(b,c){var d={};return b&&a.extend(d,b),c?(a.each(c,function(b,c){a.isArray(c)?d[b]=a.merge(d[b]||[],c):d[b]||(d[b]=null)}),d):d},l=function(b){var c=[],e=function(){c.length&&(a("

    ",b.ownerDocument).insertBefore(c[0]).append(c),c=[])};d.removeWhiteSpace(b);for(var f=b.firstChild;f;)d.isInline(f)&&!a(f).is(".sceditor-ignore")?c.push(f):e(),f=f.nextSibling;e()},k=function(b){var e,f,g,h,i,k,l=c.xhtml.allowedAttribs,m=l&&!a.isEmptyObject(l),n=c.xhtml.disallowedAttribs,p=n&&!a.isEmptyObject(n);o={},d.traverse(b,function(b){if(b.attributes&&(e=b.nodeName.toLowerCase(),h=b.attributes.length))for(o[e]||(m?o[e]=j(l["*"],l[e]):o[e]=j(n["*"],n[e]));h--;)f=b.attributes[h],g=f.name,i=o[e][g],k=!1,m?k=null!==i&&(!a.isArray(i)||a.inArray(f.value,i)<0):p&&(k=null===i||a.isArray(i)&&a.inArray(f.value,i)>-1),k&&b.removeAttribute(g)})}},c.xhtml.converters=[{tags:{"*":{width:null}},conv:function(a,b){b.css("width",b.attr("width")).removeAttr("width")}},{tags:{"*":{height:null}},conv:function(a,b){b.css("height",b.attr("height")).removeAttr("height")}},{tags:{li:{value:null}},conv:function(a,c){b.ie<8?a.removeAttribute("value"):c.removeAttr("value")}},{tags:{"*":{text:null}},conv:function(a,b){b.css("color",b.attr("text")).removeAttr("text")}},{tags:{"*":{color:null}},conv:function(a,b){b.css("color",b.attr("color")).removeAttr("color")}},{tags:{"*":{face:null}},conv:function(a,b){b.css("fontFamily",b.attr("face")).removeAttr("face")}},{tags:{"*":{align:null}},conv:function(a,b){b.css("textAlign",b.attr("align")).removeAttr("align")}},{tags:{"*":{border:null}},conv:function(a,b){b.css("borderWidth",b.attr("border")).removeAttr("border")}},{tags:{applet:{name:null},img:{name:null},layer:{name:null},map:{name:null},object:{name:null},param:{name:null}},conv:function(a,b){b.attr("id")||b.attr("id",b.attr("name")),b.removeAttr("name")}},{tags:{"*":{vspace:null}},conv:function(a,b){b.css("marginTop",b.attr("vspace")-0).css("marginBottom",b.attr("vspace")-0).removeAttr("vspace")}},{tags:{"*":{hspace:null}},conv:function(a,b){b.css("marginLeft",b.attr("hspace")-0).css("marginRight",b.attr("hspace")-0).removeAttr("hspace")}},{tags:{hr:{noshade:null}},conv:function(a,b){b.css("borderStyle","solid").removeAttr("noshade")}},{tags:{"*":{nowrap:null}},conv:function(a,b){b.css("white-space","nowrap").removeAttr("nowrap")}},{tags:{big:null},conv:function(b){a(this.convertTagTo(b,"span")).css("fontSize","larger")}},{tags:{small:null},conv:function(b){a(this.convertTagTo(b,"span")).css("fontSize","smaller")}},{tags:{b:null},conv:function(b){a(this.convertTagTo(b,"strong"))}},{tags:{u:null},conv:function(b){a(this.convertTagTo(b,"span")).css("textDecoration","underline")}},{tags:{i:null},conv:function(b){a(this.convertTagTo(b,"em"))}},{tags:{s:null,strike:null},conv:function(b){a(this.convertTagTo(b,"span")).css("textDecoration","line-through")}},{tags:{dir:null},conv:function(a){this.convertTagTo(a,"ul")}},{tags:{center:null},conv:function(b){a(this.convertTagTo(b,"div")).css("textAlign","center")}},{tags:{font:{size:null}},conv:function(a,c){var d=c.css("fontSize"),e=d;"+0"!==e&&(b.ie<9&&(e=10,d>1&&(e=13),d>2&&(e=16),d>3&&(e=18),d>4&&(e=24),d>5&&(e=32),d>6&&(e=48)),c.css("fontSize",e)),c.removeAttr("size")}},{tags:{font:null},conv:function(a){this.convertTagTo(a,"span")}},{tags:{"*":{type:["_moz"]}},conv:function(a,b){b.removeAttr("type")}},{tags:{"*":{_moz_dirty:null}},conv:function(a,b){b.removeAttr("_moz_dirty")}},{tags:{"*":{_moz_editor_bogus_node:null}},conv:function(a,b){b.remove()}}],c.xhtml.allowedAttribs={},c.xhtml.disallowedAttribs={},c.xhtml.allowedTags=[],c.xhtml.disallowedTags=[]}(jQuery); \ No newline at end of file diff --git a/js/sceditor/minified/plugins/bbcode.js b/js/sceditor/minified/plugins/bbcode.js new file mode 100644 index 00000000..80cc1867 --- /dev/null +++ b/js/sceditor/minified/plugins/bbcode.js @@ -0,0 +1,2 @@ +/* SCEditor v1.5.2 | (C) 2016, Sam Clarke | sceditor.com/license */ +!function(a,b,c){"use strict";var d=a.sceditor,e=d.plugins,f=d.escapeEntities,g=d.escapeUriScheme,h=d.ie,i=h&&h<11,j=d.command.get,k={bold:{txtExec:["[b]","[/b]"]},italic:{txtExec:["[i]","[/i]"]},underline:{txtExec:["[u]","[/u]"]},strike:{txtExec:["[s]","[/s]"]},subscript:{txtExec:["[sub]","[/sub]"]},superscript:{txtExec:["[sup]","[/sup]"]},left:{txtExec:["[left]","[/left]"]},center:{txtExec:["[center]","[/center]"]},right:{txtExec:["[right]","[/right]"]},justify:{txtExec:["[justify]","[/justify]"]},font:{txtExec:function(a){var b=this;j("font")._dropDown(b,a,function(a){b.insertText("[font="+a+"]","[/font]")})}},size:{txtExec:function(a){var b=this;j("size")._dropDown(b,a,function(a){b.insertText("[size="+a+"]","[/size]")})}},color:{txtExec:function(a){var b=this;j("color")._dropDown(b,a,function(a){b.insertText("[color="+a+"]","[/color]")})}},bulletlist:{txtExec:function(b,c){var d="";a.each(c.split(/\r?\n/),function(){d+=(d?"\n":"")+"[li]"+this+"[/li]"}),this.insertText("[ul]\n"+d+"\n[/ul]")}},orderedlist:{txtExec:function(b,c){var d="";a.each(c.split(/\r?\n/),function(){d+=(d?"\n":"")+"[li]"+this+"[/li]"}),e.bbcode.bbcode.get(""),this.insertText("[ol]\n"+d+"\n[/ol]")}},table:{txtExec:["[table][tr][td]","[/td][/tr][/table]"]},horizontalrule:{txtExec:["[hr]"]},code:{txtExec:["[code]","[/code]"]},image:{txtExec:function(a,b){var c=this,d=prompt(c._("Enter the image URL:"),b);d&&c.insertText("[img]"+d+"[/img]")}},email:{txtExec:function(a,b){var c=this,d=b&&b.indexOf("@")>-1?null:b,e=prompt(c._("Enter the e-mail address:"),d?"":b),f=prompt(c._("Enter the displayed text:"),d||e)||e;e&&c.insertText("[email="+e+"]"+f+"[/email]")}},link:{txtExec:function(b,c){var d=this,e=/^[a-z]+:\/\//i.test(a.trim(c))?null:c,f=prompt(d._("Enter URL:"),e?"http://":a.trim(c)),g=prompt(d._("Enter the displayed text:"),e||f)||f;f&&d.insertText("[url="+f+"]"+g+"[/url]")}},quote:{txtExec:["[quote]","[/quote]"]},youtube:{txtExec:function(a){var b=this;j("youtube")._dropDown(b,a,function(a){b.insertText("[youtube]"+a+"[/youtube]")})}},rtl:{txtExec:["[rtl]","[/rtl]"]},ltr:{txtExec:["[ltr]","[/ltr]"]}},l=function(a){return a?a.replace(/\\(.)/g,"$1").replace(/^(["'])(.*?)\1$/,"$2"):a},m=function(){var a,b=arguments;return b[0].replace(/\{(\d+)\}/g,function(c,d){return b[d-0+1]!==a?b[d-0+1]:"{"+d+"}"})},n={OPEN:"open",CONTENT:"content",NEWLINE:"newline",CLOSE:"close"},o=function(a,b,c,d,e,f){var g=this;g.type=a,g.name=b,g.val=c,g.attrs=d||{},g.children=e||[],g.closing=f||null};o.prototype={clone:function(a){var b=this;return new o(b.type,b.name,b.val,b.attrs,a?b.children:[],b.closing?b.closing.clone():null)},splitAt:function(b){var c,d=this,e=0,f=d.children.length;if("number"!=typeof b&&(b=a.inArray(b,d.children)),b<0||b>f)return null;for(;f--;)f>=b?e++:f=0;return c=d.clone(),c.children=d.children.splice(b,e),c}};var p=function(b){if(!(this instanceof p))return new p(b);var d,g,j,k,m,q,r,s,t,u,v,w,x,y,z,A=this;d=function(){A.bbcodes=e.bbcode.bbcodes,A.opts=a.extend({},p.defaults,b)},A.tokenize=function(a){var b,c,d,e=[],f=[{type:n.CLOSE,regex:/^\[\/[^\[\]]+\]/},{type:n.OPEN,regex:/^\[[^\[\]]+\]/},{type:n.NEWLINE,regex:/^(\r\n|\r|\n)/},{type:n.CONTENT,regex:/^([^\[\r\n]+|\[)/}];f.reverse();a:for(;a.length;){for(d=f.length;d--;)if(c=f[d].type,(b=a.match(f[d].regex))&&b[0]){e.push(g(c,b[0])),a=a.substr(b[0].length);continue a}a.length&&e.push(g(n.CONTENT,a)),a=""}return e},g=function(b,c){var d,f,g,h=/\[([^\]\s=]+)(?:([^\]]+))?\]/,i=/\[\/([^\[\]]+)\]/;return b===n.OPEN&&(d=c.match(h))&&(g=y(d[1]),d[2]&&(d[2]=a.trim(d[2]))&&(f=j(d[2]))),b===n.CLOSE&&(d=c.match(i))&&(g=y(d[1])),b===n.NEWLINE&&(g="#newline"),g&&(b!==n.OPEN&&b!==n.CLOSE||e.bbcode.bbcodes[g])||(b=n.CONTENT,g="#"),new o(b,g,c,f)},j=function(a){var b,c=/([^\s=]+)=(?:(?:(["'])((?:\\\2|[^\2])*?)\2)|((?:.(?!\s\S+=))*.))/g,d={};if("="===a.charAt(0)&&a.indexOf("=",1)<0)d.defaultattr=l(a.substr(1));else for("="===a.charAt(0)&&(a="defaultattr"+a);b=c.exec(a);)d[y(b[1])]=l(b[3])||b[4];return d},A.parse=function(a,b){var c=k(A.tokenize(a)),d=A.opts;return d.fixInvalidChildren&&t(c),d.removeEmptyTags&&s(c),d.fixInvalidNesting&&q(c),m(c,null,b),d.removeEmptyTags&&s(c),c},w=function(a,b,c){for(var d=c.length;d--;)if(c[d].type===b&&c[d].name===a)return!0;return!1},r=function(b,c){var d=b?A.bbcodes[b.name]:{},e=d.allowedChildren;return!A.opts.fixInvalidChildren||!e||a.inArray(c.name||"#",e)>-1},k=function(b){for(var c,d,e,f,g,h,i,j=[],k=[],l=[],m=function(){return z(l)},o=function(a){m()?m().children.push(a):k.push(a)},p=function(b){return m()&&(d=A.bbcodes[m().name])&&d.closedBy&&a.inArray(b,d.closedBy)>-1};c=b.shift();){switch(i=b[0],c.type){case n.OPEN:p(c.name)&&l.pop(),o(c),d=A.bbcodes[c.name],d&&d.isSelfClosing||!d.closedBy&&!w(c.name,n.CLOSE,b)?d&&d.isSelfClosing||(c.type=n.CONTENT):l.push(c);break;case n.CLOSE:if(m()&&c.name!==m().name&&p("/"+c.name)&&l.pop(),m()&&c.name===m().name)m().closing=c,l.pop();else if(w(c.name,n.OPEN,l)){for(;e=l.pop();){if(e.name===c.name){e.closing=c;break}f=e.clone(),j.length&&f.children.push(z(j)),j.push(f)}for(o(z(j)),g=j.length;g--;)l.push(j[g]);j.length=0}else c.type=n.CONTENT,o(c);break;case n.NEWLINE:m()&&i&&p((i.type===n.CLOSE?"/":"")+i.name)&&(i.type===n.CLOSE&&i.name===m().name||(d=A.bbcodes[m().name],d&&d.breakAfter?l.pop():d&&d.isInline===!1&&A.opts.breakAfterBlock&&d.breakAfter!==!1&&l.pop())),o(c);break;default:o(c)}h=c}return k},m=function(a,b,c){var d,e,f,g,h,i,j,k,l=a.length;b&&(g=A.bbcodes[b.name]);for(var o=l;o--;)if(d=a[o])if(d.type===n.NEWLINE){if(e=o>0?a[o-1]:null,f=o1?c[c.length-2].children:e,i=a.inArray(h,j),i>-1))return k.children.splice(a.inArray(f,k.children),1),void j.splice(i+1,0,f,k);c.push(f),q(f.children,c,d||l(f),e),c.pop(f)}},t=function(a,b){for(var c,d,e=a.length;e--;)(c=a[e])&&(r(b,c)||(c.name=null,c.type=n.CONTENT,r(b,c)?(d=[e+1,0].concat(c.children),c.closing&&(c.closing.name=null,c.closing.type=n.CONTENT,d.push(c.closing)),e+=d.length-1,Array.prototype.splice.apply(a,d)):b.children.splice(e,1)),c.type===n.OPEN&&t(c.children,c))},s=function(b){for(var c,d,e=function(a){for(var b=a.length;b--;){var c=a[b].type;if(c===n.OPEN||c===n.CLOSE)return!1;if(c===n.CONTENT&&/\S|\u00A0/.test(a[b].val))return!1}return!0},f=b.length;f--;)(c=b[f])&&c.type===n.OPEN&&(d=A.bbcodes[c.name],s(c.children),e(c.children)&&d&&!d.isSelfClosing&&!d.allowsEmpty&&b.splice.apply(b,a.merge([f,1],c.children)))},A.toHTML=function(a,b){return u(A.parse(a,b),!0)},u=function(b,d){var g,j,k,l,m,o,p,q,r,s=[];for(q=function(a){return(!a||(a.isHtmlInline!==g?a.isHtmlInline:a.isInline))!==!1};b.length>0;)if(j=b.shift()){if(j.type===n.OPEN)r=j.children[j.children.length-1]||{},k=A.bbcodes[j.name],o=d&&q(k),l=u(j.children,!1),k&&k.html?(q(k)||!q(A.bbcodes[r.name])||k.isPreFormatted||k.skipLastLineBreak||i||(l+="
    "),a.isFunction(k.html)?m=k.html.call(A,j,j.attrs,l):(j.attrs[0]=l,m=e.bbcode.formatBBCodeString(k.html,j.attrs))):m=j.val+l+(j.closing?j.closing.val:"");else{if(j.type===n.NEWLINE){if(!d){s.push("
    ");continue}p||(s.push("

    "),(h<8||c.documentMode&&c.documentMode<8)&&s.push(" ")),i||s.push("
    "),b.length||s.push("
    "),s.push("
    \n"),p=!1;continue}o=d,m=f(j.val,!0)}o&&!p?(s.push("
    "),p=!0):!o&&p&&(s.push("
    \n"),p=!1),s.push(m)}return p&&s.push("
    \n"),s.join("")},A.toBBCode=function(a,b){return v(A.parse(a,b))},v=function(a){for(var b,c,d,e,f,g,h,i,j,k,l=[];a.length>0;)if(b=a.shift())if(d=A.bbcodes[b.name],e=!(!d||d.isInline!==!1),f=d&&d.isSelfClosing,h=e&&A.opts.breakBeforeBlock&&d.breakBefore!==!1||d&&d.breakBefore,i=e&&!f&&A.opts.breakStartBlock&&d.breakStart!==!1||d&&d.breakStart,j=e&&A.opts.breakEndBlock&&d.breakEnd!==!1||d&&d.breakEnd,k=e&&A.opts.breakAfterBlock&&d.breakAfter!==!1||d&&d.breakAfter,g=(d?d.quoteType:null)||A.opts.quoteType||p.QuoteType.auto,d||b.type!==n.OPEN)if(b.type===n.OPEN){if(h&&l.push("\n"),l.push("["+b.name),b.attrs){b.attrs.defaultattr&&(l.push("=",x(b.attrs.defaultattr,g,"defaultattr")),delete b.attrs.defaultattr);for(c in b.attrs)b.attrs.hasOwnProperty(c)&&l.push(" ",c,"=",x(b.attrs[c],g,c))}l.push("]"),i&&l.push("\n"),b.children&&l.push(v(b.children)),f||d.excludeClosing||(j&&l.push("\n"),l.push("[/"+b.name+"]")),k&&l.push("\n"),b.closing&&f&&l.push(b.closing.val)}else l.push(b.val);else l.push(b.val),b.children&&l.push(v(b.children)),b.closing&&l.push(b.closing.val);return l.join("")},x=function(b,c,d){var e=p.QuoteType,f=/\s|=/.test(b);return a.isFunction(c)?c(b,d):c===e.never||c===e.auto&&!f?b:'"'+b.replace("\\","\\\\").replace('"','\\"')+'"'},z=function(a){return a.length?a[a.length-1]:null},y=function(a){return a.toLowerCase()},d()};p.QuoteType={always:1,never:2,auto:3},p.defaults={breakBeforeBlock:!1,breakStartBlock:!1,breakEndBlock:!1,breakAfterBlock:!0,removeEmptyTags:!0,fixInvalidNesting:!0,fixInvalidChildren:!0,quoteType:p.QuoteType.auto},a.sceditorBBCodePlugin=e.bbcode=function(){var b,f,g,h,j=this;j.bbcodes=e.bbcode.bbcodes,j.stripQuotes=l;var n={},o={},q={ul:["li","ol","ul"],ol:["li","ol","ul"],table:["tr"],tr:["td","th"],code:["br","p","div"]};j.init=function(){j.opts=this.opts,b(),this.commands=a.extend(!0,{},k,this.commands),this.toBBCode=j.signalToSource,this.fromBBCode=j.signalToWysiwyg},b=function(){a.each(j.bbcodes,function(b){var c,d=j.bbcodes[b].tags,e=j.bbcodes[b].styles;d&&a.each(d,function(a,d){c=j.bbcodes[b].isInline===!1,n[a]=n[a]||{},n[a][c]=n[a][c]||{},n[a][c][b]=d}),e&&a.each(e,function(a,d){c=j.bbcodes[b].isInline===!1,o[c]=o[c]||{},o[c][a]=o[c][a]||{},o[c][a][b]=d})})},f=function(b,c,e){var f,g,h=d.dom.getStyle;return e=!!e,o[e]?(a.each(o[e],function(d,e){f=h(b[0],d),f&&h(b.parent()[0],d)!==f&&a.each(e,function(d,e){(!e||a.inArray(f.toString(),e)>-1)&&(g=j.bbcodes[d].format,c=a.isFunction(g)?g.call(j,b,c):m(g,c))})}),c):c},g=function(b,c,e){var f,g,h=b[0],k=h.nodeName.toLowerCase();e=!!e,n[k]&&n[k][e]&&a.each(n[k][e],function(d,e){e&&(f=!1,a.each(e,function(c,d){if(b.attr(c)&&!(d&&a.inArray(b.attr(c),d)<0))return f=!0,!1}),!f)||(g=j.bbcodes[d].format,c=a.isFunction(g)?g.call(j,b,c):m(g,c))});var l=d.dom.isInline;if(e&&(!l(h,!0)||"br"===k)){for(var o,p,q,r=h.previousSibling;r&&1===r.nodeType&&!a(r).is("br")&&l(r,!0)&&!r.firstChild;)r=r.previousSibling;do p=h.parentNode,q=p.lastChild,o=q===h,h=p;while(p&&o&&l(p,!0));(!o||"li"===k||"br"===k&&i)&&(c+="\n"),"br"!==k&&r&&!a(r).is("br")&&l(r,!0)&&(c="\n"+c)}return c},j.signalToSource=function(b,e){var f,g,h=new p(j.opts.parserOptions);return e||("string"==typeof b?(f=a("
    ").css("visibility","hidden").appendTo(c.body).html(b),e=f):e=a(b)),e&&e.jquery?(d.dom.removeWhiteSpace(e[0]),a(".sceditor-ignore",e).remove(),g=j.elementToBbcode(e),f&&f.remove(),g=h.toBBCode(g,!0),j.opts.bbcodeTrim&&(g=a.trim(g)),g):""},j.elementToBbcode=function(b){var c=function(b,e){var h="";return d.dom.traverse(b,function(b){var d=a(b),j="",k=b.nodeType,l=b.nodeName.toLowerCase(),m=q[l],n=b.firstChild,o=!0;if("object"==typeof e&&(o=a.inArray(l,e)>-1,d.is("img")&&d.data("sceditor-emoticon")&&(o=!0),o||(m=e)),3===k||1===k)if(1===k){if(d.hasClass("sceditor-nlf")&&(!n||!i&&1===b.childNodes.length&&/br/i.test(n.nodeName)))return;"iframe"!==l&&(j=c(b,m)),o?("code"!==l&&(j=f(d,j),j=g(d,j),j=f(d,j,!0)),h+=g(d,j,!0)):h+=j}else h+=b.nodeValue},!1,!0),h};return c(b[0])},j.signalToWysiwyg=function(b,c){var d=new p(j.opts.parserOptions),e=d.toHTML(j.opts.bbcodeTrim?a.trim(b):b);return c?h(e):e},h=function(b){var e,f,g,h=a("
    ").hide().appendTo(c.body),j=h[0];return g=function(b,e){if(!d.dom.hasStyling(b)){if(i||1!==b.childNodes.length||!a(b.firstChild).is("br"))for(;f=b.firstChild;)j.insertBefore(f,b);if(e){var g=j.lastChild;b!==g&&a(g).is("div")&&b.nextSibling===g&&j.insertBefore(c.createElement("br"),b)}j.removeChild(b)}},j.innerHTML=b.replace(/<\/div>\n/g,"
    "),(e=j.firstChild)&&a(e).is("div")&&g(e,!0),(e=j.lastChild)&&a(e).is("div")&&g(e),j=j.innerHTML,h.remove(),j}},e.bbcode.formatBBCodeString=function(a,b){return a.replace(/\{([^}]+)\}/g,function(a,c){var d,e=!0;return"!"===c.charAt(0)&&(e=!1,c=c.substring(1)),"0"===c&&(e=!1),b[c]===d?a:e?f(b[c],!0):b[c]})};var q=function(a){return a=parseInt(a,10),isNaN(a)?"00":(a=Math.max(0,Math.min(a,255)).toString(16),a.length<2?"0"+a:a)},r=function(a){var b;return a=a||"#000",(b=a.match(/rgb\((\d{1,3}),\s*?(\d{1,3}),\s*?(\d{1,3})\)/i))?"#"+q(b[1])+q(b[2]-0)+q(b[3]-0):(b=a.match(/#([0-f])([0-f])([0-f])\s*?$/i))?"#"+b[1]+b[1]+b[2]+b[2]+b[3]+b[3]:a},s={b:{tags:{b:null,strong:null},styles:{"font-weight":["bold","bolder","401","700","800","900"]},format:"[b]{0}[/b]",html:"{0}"},i:{tags:{i:null,em:null},styles:{"font-style":["italic","oblique"]},format:"[i]{0}[/i]",html:"{0}"},u:{tags:{u:null},styles:{"text-decoration":["underline"]},format:"[u]{0}[/u]",html:"{0}"},s:{tags:{s:null,strike:null},styles:{"text-decoration":["line-through"]},format:"[s]{0}[/s]",html:"{0}"},sub:{tags:{sub:null},format:"[sub]{0}[/sub]",html:"{0}"},sup:{tags:{sup:null},format:"[sup]{0}[/sup]",html:"{0}"},font:{tags:{font:{face:null}},styles:{"font-family":null},quoteType:p.QuoteType.never,format:function(a,b){var c;return a.is("font")&&(c=a.attr("face"))||(c=a.css("font-family")),"[font="+l(c)+"]"+b+"[/font]"},html:'{0}'},size:{tags:{font:{size:null}},styles:{"font-size":null},format:function(a,b){var c=a.attr("size"),d=2;return c||(c=a.css("fontSize")),c.indexOf("px")>-1?(c=c.replace("px","")-0,c<12&&(d=1),c>15&&(d=3),c>17&&(d=4),c>23&&(d=5),c>31&&(d=6),c>47&&(d=7)):d=c,"[size="+d+"]"+b+"[/size]"},html:'{!0}'},color:{tags:{font:{color:null}},styles:{color:null},quoteType:p.QuoteType.never,format:function(a,b){var c;return a.is("font")&&(c=a.attr("color"))||(c=a[0].style.color||a.css("color")),"[color="+r(c)+"]"+b+"[/color]"},html:function(a,b,c){return''+c+""}},ul:{tags:{ul:null},breakStart:!0,isInline:!1,skipLastLineBreak:!0,format:"[ul]{0}[/ul]",html:"
      {0}
    "},list:{breakStart:!0,isInline:!1,skipLastLineBreak:!0,html:"
      {0}
    "},ol:{tags:{ol:null},breakStart:!0,isInline:!1,skipLastLineBreak:!0,format:"[ol]{0}[/ol]",html:"
      {0}
    "},li:{tags:{li:null},isInline:!1,closedBy:["/ul","/ol","/list","*","li"],format:"[li]{0}[/li]",html:"
  • {0}
  • "},"*":{isInline:!1,closedBy:["/ul","/ol","/list","*","li"],html:"
  • {0}
  • "},table:{tags:{table:null},isInline:!1,isHtmlInline:!0,skipLastLineBreak:!0,format:"[table]{0}[/table]",html:"{0}
    "},tr:{tags:{tr:null},isInline:!1,skipLastLineBreak:!0,format:"[tr]{0}[/tr]",html:"{0}"},th:{tags:{th:null},allowsEmpty:!0,isInline:!1,format:"[th]{0}[/th]",html:"{0}"},td:{tags:{td:null},allowsEmpty:!0,isInline:!1,format:"[td]{0}[/td]",html:"{0}"},emoticon:{allowsEmpty:!0,tags:{img:{src:null,"data-sceditor-emoticon":null}},format:function(a,b){return a.data("sceditor-emoticon")+b},html:"{0}"},hr:{tags:{hr:null},allowsEmpty:!0,isSelfClosing:!0,isInline:!1,format:"[hr]{0}",html:"
    "},img:{allowsEmpty:!0,tags:{img:{src:null}},allowedChildren:["#"],quoteType:p.QuoteType.never,format:function(a,b){var c,d,e="",f=a[0],g=function(a){return f.style?f.style[a]:null};return a.attr("data-sceditor-emoticon")?b:(c=a.attr("width")||g("width"),d=a.attr("height")||g("height"),(f.complete&&(c||d)||c&&d)&&(e="="+a.width()+"x"+a.height()),"[img"+e+"]"+a.attr("src")+"[/img]")},html:function(a,b,c){var d,e,h,i,j="";return e=b.width,h=b.height,b.defaultattr&&(i=b.defaultattr.split(/x/i),e=i[0],h=2===i.length?i[1]:i[0]),e!==d&&(j+=' width="'+f(e,!0)+'"'),h!==d&&(j+=' height="'+f(h,!0)+'"'),"'}},url:{allowsEmpty:!0,tags:{a:{href:null}},quoteType:p.QuoteType.never,format:function(a,b){var c=a.attr("href");return"mailto:"===c.substr(0,7)?'[email="'+c.substr(7)+'"]'+b+"[/email]":"[url="+c+"]"+b+"[/url]"},html:function(a,b,c){return b.defaultattr=f(b.defaultattr,!0)||c,''+c+""}},email:{quoteType:p.QuoteType.never,html:function(a,b,c){return''+c+""}},quote:{tags:{blockquote:null},isInline:!1,quoteType:p.QuoteType.never,format:function(b,c){var d="",e=a(b),f=e.children("cite").first();return(1===f.length||e.data("author"))&&(d=f.text()||e.data("author"),e.data("author",d),f.remove(),c=this.elementToBbcode(a(b)),d="="+d.replace(/(^\s+|\s+$)/g,""),e.prepend(f)),"[quote"+d+"]"+c+"[/quote]"},html:function(a,b,c){return b.defaultattr&&(c=""+f(b.defaultattr)+""+c),"
    "+c+"
    "}},code:{tags:{code:null},isInline:!1,allowedChildren:["#","#newline"],format:"[code]{0}[/code]",html:"{0}"},left:{styles:{"text-align":["left","-webkit-left","-moz-left","-khtml-left"]},isInline:!1,format:"[left]{0}[/left]",html:'
    {0}
    '},center:{styles:{"text-align":["center","-webkit-center","-moz-center","-khtml-center"]},isInline:!1,format:"[center]{0}[/center]",html:'
    {0}
    '},right:{styles:{"text-align":["right","-webkit-right","-moz-right","-khtml-right"]},isInline:!1,format:"[right]{0}[/right]",html:'
    {0}
    '},justify:{styles:{"text-align":["justify","-webkit-justify","-moz-justify","-khtml-justify"]},isInline:!1,format:"[justify]{0}[/justify]",html:'
    {0}
    '},youtube:{allowsEmpty:!0,tags:{iframe:{"data-youtube-id":null}},format:function(a,b){return a=a.attr("data-youtube-id"),a?"[youtube]"+a+"[/youtube]":b},html:''},rtl:{styles:{direction:["rtl"]},format:"[rtl]{0}[/rtl]",html:'
    {0}
    '},ltr:{styles:{direction:["ltr"]},format:"[ltr]{0}[/ltr]",html:'
    {0}
    '},ignore:{}};e.bbcode.bbcode={get:function(a){return s[a]||null},set:function(b,c){return!(!b||!c)&&(c=a.extend(s[b]||{},c),c.remove=function(){delete s[b]},s[b]=c,this)},rename:function(a,b){return a in s&&(s[b]=s[a],delete s[a],this)},remove:function(a){return a in s&&delete s[a],this}},a.fn.sceditorBBCodePlugin=function(b){return b=b||{},a.isPlainObject(b)&&(b.plugins=(b.plugins||"")+"bbcode"),this.sceditor(b)},e.bbcode.normaliseColour=r,e.bbcode.formatString=m,e.bbcode.stripQuotes=l,e.bbcode.bbcodes=s,d.BBCodeParser=p}(jQuery,window,document); \ No newline at end of file diff --git a/js/sceditor/minified/plugins/format.js b/js/sceditor/minified/plugins/format.js new file mode 100644 index 00000000..233c8f59 --- /dev/null +++ b/js/sceditor/minified/plugins/format.js @@ -0,0 +1,2 @@ +/* SCEditor v1.5.2 | (C) 2016, Sam Clarke | sceditor.com/license */ +!function(a){"use strict";a.sceditor.plugins.format=function(){var b,c,d=this,e={p:"Paragraph",h1:"Heading 1",h2:"Heading 2",h3:"Heading 3",h4:"Heading 4",h5:"Heading 5",h6:"Heading 6",address:"Address",pre:"Preformatted Text"};d.init=function(){var b=this.opts,d=b.paragraphformat;b.plugins&&b.plugins.indexOf("bbcode")>-1||(d&&(d.tags&&(e=d.tags),d.excludeTags&&a.each(d.excludeTags,function(a,b){delete e[b]})),this.commands.format||(this.commands.format={exec:c,txtExec:c,tooltip:"Format Paragraph"}),b.toolbar===a.sceditor.defaultOptions.toolbar&&(b.toolbar=b.toolbar.replace(",color,",",color,format,")))},b=function(a,b){a.sourceMode()?a.insert("<"+b+">",""):a.execCommand("formatblock","<"+b+">")},c=function(c){var d=this,f=a("
    ");a.each(e,function(c,e){a(''+(e.name||e)+"").click(function(){return d.closeDropDown(!0),e.exec?e.exec(d):b(d,c),!1}).appendTo(f)}),d.createDropDown(c,"format",f)}}}(jQuery); \ No newline at end of file diff --git a/js/sceditor/minified/plugins/undo.js b/js/sceditor/minified/plugins/undo.js new file mode 100644 index 00000000..5ccc6e59 --- /dev/null +++ b/js/sceditor/minified/plugins/undo.js @@ -0,0 +1,2 @@ +/* SCEditor v1.5.2 | (C) 2016, Sam Clarke | sceditor.com/license */ +!function(a){"use strict";a.sceditor.plugins.undo=function(){var a,b,c=this,d=0,e=50,f=[],g=[],h=!1,i=function(c){h=!0,b=c.value,a.sourceMode(c.sourceMode),a.val(c.value,!1),a.focus(),c.sourceMode?a.sourceEditorCaret(c.caret):a.getRangeHelper().restoreRange(),h=!1},j=function(a,b){var c,d,e,f,g=a.length,h=b.length,i=Math.max(g,h);for(c=0;c=0&&a.charAt(d-e)===b.charAt(d-f);d--);return d-c+1};c.init=function(){a=this,e=a.undoLimit||e,a.addShortcut("ctrl+z",c.undo),a.addShortcut("ctrl+shift+z",c.redo),a.addShortcut("ctrl+y",c.redo)},c.undo=function(){var b=g.pop(),c=a.val(null,!1);return b&&!f.length&&c===b.value&&(b=g.pop()),b&&(f.length||f.push({caret:a.sourceEditorCaret(),sourceMode:a.sourceMode(),value:c}),f.push(b),i(b)),!1},c.redo=function(){var a=f.pop();return g.length||(g.push(a),a=f.pop()),a&&(g.push(a),i(a)),!1},c.signalReady=function(){var c=a.val(null,!1);b=c,g.push({caret:this.sourceEditorCaret(),sourceMode:this.sourceMode(),value:c})},c.signalValuechangedEvent=function(c){var i=c.rawValue;e>0&&g.length>e&&g.shift(),!h&&b&&b!==i&&(f.length=0,d+=j(b,i),d<20||d<50&&!/\s$/g.test(c.rawValue)||(g.push({caret:a.sourceEditorCaret(),sourceMode:a.sourceMode(),value:i}),d=0,b=i))}}}(jQuery); \ No newline at end of file diff --git a/js/sceditor/minified/plugins/xhtml.js b/js/sceditor/minified/plugins/xhtml.js new file mode 100644 index 00000000..94552c4a --- /dev/null +++ b/js/sceditor/minified/plugins/xhtml.js @@ -0,0 +1,2 @@ +/* SCEditor v1.5.2 | (C) 2016, Sam Clarke | sceditor.com/license */ +!function(a){"use strict";var b=a.sceditor,c=b.plugins,d=b.dom,e={bold:{txtExec:["",""]},italic:{txtExec:["",""]},underline:{txtExec:['',""]},strike:{txtExec:['',""]},subscript:{txtExec:["",""]},superscript:{txtExec:["",""]},left:{txtExec:['
    ',"
    "]},center:{txtExec:['
    ',"
    "]},right:{txtExec:['
    ',"
    "]},justify:{txtExec:['
    ',"
    "]},font:{txtExec:function(a){var c=this;b.command.get("font")._dropDown(c,a,function(a){c.insertText('',"")})}},size:{txtExec:function(a){var c=this;b.command.get("size")._dropDown(c,a,function(a){c.insertText('',"")})}},color:{txtExec:function(a){var c=this;b.command.get("color")._dropDown(c,a,function(a){c.insertText('',"")})}},bulletlist:{txtExec:["
    • ","
    "]},orderedlist:{txtExec:["
    1. ","
    "]},table:{txtExec:["
    ","
    "]},horizontalrule:{txtExec:["
    "]},code:{txtExec:["",""]},image:{txtExec:function(a,b){var c=prompt(this._("Enter the image URL:"),b);c&&this.insertText('')}},email:{txtExec:function(a,b){var c,d,e=b&&b.indexOf("@")>-1?null:b;c=prompt(this._("Enter the e-mail address:"),e?"":b),d=prompt(this._("Enter the displayed text:"),e||c)||c,c&&this.insertText(''+d+"")}},link:{txtExec:function(a,b){var c=b&&b.indexOf("http://")>-1?null:b,d=prompt(this._("Enter URL:"),c?"http://":b),e=prompt(this._("Enter the displayed text:"),c||d)||d;d&&this.insertText(''+e+"")}},quote:{txtExec:["
    ","
    "]},youtube:{txtExec:function(a){var c=this;b.command.get("youtube")._dropDown(c,a,function(a){c.insertText('')})}},rtl:{txtExec:['
    ',"
    "]},ltr:{txtExec:['
    ',"
    "]}};b.XHTMLSerializer=function(){var c,e,f,g,h,i,j,k,l,m,n=this,o={indentStr:"\t"},p=[],q=0;c=function(a){var b={"&":"&","<":"<",">":">",'"':"""};return a?a.replace(/[&<>"]/g,function(a){return b[a]||a}):""},e=function(a){return a.replace(/[\r\n]/," ").replace(/[^\S|\u00A0]+/g," ")},n.serialize=function(a,b){if(p=[],b)for(a=a.firstChild;a;)f(a),a=a.nextSibling;else f(a);return p.join("")},f=function(a,b){switch(a.nodeType){case 1:var c=a.nodeName.toLowerCase();"!"===c?j(a):h(a,b);break;case 3:k(a,b);break;case 4:i(a);break;case 8:j(a);break;case 9:case 11:g(a);break;case 2:case 5:case 6:case 7:case 10:case 12:}},g=function(a){for(var b=a.firstChild;b;)f(b),b=b.nextSibling},h=function(e,g){var h,i,j,k=e.nodeName.toLowerCase(),n="iframe"===k,o=e.attributes.length,p=e.firstChild,r=g||/pre(?:\-wrap)?$/i.test(a(e).css("whiteSpace")),s=!e.firstChild&&!d.canHaveChildren(e)&&!n;if(!a(e).hasClass("sceditor-ignore")){for(l("<"+k,!g&&m(e));o--;)i=e.attributes[o],(!b.ie||i.specified||"input"===k&&"value"===i.name)&&(j=b.ie<8&&/style/i.test(i.name)?e.style.cssText:i.value,l(" "+i.name.toLowerCase()+'="'+c(j)+'"',!1));for(l(s?" />":">",!1),n||(h=p);h;)q++,f(h,r),h=h.nextSibling,q--;s||l("",!r&&!n&&m(e)&&p&&m(p))}},i=function(a){l("")},j=function(a){l("")},k=function(a,b){var d=a.nodeValue;b||(d=e(d)),d&&l(c(d),!b&&m(a))},l=function(a,b){var c=q;if(b!==!1)for(p.length&&p.push("\n");c--;)p.push(o.indentStr);p.push(a)},m=function(a){var b=a.previousSibling;return 1!==a.nodeType&&b?!d.isInline(b):!b&&!d.isInline(a.parentNode)||!d.isInline(a)}},c.xhtml=function(){var f,g,h,i,j,k,l,m=this,n={},o={};m.init=function(){a.isEmptyObject(c.xhtml.converters||{})||a.each(c.xhtml.converters,function(b,c){a.each(c.tags,function(a){n[a]||(n[a]=[]),n[a].push(c)})}),this.commands=a.extend(!0,{},e,this.commands)},m.signalToSource=function(a,c){return c=c.jquery?c[0]:c,f(c),i(c),k(c),l(c),(new b.XHTMLSerializer).serialize(c,!0)},m.signalToWysiwyg=function(a){return a},m.convertTagTo=d.convertElement,g=function(c,d,e){n[c]&&a.each(n[c],function(f,g){g.tags[c]?a.each(g.tags[c],function(c,f){e.getAttributeNode&&(c=e.getAttributeNode(c),!c||b.ie<8&&!c.specified||f&&a.inArray(c.value,f)<0||g.conv.call(m,e,d))}):g.conv&&g.conv.call(m,e,d)})},f=function(b){d.traverse(b,function(b){var c=a(b),d=b.nodeName.toLowerCase();g("*",c,b),g(d,c,b)},!0)},h=function(b,c){var e=b.childNodes,f=b.nodeName.toLowerCase(),g=b.nodeValue,i=e.length;if(c&&"br"===f)return!0;if(a(b).hasClass("sceditor-ignore"))return!0;if(!d.canHaveChildren(b))return!1;if(g&&/\S|\u00A0/.test(g))return!1;for(;i--;)if(!h(e[i],c&&!b.previousSibling&&!b.nextSibling))return!1;return!0},i=function(b){d.traverse(b,function(e){var f,g=e.nodeName.toLowerCase(),i=e.parentNode,j=e.nodeType,k=!d.isInline(e),l=e.previousSibling,m=e.nextSibling,n=i===b,o=!l&&!m,p="iframe"!==g&&h(e,n&&o&&"br"!==g),q=e.ownerDocument,r=c.xhtml.allowedTags,s=c.xhtml.disallowedTags;if(3!==j&&(4===j?g="!cdata":"!"!==g&&8!==j||(g="!comment"),p?f=!0:r&&r.length?f=a.inArray(g,r)<0:s&&s.length&&(f=a.inArray(g,s)>-1),f)){if(!p){for(k&&l&&d.isInline(l)&&i.insertBefore(q.createTextNode(" "),e);e.firstChild;)i.insertBefore(e.firstChild,m);k&&m&&d.isInline(m)&&i.insertBefore(q.createTextNode(" "),m)}i.removeChild(e)}},!0)},j=function(b,c){var d={};return b&&a.extend(d,b),c?(a.each(c,function(b,c){a.isArray(c)?d[b]=a.merge(d[b]||[],c):d[b]||(d[b]=null)}),d):d},l=function(b){var c=[],e=function(){c.length&&(a("

    ",b.ownerDocument).insertBefore(c[0]).append(c),c=[])};d.removeWhiteSpace(b);for(var f=b.firstChild;f;)d.isInline(f)&&!a(f).is(".sceditor-ignore")?c.push(f):e(),f=f.nextSibling;e()},k=function(b){var e,f,g,h,i,k,l=c.xhtml.allowedAttribs,m=l&&!a.isEmptyObject(l),n=c.xhtml.disallowedAttribs,p=n&&!a.isEmptyObject(n);o={},d.traverse(b,function(b){if(b.attributes&&(e=b.nodeName.toLowerCase(),h=b.attributes.length))for(o[e]||(m?o[e]=j(l["*"],l[e]):o[e]=j(n["*"],n[e]));h--;)f=b.attributes[h],g=f.name,i=o[e][g],k=!1,m?k=null!==i&&(!a.isArray(i)||a.inArray(f.value,i)<0):p&&(k=null===i||a.isArray(i)&&a.inArray(f.value,i)>-1),k&&b.removeAttribute(g)})}},c.xhtml.converters=[{tags:{"*":{width:null}},conv:function(a,b){b.css("width",b.attr("width")).removeAttr("width")}},{tags:{"*":{height:null}},conv:function(a,b){b.css("height",b.attr("height")).removeAttr("height")}},{tags:{li:{value:null}},conv:function(a,c){b.ie<8?a.removeAttribute("value"):c.removeAttr("value")}},{tags:{"*":{text:null}},conv:function(a,b){b.css("color",b.attr("text")).removeAttr("text")}},{tags:{"*":{color:null}},conv:function(a,b){b.css("color",b.attr("color")).removeAttr("color")}},{tags:{"*":{face:null}},conv:function(a,b){b.css("fontFamily",b.attr("face")).removeAttr("face")}},{tags:{"*":{align:null}},conv:function(a,b){b.css("textAlign",b.attr("align")).removeAttr("align")}},{tags:{"*":{border:null}},conv:function(a,b){b.css("borderWidth",b.attr("border")).removeAttr("border")}},{tags:{applet:{name:null},img:{name:null},layer:{name:null},map:{name:null},object:{name:null},param:{name:null}},conv:function(a,b){b.attr("id")||b.attr("id",b.attr("name")),b.removeAttr("name")}},{tags:{"*":{vspace:null}},conv:function(a,b){b.css("marginTop",b.attr("vspace")-0).css("marginBottom",b.attr("vspace")-0).removeAttr("vspace")}},{tags:{"*":{hspace:null}},conv:function(a,b){b.css("marginLeft",b.attr("hspace")-0).css("marginRight",b.attr("hspace")-0).removeAttr("hspace")}},{tags:{hr:{noshade:null}},conv:function(a,b){b.css("borderStyle","solid").removeAttr("noshade")}},{tags:{"*":{nowrap:null}},conv:function(a,b){b.css("white-space","nowrap").removeAttr("nowrap")}},{tags:{big:null},conv:function(b){a(this.convertTagTo(b,"span")).css("fontSize","larger")}},{tags:{small:null},conv:function(b){a(this.convertTagTo(b,"span")).css("fontSize","smaller")}},{tags:{b:null},conv:function(b){a(this.convertTagTo(b,"strong"))}},{tags:{u:null},conv:function(b){a(this.convertTagTo(b,"span")).css("textDecoration","underline")}},{tags:{i:null},conv:function(b){a(this.convertTagTo(b,"em"))}},{tags:{s:null,strike:null},conv:function(b){a(this.convertTagTo(b,"span")).css("textDecoration","line-through")}},{tags:{dir:null},conv:function(a){this.convertTagTo(a,"ul")}},{tags:{center:null},conv:function(b){a(this.convertTagTo(b,"div")).css("textAlign","center")}},{tags:{font:{size:null}},conv:function(a,c){var d=c.css("fontSize"),e=d;"+0"!==e&&(b.ie<9&&(e=10,d>1&&(e=13),d>2&&(e=16),d>3&&(e=18),d>4&&(e=24),d>5&&(e=32),d>6&&(e=48)),c.css("fontSize",e)),c.removeAttr("size")}},{tags:{font:null},conv:function(a){this.convertTagTo(a,"span")}},{tags:{"*":{type:["_moz"]}},conv:function(a,b){b.removeAttr("type")}},{tags:{"*":{_moz_dirty:null}},conv:function(a,b){b.removeAttr("_moz_dirty")}},{tags:{"*":{_moz_editor_bogus_node:null}},conv:function(a,b){b.remove()}}],c.xhtml.allowedAttribs={},c.xhtml.disallowedAttribs={},c.xhtml.allowedTags=[],c.xhtml.disallowedTags=[]}(jQuery); \ No newline at end of file diff --git a/js/sceditor/minified/themes/default.min.css b/js/sceditor/minified/themes/default.min.css new file mode 100644 index 00000000..d3eaca63 --- /dev/null +++ b/js/sceditor/minified/themes/default.min.css @@ -0,0 +1 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */.sceditor-button div,div.sceditor-grip{background-image:url(famfamfam.png);background-repeat:no-repeat;width:16px;height:16px}.sceditor-button-youtube div{background-position:0 0}.sceditor-button-link div{background-position:0 -16px}.sceditor-button-unlink div{background-position:0 -32px}.sceditor-button-underline div{background-position:0 -48px}.sceditor-button-time div{background-position:0 -64px}.sceditor-button-table div{background-position:0 -80px}.sceditor-button-superscript div{background-position:0 -96px}.sceditor-button-subscript div{background-position:0 -112px}.sceditor-button-strike div{background-position:0 -128px}.sceditor-button-source div{background-position:0 -144px}.sceditor-button-size div{background-position:0 -160px}.sceditor-button-rtl div{background-position:0 -176px}.sceditor-button-right div{background-position:0 -192px}.sceditor-button-removeformat div{background-position:0 -208px}.sceditor-button-quote div{background-position:0 -224px}.sceditor-button-print div{background-position:0 -240px}.sceditor-button-pastetext div{background-position:0 -256px}.sceditor-button-paste div{background-position:0 -272px}.sceditor-button-outdent div{background-position:0 -288px}.sceditor-button-orderedlist div{background-position:0 -304px}.sceditor-button-maximize div{background-position:0 -320px}.sceditor-button-ltr div{background-position:0 -336px}.sceditor-button-left div{background-position:0 -352px}.sceditor-button-justify div{background-position:0 -368px}.sceditor-button-italic div{background-position:0 -384px}.sceditor-button-indent div{background-position:0 -400px}.sceditor-button-image div{background-position:0 -416px}.sceditor-button-horizontalrule div{background-position:0 -432px}.sceditor-button-format div{background-position:0 -448px}.sceditor-button-font div{background-position:0 -464px}.sceditor-button-emoticon div{background-position:0 -480px}.sceditor-button-email div{background-position:0 -496px}.sceditor-button-date div{background-position:0 -512px}.sceditor-button-cut div{background-position:0 -528px}.sceditor-button-copy div{background-position:0 -544px}.sceditor-button-color div{background-position:0 -560px}.sceditor-button-code div{background-position:0 -576px}.sceditor-button-center div{background-position:0 -592px}.sceditor-button-bulletlist div{background-position:0 -608px}.sceditor-button-bold div{background-position:0 -624px}div.sceditor-grip{background-position:0 -640px}.rtl div.sceditor-grip{background-position:0 -650px;width:10px;height:10px}.sceditor-container{position:relative;background:#fff;border:1px solid #d9d9d9;font-size:13px;font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;color:#222;line-height:1;font-weight:700;border-radius:4px;background-clip:padding-box}.sceditor-container *,.sceditor-container :after,.sceditor-container :before{box-sizing:content-box}.sceditor-container,.sceditor-container div,div.sceditor-dropdown,div.sceditor-dropdown div{padding:0;margin:0;z-index:3}.sceditor-container iframe,.sceditor-container textarea{line-height:1;border:0;outline:0;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:13px;color:#111;padding:0;margin:5px;resize:none;background:#fff;display:block}div.sceditor-resize-cover{position:absolute;top:0;left:0;background:#000;width:100%;height:100%;z-index:10;opacity:.3}.ie6 div.sceditor-resize-cover,.ie7 div.sceditor-resize-cover,.ie8 div.sceditor-resize-cover{background:#efefef}.sceditor-maximize,.sceditor-maximize div.sceditor-toolbar{border-radius:0;background-clip:padding-box}.sceditor-container.ie6{overflow:hidden}div.sceditor-grip{overflow:hidden;width:10px;height:10px;cursor:pointer;position:absolute;bottom:0;right:0;z-index:3}.sceditor-maximize{position:fixed;top:0;left:0;height:100%!important;width:100%!important;z-index:2000}body.sceditor-maximize,html.sceditor-maximize{height:100%;width:100%;padding:0;margin:0;overflow:hidden}.ie6.sceditor-maximize{position:absolute}.sceditor-maximize div.sceditor-grip{display:none}div.sceditor-dropdown{position:absolute;border:1px solid #ccc;background:#fff;color:#333;z-index:4000;padding:10px;line-height:1;border-radius:2px;background-clip:padding-box;box-shadow:1px 2px 4px rgba(0,0,0,.2)}div.sceditor-dropdown a,div.sceditor-dropdown a:link{color:#333}div.sceditor-dropdown form{margin:0}div.sceditor-dropdown label{display:block;font-weight:700;color:#3c3c3c;padding:4px 0}div.sceditor-dropdown input,div.sceditor-dropdown textarea{font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;outline:0;padding:4px;border:1px solid #ccc;border-top-color:#888;margin:0 0 .75em;border-radius:1px;background-clip:padding-box}div.sceditor-dropdown textarea{padding:6px}div.sceditor-dropdown input:focus,div.sceditor-dropdown textarea:focus{border-color:#666 #aaa #aaa;box-shadow:inset 0 1px 5px rgba(0,0,0,.1)}div.sceditor-dropdown .button{font-weight:700;color:#444;padding:6px 12px;background:#ececec;border:1px solid #ccc;border-radius:2px;background-clip:padding-box;cursor:pointer;margin:.3em 0 0}div.sceditor-dropdown .button:hover{background:#f3f3f3;box-shadow:0 1px 1px rgba(0,0,0,.15)}div.sceditor-font-picker,div.sceditor-fontsize-picker,div.sceditor-format{padding:6px 0}div.sceditor-color-picker,div.sceditor-emoticons,div.sceditor-more-emoticons{padding:0}.sceditor-pastetext textarea{border:1px solid #bbb;width:20em}.sceditor-emoticons img,.sceditor-more-emoticons img{padding:0;cursor:pointer;margin:2px}.sceditor-more{border-top:1px solid #bbb;display:block;text-align:center;cursor:pointer;font-weight:700;padding:6px 0}.sceditor-dropdown a:hover{background:#eee}.sceditor-font-option,.sceditor-fontsize-option,.sceditor-format a{display:block;padding:7px 10px;cursor:pointer;text-decoration:none;color:#222}.sceditor-fontsize-option{padding:7px 13px}.sceditor-color-column{float:left}.sceditor-color-option{display:block;border:1px solid #fff;height:10px;width:10px;overflow:hidden}.sceditor-color-option:hover{border:1px solid #333}div.sceditor-toolbar{overflow:hidden;padding:3px 5px 2px;background:#f7f7f7;border-bottom:1px solid silver;line-height:0;text-align:left;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:3px 3px 0 0;background-clip:padding-box}div.sceditor-group{display:inline-block;background:#ddd;margin:1px 5px 1px 0;padding:1px;border-bottom:1px solid #aaa;border-radius:3px;background-clip:padding-box}.ie6 div.sceditor-group,.ie7 div.sceditor-group{display:inline;zoom:1}.sceditor-button{float:left;cursor:pointer;padding:3px 5px;width:16px;height:20px;border-radius:3px;background-clip:padding-box;text-indent:-9999px}.ie .sceditor-button{text-indent:0}.ie6 .sceditor-button,.ie7 .sceditor-button{float:none!important;display:inline;zoom:1}.ie6 .sceditor-button{padding:0}.ie6 .sceditor-button div{margin:5px}.ie7 .sceditor-button div{margin:5px 0}.sceditor-button.active,.sceditor-button:active,.sceditor-button:hover{background:#fff;box-shadow:inset 1px 1px 0 rgba(0,0,0,.3),inset -1px 0 rgba(0,0,0,.3),inset 0 -1px 0 rgba(0,0,0,.2)}.sceditor-button:active{background:#fff;box-shadow:inset 1px 1px 0 rgba(0,0,0,.3),inset -1px 0 rgba(0,0,0,.3),inset 0 -1px 0 rgba(0,0,0,.2),inset 0 0 8px rgba(0,0,0,.3)}.sceditor-button.disabled:hover{background:inherit;cursor:default;box-shadow:none}.sceditor-button,.sceditor-button div{display:block}.sceditor-button div{margin:2px 0;padding:0;overflow:hidden;line-height:0;font-size:0;color:transparent}.sceditor-button.disabled div{filter:alpha(opacity=30);opacity:.3}.sceditor-button.text,.sceditor-button.text div,.sceditor-button.text-icon,.sceditor-button.text-icon div,.text .sceditor-button,.text .sceditor-button div,.text-icon .sceditor-button,.text-icon .sceditor-button div{width:auto;overflow:visible;line-height:16px;font-size:1em;color:inherit;text-indent:0}.sceditor-button.text div,.text .sceditor-button div{padding:0 2px;background:0 0}.sceditor-button.text-icon div,.text-icon .sceditor-button div{padding:0 2px 0 20px}.rtl div.sceditor-toolbar{text-align:right}.rtl .sceditor-button{float:right}.rtl div.sceditor-grip{right:auto;left:0} \ No newline at end of file diff --git a/js/sceditor/minified/themes/famfamfam.png b/js/sceditor/minified/themes/famfamfam.png new file mode 100644 index 0000000000000000000000000000000000000000..c95ef4acda121fdda34d1944ca54d973ffa80718 GIT binary patch literal 11682 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 literal 0 HcmV?d00001 diff --git a/js/sceditor/minified/themes/monocons/monocons.ttf b/js/sceditor/minified/themes/monocons/monocons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d100abdf72a460aa813066000555d43240e47ded GIT binary patch literal 7860 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 aEObwBt`HleB`z_7y|Zxc`vPwKX8Ru)Dfl)3 literal 0 HcmV?d00001 diff --git a/js/sceditor/minified/themes/office-toolbar.min.css b/js/sceditor/minified/themes/office-toolbar.min.css new file mode 100644 index 00000000..70811a29 --- /dev/null +++ b/js/sceditor/minified/themes/office-toolbar.min.css @@ -0,0 +1 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */.sceditor-button div,div.sceditor-grip{background-image:url(famfamfam.png);background-repeat:no-repeat;width:16px;height:16px}.sceditor-button-youtube div{background-position:0 0}.sceditor-button-link div{background-position:0 -16px}.sceditor-button-unlink div{background-position:0 -32px}.sceditor-button-underline div{background-position:0 -48px}.sceditor-button-time div{background-position:0 -64px}.sceditor-button-table div{background-position:0 -80px}.sceditor-button-superscript div{background-position:0 -96px}.sceditor-button-subscript div{background-position:0 -112px}.sceditor-button-strike div{background-position:0 -128px}.sceditor-button-source div{background-position:0 -144px}.sceditor-button-size div{background-position:0 -160px}.sceditor-button-rtl div{background-position:0 -176px}.sceditor-button-right div{background-position:0 -192px}.sceditor-button-removeformat div{background-position:0 -208px}.sceditor-button-quote div{background-position:0 -224px}.sceditor-button-print div{background-position:0 -240px}.sceditor-button-pastetext div{background-position:0 -256px}.sceditor-button-paste div{background-position:0 -272px}.sceditor-button-outdent div{background-position:0 -288px}.sceditor-button-orderedlist div{background-position:0 -304px}.sceditor-button-maximize div{background-position:0 -320px}.sceditor-button-ltr div{background-position:0 -336px}.sceditor-button-left div{background-position:0 -352px}.sceditor-button-justify div{background-position:0 -368px}.sceditor-button-italic div{background-position:0 -384px}.sceditor-button-indent div{background-position:0 -400px}.sceditor-button-image div{background-position:0 -416px}.sceditor-button-horizontalrule div{background-position:0 -432px}.sceditor-button-format div{background-position:0 -448px}.sceditor-button-font div{background-position:0 -464px}.sceditor-button-emoticon div{background-position:0 -480px}.sceditor-button-email div{background-position:0 -496px}.sceditor-button-date div{background-position:0 -512px}.sceditor-button-cut div{background-position:0 -528px}.sceditor-button-copy div{background-position:0 -544px}.sceditor-button-color div{background-position:0 -560px}.sceditor-button-code div{background-position:0 -576px}.sceditor-button-center div{background-position:0 -592px}.sceditor-button-bulletlist div{background-position:0 -608px}.sceditor-button-bold div{background-position:0 -624px}div.sceditor-grip{background-position:0 -640px}.rtl div.sceditor-grip{background-position:0 -650px;width:10px;height:10px}.sceditor-container{position:relative;background:#fff;font-size:13px;font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;color:#222;line-height:1;font-weight:700;border-radius:4px;background-clip:padding-box}.sceditor-container *,.sceditor-container :after,.sceditor-container :before{box-sizing:content-box}.sceditor-container,.sceditor-container div,div.sceditor-dropdown,div.sceditor-dropdown div{padding:0;margin:0;z-index:3}.sceditor-container iframe,.sceditor-container textarea{line-height:1;border:0;outline:0;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:13px;color:#111;padding:0;margin:5px;resize:none;background:#fff;display:block}div.sceditor-resize-cover{position:absolute;top:0;left:0;background:#000;width:100%;height:100%;z-index:10;opacity:.3}.ie6 div.sceditor-resize-cover,.ie7 div.sceditor-resize-cover,.ie8 div.sceditor-resize-cover{background:#efefef}.sceditor-maximize,.sceditor-maximize div.sceditor-toolbar{border-radius:0;background-clip:padding-box}.sceditor-container.ie6{overflow:hidden}div.sceditor-grip{overflow:hidden;width:10px;height:10px;cursor:pointer;position:absolute;bottom:0;right:0;z-index:3}.sceditor-maximize{position:fixed;top:0;left:0;height:100%!important;width:100%!important;z-index:2000}body.sceditor-maximize,html.sceditor-maximize{height:100%;width:100%;padding:0;margin:0;overflow:hidden}.ie6.sceditor-maximize{position:absolute}.sceditor-maximize div.sceditor-grip{display:none}div.sceditor-dropdown{position:absolute;border:1px solid #ccc;background:#fff;color:#333;z-index:4000;padding:10px;line-height:1;border-radius:2px;background-clip:padding-box;box-shadow:1px 2px 4px rgba(0,0,0,.2)}div.sceditor-dropdown a,div.sceditor-dropdown a:link{color:#333}div.sceditor-dropdown form{margin:0}div.sceditor-dropdown label{display:block;font-weight:700;color:#3c3c3c;padding:4px 0}div.sceditor-dropdown input,div.sceditor-dropdown textarea{font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;outline:0;padding:4px;border:1px solid #ccc;border-top-color:#888;margin:0 0 .75em;border-radius:1px;background-clip:padding-box}div.sceditor-dropdown textarea{padding:6px}div.sceditor-dropdown input:focus,div.sceditor-dropdown textarea:focus{border-color:#666 #aaa #aaa;box-shadow:inset 0 1px 5px rgba(0,0,0,.1)}div.sceditor-dropdown .button{font-weight:700;color:#444;padding:6px 12px;background:#ececec;border:1px solid #ccc;border-radius:2px;background-clip:padding-box;cursor:pointer;margin:.3em 0 0}div.sceditor-dropdown .button:hover{background:#f3f3f3;box-shadow:0 1px 1px rgba(0,0,0,.15)}div.sceditor-font-picker,div.sceditor-fontsize-picker,div.sceditor-format{padding:6px 0}div.sceditor-color-picker,div.sceditor-emoticons,div.sceditor-more-emoticons{padding:0}.sceditor-pastetext textarea{border:1px solid #bbb;width:20em}.sceditor-emoticons img,.sceditor-more-emoticons img{padding:0;cursor:pointer;margin:2px}.sceditor-more{border-top:1px solid #bbb;display:block;text-align:center;cursor:pointer;font-weight:700;padding:6px 0}.sceditor-dropdown a:hover{background:#eee}.sceditor-font-option,.sceditor-fontsize-option,.sceditor-format a{display:block;padding:7px 10px;cursor:pointer;text-decoration:none;color:#222}.sceditor-fontsize-option{padding:7px 13px}.sceditor-color-column{float:left}.sceditor-color-option{display:block;border:1px solid #fff;height:10px;width:10px;overflow:hidden}.sceditor-color-option:hover{border:1px solid #333}div.sceditor-toolbar{overflow:hidden;padding:3px 5px 2px;line-height:0;text-align:left;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:3px 3px 0 0;background-clip:padding-box}div.sceditor-group{display:inline-block;margin:1px 5px 1px 0;border-radius:3px;background-clip:padding-box}.ie6 div.sceditor-group,.ie7 div.sceditor-group{display:inline;zoom:1}.sceditor-button{float:left;cursor:pointer;width:16px;text-indent:-9999px}.ie .sceditor-button{text-indent:0}.ie6 .sceditor-button,.ie7 .sceditor-button{float:none!important;display:inline;zoom:1}.ie6 .sceditor-button{padding:0}.ie6 .sceditor-button div{margin:5px}.ie7 .sceditor-button div{margin:5px 0}.sceditor-button.disabled:hover{background:inherit;cursor:default;box-shadow:none}.sceditor-button,.sceditor-button div{display:block}.sceditor-button div{padding:0;overflow:hidden;line-height:0;font-size:0;color:transparent;margin:0}.sceditor-button.disabled div{filter:alpha(opacity=30);opacity:.3}.sceditor-button.text,.sceditor-button.text div,.sceditor-button.text-icon,.sceditor-button.text-icon div,.text .sceditor-button,.text .sceditor-button div,.text-icon .sceditor-button,.text-icon .sceditor-button div{width:auto;overflow:visible;line-height:16px;font-size:1em;color:inherit;text-indent:0}.sceditor-button.text div,.text .sceditor-button div{padding:0 2px;background:0 0}.sceditor-button.text-icon div,.text-icon .sceditor-button div{padding:0 2px 0 20px}.rtl div.sceditor-toolbar{text-align:right}.rtl .sceditor-button{float:right}.rtl div.sceditor-grip{right:auto;left:0}.sceditor-container{border:1px solid #8db2e3}.sceditor-container textarea{font-family:Consolas,"Bitstream Vera Sans Mono","Andale Mono",Monaco,"DejaVu Sans Mono","Lucida Console",monospace}div.sceditor-toolbar{border-bottom:1px solid #95a9c3;background:#dee8f5;background:linear-gradient(to bottom,#dee8f5 0,#c7d8ed 29%,#ccdcee 61%,#c0d8ef 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dee8f5', endColorstr='#c0d8ef', GradientType=0)}.ie9 div.sceditor-toolbar{-webkit-filter:none;filter:none;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RlZThmNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjI5JSIgc3RvcC1jb2xvcj0iI2M3ZDhlZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjYxJSIgc3RvcC1jb2xvcj0iI2NjZGNlZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNjMGQ4ZWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}div.sceditor-group{border:1px solid #7596bf;padding:0;background:#cadcf0;background:linear-gradient(to bottom,#cadcf0 24%,#bcd0e9 38%,#d0e1f7 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#cadcf0', endColorstr='#d0e1f7', GradientType=0)}.ie9 div.sceditor-group{-webkit-filter:none;filter:none;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIyNCUiIHN0b3AtY29sb3I9IiNjYWRjZjAiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIzOCUiIHN0b3AtY29sb3I9IiNiY2QwZTkiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNkMGUxZjciIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button{height:16px;padding:3px 4px;border-radius:0;background-clip:padding-box;box-shadow:inset 0 1px #d5e3f1,inset 0 -1px #e3edfb,inset 1px 0 #cddcef,inset -1px 0 #b8ceea}.sceditor-button:first-child{border-radius:4px 0 0 4px;background-clip:padding-box}.sceditor-button:last-child{border-radius:0 4px 4px 0;background-clip:padding-box}.ie9 .sceditor-button{-webkit-filter:none!important;filter:none!important}.sceditor-button.active{background:#fbdbb5;background:linear-gradient(to bottom,#fbdbb5 11%,#feb456 29%,#fdeb9f 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbdbb5', endColorstr='#fdeb9f', GradientType=0);box-shadow:inset 0 1px #ebd1b4,inset 0 -1px #ffe47f,inset -1px 0 #b8ceea}.ie9 .sceditor-button.active{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIxMSUiIHN0b3AtY29sb3I9IiNmYmRiYjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIyOSUiIHN0b3AtY29sb3I9IiNmZWI0NTYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNmZGZkOWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button:hover{background:#fef7d5;background:linear-gradient(to bottom,#fef7d5 0,#fae5a9 42%,#ffd048 42%,#ffe59f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fef7d5', endColorstr='#ffe59f', GradientType=0);box-shadow:inset 0 1px #fffbe8,inset -1px 0 #ffefc4,inset 0 -1px #fff9cc}.ie9 .sceditor-button:hover{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZjdkNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZhZTVhOSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZmZDA0OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmU1OWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button:active{background:#e7a66d;background:linear-gradient(to bottom,#e7a66d 0,#fcb16d 1%,#ff8d05 42%,#ffc450 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e7a66d', endColorstr='#ffc450', GradientType=0);box-shadow:inset 0 1px 1px #7b6645,inset 0 -1px #d19c33}.ie9 .sceditor-button:active{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2U3YTY2ZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjElIiBzdG9wLWNvbG9yPSIjZmNiMTZkIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNDIlIiBzdG9wLWNvbG9yPSIjZmY4ZDA1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmYzQ1MCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=)}.sceditor-button.active:hover{background:#dba368;background:linear-gradient(to bottom,#dba368 0,#ffbd79 4%,#fea335 34%,#ffc64c 66%,#fee069 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dba368', endColorstr='#fee069', GradientType=0);box-shadow:inset 0 1px 1px #9e8255,inset 0 -1px #fcce6b}.ie9 .sceditor-button.active:hover{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RiYTM2OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQlIiBzdG9wLWNvbG9yPSIjZmZiZDc5IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMzQlIiBzdG9wLWNvbG9yPSIjZmVhMzM1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNjYlIiBzdG9wLWNvbG9yPSIjZmZjNjRjIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZlZTA2OSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=)} \ No newline at end of file diff --git a/js/sceditor/minified/themes/office.min.css b/js/sceditor/minified/themes/office.min.css new file mode 100644 index 00000000..49d6873c --- /dev/null +++ b/js/sceditor/minified/themes/office.min.css @@ -0,0 +1 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */.sceditor-button div,div.sceditor-grip{background-image:url(famfamfam.png);background-repeat:no-repeat;width:16px;height:16px}.sceditor-button-youtube div{background-position:0 0}.sceditor-button-link div{background-position:0 -16px}.sceditor-button-unlink div{background-position:0 -32px}.sceditor-button-underline div{background-position:0 -48px}.sceditor-button-time div{background-position:0 -64px}.sceditor-button-table div{background-position:0 -80px}.sceditor-button-superscript div{background-position:0 -96px}.sceditor-button-subscript div{background-position:0 -112px}.sceditor-button-strike div{background-position:0 -128px}.sceditor-button-source div{background-position:0 -144px}.sceditor-button-size div{background-position:0 -160px}.sceditor-button-rtl div{background-position:0 -176px}.sceditor-button-right div{background-position:0 -192px}.sceditor-button-removeformat div{background-position:0 -208px}.sceditor-button-quote div{background-position:0 -224px}.sceditor-button-print div{background-position:0 -240px}.sceditor-button-pastetext div{background-position:0 -256px}.sceditor-button-paste div{background-position:0 -272px}.sceditor-button-outdent div{background-position:0 -288px}.sceditor-button-orderedlist div{background-position:0 -304px}.sceditor-button-maximize div{background-position:0 -320px}.sceditor-button-ltr div{background-position:0 -336px}.sceditor-button-left div{background-position:0 -352px}.sceditor-button-justify div{background-position:0 -368px}.sceditor-button-italic div{background-position:0 -384px}.sceditor-button-indent div{background-position:0 -400px}.sceditor-button-image div{background-position:0 -416px}.sceditor-button-horizontalrule div{background-position:0 -432px}.sceditor-button-format div{background-position:0 -448px}.sceditor-button-font div{background-position:0 -464px}.sceditor-button-emoticon div{background-position:0 -480px}.sceditor-button-email div{background-position:0 -496px}.sceditor-button-date div{background-position:0 -512px}.sceditor-button-cut div{background-position:0 -528px}.sceditor-button-copy div{background-position:0 -544px}.sceditor-button-color div{background-position:0 -560px}.sceditor-button-code div{background-position:0 -576px}.sceditor-button-center div{background-position:0 -592px}.sceditor-button-bulletlist div{background-position:0 -608px}.sceditor-button-bold div{background-position:0 -624px}div.sceditor-grip{background-position:0 -640px}.rtl div.sceditor-grip{background-position:0 -650px;width:10px;height:10px}.sceditor-container{position:relative;font-size:13px;font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;color:#222;line-height:1;font-weight:700;border-radius:4px;background-clip:padding-box}.sceditor-container *,.sceditor-container :after,.sceditor-container :before{box-sizing:content-box}.sceditor-container,.sceditor-container div,div.sceditor-dropdown,div.sceditor-dropdown div{padding:0;margin:0;z-index:3}.sceditor-container iframe,.sceditor-container textarea{line-height:1;outline:0;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:13px;color:#111;resize:none;display:block}div.sceditor-resize-cover{position:absolute;top:0;left:0;background:#000;width:100%;height:100%;z-index:10;opacity:.3}.ie6 div.sceditor-resize-cover,.ie7 div.sceditor-resize-cover,.ie8 div.sceditor-resize-cover{background:#efefef}.sceditor-maximize,.sceditor-maximize div.sceditor-toolbar{border-radius:0;background-clip:padding-box}.sceditor-container.ie6{overflow:hidden}div.sceditor-grip{overflow:hidden;width:10px;height:10px;cursor:pointer;position:absolute;bottom:0;right:0;z-index:3}.sceditor-maximize{position:fixed;top:0;left:0;height:100%!important;width:100%!important;z-index:2000}body.sceditor-maximize,html.sceditor-maximize{height:100%;width:100%;padding:0;margin:0;overflow:hidden}.ie6.sceditor-maximize{position:absolute}.sceditor-maximize div.sceditor-grip{display:none}div.sceditor-dropdown{position:absolute;border:1px solid #ccc;background:#fff;color:#333;z-index:4000;padding:10px;line-height:1;border-radius:2px;background-clip:padding-box;box-shadow:1px 2px 4px rgba(0,0,0,.2)}div.sceditor-dropdown a,div.sceditor-dropdown a:link{color:#333}div.sceditor-dropdown form{margin:0}div.sceditor-dropdown label{display:block;font-weight:700;color:#3c3c3c;padding:4px 0}div.sceditor-dropdown input,div.sceditor-dropdown textarea{font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;outline:0;padding:4px;border:1px solid #ccc;border-top-color:#888;margin:0 0 .75em;border-radius:1px;background-clip:padding-box}div.sceditor-dropdown textarea{padding:6px}div.sceditor-dropdown input:focus,div.sceditor-dropdown textarea:focus{border-color:#666 #aaa #aaa;box-shadow:inset 0 1px 5px rgba(0,0,0,.1)}div.sceditor-dropdown .button{font-weight:700;color:#444;padding:6px 12px;background:#ececec;border:1px solid #ccc;border-radius:2px;background-clip:padding-box;cursor:pointer;margin:.3em 0 0}div.sceditor-dropdown .button:hover{background:#f3f3f3;box-shadow:0 1px 1px rgba(0,0,0,.15)}div.sceditor-font-picker,div.sceditor-fontsize-picker,div.sceditor-format{padding:6px 0}div.sceditor-color-picker,div.sceditor-emoticons,div.sceditor-more-emoticons{padding:0}.sceditor-pastetext textarea{border:1px solid #bbb;width:20em}.sceditor-emoticons img,.sceditor-more-emoticons img{padding:0;cursor:pointer;margin:2px}.sceditor-more{border-top:1px solid #bbb;display:block;text-align:center;cursor:pointer;font-weight:700;padding:6px 0}.sceditor-dropdown a:hover{background:#eee}.sceditor-font-option,.sceditor-fontsize-option,.sceditor-format a{display:block;padding:7px 10px;cursor:pointer;text-decoration:none;color:#222}.sceditor-fontsize-option{padding:7px 13px}.sceditor-color-column{float:left}.sceditor-color-option{display:block;border:1px solid #fff;height:10px;width:10px;overflow:hidden}.sceditor-color-option:hover{border:1px solid #333}div.sceditor-toolbar{overflow:hidden;padding:3px 5px 2px;line-height:0;text-align:left;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:3px 3px 0 0;background-clip:padding-box}div.sceditor-group{display:inline-block;margin:1px 5px 1px 0;border-radius:3px;background-clip:padding-box}.ie6 div.sceditor-group,.ie7 div.sceditor-group{display:inline;zoom:1}.sceditor-button{float:left;cursor:pointer;width:16px;text-indent:-9999px}.ie .sceditor-button{text-indent:0}.ie6 .sceditor-button,.ie7 .sceditor-button{float:none!important;display:inline;zoom:1}.ie6 .sceditor-button{padding:0}.ie6 .sceditor-button div{margin:5px}.ie7 .sceditor-button div{margin:5px 0}.sceditor-button.disabled:hover{background:inherit;cursor:default;box-shadow:none}.sceditor-button,.sceditor-button div{display:block}.sceditor-button div{padding:0;overflow:hidden;line-height:0;font-size:0;color:transparent;margin:0}.sceditor-button.disabled div{filter:alpha(opacity=30);opacity:.3}.sceditor-button.text,.sceditor-button.text div,.sceditor-button.text-icon,.sceditor-button.text-icon div,.text .sceditor-button,.text .sceditor-button div,.text-icon .sceditor-button,.text-icon .sceditor-button div{width:auto;overflow:visible;line-height:16px;font-size:1em;color:inherit;text-indent:0}.sceditor-button.text div,.text .sceditor-button div{padding:0 2px;background:0 0}.sceditor-button.text-icon div,.text-icon .sceditor-button div{padding:0 2px 0 20px}.rtl div.sceditor-toolbar{text-align:right}.rtl .sceditor-button{float:right}.rtl div.sceditor-grip{right:auto;left:0}.sceditor-container{border:1px solid #8db2e3}.sceditor-container textarea{font-family:Consolas,"Bitstream Vera Sans Mono","Andale Mono",Monaco,"DejaVu Sans Mono","Lucida Console",monospace}div.sceditor-toolbar{border-bottom:1px solid #95a9c3;background:#dee8f5;background:linear-gradient(to bottom,#dee8f5 0,#c7d8ed 29%,#ccdcee 61%,#c0d8ef 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dee8f5', endColorstr='#c0d8ef', GradientType=0)}.ie9 div.sceditor-toolbar{-webkit-filter:none;filter:none;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RlZThmNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjI5JSIgc3RvcC1jb2xvcj0iI2M3ZDhlZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjYxJSIgc3RvcC1jb2xvcj0iI2NjZGNlZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNjMGQ4ZWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}div.sceditor-group{border:1px solid #7596bf;padding:0;background:#cadcf0;background:linear-gradient(to bottom,#cadcf0 24%,#bcd0e9 38%,#d0e1f7 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#cadcf0', endColorstr='#d0e1f7', GradientType=0)}.ie9 div.sceditor-group{-webkit-filter:none;filter:none;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIyNCUiIHN0b3AtY29sb3I9IiNjYWRjZjAiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIzOCUiIHN0b3AtY29sb3I9IiNiY2QwZTkiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNkMGUxZjciIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button{height:16px;padding:3px 4px;border-radius:0;background-clip:padding-box;box-shadow:inset 0 1px #d5e3f1,inset 0 -1px #e3edfb,inset 1px 0 #cddcef,inset -1px 0 #b8ceea}.sceditor-button:first-child{border-radius:4px 0 0 4px;background-clip:padding-box}.sceditor-button:last-child{border-radius:0 4px 4px 0;background-clip:padding-box}.ie9 .sceditor-button{-webkit-filter:none!important;filter:none!important}.sceditor-button.active{background:#fbdbb5;background:linear-gradient(to bottom,#fbdbb5 11%,#feb456 29%,#fdeb9f 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbdbb5', endColorstr='#fdeb9f', GradientType=0);box-shadow:inset 0 1px #ebd1b4,inset 0 -1px #ffe47f,inset -1px 0 #b8ceea}.ie9 .sceditor-button.active{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIxMSUiIHN0b3AtY29sb3I9IiNmYmRiYjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIyOSUiIHN0b3AtY29sb3I9IiNmZWI0NTYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNmZGZkOWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button:hover{background:#fef7d5;background:linear-gradient(to bottom,#fef7d5 0,#fae5a9 42%,#ffd048 42%,#ffe59f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fef7d5', endColorstr='#ffe59f', GradientType=0);box-shadow:inset 0 1px #fffbe8,inset -1px 0 #ffefc4,inset 0 -1px #fff9cc}.ie9 .sceditor-button:hover{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZjdkNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZhZTVhOSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZmZDA0OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmU1OWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button:active{background:#e7a66d;background:linear-gradient(to bottom,#e7a66d 0,#fcb16d 1%,#ff8d05 42%,#ffc450 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e7a66d', endColorstr='#ffc450', GradientType=0);box-shadow:inset 0 1px 1px #7b6645,inset 0 -1px #d19c33}.ie9 .sceditor-button:active{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2U3YTY2ZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjElIiBzdG9wLWNvbG9yPSIjZmNiMTZkIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNDIlIiBzdG9wLWNvbG9yPSIjZmY4ZDA1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmYzQ1MCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=)}.sceditor-button.active:hover{background:#dba368;background:linear-gradient(to bottom,#dba368 0,#ffbd79 4%,#fea335 34%,#ffc64c 66%,#fee069 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dba368', endColorstr='#fee069', GradientType=0);box-shadow:inset 0 1px 1px #9e8255,inset 0 -1px #fcce6b}.ie9 .sceditor-button.active:hover{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RiYTM2OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQlIiBzdG9wLWNvbG9yPSIjZmZiZDc5IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMzQlIiBzdG9wLWNvbG9yPSIjZmVhMzM1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNjYlIiBzdG9wLWNvbG9yPSIjZmZjNjRjIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZlZTA2OSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=)}.sceditor-container{background:#a3c2ea;background:linear-gradient(to bottom,#a3c2ea 0,#6d92c1 39%,#577fb3 64%,#6591cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#a3c2ea', endColorstr='#6591cc', GradientType=0)}.sceditor-container iframe,.sceditor-container textarea{border:1px solid #646464;background:#fff;margin:7px 40px;padding:20px;box-shadow:1px 1px 5px #293a52} \ No newline at end of file diff --git a/js/sceditor/minified/themes/square.min.css b/js/sceditor/minified/themes/square.min.css new file mode 100644 index 00000000..baa91dee --- /dev/null +++ b/js/sceditor/minified/themes/square.min.css @@ -0,0 +1 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */.sceditor-button div,div.sceditor-grip{background-image:url(famfamfam.png);background-repeat:no-repeat;width:16px;height:16px}.sceditor-button-youtube div{background-position:0 0}.sceditor-button-link div{background-position:0 -16px}.sceditor-button-unlink div{background-position:0 -32px}.sceditor-button-underline div{background-position:0 -48px}.sceditor-button-time div{background-position:0 -64px}.sceditor-button-table div{background-position:0 -80px}.sceditor-button-superscript div{background-position:0 -96px}.sceditor-button-subscript div{background-position:0 -112px}.sceditor-button-strike div{background-position:0 -128px}.sceditor-button-source div{background-position:0 -144px}.sceditor-button-size div{background-position:0 -160px}.sceditor-button-rtl div{background-position:0 -176px}.sceditor-button-right div{background-position:0 -192px}.sceditor-button-removeformat div{background-position:0 -208px}.sceditor-button-quote div{background-position:0 -224px}.sceditor-button-print div{background-position:0 -240px}.sceditor-button-pastetext div{background-position:0 -256px}.sceditor-button-paste div{background-position:0 -272px}.sceditor-button-outdent div{background-position:0 -288px}.sceditor-button-orderedlist div{background-position:0 -304px}.sceditor-button-maximize div{background-position:0 -320px}.sceditor-button-ltr div{background-position:0 -336px}.sceditor-button-left div{background-position:0 -352px}.sceditor-button-justify div{background-position:0 -368px}.sceditor-button-italic div{background-position:0 -384px}.sceditor-button-indent div{background-position:0 -400px}.sceditor-button-image div{background-position:0 -416px}.sceditor-button-horizontalrule div{background-position:0 -432px}.sceditor-button-format div{background-position:0 -448px}.sceditor-button-font div{background-position:0 -464px}.sceditor-button-emoticon div{background-position:0 -480px}.sceditor-button-email div{background-position:0 -496px}.sceditor-button-date div{background-position:0 -512px}.sceditor-button-cut div{background-position:0 -528px}.sceditor-button-copy div{background-position:0 -544px}.sceditor-button-color div{background-position:0 -560px}.sceditor-button-code div{background-position:0 -576px}.sceditor-button-center div{background-position:0 -592px}.sceditor-button-bulletlist div{background-position:0 -608px}.sceditor-button-bold div{background-position:0 -624px}div.sceditor-grip{background-position:0 -640px}.rtl div.sceditor-grip{background-position:0 -650px;width:10px;height:10px}.sceditor-container{position:relative;background:#fff;font-size:13px;font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;color:#222;line-height:1;font-weight:700}.sceditor-container *,.sceditor-container :after,.sceditor-container :before{box-sizing:content-box}.sceditor-container,.sceditor-container div,div.sceditor-dropdown,div.sceditor-dropdown div{padding:0;margin:0;z-index:3}.sceditor-container iframe,.sceditor-container textarea{line-height:1;border:0;outline:0;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:13px;color:#111;padding:0;margin:5px;resize:none;background:#fff;display:block}div.sceditor-resize-cover{position:absolute;top:0;left:0;background:#000;width:100%;height:100%;z-index:10;opacity:.3}.ie6 div.sceditor-resize-cover,.ie7 div.sceditor-resize-cover,.ie8 div.sceditor-resize-cover{background:#efefef}.sceditor-maximize,.sceditor-maximize div.sceditor-toolbar{border-radius:0;background-clip:padding-box}.sceditor-container.ie6{overflow:hidden}div.sceditor-grip{overflow:hidden;width:10px;height:10px;cursor:pointer;position:absolute;bottom:0;right:0;z-index:3}.sceditor-maximize{position:fixed;top:0;left:0;height:100%!important;width:100%!important;z-index:2000}body.sceditor-maximize,html.sceditor-maximize{height:100%;width:100%;padding:0;margin:0;overflow:hidden}.ie6.sceditor-maximize{position:absolute}.sceditor-maximize div.sceditor-grip{display:none}div.sceditor-dropdown{position:absolute;border:1px solid #ccc;background:#fff;color:#333;z-index:4000;padding:10px;line-height:1;border-radius:2px;background-clip:padding-box;box-shadow:1px 2px 4px rgba(0,0,0,.2)}div.sceditor-dropdown a,div.sceditor-dropdown a:link{color:#333}div.sceditor-dropdown form{margin:0}div.sceditor-dropdown label{display:block;font-weight:700;color:#3c3c3c;padding:4px 0}div.sceditor-dropdown input,div.sceditor-dropdown textarea{font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;outline:0;padding:4px;border:1px solid #ccc;border-top-color:#888;margin:0 0 .75em;border-radius:1px;background-clip:padding-box}div.sceditor-dropdown textarea{padding:6px}div.sceditor-dropdown input:focus,div.sceditor-dropdown textarea:focus{border-color:#666 #aaa #aaa;box-shadow:inset 0 1px 5px rgba(0,0,0,.1)}div.sceditor-dropdown .button{font-weight:700;color:#444;padding:6px 12px;background:#ececec;border:1px solid #ccc;border-radius:2px;background-clip:padding-box;cursor:pointer;margin:.3em 0 0}div.sceditor-dropdown .button:hover{background:#f3f3f3;box-shadow:0 1px 1px rgba(0,0,0,.15)}div.sceditor-font-picker,div.sceditor-fontsize-picker,div.sceditor-format{padding:6px 0}div.sceditor-color-picker,div.sceditor-emoticons,div.sceditor-more-emoticons{padding:0}.sceditor-pastetext textarea{border:1px solid #bbb;width:20em}.sceditor-emoticons img,.sceditor-more-emoticons img{padding:0;cursor:pointer;margin:2px}.sceditor-more{border-top:1px solid #bbb;display:block;text-align:center;cursor:pointer;font-weight:700;padding:6px 0}.sceditor-dropdown a:hover{background:#eee}.sceditor-font-option,.sceditor-fontsize-option,.sceditor-format a{display:block;padding:7px 10px;cursor:pointer;text-decoration:none;color:#222}.sceditor-fontsize-option{padding:7px 13px}.sceditor-color-column{float:left}.sceditor-color-option{display:block;border:1px solid #fff;height:10px;width:10px;overflow:hidden}.sceditor-color-option:hover{border:1px solid #333}div.sceditor-toolbar{overflow:hidden;line-height:0;text-align:left;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:3px 3px 0 0;background-clip:padding-box}div.sceditor-group{display:inline-block}.ie6 div.sceditor-group,.ie7 div.sceditor-group{display:inline;zoom:1}.sceditor-button{float:left;cursor:pointer;width:16px;text-indent:-9999px}.ie .sceditor-button{text-indent:0}.ie6 .sceditor-button,.ie7 .sceditor-button{float:none!important;display:inline;zoom:1}.ie6 .sceditor-button{padding:0}.ie6 .sceditor-button div{margin:5px}.ie7 .sceditor-button div{margin:5px 0}.sceditor-button.disabled:hover{background:inherit;cursor:default;box-shadow:none}.sceditor-button,.sceditor-button div{display:block}.sceditor-button div{padding:0;overflow:hidden;line-height:0;font-size:0;color:transparent}.sceditor-button.disabled div{filter:alpha(opacity=30);opacity:.3}.sceditor-button.text,.sceditor-button.text div,.sceditor-button.text-icon,.sceditor-button.text-icon div,.text .sceditor-button,.text .sceditor-button div,.text-icon .sceditor-button,.text-icon .sceditor-button div{width:auto;overflow:visible;line-height:16px;font-size:1em;color:inherit;text-indent:0}.sceditor-button.text div,.text .sceditor-button div{padding:0 2px;background:0 0}.sceditor-button.text-icon div,.text-icon .sceditor-button div{padding:0 2px 0 20px}.rtl div.sceditor-toolbar{text-align:right}.rtl .sceditor-button{float:right}.rtl div.sceditor-grip{right:auto;left:0}.sceditor-container{border:1px solid #d6d6d6;border-radius:0;background-clip:padding-box}.sceditor-container textarea{font-family:Consolas,"Bitstream Vera Sans Mono","Andale Mono",Monaco,"DejaVu Sans Mono","Lucida Console",monospace;background:#2e3436;color:#fff;margin:0;padding:5px}div.sceditor-group,div.sceditor-toolbar{background:#f2f2f2;background:linear-gradient(to bottom,#f2f2f2 0,#ddd 89%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f2f2f2', endColorstr='#dddddd', GradientType=0)}div.sceditor-toolbar{padding:0;border-bottom:1px solid #bbb;background-size:100% 32px}div.sceditor-group{margin:0;padding:2px 4px;border:0;border-right:1px solid #ccc;border-left:1px solid #eaeaea;border-radius:0;background-clip:padding-box}div.sceditor-group:last-child{border-right:0}div.sceditor-group:first-child{border-left:0}.sceditor-button{height:16px;padding:5px;margin:1px;border-radius:0;background-clip:padding-box}.sceditor-button div{margin:0}.sceditor-button.active,.sceditor-button.active:hover,.sceditor-button:active,.sceditor-button:hover{margin:0;box-shadow:none}.sceditor-button.active{background:#f4f4f4;border:1px solid #ccc}.sceditor-button:hover{background:#fefefe;border:1px solid #ddd}.sceditor-button.disabled:hover{margin:1px;border:0}.sceditor-button:active{background:#eee;border:1px solid #ccc}.sceditor-button.active:hover{background:#f8f8f8;border:1px solid #ddd} \ No newline at end of file diff --git a/stylesheets/sceditor/jquery.sceditor.default.min.css b/stylesheets/sceditor/jquery.sceditor.default.min.css new file mode 100644 index 00000000..2d504cbb --- /dev/null +++ b/stylesheets/sceditor/jquery.sceditor.default.min.css @@ -0,0 +1 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */body,html{overflow:auto}blockquote,code{position:relative;border:1px solid #aaa;padding:.25em}body,code:before,html,p,table{margin:0;padding:0;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:13px;color:#111}html{height:100%;-webkit-overflow-scrolling:touch}body{position:relative;min-height:100%;word-wrap:break-word}ol,ul{margin-top:0;margin-bottom:0;padding-top:0;padding-bottom:0}table,td{border:1px dotted #000;empty-cells:show}code:before{position:absolute;content:'Code:';top:-1.35em;left:0}code{margin-top:1.5em;background:#eee;white-space:pre;display:block}.ie6 code,.ie7 code{margin-top:0}code,code:before{display:block;text-align:left}blockquote{background:#fff6c7;margin:.25em 0}blockquote cite{font-weight:700;display:block;font-size:1em;border-bottom:1px solid #aaa}h1,h2,h3,h4,h5,h6{padding:0;margin:0}div,p{min-height:1.25em} \ No newline at end of file diff --git a/stylesheets/sceditor/themes/default.min.css b/stylesheets/sceditor/themes/default.min.css new file mode 100644 index 00000000..d3eaca63 --- /dev/null +++ b/stylesheets/sceditor/themes/default.min.css @@ -0,0 +1 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */.sceditor-button div,div.sceditor-grip{background-image:url(famfamfam.png);background-repeat:no-repeat;width:16px;height:16px}.sceditor-button-youtube div{background-position:0 0}.sceditor-button-link div{background-position:0 -16px}.sceditor-button-unlink div{background-position:0 -32px}.sceditor-button-underline div{background-position:0 -48px}.sceditor-button-time div{background-position:0 -64px}.sceditor-button-table div{background-position:0 -80px}.sceditor-button-superscript div{background-position:0 -96px}.sceditor-button-subscript div{background-position:0 -112px}.sceditor-button-strike div{background-position:0 -128px}.sceditor-button-source div{background-position:0 -144px}.sceditor-button-size div{background-position:0 -160px}.sceditor-button-rtl div{background-position:0 -176px}.sceditor-button-right div{background-position:0 -192px}.sceditor-button-removeformat div{background-position:0 -208px}.sceditor-button-quote div{background-position:0 -224px}.sceditor-button-print div{background-position:0 -240px}.sceditor-button-pastetext div{background-position:0 -256px}.sceditor-button-paste div{background-position:0 -272px}.sceditor-button-outdent div{background-position:0 -288px}.sceditor-button-orderedlist div{background-position:0 -304px}.sceditor-button-maximize div{background-position:0 -320px}.sceditor-button-ltr div{background-position:0 -336px}.sceditor-button-left div{background-position:0 -352px}.sceditor-button-justify div{background-position:0 -368px}.sceditor-button-italic div{background-position:0 -384px}.sceditor-button-indent div{background-position:0 -400px}.sceditor-button-image div{background-position:0 -416px}.sceditor-button-horizontalrule div{background-position:0 -432px}.sceditor-button-format div{background-position:0 -448px}.sceditor-button-font div{background-position:0 -464px}.sceditor-button-emoticon div{background-position:0 -480px}.sceditor-button-email div{background-position:0 -496px}.sceditor-button-date div{background-position:0 -512px}.sceditor-button-cut div{background-position:0 -528px}.sceditor-button-copy div{background-position:0 -544px}.sceditor-button-color div{background-position:0 -560px}.sceditor-button-code div{background-position:0 -576px}.sceditor-button-center div{background-position:0 -592px}.sceditor-button-bulletlist div{background-position:0 -608px}.sceditor-button-bold div{background-position:0 -624px}div.sceditor-grip{background-position:0 -640px}.rtl div.sceditor-grip{background-position:0 -650px;width:10px;height:10px}.sceditor-container{position:relative;background:#fff;border:1px solid #d9d9d9;font-size:13px;font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;color:#222;line-height:1;font-weight:700;border-radius:4px;background-clip:padding-box}.sceditor-container *,.sceditor-container :after,.sceditor-container :before{box-sizing:content-box}.sceditor-container,.sceditor-container div,div.sceditor-dropdown,div.sceditor-dropdown div{padding:0;margin:0;z-index:3}.sceditor-container iframe,.sceditor-container textarea{line-height:1;border:0;outline:0;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:13px;color:#111;padding:0;margin:5px;resize:none;background:#fff;display:block}div.sceditor-resize-cover{position:absolute;top:0;left:0;background:#000;width:100%;height:100%;z-index:10;opacity:.3}.ie6 div.sceditor-resize-cover,.ie7 div.sceditor-resize-cover,.ie8 div.sceditor-resize-cover{background:#efefef}.sceditor-maximize,.sceditor-maximize div.sceditor-toolbar{border-radius:0;background-clip:padding-box}.sceditor-container.ie6{overflow:hidden}div.sceditor-grip{overflow:hidden;width:10px;height:10px;cursor:pointer;position:absolute;bottom:0;right:0;z-index:3}.sceditor-maximize{position:fixed;top:0;left:0;height:100%!important;width:100%!important;z-index:2000}body.sceditor-maximize,html.sceditor-maximize{height:100%;width:100%;padding:0;margin:0;overflow:hidden}.ie6.sceditor-maximize{position:absolute}.sceditor-maximize div.sceditor-grip{display:none}div.sceditor-dropdown{position:absolute;border:1px solid #ccc;background:#fff;color:#333;z-index:4000;padding:10px;line-height:1;border-radius:2px;background-clip:padding-box;box-shadow:1px 2px 4px rgba(0,0,0,.2)}div.sceditor-dropdown a,div.sceditor-dropdown a:link{color:#333}div.sceditor-dropdown form{margin:0}div.sceditor-dropdown label{display:block;font-weight:700;color:#3c3c3c;padding:4px 0}div.sceditor-dropdown input,div.sceditor-dropdown textarea{font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;outline:0;padding:4px;border:1px solid #ccc;border-top-color:#888;margin:0 0 .75em;border-radius:1px;background-clip:padding-box}div.sceditor-dropdown textarea{padding:6px}div.sceditor-dropdown input:focus,div.sceditor-dropdown textarea:focus{border-color:#666 #aaa #aaa;box-shadow:inset 0 1px 5px rgba(0,0,0,.1)}div.sceditor-dropdown .button{font-weight:700;color:#444;padding:6px 12px;background:#ececec;border:1px solid #ccc;border-radius:2px;background-clip:padding-box;cursor:pointer;margin:.3em 0 0}div.sceditor-dropdown .button:hover{background:#f3f3f3;box-shadow:0 1px 1px rgba(0,0,0,.15)}div.sceditor-font-picker,div.sceditor-fontsize-picker,div.sceditor-format{padding:6px 0}div.sceditor-color-picker,div.sceditor-emoticons,div.sceditor-more-emoticons{padding:0}.sceditor-pastetext textarea{border:1px solid #bbb;width:20em}.sceditor-emoticons img,.sceditor-more-emoticons img{padding:0;cursor:pointer;margin:2px}.sceditor-more{border-top:1px solid #bbb;display:block;text-align:center;cursor:pointer;font-weight:700;padding:6px 0}.sceditor-dropdown a:hover{background:#eee}.sceditor-font-option,.sceditor-fontsize-option,.sceditor-format a{display:block;padding:7px 10px;cursor:pointer;text-decoration:none;color:#222}.sceditor-fontsize-option{padding:7px 13px}.sceditor-color-column{float:left}.sceditor-color-option{display:block;border:1px solid #fff;height:10px;width:10px;overflow:hidden}.sceditor-color-option:hover{border:1px solid #333}div.sceditor-toolbar{overflow:hidden;padding:3px 5px 2px;background:#f7f7f7;border-bottom:1px solid silver;line-height:0;text-align:left;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:3px 3px 0 0;background-clip:padding-box}div.sceditor-group{display:inline-block;background:#ddd;margin:1px 5px 1px 0;padding:1px;border-bottom:1px solid #aaa;border-radius:3px;background-clip:padding-box}.ie6 div.sceditor-group,.ie7 div.sceditor-group{display:inline;zoom:1}.sceditor-button{float:left;cursor:pointer;padding:3px 5px;width:16px;height:20px;border-radius:3px;background-clip:padding-box;text-indent:-9999px}.ie .sceditor-button{text-indent:0}.ie6 .sceditor-button,.ie7 .sceditor-button{float:none!important;display:inline;zoom:1}.ie6 .sceditor-button{padding:0}.ie6 .sceditor-button div{margin:5px}.ie7 .sceditor-button div{margin:5px 0}.sceditor-button.active,.sceditor-button:active,.sceditor-button:hover{background:#fff;box-shadow:inset 1px 1px 0 rgba(0,0,0,.3),inset -1px 0 rgba(0,0,0,.3),inset 0 -1px 0 rgba(0,0,0,.2)}.sceditor-button:active{background:#fff;box-shadow:inset 1px 1px 0 rgba(0,0,0,.3),inset -1px 0 rgba(0,0,0,.3),inset 0 -1px 0 rgba(0,0,0,.2),inset 0 0 8px rgba(0,0,0,.3)}.sceditor-button.disabled:hover{background:inherit;cursor:default;box-shadow:none}.sceditor-button,.sceditor-button div{display:block}.sceditor-button div{margin:2px 0;padding:0;overflow:hidden;line-height:0;font-size:0;color:transparent}.sceditor-button.disabled div{filter:alpha(opacity=30);opacity:.3}.sceditor-button.text,.sceditor-button.text div,.sceditor-button.text-icon,.sceditor-button.text-icon div,.text .sceditor-button,.text .sceditor-button div,.text-icon .sceditor-button,.text-icon .sceditor-button div{width:auto;overflow:visible;line-height:16px;font-size:1em;color:inherit;text-indent:0}.sceditor-button.text div,.text .sceditor-button div{padding:0 2px;background:0 0}.sceditor-button.text-icon div,.text-icon .sceditor-button div{padding:0 2px 0 20px}.rtl div.sceditor-toolbar{text-align:right}.rtl .sceditor-button{float:right}.rtl div.sceditor-grip{right:auto;left:0} \ No newline at end of file diff --git a/stylesheets/sceditor/themes/famfamfam.png b/stylesheets/sceditor/themes/famfamfam.png new file mode 100644 index 0000000000000000000000000000000000000000..c95ef4acda121fdda34d1944ca54d973ffa80718 GIT binary patch literal 11682 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 literal 0 HcmV?d00001 diff --git a/stylesheets/sceditor/themes/monocons/monocons.ttf b/stylesheets/sceditor/themes/monocons/monocons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d100abdf72a460aa813066000555d43240e47ded GIT binary patch literal 7860 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 aEObwBt`HleB`z_7y|Zxc`vPwKX8Ru)Dfl)3 literal 0 HcmV?d00001 diff --git a/stylesheets/sceditor/themes/office-toolbar.min.css b/stylesheets/sceditor/themes/office-toolbar.min.css new file mode 100644 index 00000000..70811a29 --- /dev/null +++ b/stylesheets/sceditor/themes/office-toolbar.min.css @@ -0,0 +1 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */.sceditor-button div,div.sceditor-grip{background-image:url(famfamfam.png);background-repeat:no-repeat;width:16px;height:16px}.sceditor-button-youtube div{background-position:0 0}.sceditor-button-link div{background-position:0 -16px}.sceditor-button-unlink div{background-position:0 -32px}.sceditor-button-underline div{background-position:0 -48px}.sceditor-button-time div{background-position:0 -64px}.sceditor-button-table div{background-position:0 -80px}.sceditor-button-superscript div{background-position:0 -96px}.sceditor-button-subscript div{background-position:0 -112px}.sceditor-button-strike div{background-position:0 -128px}.sceditor-button-source div{background-position:0 -144px}.sceditor-button-size div{background-position:0 -160px}.sceditor-button-rtl div{background-position:0 -176px}.sceditor-button-right div{background-position:0 -192px}.sceditor-button-removeformat div{background-position:0 -208px}.sceditor-button-quote div{background-position:0 -224px}.sceditor-button-print div{background-position:0 -240px}.sceditor-button-pastetext div{background-position:0 -256px}.sceditor-button-paste div{background-position:0 -272px}.sceditor-button-outdent div{background-position:0 -288px}.sceditor-button-orderedlist div{background-position:0 -304px}.sceditor-button-maximize div{background-position:0 -320px}.sceditor-button-ltr div{background-position:0 -336px}.sceditor-button-left div{background-position:0 -352px}.sceditor-button-justify div{background-position:0 -368px}.sceditor-button-italic div{background-position:0 -384px}.sceditor-button-indent div{background-position:0 -400px}.sceditor-button-image div{background-position:0 -416px}.sceditor-button-horizontalrule div{background-position:0 -432px}.sceditor-button-format div{background-position:0 -448px}.sceditor-button-font div{background-position:0 -464px}.sceditor-button-emoticon div{background-position:0 -480px}.sceditor-button-email div{background-position:0 -496px}.sceditor-button-date div{background-position:0 -512px}.sceditor-button-cut div{background-position:0 -528px}.sceditor-button-copy div{background-position:0 -544px}.sceditor-button-color div{background-position:0 -560px}.sceditor-button-code div{background-position:0 -576px}.sceditor-button-center div{background-position:0 -592px}.sceditor-button-bulletlist div{background-position:0 -608px}.sceditor-button-bold div{background-position:0 -624px}div.sceditor-grip{background-position:0 -640px}.rtl div.sceditor-grip{background-position:0 -650px;width:10px;height:10px}.sceditor-container{position:relative;background:#fff;font-size:13px;font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;color:#222;line-height:1;font-weight:700;border-radius:4px;background-clip:padding-box}.sceditor-container *,.sceditor-container :after,.sceditor-container :before{box-sizing:content-box}.sceditor-container,.sceditor-container div,div.sceditor-dropdown,div.sceditor-dropdown div{padding:0;margin:0;z-index:3}.sceditor-container iframe,.sceditor-container textarea{line-height:1;border:0;outline:0;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:13px;color:#111;padding:0;margin:5px;resize:none;background:#fff;display:block}div.sceditor-resize-cover{position:absolute;top:0;left:0;background:#000;width:100%;height:100%;z-index:10;opacity:.3}.ie6 div.sceditor-resize-cover,.ie7 div.sceditor-resize-cover,.ie8 div.sceditor-resize-cover{background:#efefef}.sceditor-maximize,.sceditor-maximize div.sceditor-toolbar{border-radius:0;background-clip:padding-box}.sceditor-container.ie6{overflow:hidden}div.sceditor-grip{overflow:hidden;width:10px;height:10px;cursor:pointer;position:absolute;bottom:0;right:0;z-index:3}.sceditor-maximize{position:fixed;top:0;left:0;height:100%!important;width:100%!important;z-index:2000}body.sceditor-maximize,html.sceditor-maximize{height:100%;width:100%;padding:0;margin:0;overflow:hidden}.ie6.sceditor-maximize{position:absolute}.sceditor-maximize div.sceditor-grip{display:none}div.sceditor-dropdown{position:absolute;border:1px solid #ccc;background:#fff;color:#333;z-index:4000;padding:10px;line-height:1;border-radius:2px;background-clip:padding-box;box-shadow:1px 2px 4px rgba(0,0,0,.2)}div.sceditor-dropdown a,div.sceditor-dropdown a:link{color:#333}div.sceditor-dropdown form{margin:0}div.sceditor-dropdown label{display:block;font-weight:700;color:#3c3c3c;padding:4px 0}div.sceditor-dropdown input,div.sceditor-dropdown textarea{font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;outline:0;padding:4px;border:1px solid #ccc;border-top-color:#888;margin:0 0 .75em;border-radius:1px;background-clip:padding-box}div.sceditor-dropdown textarea{padding:6px}div.sceditor-dropdown input:focus,div.sceditor-dropdown textarea:focus{border-color:#666 #aaa #aaa;box-shadow:inset 0 1px 5px rgba(0,0,0,.1)}div.sceditor-dropdown .button{font-weight:700;color:#444;padding:6px 12px;background:#ececec;border:1px solid #ccc;border-radius:2px;background-clip:padding-box;cursor:pointer;margin:.3em 0 0}div.sceditor-dropdown .button:hover{background:#f3f3f3;box-shadow:0 1px 1px rgba(0,0,0,.15)}div.sceditor-font-picker,div.sceditor-fontsize-picker,div.sceditor-format{padding:6px 0}div.sceditor-color-picker,div.sceditor-emoticons,div.sceditor-more-emoticons{padding:0}.sceditor-pastetext textarea{border:1px solid #bbb;width:20em}.sceditor-emoticons img,.sceditor-more-emoticons img{padding:0;cursor:pointer;margin:2px}.sceditor-more{border-top:1px solid #bbb;display:block;text-align:center;cursor:pointer;font-weight:700;padding:6px 0}.sceditor-dropdown a:hover{background:#eee}.sceditor-font-option,.sceditor-fontsize-option,.sceditor-format a{display:block;padding:7px 10px;cursor:pointer;text-decoration:none;color:#222}.sceditor-fontsize-option{padding:7px 13px}.sceditor-color-column{float:left}.sceditor-color-option{display:block;border:1px solid #fff;height:10px;width:10px;overflow:hidden}.sceditor-color-option:hover{border:1px solid #333}div.sceditor-toolbar{overflow:hidden;padding:3px 5px 2px;line-height:0;text-align:left;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:3px 3px 0 0;background-clip:padding-box}div.sceditor-group{display:inline-block;margin:1px 5px 1px 0;border-radius:3px;background-clip:padding-box}.ie6 div.sceditor-group,.ie7 div.sceditor-group{display:inline;zoom:1}.sceditor-button{float:left;cursor:pointer;width:16px;text-indent:-9999px}.ie .sceditor-button{text-indent:0}.ie6 .sceditor-button,.ie7 .sceditor-button{float:none!important;display:inline;zoom:1}.ie6 .sceditor-button{padding:0}.ie6 .sceditor-button div{margin:5px}.ie7 .sceditor-button div{margin:5px 0}.sceditor-button.disabled:hover{background:inherit;cursor:default;box-shadow:none}.sceditor-button,.sceditor-button div{display:block}.sceditor-button div{padding:0;overflow:hidden;line-height:0;font-size:0;color:transparent;margin:0}.sceditor-button.disabled div{filter:alpha(opacity=30);opacity:.3}.sceditor-button.text,.sceditor-button.text div,.sceditor-button.text-icon,.sceditor-button.text-icon div,.text .sceditor-button,.text .sceditor-button div,.text-icon .sceditor-button,.text-icon .sceditor-button div{width:auto;overflow:visible;line-height:16px;font-size:1em;color:inherit;text-indent:0}.sceditor-button.text div,.text .sceditor-button div{padding:0 2px;background:0 0}.sceditor-button.text-icon div,.text-icon .sceditor-button div{padding:0 2px 0 20px}.rtl div.sceditor-toolbar{text-align:right}.rtl .sceditor-button{float:right}.rtl div.sceditor-grip{right:auto;left:0}.sceditor-container{border:1px solid #8db2e3}.sceditor-container textarea{font-family:Consolas,"Bitstream Vera Sans Mono","Andale Mono",Monaco,"DejaVu Sans Mono","Lucida Console",monospace}div.sceditor-toolbar{border-bottom:1px solid #95a9c3;background:#dee8f5;background:linear-gradient(to bottom,#dee8f5 0,#c7d8ed 29%,#ccdcee 61%,#c0d8ef 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dee8f5', endColorstr='#c0d8ef', GradientType=0)}.ie9 div.sceditor-toolbar{-webkit-filter:none;filter:none;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RlZThmNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjI5JSIgc3RvcC1jb2xvcj0iI2M3ZDhlZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjYxJSIgc3RvcC1jb2xvcj0iI2NjZGNlZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNjMGQ4ZWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}div.sceditor-group{border:1px solid #7596bf;padding:0;background:#cadcf0;background:linear-gradient(to bottom,#cadcf0 24%,#bcd0e9 38%,#d0e1f7 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#cadcf0', endColorstr='#d0e1f7', GradientType=0)}.ie9 div.sceditor-group{-webkit-filter:none;filter:none;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIyNCUiIHN0b3AtY29sb3I9IiNjYWRjZjAiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIzOCUiIHN0b3AtY29sb3I9IiNiY2QwZTkiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNkMGUxZjciIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button{height:16px;padding:3px 4px;border-radius:0;background-clip:padding-box;box-shadow:inset 0 1px #d5e3f1,inset 0 -1px #e3edfb,inset 1px 0 #cddcef,inset -1px 0 #b8ceea}.sceditor-button:first-child{border-radius:4px 0 0 4px;background-clip:padding-box}.sceditor-button:last-child{border-radius:0 4px 4px 0;background-clip:padding-box}.ie9 .sceditor-button{-webkit-filter:none!important;filter:none!important}.sceditor-button.active{background:#fbdbb5;background:linear-gradient(to bottom,#fbdbb5 11%,#feb456 29%,#fdeb9f 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbdbb5', endColorstr='#fdeb9f', GradientType=0);box-shadow:inset 0 1px #ebd1b4,inset 0 -1px #ffe47f,inset -1px 0 #b8ceea}.ie9 .sceditor-button.active{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIxMSUiIHN0b3AtY29sb3I9IiNmYmRiYjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIyOSUiIHN0b3AtY29sb3I9IiNmZWI0NTYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNmZGZkOWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button:hover{background:#fef7d5;background:linear-gradient(to bottom,#fef7d5 0,#fae5a9 42%,#ffd048 42%,#ffe59f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fef7d5', endColorstr='#ffe59f', GradientType=0);box-shadow:inset 0 1px #fffbe8,inset -1px 0 #ffefc4,inset 0 -1px #fff9cc}.ie9 .sceditor-button:hover{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZjdkNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZhZTVhOSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZmZDA0OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmU1OWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button:active{background:#e7a66d;background:linear-gradient(to bottom,#e7a66d 0,#fcb16d 1%,#ff8d05 42%,#ffc450 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e7a66d', endColorstr='#ffc450', GradientType=0);box-shadow:inset 0 1px 1px #7b6645,inset 0 -1px #d19c33}.ie9 .sceditor-button:active{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2U3YTY2ZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjElIiBzdG9wLWNvbG9yPSIjZmNiMTZkIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNDIlIiBzdG9wLWNvbG9yPSIjZmY4ZDA1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmYzQ1MCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=)}.sceditor-button.active:hover{background:#dba368;background:linear-gradient(to bottom,#dba368 0,#ffbd79 4%,#fea335 34%,#ffc64c 66%,#fee069 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dba368', endColorstr='#fee069', GradientType=0);box-shadow:inset 0 1px 1px #9e8255,inset 0 -1px #fcce6b}.ie9 .sceditor-button.active:hover{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RiYTM2OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQlIiBzdG9wLWNvbG9yPSIjZmZiZDc5IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMzQlIiBzdG9wLWNvbG9yPSIjZmVhMzM1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNjYlIiBzdG9wLWNvbG9yPSIjZmZjNjRjIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZlZTA2OSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=)} \ No newline at end of file diff --git a/stylesheets/sceditor/themes/office.min.css b/stylesheets/sceditor/themes/office.min.css new file mode 100644 index 00000000..49d6873c --- /dev/null +++ b/stylesheets/sceditor/themes/office.min.css @@ -0,0 +1 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */.sceditor-button div,div.sceditor-grip{background-image:url(famfamfam.png);background-repeat:no-repeat;width:16px;height:16px}.sceditor-button-youtube div{background-position:0 0}.sceditor-button-link div{background-position:0 -16px}.sceditor-button-unlink div{background-position:0 -32px}.sceditor-button-underline div{background-position:0 -48px}.sceditor-button-time div{background-position:0 -64px}.sceditor-button-table div{background-position:0 -80px}.sceditor-button-superscript div{background-position:0 -96px}.sceditor-button-subscript div{background-position:0 -112px}.sceditor-button-strike div{background-position:0 -128px}.sceditor-button-source div{background-position:0 -144px}.sceditor-button-size div{background-position:0 -160px}.sceditor-button-rtl div{background-position:0 -176px}.sceditor-button-right div{background-position:0 -192px}.sceditor-button-removeformat div{background-position:0 -208px}.sceditor-button-quote div{background-position:0 -224px}.sceditor-button-print div{background-position:0 -240px}.sceditor-button-pastetext div{background-position:0 -256px}.sceditor-button-paste div{background-position:0 -272px}.sceditor-button-outdent div{background-position:0 -288px}.sceditor-button-orderedlist div{background-position:0 -304px}.sceditor-button-maximize div{background-position:0 -320px}.sceditor-button-ltr div{background-position:0 -336px}.sceditor-button-left div{background-position:0 -352px}.sceditor-button-justify div{background-position:0 -368px}.sceditor-button-italic div{background-position:0 -384px}.sceditor-button-indent div{background-position:0 -400px}.sceditor-button-image div{background-position:0 -416px}.sceditor-button-horizontalrule div{background-position:0 -432px}.sceditor-button-format div{background-position:0 -448px}.sceditor-button-font div{background-position:0 -464px}.sceditor-button-emoticon div{background-position:0 -480px}.sceditor-button-email div{background-position:0 -496px}.sceditor-button-date div{background-position:0 -512px}.sceditor-button-cut div{background-position:0 -528px}.sceditor-button-copy div{background-position:0 -544px}.sceditor-button-color div{background-position:0 -560px}.sceditor-button-code div{background-position:0 -576px}.sceditor-button-center div{background-position:0 -592px}.sceditor-button-bulletlist div{background-position:0 -608px}.sceditor-button-bold div{background-position:0 -624px}div.sceditor-grip{background-position:0 -640px}.rtl div.sceditor-grip{background-position:0 -650px;width:10px;height:10px}.sceditor-container{position:relative;font-size:13px;font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;color:#222;line-height:1;font-weight:700;border-radius:4px;background-clip:padding-box}.sceditor-container *,.sceditor-container :after,.sceditor-container :before{box-sizing:content-box}.sceditor-container,.sceditor-container div,div.sceditor-dropdown,div.sceditor-dropdown div{padding:0;margin:0;z-index:3}.sceditor-container iframe,.sceditor-container textarea{line-height:1;outline:0;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:13px;color:#111;resize:none;display:block}div.sceditor-resize-cover{position:absolute;top:0;left:0;background:#000;width:100%;height:100%;z-index:10;opacity:.3}.ie6 div.sceditor-resize-cover,.ie7 div.sceditor-resize-cover,.ie8 div.sceditor-resize-cover{background:#efefef}.sceditor-maximize,.sceditor-maximize div.sceditor-toolbar{border-radius:0;background-clip:padding-box}.sceditor-container.ie6{overflow:hidden}div.sceditor-grip{overflow:hidden;width:10px;height:10px;cursor:pointer;position:absolute;bottom:0;right:0;z-index:3}.sceditor-maximize{position:fixed;top:0;left:0;height:100%!important;width:100%!important;z-index:2000}body.sceditor-maximize,html.sceditor-maximize{height:100%;width:100%;padding:0;margin:0;overflow:hidden}.ie6.sceditor-maximize{position:absolute}.sceditor-maximize div.sceditor-grip{display:none}div.sceditor-dropdown{position:absolute;border:1px solid #ccc;background:#fff;color:#333;z-index:4000;padding:10px;line-height:1;border-radius:2px;background-clip:padding-box;box-shadow:1px 2px 4px rgba(0,0,0,.2)}div.sceditor-dropdown a,div.sceditor-dropdown a:link{color:#333}div.sceditor-dropdown form{margin:0}div.sceditor-dropdown label{display:block;font-weight:700;color:#3c3c3c;padding:4px 0}div.sceditor-dropdown input,div.sceditor-dropdown textarea{font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;outline:0;padding:4px;border:1px solid #ccc;border-top-color:#888;margin:0 0 .75em;border-radius:1px;background-clip:padding-box}div.sceditor-dropdown textarea{padding:6px}div.sceditor-dropdown input:focus,div.sceditor-dropdown textarea:focus{border-color:#666 #aaa #aaa;box-shadow:inset 0 1px 5px rgba(0,0,0,.1)}div.sceditor-dropdown .button{font-weight:700;color:#444;padding:6px 12px;background:#ececec;border:1px solid #ccc;border-radius:2px;background-clip:padding-box;cursor:pointer;margin:.3em 0 0}div.sceditor-dropdown .button:hover{background:#f3f3f3;box-shadow:0 1px 1px rgba(0,0,0,.15)}div.sceditor-font-picker,div.sceditor-fontsize-picker,div.sceditor-format{padding:6px 0}div.sceditor-color-picker,div.sceditor-emoticons,div.sceditor-more-emoticons{padding:0}.sceditor-pastetext textarea{border:1px solid #bbb;width:20em}.sceditor-emoticons img,.sceditor-more-emoticons img{padding:0;cursor:pointer;margin:2px}.sceditor-more{border-top:1px solid #bbb;display:block;text-align:center;cursor:pointer;font-weight:700;padding:6px 0}.sceditor-dropdown a:hover{background:#eee}.sceditor-font-option,.sceditor-fontsize-option,.sceditor-format a{display:block;padding:7px 10px;cursor:pointer;text-decoration:none;color:#222}.sceditor-fontsize-option{padding:7px 13px}.sceditor-color-column{float:left}.sceditor-color-option{display:block;border:1px solid #fff;height:10px;width:10px;overflow:hidden}.sceditor-color-option:hover{border:1px solid #333}div.sceditor-toolbar{overflow:hidden;padding:3px 5px 2px;line-height:0;text-align:left;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:3px 3px 0 0;background-clip:padding-box}div.sceditor-group{display:inline-block;margin:1px 5px 1px 0;border-radius:3px;background-clip:padding-box}.ie6 div.sceditor-group,.ie7 div.sceditor-group{display:inline;zoom:1}.sceditor-button{float:left;cursor:pointer;width:16px;text-indent:-9999px}.ie .sceditor-button{text-indent:0}.ie6 .sceditor-button,.ie7 .sceditor-button{float:none!important;display:inline;zoom:1}.ie6 .sceditor-button{padding:0}.ie6 .sceditor-button div{margin:5px}.ie7 .sceditor-button div{margin:5px 0}.sceditor-button.disabled:hover{background:inherit;cursor:default;box-shadow:none}.sceditor-button,.sceditor-button div{display:block}.sceditor-button div{padding:0;overflow:hidden;line-height:0;font-size:0;color:transparent;margin:0}.sceditor-button.disabled div{filter:alpha(opacity=30);opacity:.3}.sceditor-button.text,.sceditor-button.text div,.sceditor-button.text-icon,.sceditor-button.text-icon div,.text .sceditor-button,.text .sceditor-button div,.text-icon .sceditor-button,.text-icon .sceditor-button div{width:auto;overflow:visible;line-height:16px;font-size:1em;color:inherit;text-indent:0}.sceditor-button.text div,.text .sceditor-button div{padding:0 2px;background:0 0}.sceditor-button.text-icon div,.text-icon .sceditor-button div{padding:0 2px 0 20px}.rtl div.sceditor-toolbar{text-align:right}.rtl .sceditor-button{float:right}.rtl div.sceditor-grip{right:auto;left:0}.sceditor-container{border:1px solid #8db2e3}.sceditor-container textarea{font-family:Consolas,"Bitstream Vera Sans Mono","Andale Mono",Monaco,"DejaVu Sans Mono","Lucida Console",monospace}div.sceditor-toolbar{border-bottom:1px solid #95a9c3;background:#dee8f5;background:linear-gradient(to bottom,#dee8f5 0,#c7d8ed 29%,#ccdcee 61%,#c0d8ef 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dee8f5', endColorstr='#c0d8ef', GradientType=0)}.ie9 div.sceditor-toolbar{-webkit-filter:none;filter:none;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RlZThmNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjI5JSIgc3RvcC1jb2xvcj0iI2M3ZDhlZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjYxJSIgc3RvcC1jb2xvcj0iI2NjZGNlZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNjMGQ4ZWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}div.sceditor-group{border:1px solid #7596bf;padding:0;background:#cadcf0;background:linear-gradient(to bottom,#cadcf0 24%,#bcd0e9 38%,#d0e1f7 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#cadcf0', endColorstr='#d0e1f7', GradientType=0)}.ie9 div.sceditor-group{-webkit-filter:none;filter:none;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIyNCUiIHN0b3AtY29sb3I9IiNjYWRjZjAiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIzOCUiIHN0b3AtY29sb3I9IiNiY2QwZTkiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNkMGUxZjciIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button{height:16px;padding:3px 4px;border-radius:0;background-clip:padding-box;box-shadow:inset 0 1px #d5e3f1,inset 0 -1px #e3edfb,inset 1px 0 #cddcef,inset -1px 0 #b8ceea}.sceditor-button:first-child{border-radius:4px 0 0 4px;background-clip:padding-box}.sceditor-button:last-child{border-radius:0 4px 4px 0;background-clip:padding-box}.ie9 .sceditor-button{-webkit-filter:none!important;filter:none!important}.sceditor-button.active{background:#fbdbb5;background:linear-gradient(to bottom,#fbdbb5 11%,#feb456 29%,#fdeb9f 99%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbdbb5', endColorstr='#fdeb9f', GradientType=0);box-shadow:inset 0 1px #ebd1b4,inset 0 -1px #ffe47f,inset -1px 0 #b8ceea}.ie9 .sceditor-button.active{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIxMSUiIHN0b3AtY29sb3I9IiNmYmRiYjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSIyOSUiIHN0b3AtY29sb3I9IiNmZWI0NTYiIHN0b3Atb3BhY2l0eT0iMSIvPgogICAgPHN0b3Agb2Zmc2V0PSI5OSUiIHN0b3AtY29sb3I9IiNmZGZkOWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button:hover{background:#fef7d5;background:linear-gradient(to bottom,#fef7d5 0,#fae5a9 42%,#ffd048 42%,#ffe59f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fef7d5', endColorstr='#ffe59f', GradientType=0);box-shadow:inset 0 1px #fffbe8,inset -1px 0 #ffefc4,inset 0 -1px #fff9cc}.ie9 .sceditor-button:hover{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZjdkNSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZhZTVhOSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQyJSIgc3RvcC1jb2xvcj0iI2ZmZDA0OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmZmU1OWYiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}.sceditor-button:active{background:#e7a66d;background:linear-gradient(to bottom,#e7a66d 0,#fcb16d 1%,#ff8d05 42%,#ffc450 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e7a66d', endColorstr='#ffc450', GradientType=0);box-shadow:inset 0 1px 1px #7b6645,inset 0 -1px #d19c33}.ie9 .sceditor-button:active{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2U3YTY2ZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjElIiBzdG9wLWNvbG9yPSIjZmNiMTZkIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNDIlIiBzdG9wLWNvbG9yPSIjZmY4ZDA1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZmYzQ1MCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=)}.sceditor-button.active:hover{background:#dba368;background:linear-gradient(to bottom,#dba368 0,#ffbd79 4%,#fea335 34%,#ffc64c 66%,#fee069 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#dba368', endColorstr='#fee069', GradientType=0);box-shadow:inset 0 1px 1px #9e8255,inset 0 -1px #fcce6b}.ie9 .sceditor-button.active:hover{background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RiYTM2OCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQlIiBzdG9wLWNvbG9yPSIjZmZiZDc5IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMzQlIiBzdG9wLWNvbG9yPSIjZmVhMzM1IiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iNjYlIiBzdG9wLWNvbG9yPSIjZmZjNjRjIiBzdG9wLW9wYWNpdHk9IjEiLz4KICAgIDxzdG9wIG9mZnNldD0iMTAwJSIgc3RvcC1jb2xvcj0iI2ZlZTA2OSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgPC9saW5lYXJHcmFkaWVudD4KICA8cmVjdCB4PSIwIiB5PSIwIiB3aWR0aD0iMSIgaGVpZ2h0PSIxIiBmaWxsPSJ1cmwoI2dyYWQtdWNnZy1nZW5lcmF0ZWQpIiAvPgo8L3N2Zz4=)}.sceditor-container{background:#a3c2ea;background:linear-gradient(to bottom,#a3c2ea 0,#6d92c1 39%,#577fb3 64%,#6591cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#a3c2ea', endColorstr='#6591cc', GradientType=0)}.sceditor-container iframe,.sceditor-container textarea{border:1px solid #646464;background:#fff;margin:7px 40px;padding:20px;box-shadow:1px 1px 5px #293a52} \ No newline at end of file diff --git a/stylesheets/sceditor/themes/square.min.css b/stylesheets/sceditor/themes/square.min.css new file mode 100644 index 00000000..baa91dee --- /dev/null +++ b/stylesheets/sceditor/themes/square.min.css @@ -0,0 +1 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */.sceditor-button div,div.sceditor-grip{background-image:url(famfamfam.png);background-repeat:no-repeat;width:16px;height:16px}.sceditor-button-youtube div{background-position:0 0}.sceditor-button-link div{background-position:0 -16px}.sceditor-button-unlink div{background-position:0 -32px}.sceditor-button-underline div{background-position:0 -48px}.sceditor-button-time div{background-position:0 -64px}.sceditor-button-table div{background-position:0 -80px}.sceditor-button-superscript div{background-position:0 -96px}.sceditor-button-subscript div{background-position:0 -112px}.sceditor-button-strike div{background-position:0 -128px}.sceditor-button-source div{background-position:0 -144px}.sceditor-button-size div{background-position:0 -160px}.sceditor-button-rtl div{background-position:0 -176px}.sceditor-button-right div{background-position:0 -192px}.sceditor-button-removeformat div{background-position:0 -208px}.sceditor-button-quote div{background-position:0 -224px}.sceditor-button-print div{background-position:0 -240px}.sceditor-button-pastetext div{background-position:0 -256px}.sceditor-button-paste div{background-position:0 -272px}.sceditor-button-outdent div{background-position:0 -288px}.sceditor-button-orderedlist div{background-position:0 -304px}.sceditor-button-maximize div{background-position:0 -320px}.sceditor-button-ltr div{background-position:0 -336px}.sceditor-button-left div{background-position:0 -352px}.sceditor-button-justify div{background-position:0 -368px}.sceditor-button-italic div{background-position:0 -384px}.sceditor-button-indent div{background-position:0 -400px}.sceditor-button-image div{background-position:0 -416px}.sceditor-button-horizontalrule div{background-position:0 -432px}.sceditor-button-format div{background-position:0 -448px}.sceditor-button-font div{background-position:0 -464px}.sceditor-button-emoticon div{background-position:0 -480px}.sceditor-button-email div{background-position:0 -496px}.sceditor-button-date div{background-position:0 -512px}.sceditor-button-cut div{background-position:0 -528px}.sceditor-button-copy div{background-position:0 -544px}.sceditor-button-color div{background-position:0 -560px}.sceditor-button-code div{background-position:0 -576px}.sceditor-button-center div{background-position:0 -592px}.sceditor-button-bulletlist div{background-position:0 -608px}.sceditor-button-bold div{background-position:0 -624px}div.sceditor-grip{background-position:0 -640px}.rtl div.sceditor-grip{background-position:0 -650px;width:10px;height:10px}.sceditor-container{position:relative;background:#fff;font-size:13px;font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;color:#222;line-height:1;font-weight:700}.sceditor-container *,.sceditor-container :after,.sceditor-container :before{box-sizing:content-box}.sceditor-container,.sceditor-container div,div.sceditor-dropdown,div.sceditor-dropdown div{padding:0;margin:0;z-index:3}.sceditor-container iframe,.sceditor-container textarea{line-height:1;border:0;outline:0;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:13px;color:#111;padding:0;margin:5px;resize:none;background:#fff;display:block}div.sceditor-resize-cover{position:absolute;top:0;left:0;background:#000;width:100%;height:100%;z-index:10;opacity:.3}.ie6 div.sceditor-resize-cover,.ie7 div.sceditor-resize-cover,.ie8 div.sceditor-resize-cover{background:#efefef}.sceditor-maximize,.sceditor-maximize div.sceditor-toolbar{border-radius:0;background-clip:padding-box}.sceditor-container.ie6{overflow:hidden}div.sceditor-grip{overflow:hidden;width:10px;height:10px;cursor:pointer;position:absolute;bottom:0;right:0;z-index:3}.sceditor-maximize{position:fixed;top:0;left:0;height:100%!important;width:100%!important;z-index:2000}body.sceditor-maximize,html.sceditor-maximize{height:100%;width:100%;padding:0;margin:0;overflow:hidden}.ie6.sceditor-maximize{position:absolute}.sceditor-maximize div.sceditor-grip{display:none}div.sceditor-dropdown{position:absolute;border:1px solid #ccc;background:#fff;color:#333;z-index:4000;padding:10px;line-height:1;border-radius:2px;background-clip:padding-box;box-shadow:1px 2px 4px rgba(0,0,0,.2)}div.sceditor-dropdown a,div.sceditor-dropdown a:link{color:#333}div.sceditor-dropdown form{margin:0}div.sceditor-dropdown label{display:block;font-weight:700;color:#3c3c3c;padding:4px 0}div.sceditor-dropdown input,div.sceditor-dropdown textarea{font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;outline:0;padding:4px;border:1px solid #ccc;border-top-color:#888;margin:0 0 .75em;border-radius:1px;background-clip:padding-box}div.sceditor-dropdown textarea{padding:6px}div.sceditor-dropdown input:focus,div.sceditor-dropdown textarea:focus{border-color:#666 #aaa #aaa;box-shadow:inset 0 1px 5px rgba(0,0,0,.1)}div.sceditor-dropdown .button{font-weight:700;color:#444;padding:6px 12px;background:#ececec;border:1px solid #ccc;border-radius:2px;background-clip:padding-box;cursor:pointer;margin:.3em 0 0}div.sceditor-dropdown .button:hover{background:#f3f3f3;box-shadow:0 1px 1px rgba(0,0,0,.15)}div.sceditor-font-picker,div.sceditor-fontsize-picker,div.sceditor-format{padding:6px 0}div.sceditor-color-picker,div.sceditor-emoticons,div.sceditor-more-emoticons{padding:0}.sceditor-pastetext textarea{border:1px solid #bbb;width:20em}.sceditor-emoticons img,.sceditor-more-emoticons img{padding:0;cursor:pointer;margin:2px}.sceditor-more{border-top:1px solid #bbb;display:block;text-align:center;cursor:pointer;font-weight:700;padding:6px 0}.sceditor-dropdown a:hover{background:#eee}.sceditor-font-option,.sceditor-fontsize-option,.sceditor-format a{display:block;padding:7px 10px;cursor:pointer;text-decoration:none;color:#222}.sceditor-fontsize-option{padding:7px 13px}.sceditor-color-column{float:left}.sceditor-color-option{display:block;border:1px solid #fff;height:10px;width:10px;overflow:hidden}.sceditor-color-option:hover{border:1px solid #333}div.sceditor-toolbar{overflow:hidden;line-height:0;text-align:left;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:3px 3px 0 0;background-clip:padding-box}div.sceditor-group{display:inline-block}.ie6 div.sceditor-group,.ie7 div.sceditor-group{display:inline;zoom:1}.sceditor-button{float:left;cursor:pointer;width:16px;text-indent:-9999px}.ie .sceditor-button{text-indent:0}.ie6 .sceditor-button,.ie7 .sceditor-button{float:none!important;display:inline;zoom:1}.ie6 .sceditor-button{padding:0}.ie6 .sceditor-button div{margin:5px}.ie7 .sceditor-button div{margin:5px 0}.sceditor-button.disabled:hover{background:inherit;cursor:default;box-shadow:none}.sceditor-button,.sceditor-button div{display:block}.sceditor-button div{padding:0;overflow:hidden;line-height:0;font-size:0;color:transparent}.sceditor-button.disabled div{filter:alpha(opacity=30);opacity:.3}.sceditor-button.text,.sceditor-button.text div,.sceditor-button.text-icon,.sceditor-button.text-icon div,.text .sceditor-button,.text .sceditor-button div,.text-icon .sceditor-button,.text-icon .sceditor-button div{width:auto;overflow:visible;line-height:16px;font-size:1em;color:inherit;text-indent:0}.sceditor-button.text div,.text .sceditor-button div{padding:0 2px;background:0 0}.sceditor-button.text-icon div,.text-icon .sceditor-button div{padding:0 2px 0 20px}.rtl div.sceditor-toolbar{text-align:right}.rtl .sceditor-button{float:right}.rtl div.sceditor-grip{right:auto;left:0}.sceditor-container{border:1px solid #d6d6d6;border-radius:0;background-clip:padding-box}.sceditor-container textarea{font-family:Consolas,"Bitstream Vera Sans Mono","Andale Mono",Monaco,"DejaVu Sans Mono","Lucida Console",monospace;background:#2e3436;color:#fff;margin:0;padding:5px}div.sceditor-group,div.sceditor-toolbar{background:#f2f2f2;background:linear-gradient(to bottom,#f2f2f2 0,#ddd 89%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f2f2f2', endColorstr='#dddddd', GradientType=0)}div.sceditor-toolbar{padding:0;border-bottom:1px solid #bbb;background-size:100% 32px}div.sceditor-group{margin:0;padding:2px 4px;border:0;border-right:1px solid #ccc;border-left:1px solid #eaeaea;border-radius:0;background-clip:padding-box}div.sceditor-group:last-child{border-right:0}div.sceditor-group:first-child{border-left:0}.sceditor-button{height:16px;padding:5px;margin:1px;border-radius:0;background-clip:padding-box}.sceditor-button div{margin:0}.sceditor-button.active,.sceditor-button.active:hover,.sceditor-button:active,.sceditor-button:hover{margin:0;box-shadow:none}.sceditor-button.active{background:#f4f4f4;border:1px solid #ccc}.sceditor-button:hover{background:#fefefe;border:1px solid #ddd}.sceditor-button.disabled:hover{margin:1px;border:0}.sceditor-button:active{background:#eee;border:1px solid #ccc}.sceditor-button.active:hover{background:#f8f8f8;border:1px solid #ddd} \ No newline at end of file diff --git a/stylesheets/sceditor/themes/transparent.min.css b/stylesheets/sceditor/themes/transparent.min.css new file mode 100644 index 00000000..9b716fe0 --- /dev/null +++ b/stylesheets/sceditor/themes/transparent.min.css @@ -0,0 +1,3 @@ +/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */.sceditor-button div,div.sceditor-grip{background-image:url(famfamfam.png);background-repeat:no-repeat;width:16px;height:16px}.sceditor-button-youtube div{background-position:0 0}.sceditor-button-link div{background-position:0 -16px}.sceditor-button-unlink div{background-position:0 -32px}.sceditor-button-underline div{background-position:0 -48px}.sceditor-button-time div{background-position:0 -64px}.sceditor-button-table div{background-position:0 -80px}.sceditor-button-superscript div{background-position:0 -96px}.sceditor-button-subscript div{background-position:0 -112px}.sceditor-button-strike div{background-position:0 -128px}.sceditor-button-source div{background-position:0 -144px}.sceditor-button-size div{background-position:0 -160px}.sceditor-button-rtl div{background-position:0 -176px}.sceditor-button-right div{background-position:0 -192px}.sceditor-button-removeformat div{background-position:0 -208px}.sceditor-button-quote div{background-position:0 -224px}.sceditor-button-print div{background-position:0 -240px}.sceditor-button-pastetext div{background-position:0 -256px}.sceditor-button-paste div{background-position:0 -272px}.sceditor-button-outdent div{background-position:0 -288px}.sceditor-button-orderedlist div{background-position:0 -304px}.sceditor-button-maximize div{background-position:0 -320px}.sceditor-button-ltr div{background-position:0 -336px}.sceditor-button-left div{background-position:0 -352px}.sceditor-button-justify div{background-position:0 -368px}.sceditor-button-italic div{background-position:0 -384px}.sceditor-button-indent div{background-position:0 -400px}.sceditor-button-image div{background-position:0 -416px}.sceditor-button-horizontalrule div{background-position:0 -432px}.sceditor-button-format div{background-position:0 -448px}.sceditor-button-font div{background-position:0 -464px}.sceditor-button-emoticon div{background-position:0 -480px}.sceditor-button-email div{background-position:0 -496px}.sceditor-button-date div{background-position:0 -512px}.sceditor-button-cut div{background-position:0 -528px}.sceditor-button-copy div{background-position:0 -544px}.sceditor-button-color div{background-position:0 -560px}.sceditor-button-code div{background-position:0 -576px}.sceditor-button-center div{background-position:0 -592px}.sceditor-button-bulletlist div{background-position:0 -608px}.sceditor-button-bold div{background-position:0 -624px}div.sceditor-grip{background-position:0 -640px}.rtl div.sceditor-grip{background-position:0 -650px;width:10px;height:10px}.sceditor-container{position:relative;background:transparent;border:1px solid #d9d9d9;font-size:13px;font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;color:#222;line-height:1;font-weight:700;border-radius:4px;background-clip:padding-box}.sceditor-container *,.sceditor-container :after,.sceditor-container :before{box-sizing:content-box}.sceditor-container,.sceditor-container div,div.sceditor-dropdown,div.sceditor-dropdown div{padding:0;margin:0;z-index:3}.sceditor-container iframe,.sceditor-container textarea{line-height:1;border:0;outline:0;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:13px;color:#111;padding:0;margin:5px;resize:none;background:transparent;display:block}div.sceditor-resize-cover{position:absolute;top:0;left:0;background:#000;width:100%;height:100%;z-index:10;opacity:.3}.ie6 div.sceditor-resize-cover,.ie7 div.sceditor-resize-cover,.ie8 div.sceditor-resize-cover{background:#efefef}.sceditor-maximize,.sceditor-maximize div.sceditor-toolbar{border-radius:0;background-clip:padding-box}.sceditor-container.ie6{overflow:hidden}div.sceditor-grip{overflow:hidden;width:10px;height:10px;cursor:pointer;position:absolute;bottom:0;right:0;z-index:3}.sceditor-maximize{position:fixed;top:0;left:0;height:100%!important;width:100%!important;z-index:2000}body.sceditor-maximize,html.sceditor-maximize{height:100%;width:100%;padding:0;margin:0;overflow:hidden}.ie6.sceditor-maximize{position:absolute}.sceditor-maximize div.sceditor-grip{display:none}div.sceditor-dropdown{position:absolute;border:1px solid #ccc;background:#transparent;color:#333;z-index:4000;padding:10px;line-height:1;border-radius:2px;background-clip:padding-box;box-shadow:1px 2px 4px rgba(0,0,0,.2)}div.sceditor-dropdown a,div.sceditor-dropdown a:link{color:#333}div.sceditor-dropdown form{margin:0}div.sceditor-dropdown label{display:block;font-weight:700;color:#3c3c3c;padding:4px 0}div.sceditor-dropdown input,div.sceditor-dropdown textarea{font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;outline:0;padding:4px;border:1px solid #ccc;border-top-color:#888;margin:0 0 .75em;border-radius:1px;background-clip:padding-box}div.sceditor-dropdown textarea{padding:6px}div.sceditor-dropdown input:focus,div.sceditor-dropdown textarea:focus{border-color:#666 #aaa #aaa;box-shadow:inset 0 1px 5px rgba(0,0,0,.1)}div.sceditor-dropdown .button{font-weight:700;color:#444;padding:6px 12px;background:#ececec;border:1px solid #ccc;border-radius:2px;background-clip:padding-box;cursor:pointer;margin:.3em 0 0}div.sceditor-dropdown .button:hover{background:#f3f3f3;box-shadow:0 1px 1px rgba(0,0,0,.15)}div.sceditor-font-picker,div.sceditor-fontsize-picker,div.sceditor-format{padding:6px 0}div.sceditor-color-picker,div.sceditor-emoticons,div.sceditor-more-emoticons{padding:0}.sceditor-pastetext textarea{border:1px solid #bbb;width:20em}.sceditor-emoticons img,.sceditor-more-emoticons img{padding:0;cursor:pointer;margin:2px}.sceditor-more{border-top:1px solid #bbb;display:block;text-align:center;cursor:pointer;font-weight:700;padding:6px 0}.sceditor-dropdown a:hover{background:#eee}.sceditor-font-option,.sceditor-fontsize-option,.sceditor-format a{display:block;padding:7px 10px;cursor:pointer;text-decoration:none;color:#222}.sceditor-fontsize-option{padding:7px 13px}.sceditor-color-column{float:left}.sceditor-color-option{display:block;border:1px solid #fff;height:10px;width:10px;overflow:hidden}.sceditor-color-option:hover{border:1px solid #333}div.sceditor-toolbar{overflow:hidden;padding:3px 5px 2px;background:transparent;border-bottom:1px solid silver;line-height:0;text-align:left;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border-radius:3px 3px 0 0;background-clip:padding-box}div.sceditor-group{display:inline-block;background:#ddd;margin:1px 5px 1px 0;padding:1px;border-bottom:1px solid #aaa;border-radius:3px;background-clip:padding-box}.ie6 div.sceditor-group,.ie7 div.sceditor-group{display:inline;zoom:1}.sceditor-button{float:left;cursor:pointer;padding:3px 5px;width:16px;height:20px;border-radius:3px;background-clip:padding-box;text-indent:-9999px}.ie .sceditor-button{text-indent:0}.ie6 .sceditor-button,.ie7 .sceditor-button{float:none!important;display:inline;zoom:1}.ie6 .sceditor-button{padding:0}.ie6 .sceditor-button div{margin:5px}.ie7 .sceditor-button div{margin:5px 0}.sceditor-button.active,.sceditor-button:active,.sceditor-button:hover{background:#fff;box-shadow:inset 1px 1px 0 rgba(0,0,0,.3),inset -1px 0 rgba(0,0,0,.3),inset 0 -1px 0 rgba(0,0,0,.2)}.sceditor-button:active{background:#fff;box-shadow:inset 1px 1px 0 rgba(0,0,0,.3),inset -1px 0 rgba(0,0,0,.3),inset 0 -1px 0 rgba(0,0,0,.2),inset 0 0 8px rgba(0,0,0,.3)}.sceditor-button.disabled:hover{background:inherit;cursor:default;box-shadow:none}.sceditor-button,.sceditor-button div{display:block}.sceditor-button div{margin:2px 0;padding:0;overflow:hidden;line-height:0;font-size:0;color:transparent}.sceditor-button.disabled div{filter:alpha(opacity=30);opacity:.3}.sceditor-button.text,.sceditor-button.text div,.sceditor-button.text-icon,.sceditor-button.text-icon div,.text .sceditor-button,.text .sceditor-button div,.text-icon .sceditor-button,.text-icon .sceditor-button div{width:auto;overflow:visible;line-height:16px;font-size:1em;color:inherit;text-indent:0}.sceditor-button.text div,.text .sceditor-button div{padding:0 2px;background:0 0}.sceditor-button.text-icon div,.text-icon .sceditor-button div{padding:0 2px 0 20px}.rtl div.sceditor-toolbar{text-align:right}.rtl .sceditor-button{float:right}.rtl div.sceditor-grip{right:auto;left:0} .sceditor-button-t div { background: url('/static/headingiconsceditor.png'); } .sceditor-button-spoiler div { background: url('/static/spoilericonsceditor.png'); } span.heading {color: #AF0A0F; font-size: 11pt; font-weight: bold;} span.spoiler { background: black;color: black; padding: 0 1px; } div.post.reply div.body span.spoiler a { color: black; } span.spoiler:hover,div.post.reply div.body span.spoiler:hover a {color: white;} + +