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", + "
"); +} + +$('.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 theSets 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]
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 = $('' + (IE_VER ? '' : '
') + '
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); + + // Lastor
Binds a handler to the specified events
+ * + *This function only binds to a limited list of
+ * supported events.
+ * The supported events are:
+ *
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 = $('', $wysiwygDoc[0]) + .appendTo($wysiwygDoc.find('head'))[0]; + } + + if (typeof css !== 'string') { + return inlineCss.styleSheet ? + inlineCss.styleSheet.cssText : inlineCss.innerHTML; + } + + if (inlineCss.styleSheet) { + inlineCss.styleSheet.cssText = css; + } else { + inlineCss.innerHTML = css; + } + + return base; + }; + + /** + * Handles the keydown event, used for shortcuts + * @private + */ + handleKeyDown = function (e) { + var shortcut = [], + SHIFT_KEYS = { + '`': '~', + '1': '!', + '2': '@', + '3': '#', + '4': '$', + '5': '%', + '6': '^', + '7': '&', + '8': '*', + '9': '(', + '0': ')', + '-': '_', + '=': '+', + ';': ': ', + '\'': '"', + ',': '<', + '.': '>', + '/': '?', + '\\': '|', + '[': '{', + ']': '}' + }, + SPECIAL_KEYS = { + 8: 'backspace', + 9: 'tab', + 13: 'enter', + 19: 'pause', + 20: 'capslock', + 27: 'esc', + 32: 'space', + 33: 'pageup', + 34: 'pagedown', + 35: 'end', + 36: 'home', + 37: 'left', + 38: 'up', + 39: 'right', + 40: 'down', + 45: 'insert', + 46: 'del', + 91: 'win', + 92: 'win', + 93: 'select', + 96: '0', + 97: '1', + 98: '2', + 99: '3', + 100: '4', + 101: '5', + 102: '6', + 103: '7', + 104: '8', + 105: '9', + 106: '*', + 107: '+', + 109: '-', + 110: '.', + 111: '/', + 112: 'f1', + 113: 'f2', + 114: 'f3', + 115: 'f4', + 116: 'f5', + 117: 'f6', + 118: 'f7', + 119: 'f8', + 120: 'f9', + 121: 'f10', + 122: 'f11', + 123: 'f12', + 144: 'numlock', + 145: 'scrolllock', + 186: ';', + 187: '=', + 188: ',', + 189: '-', + 190: '.', + 191: '/', + 192: '`', + 219: '[', + 220: '\\', + 221: ']', + 222: '\'' + }, + NUMPAD_SHIFT_KEYS = { + 109: '-', + 110: 'del', + 111: '/', + 96: '0', + 97: '1', + 98: '2', + 99: '3', + 100: '4', + 101: '5', + 102: '6', + 103: '7', + 104: '8', + 105: '9' + }, + which = e.which, + character = SPECIAL_KEYS[which] || + String.fromCharCode(which).toLowerCase(); + + if (e.ctrlKey || e.metaKey) { + shortcut.push('ctrl'); + } + + if (e.altKey) { + shortcut.push('alt'); + } + + if (e.shiftKey) { + shortcut.push('shift'); + + if (NUMPAD_SHIFT_KEYS[which]) { + character = NUMPAD_SHIFT_KEYS[which]; + } else if (SHIFT_KEYS[character]) { + character = SHIFT_KEYS[character]; + } + } + + // Shift is 16, ctrl is 17 and alt is 18 + if (character && (which < 16 || which > 18)) { + shortcut.push(character); + } + + shortcut = shortcut.join('+'); + if (shortcutHandlers[shortcut]) { + return shortcutHandlers[shortcut].call(base); + } + }; + + /** + * Adds a shortcut handler to the editor + * @param {String} shortcut + * @param {String|Function} cmd + * @return {jQuery.sceditor} + */ + base.addShortcut = function (shortcut, cmd) { + shortcut = shortcut.toLowerCase(); + + if (typeof cmd === 'string') { + shortcutHandlers[shortcut] = function () { + handleCommand( + toolbarButtons[cmd], + base.commands[cmd] + ); + + return false; + }; + } else { + shortcutHandlers[shortcut] = cmd; + } + + return base; + }; + + /** + * Removes a shortcut handler + * @param {String} shortcut + * @return {jQuery.sceditor} + */ + base.removeShortcut = function (shortcut) { + delete shortcutHandlers[shortcut.toLowerCase()]; + + return base; + }; + + /** + * Handles the backspace key press + * + * Will remove block styling like quotes/code ect if at the start. + * @private + */ + handleBackSpace = function (e) { + var node, offset, tmpRange, range, parent; + + // 8 is the backspace key + if (options.disableBlockRemove || e.which !== 8 || + !(range = rangeHelper.selectedRange())) { + return; + } + + if (!globalWin.getSelection) { + node = range.parentElement(); + tmpRange = $wysiwygDoc[0].selection.createRange(); + + // Select the entire parent and set the end + // as start of the current range + tmpRange.moveToElementText(node); + tmpRange.setEndPoint('EndToStart', range); + + // Number of characters selected is the start offset + // relative to the parent node + offset = tmpRange.text.length; + } else { + node = range.startContainer; + offset = range.startOffset; + } + + if (offset !== 0 || !(parent = currentStyledBlockNode())) { + return; + } + + while (node !== parent) { + while (node.previousSibling) { + node = node.previousSibling; + + // Everything but empty text nodes before the cursor + // should prevent the style from being removed + if (node.nodeType !== 3 || node.nodeValue) { + return; + } + } + + if (!(node = node.parentNode)) { + return; + } + } + + if (!parent || $(parent).is('body')) { + return; + } + + // The backspace was pressed at the start of + // the container so clear the style + base.clearBlockFormatting(parent); + return false; + }; + + /** + * Gets the first styled block node that contains the cursor + * @return {HTMLElement} + */ + currentStyledBlockNode = function () { + var block = currentBlockNode; + + while (!dom.hasStyling(block) || dom.isInline(block, true)) { + if (!(block = block.parentNode) || $(block).is('body')) { + return; + } + } + + return block; + }; + + /** + * Clears the formatting of the passed block element. + * + * If block is false, if will clear the styling of the first + * block level element that contains the cursor. + * @param {HTMLElement} block + * @since 1.4.4 + */ + base.clearBlockFormatting = function (block) { + block = block || currentStyledBlockNode(); + + if (!block || $(block).is('body')) { + return base; + } + + rangeHelper.saveRange(); + + block.className = ''; + lastRange = null; + + $(block).attr('style', ''); + + if (!$(block).is('p,div,td')) { + dom.convertElement(block, 'p'); + } + + rangeHelper.restoreRange(); + return base; + }; + + /** + * Triggers the valueChanged signal if there is + * a plugin that handles it. + * + * If rangeHelper.saveRange() has already been + * called, then saveRange should be set to false + * to prevent the range being saved twice. + * + * @since 1.4.5 + * @param {Boolean} saveRange If to call rangeHelper.saveRange(). + * @private + */ + triggerValueChanged = function (saveRange) { + if (!pluginManager || + (!pluginManager.hasHandler('valuechangedEvent') && + !triggerValueChanged.hasHandler)) { + return; + } + + var currentHtml, + sourceMode = base.sourceMode(), + hasSelection = !sourceMode && rangeHelper.hasSelection(); + + // Don't need to save the range if sceditor-start-marker + // is present as the range is already saved + saveRange = saveRange !== false && + !$wysiwygDoc[0].getElementById('sceditor-start-marker'); + + // Clear any current timeout as it's now been triggered + if (valueChangedKeyUp.timer) { + clearTimeout(valueChangedKeyUp.timer); + valueChangedKeyUp.timer = false; + } + + if (hasSelection && saveRange) { + rangeHelper.saveRange(); + } + + currentHtml = sourceMode ? + $sourceEditor.val() : + $wysiwygBody.html(); + + // Only trigger if something has actually changed. + if (currentHtml !== triggerValueChanged.lastHtmlValue) { + triggerValueChanged.lastHtmlValue = currentHtml; + + $editorContainer.trigger($.Event('valuechanged', { + rawValue: sourceMode ? base.val() : currentHtml + })); + } + + if (hasSelection && saveRange) { + rangeHelper.removeMarkers(); + } + }; + + /** + * Should be called whenever there is a blur event + * @private + */ + valueChangedBlur = function () { + if (valueChangedKeyUp.timer) { + triggerValueChanged(); + } + }; + + /** + * Should be called whenever there is a keypress event + * @param {Event} e The keypress event + * @private + */ + valueChangedKeyUp = function (e) { + var which = e.which, + lastChar = valueChangedKeyUp.lastChar, + lastWasSpace = (lastChar === 13 || lastChar === 32), + lastWasDelete = (lastChar === 8 || lastChar === 46); + + valueChangedKeyUp.lastChar = which; + + // 13 = return & 32 = space + if (which === 13 || which === 32) { + if (!lastWasSpace) { + triggerValueChanged(); + } else { + valueChangedKeyUp.triggerNextChar = true; + } + // 8 = backspace & 46 = del + } else if (which === 8 || which === 46) { + if (!lastWasDelete) { + triggerValueChanged(); + } else { + valueChangedKeyUp.triggerNextChar = true; + } + } else if (valueChangedKeyUp.triggerNextChar) { + triggerValueChanged(); + valueChangedKeyUp.triggerNextChar = false; + } + + // Clear the previous timeout and set a new one. + if (valueChangedKeyUp.timer) { + clearTimeout(valueChangedKeyUp.timer); + } + + // Trigger the event 1.5s after the last keypress if space + // isn't pressed. This might need to be lowered, will need + // to look into what the slowest average Chars Per Min is. + valueChangedKeyUp.timer = setTimeout(function () { + triggerValueChanged(); + }, 1500); + }; + + autoUpdate = function () { + if (!autoUpdateCanceled) { + base.updateOriginal(); + } + + autoUpdateCanceled = false; + }; + + // run the initializer + init(); + }; + + + /** + * Map containing the loaded SCEditor locales + * @type {Object} + * @name locale + * @memberOf jQuery.sceditor + */ + SCEditor.locale = {}; + + + /** + * Static command helper class + * @class command + * @name jQuery.sceditor.command + */ + SCEditor.command = + /** @lends jQuery.sceditor.command */ + { + /** + * Gets a command + * + * @param {String} name + * @return {Object|null} + * @since v1.3.5 + */ + get: function (name) { + return SCEditor.commands[name] || null; + }, + + /** + *Adds a command to the editor or updates an existing + * command if a command with the specified name already exists.
+ * + *Once a command is add it can be included in the toolbar by + * adding it's name to the toolbar option in the constructor. It + * can also be executed manually by calling + * {@link jQuery.sceditor.execCommand}
+ * + * @example + * SCEditor.command.set("hello", + * { + * exec: function () { + * alert("Hello World!"); + * } + * }); + * + * @param {String} name + * @param {Object} cmd + * @return {this|false} Returns false if name or cmd is false + * @since v1.3.5 + */ + set: function (name, cmd) { + if (!name || !cmd) { + return false; + } + + // merge any existing command properties + cmd = $.extend(SCEditor.commands[name] || {}, cmd); + + cmd.remove = function () { + SCEditor.command.remove(name); + }; + + SCEditor.commands[name] = cmd; + return this; + }, + + /** + * Removes a command + * + * @param {String} name + * @return {this} + * @since v1.3.5 + */ + remove: function (name) { + if (SCEditor.commands[name]) { + delete SCEditor.commands[name]; + } + + return this; + } + }; + + return SCEditor; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { + 'use strict'; + + var plugins = {}; + + /** + * Plugin Manager class + * @class PluginManager + * @name PluginManager + */ + var PluginManager = function (thisObj) { + /** + * Alias of this + * + * @private + * @type {Object} + */ + var base = this; + + /** + * Array of all currently registered plugins + * + * @type {Array} + * @private + */ + var registeredPlugins = []; + + + /** + * Changes a signals name from "name" into "signalName". + * + * @param {String} signal + * @return {String} + * @private + */ + var formatSignalName = function (signal) { + return 'signal' + signal.charAt(0).toUpperCase() + signal.slice(1); + }; + + /** + * Calls handlers for a signal + * + * @see call() + * @see callOnlyFirst() + * @param {Array} args + * @param {Boolean} returnAtFirst + * @return {Mixed} + * @private + */ + var callHandlers = function (args, returnAtFirst) { + args = [].slice.call(args); + + var idx, ret, + signal = formatSignalName(args.shift()); + + for (idx = 0; idx < registeredPlugins.length; idx++) { + if (signal in registeredPlugins[idx]) { + ret = registeredPlugins[idx][signal].apply(thisObj, args); + + if (returnAtFirst) { + return ret; + } + } + } + }; + + /** + * Calls all handlers for the passed signal + * + * @param {String} signal + * @param {...String} args + * @return {Void} + * @function + * @name call + * @memberOf PluginManager.prototype + */ + base.call = function () { + callHandlers(arguments, false); + }; + + /** + * Calls the first handler for a signal, and returns the + * + * @param {String} signal + * @param {...String} args + * @return {Mixed} The result of calling the handler + * @function + * @name callOnlyFirst + * @memberOf PluginManager.prototype + */ + base.callOnlyFirst = function () { + return callHandlers(arguments, true); + }; + + /** + * Checks if a signal has a handler + * + * @param {String} signal + * @return {Boolean} + * @function + * @name hasHandler + * @memberOf PluginManager.prototype + */ + base.hasHandler = function (signal) { + var i = registeredPlugins.length; + signal = formatSignalName(signal); + + while (i--) { + if (signal in registeredPlugins[i]) { + return true; + } + } + + return false; + }; + + /** + * Checks if the plugin exists in plugins + * + * @param {String} plugin + * @return {Boolean} + * @function + * @name exists + * @memberOf PluginManager.prototype + */ + base.exists = function (plugin) { + if (plugin in plugins) { + plugin = plugins[plugin]; + + return typeof plugin === 'function' && + typeof plugin.prototype === 'object'; + } + + return false; + }; + + /** + * Checks if the passed plugin is currently registered. + * + * @param {String} plugin + * @return {Boolean} + * @function + * @name isRegistered + * @memberOf PluginManager.prototype + */ + base.isRegistered = function (plugin) { + if (base.exists(plugin)) { + var idx = registeredPlugins.length; + + while (idx--) { + if (registeredPlugins[idx] instanceof plugins[plugin]) { + return true; + } + } + } + + return false; + }; + + /** + * Registers a plugin to receive signals + * + * @param {String} plugin + * @return {Boolean} + * @function + * @name register + * @memberOf PluginManager.prototype + */ + base.register = function (plugin) { + if (!base.exists(plugin) || base.isRegistered(plugin)) { + return false; + } + + plugin = new plugins[plugin](); + registeredPlugins.push(plugin); + + if ('init' in plugin) { + plugin.init.call(thisObj); + } + + return true; + }; + + /** + * Deregisters a plugin. + * + * @param {String} plugin + * @return {Boolean} + * @function + * @name deregister + * @memberOf PluginManager.prototype + */ + base.deregister = function (plugin) { + var removedPlugin, + pluginIdx = registeredPlugins.length, + removed = false; + + if (!base.isRegistered(plugin)) { + return removed; + } + + while (pluginIdx--) { + if (registeredPlugins[pluginIdx] instanceof plugins[plugin]) { + removedPlugin = registeredPlugins.splice(pluginIdx, 1)[0]; + removed = true; + + if ('destroy' in removedPlugin) { + removedPlugin.destroy.call(thisObj); + } + } + } + + return removed; + }; + + /** + * Clears all plugins and removes the owner reference. + * + * Calling any functions on this object after calling + * destroy will cause a JS error. + * + * @name destroy + * @memberOf PluginManager.prototype + */ + base.destroy = function () { + var i = registeredPlugins.length; + + while (i--) { + if ('destroy' in registeredPlugins[i]) { + registeredPlugins[i].destroy.call(thisObj); + } + } + + registeredPlugins = []; + thisObj = null; + }; + }; + + PluginManager.plugins = plugins; + + return PluginManager; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var dom = __webpack_require__(5); + var escape = __webpack_require__(7); + var browser = __webpack_require__(6); + + 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; + + + var _nodeToHtml = function (node) { + return $('', node.ownerDocument).append(node).html(); + }; + + /** + * Gets the text, start/end node and offset for + * length chars left or right of the passed node + * at the specified offset. + * + * @param {Node} node + * @param {Number} offset + * @param {Boolean} isLeft + * @param {Number} length + * @return {Object} + * @private + */ + var outerText = function (range, isLeft, length) { + var nodeValue, remaining, start, end, node, + text = '', + next = range.startContainer, + offset = range.startOffset; + + // Handle cases where node is a paragraph and offset + // refers to the index of a text node. + // 3 = text node + if (next && next.nodeType !== 3) { + next = next.childNodes[offset]; + offset = 0; + } + + start = end = offset; + + while (length > text.length && next && next.nodeType === 3) { + nodeValue = next.nodeValue; + remaining = length - text.length; + + // If not the first node, start and end should be at their + // max values as will be updated when getting the text + if (node) { + end = nodeValue.length; + start = 0; + } + + node = next; + + if (isLeft) { + start = Math.max(end - remaining, 0); + offset = start; + + text = nodeValue.substr(start, end - start) + text; + next = node.previousSibling; + } else { + end = Math.min(remaining, nodeValue.length); + offset = start + end; + + text += nodeValue.substr(start, end); + next = node.nextSibling; + } + } + + return { + node: node || next, + offset: offset, + text: text + }; + }; + + var RangeHelper = function (w, d) { + var _createMarker, _isOwner, _prepareInput, + doc = d || w.contentDocument || w.document, + win = w, + isW3C = !!w.getSelection, + startMarker = 'sceditor-start-marker', + endMarker = 'sceditor-end-marker', + CHARACTER = 'character', // Used to improve minification + base = this; + + /** + *
Inserts HTML into the current range replacing any selected + * text.
+ * + *If endHTML is specified the selected contents will be put between + * html and endHTML. If there is nothing selected html and endHTML are + * just concatenate together.
+ * + * @param {string} html + * @param {string} endHTML + * @return False on fail + * @function + * @name insertHTML + * @memberOf RangeHelper.prototype + */ + base.insertHTML = function (html, endHTML) { + var node, div, + range = base.selectedRange(); + + if (!range) { + return false; + } + + if (isW3C) { + if (endHTML) { + html += base.selectedHtml() + endHTML; + } + + div = doc.createElement('p'); + node = doc.createDocumentFragment(); + div.innerHTML = html; + + while (div.firstChild) { + node.appendChild(div.firstChild); + } + + base.insertNode(node); + } else { + range.pasteHTML(_prepareInput(html, endHTML, true)); + base.restoreRange(); + } + }; + + /** + * Prepares HTML to be inserted by adding a zero width space + * if the last child is empty and adding the range start/end + * markers to the last child. + * + * @param {Node|string} node + * @param {Node|string} endNode + * @param {boolean} returnHtml + * @return {Node|string} + * @private + */ + _prepareInput = function (node, endNode, returnHtml) { + var lastChild, $lastChild, + div = doc.createElement('div'), + $div = $(div); + + if (typeof node === 'string') { + if (endNode) { + node += base.selectedHtml() + endNode; + } + + $div.html(node); + } else { + $div.append(node); + + if (endNode) { + $div + .append(base.selectedRange().extractContents()) + .append(endNode); + } + } + + if (!(lastChild = div.lastChild)) { + return; + } + + while (!dom.isInline(lastChild.lastChild, true)) { + lastChild = lastChild.lastChild; + } + + if (dom.canHaveChildren(lastChild)) { + $lastChild = $(lastChild); + + // IE <= 8 and Webkit won't allow the cursor to be placed + // inside an empty tag, so add a zero width space to it. + if (!lastChild.lastChild) { + $lastChild.append('\u200B'); + } + } + + // Needed so IE <= 8 can place the cursor after emoticons and images + if (IE_VER && IE_VER < 9 && $(lastChild).is('img')) { + $div.append('\u200B'); + } + + base.removeMarkers(); + + // Append marks to last child so when restored cursor will be in + // the right place + ($lastChild || $div) + .append(_createMarker(startMarker)) + .append(_createMarker(endMarker)); + + if (returnHtml) { + return $div.html(); + } + + return $(doc.createDocumentFragment()).append($div.contents())[0]; + }; + + /** + *The same as insertHTML except with DOM nodes instead
+ * + *Warning: the nodes must belong to the + * document they are being inserted into. Some browsers + * will throw exceptions if they don't.
+ * + * @param {Node} node + * @param {Node} endNode + * @return False on fail + * @function + * @name insertNode + * @memberOf RangeHelper.prototype + */ + base.insertNode = function (node, endNode) { + if (isW3C) { + var input = _prepareInput(node, endNode), + range = base.selectedRange(), + parent = range.commonAncestorContainer; + + if (!input) { + return false; + } + + range.deleteContents(); + + // FF allowsClones the selected Range
+ * + *IE <= 8 will return a TextRange, all other browsers + * will return a Range object.
+ * + * @return {Range|TextRange} + * @function + * @name cloneSelected + * @memberOf RangeHelper.prototype + */ + base.cloneSelected = function () { + var range = base.selectedRange(); + + if (range) { + return isW3C ? range.cloneRange() : range.duplicate(); + } + }; + + /** + *Gets the selected Range
+ * + *IE <= 8 will return a TextRange, all other browsers + * will return a Range object.
+ * + * @return {Range|TextRange} + * @function + * @name selectedRange + * @memberOf RangeHelper.prototype + */ + base.selectedRange = function () { + var range, firstChild, + sel = isW3C ? win.getSelection() : doc.selection; + + if (!sel) { + return; + } + + // When creating a new range, set the start to the first child + // element of the body element to avoid errors in FF. + if (sel.getRangeAt && sel.rangeCount <= 0) { + firstChild = doc.body; + while (firstChild.firstChild) { + firstChild = firstChild.firstChild; + } + + range = doc.createRange(); + // Must be setStartBefore otherwise it can cause infinite + // loops with lists in WebKit. See issue 442 + range.setStartBefore(firstChild); + + sel.addRange(range); + } + + if (isW3C && sel.rangeCount > 0) { + range = sel.getRangeAt(0); + } + + if (!isW3C && sel.type !== 'Control') { + range = sel.createRange(); + } + + // IE fix to make sure only return selections that + // are part of the WYSIWYG iframe + return _isOwner(range) ? range : null; + }; + + /** + * Checks if an IE TextRange range belongs to + * this document or not. + * + * Returns true if the range isn't an IE range or + * if the range is null. + * + * @private + */ + _isOwner = function (range) { + var parent; + + if (range && !isW3C) { + parent = range.parentElement(); + } + + // IE fix to make sure only return selections + // that are part of the WYSIWYG iframe + return parent ? + parent.ownerDocument === doc : + true; + }; + + /** + * Gets if there is currently a selection + * + * @return {boolean} + * @function + * @name hasSelection + * @since 1.4.4 + * @memberOf RangeHelper.prototype + */ + base.hasSelection = function () { + var sel = isW3C ? win.getSelection() : doc.selection; + + if (isW3C || !sel) { + return sel && sel.rangeCount > 0; + } + + return sel.type !== 'None' && _isOwner(sel.createRange()); + }; + + /** + * Gets the currently selected HTML + * + * @return {string} + * @function + * @name selectedHtml + * @memberOf RangeHelper.prototype + */ + base.selectedHtml = function () { + var div, + range = base.selectedRange(); + + if (range) { + + // IE9+ and all other browsers + if (isW3C) { + div = doc.createElement('p'); + div.appendChild(range.cloneContents()); + + return div.innerHTML; + // IE < 9 + } else if (range.text !== '' && range.htmlText) { + return range.htmlText; + } + } + + return ''; + }; + + /** + * Gets the parent node of the selected contents in the range + * + * @return {HTMLElement} + * @function + * @name parentNode + * @memberOf RangeHelper.prototype + */ + base.parentNode = function () { + var range = base.selectedRange(); + + if (range) { + return range.parentElement ? + range.parentElement() : + range.commonAncestorContainer; + } + }; + + /** + * Gets the first block level parent of the selected + * contents of the range. + * + * @return {HTMLElement} + * @function + * @name getFirstBlockParent + * @memberOf RangeHelper.prototype + */ + /** + * Gets the first block level parent of the selected + * contents of the range. + * + * @param {Node} n The element to get the first block level parent from + * @return {HTMLElement} + * @function + * @name getFirstBlockParent^2 + * @since 1.4.1 + * @memberOf RangeHelper.prototype + */ + base.getFirstBlockParent = function (n) { + var func = function (node) { + if (!dom.isInline(node, true)) { + return node; + } + + node = node ? node.parentNode : null; + + return node ? func(node) : node; + }; + + return func(n || base.parentNode()); + }; + + /** + * Inserts a node at either the start or end of the current selection + * + * @param {Bool} start + * @param {Node} node + * @function + * @name insertNodeAt + * @memberOf RangeHelper.prototype + */ + base.insertNodeAt = function (start, node) { + var currentRange = base.selectedRange(), + range = base.cloneSelected(); + + if (!range) { + return false; + } + + range.collapse(start); + + if (isW3C) { + range.insertNode(node); + } else { + range.pasteHTML(_nodeToHtml(node)); + } + + // Reselect the current range. + // Fixes issue with Chrome losing the selection. Issue#82 + base.selectRange(currentRange); + }; + + /** + * Creates a marker node + * + * @param {string} id + * @return {Node} + * @private + */ + _createMarker = function (id) { + base.removeMarker(id); + + var marker = doc.createElement('span'); + marker.id = id; + marker.style.lineHeight = '0'; + marker.style.display = 'none'; + marker.className = 'sceditor-selection sceditor-ignore'; + marker.innerHTML = ' '; + + return marker; + }; + + /** + * Inserts start/end markers for the current selection + * which can be used by restoreRange to re-select the + * range. + * + * @memberOf RangeHelper.prototype + * @function + * @name insertMarkers + */ + base.insertMarkers = function () { + base.insertNodeAt(true, _createMarker(startMarker)); + base.insertNodeAt(false, _createMarker(endMarker)); + }; + + /** + * Gets the marker with the specified ID + * + * @param {string} id + * @return {Node} + * @function + * @name getMarker + * @memberOf RangeHelper.prototype + */ + base.getMarker = function (id) { + return doc.getElementById(id); + }; + + /** + * Removes the marker with the specified ID + * + * @param {string} id + * @function + * @name removeMarker + * @memberOf RangeHelper.prototype + */ + base.removeMarker = function (id) { + var marker = base.getMarker(id); + + if (marker) { + marker.parentNode.removeChild(marker); + } + }; + + /** + * Removes the start/end markers + * + * @function + * @name removeMarkers + * @memberOf RangeHelper.prototype + */ + base.removeMarkers = function () { + base.removeMarker(startMarker); + base.removeMarker(endMarker); + }; + + /** + * Saves the current range location. Alias of insertMarkers() + * + * @function + * @name saveRage + * @memberOf RangeHelper.prototype + */ + base.saveRange = function () { + base.insertMarkers(); + }; + + /** + * Select the specified range + * + * @param {Range|TextRange} range + * @function + * @name selectRange + * @memberOf RangeHelper.prototype + */ + base.selectRange = function (range) { + if (isW3C) { + var lastChild; + var sel = win.getSelection(); + var container = range.endContainer; + + // 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 && range.collapsed && container && + !dom.isInline(container, true)) { + + lastChild = container.lastChild; + while (lastChild && $(lastChild).is('.sceditor-ignore')) { + lastChild = lastChild.previousSibling; + } + + if ($(lastChild).is('br')) { + var rng = doc.createRange(); + rng.setEndAfter(lastChild); + rng.collapse(false); + + if (base.compare(range, rng)) { + range.setStartBefore(lastChild); + range.collapse(true); + } + } + } + + if (sel) { + base.clear(); + sel.addRange(range); + } + } else { + range.select(); + } + }; + + /** + * Restores the last range saved by saveRange() or insertMarkers() + * + * @function + * @name restoreRange + * @memberOf RangeHelper.prototype + */ + base.restoreRange = function () { + var marker, isCollapsed, previousSibling, + range = base.selectedRange(), + start = base.getMarker(startMarker), + end = base.getMarker(endMarker); + + if (!start || !end || !range) { + return false; + } + + isCollapsed = start.nextSibling === end; + + if (!isW3C) { + range = doc.body.createTextRange(); + marker = doc.body.createTextRange(); + + // IE < 9 cannot set focus after a BR so need to insert + // a dummy char after it to allow the cursor to be placed + previousSibling = start.previousSibling; + if (start.nextSibling === end && (!previousSibling || + !dom.isInline(previousSibling, true) || + $(previousSibling).is('br'))) { + $(start).before('\u200B'); + } + + marker.moveToElementText(start); + range.setEndPoint('StartToStart', marker); + range.moveStart(CHARACTER, 0); + + marker.moveToElementText(end); + range.setEndPoint('EndToStart', marker); + range.moveEnd(CHARACTER, 0); + } else { + range = doc.createRange(); + + range.setStartBefore(start); + range.setEndAfter(end); + } + + if (isCollapsed) { + range.collapse(true); + } + + base.selectRange(range); + base.removeMarkers(); + }; + + /** + * Selects the text left and right of the current selection + * + * @param {int} left + * @param {int} right + * @since 1.4.3 + * @function + * @name selectOuterText + * @memberOf RangeHelper.prototype + */ + base.selectOuterText = function (left, right) { + var start, end, + range = base.cloneSelected(); + + if (!range) { + return false; + } + + range.collapse(false); + + if (!isW3C) { + range.moveStart(CHARACTER, 0 - left); + range.moveEnd(CHARACTER, right); + } else { + start = outerText(range, true, left); + end = outerText(range, false, right); + + range.setStart(start.node, start.offset); + range.setEnd(end.node, end.offset); + } + + base.selectRange(range); + }; + + /** + * Gets the text left or right of the current selection + * + * @param {boolean} before + * @param {number} length + * @since 1.4.3 + * @function + * @name selectOuterText + * @memberOf RangeHelper.prototype + */ + base.getOuterText = function (before, length) { + var range = base.cloneSelected(); + + if (!range) { + return ''; + } + + range.collapse(!before); + + if (!isW3C) { + if (before) { + range.moveStart(CHARACTER, 0 - length); + } else { + range.moveEnd(CHARACTER, length); + } + + return range.text; + } + + return outerText(range, before, length).text; + }; + + /** + * Replaces keywords with values based on the current caret position + * + * @param {Array} keywords + * @param {boolean} includeAfter If to include the text after the + * current caret position or just + * text before + * @param {boolean} keywordsSorted If the keywords array is pre + * sorted shortest to longest + * @param {number} longestKeyword Length of the longest keyword + * @param {boolean} requireWhitespace If the key must be surrounded + * by whitespace + * @param {string} keypressChar If this is being called from + * a keypress event, this should be + * set to the pressed character + * @return {boolean} + * @function + * @name replaceKeyword + * @memberOf RangeHelper.prototype + */ + /*jshint maxparams: false*/ + base.replaceKeyword = function ( + keywords, + includeAfter, + keywordsSorted, + longestKeyword, + requireWhitespace, + keypressChar + ) { + if (!keywordsSorted) { + keywords.sort(function (a, b) { + return a[0].length - b[0].length; + }); + } + + var outerText, matchPos, startIndex, leftLen, + charsLeft, keyword, keywordLen, + whitespaceRegex = '[\\s\xA0\u2002\u2003\u2009]', + keywordIdx = keywords.length, + whitespaceLen = requireWhitespace ? 1 : 0, + maxKeyLen = longestKeyword || + keywords[keywordIdx - 1][0].length; + + if (requireWhitespace) { + // requireWhitespace doesn't work with textRanges as they + // select text on the other side of elements causing + // space-img-key to match when it shouldn't. + if (!isW3C) { + return false; + } + + maxKeyLen++; + } + + keypressChar = keypressChar || ''; + outerText = base.getOuterText(true, maxKeyLen); + leftLen = outerText.length; + outerText += keypressChar; + + if (includeAfter) { + outerText += base.getOuterText(false, maxKeyLen); + } + + while (keywordIdx--) { + keyword = keywords[keywordIdx][0]; + keywordLen = keyword.length; + startIndex = Math.max(0, leftLen - keywordLen - whitespaceLen); + + if (requireWhitespace) { + matchPos = outerText + .substr(startIndex) + .search(new RegExp( + '(?:' + whitespaceRegex + ')' + + escape.regex(keyword) + + '(?=' + whitespaceRegex + ')' + )); + } else { + matchPos = outerText.indexOf(keyword, startIndex); + } + + if (matchPos > -1) { + // Add the length of the text that was removed by substr() + // when matching and also add 1 for the whitespace + if (requireWhitespace) { + matchPos += startIndex + 1; + } + + // Make sure the match is between before and + // after, not just entirely in one side or the other + if (matchPos <= leftLen && + matchPos + keywordLen + whitespaceLen >= leftLen) { + charsLeft = leftLen - matchPos; + + // If the keypress char is white space then it should + // not be replaced, only chars that are part of the + // key should be replaced. + base.selectOuterText( + charsLeft, + keywordLen - charsLeft - + (/^\S/.test(keypressChar) ? 1 : 0) + ); + + base.insertHTML(keywords[keywordIdx][1]); + return true; + } + } + } + + return false; + }; + + /** + * Compares two ranges. + * + * If rangeB is undefined it will be set to + * the current selected range + * + * @param {Range|TextRange} rangeA + * @param {Range|TextRange} rangeB + * @return {boolean} + */ + base.compare = function (rangeA, rangeB) { + var END_TO_END = isW3C ? Range.END_TO_END : 'EndToEnd', + START_TO_START = isW3C ? Range.START_TO_START : 'StartToStart', + comparePoints = isW3C ? + 'compareBoundaryPoints' : + 'compareEndPoints'; + + if (!rangeB) { + rangeB = base.selectedRange(); + } + + if (!rangeA || !rangeB) { + return !rangeA && !rangeB; + } + + return _isOwner(rangeA) && _isOwner(rangeB) && + rangeA[comparePoints](END_TO_END, rangeB) === 0 && + rangeA[comparePoints](START_TO_START, rangeB) === 0; + }; + + /** + * Removes any current selection + * + * @since 1.4.6 + */ + base.clear = function () { + var sel = isW3C ? win.getSelection() : doc.selection; + + if (sel) { + if (sel.removeAllRanges) { + sel.removeAllRanges(); + } else if (sel.empty) { + sel.empty(); + } + } + }; + }; + + return RangeHelper; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var browser = __webpack_require__(6); + + var _propertyNameCache = {}; + + var dom = { + /** + * Loop all child nodes of the passed node + * + * The function should accept 1 parameter being the node. + * If the function returns false the loop will be exited. + * + * @param {HTMLElement} node + * @param {Function} func Callback which is called with every + * child node as the first argument. + * @param {bool} innermostFirst If the innermost node should be passed + * to the function before it's parents. + * @param {bool} siblingsOnly If to only traverse the nodes siblings + * @param {bool} reverse If to traverse the nodes in reverse + */ + /*jshint maxparams: false*/ + traverse: function (node, func, innermostFirst, siblingsOnly, reverse) { + if (node) { + node = reverse ? node.lastChild : node.firstChild; + + while (node) { + var next = reverse ? + node.previousSibling : + node.nextSibling; + + if ( + (!innermostFirst && func(node) === false) || + (!siblingsOnly && dom.traverse( + node, func, innermostFirst, siblingsOnly, reverse + ) === false) || + (innermostFirst && func(node) === false) + ) { + return false; + } + + // move to next child + node = next; + } + } + }, + + /** + * Like traverse but loops in reverse + * @see traverse + */ + rTraverse: function (node, func, innermostFirst, siblingsOnly) { + this.traverse(node, func, innermostFirst, siblingsOnly, true); + }, + + /** + * Parses HTML + * + * @param {String} html + * @param {Document} context + * @since 1.4.4 + * @return {Array} + */ + parseHTML: function (html, context) { + var ret = [], + tmp = (context || document).createElement('div'); + + tmp.innerHTML = html; + + $.merge(ret, tmp.childNodes); + + return ret; + }, + + /** + * Checks if an element has any styling. + * + * It has styling if it is not a plain or
+ * if it has a class, style attribute or data.
+ *
+ * @param {HTMLElement} elm
+ * @return {Boolean}
+ * @since 1.4.4
+ */
+ hasStyling: function (elm) {
+ var $elm = $(elm);
+
+ return elm && (!$elm.is('p,div') || elm.className ||
+ $elm.attr('style') || !$.isEmptyObject($elm.data()));
+ },
+
+ /**
+ * Converts an element from one type to another.
+ *
+ * For example it can convert the element to
+ *
+ * @param {HTMLElement} oldElm
+ * @param {String} toTagName
+ * @return {HTMLElement}
+ * @since 1.4.4
+ */
+ convertElement: function (oldElm, toTagName) {
+ var child, attr,
+ oldAttrs = oldElm.attributes,
+ attrsIdx = oldAttrs.length,
+ newElm = oldElm.ownerDocument.createElement(toTagName);
+
+ while (attrsIdx--) {
+ attr = oldAttrs[attrsIdx];
+
+ // IE < 8 returns all possible attributes instead of just
+ // the specified ones so have to check it is specified.
+ if (!browser.ie || attr.specified) {
+ // IE < 8 doesn't return the CSS for the style attribute
+ // so must copy it manually
+ if (browser.ie < 8 && /style/i.test(attr.name)) {
+ dom.copyCSS(oldElm, newElm);
+ } else {
+ // Some browsers parse invalid attributes names like
+ // 'size"2' which throw an exception when set, just
+ // ignore these.
+ try {
+ newElm.setAttribute(attr.name, attr.value);
+ } catch (ex) {}
+ }
+ }
+ }
+
+ while ((child = oldElm.firstChild)) {
+ newElm.appendChild(child);
+ }
+
+ oldElm.parentNode.replaceChild(newElm, oldElm);
+
+ return newElm;
+ },
+
+ /**
+ * List of block level elements separated by bars (|)
+ * @type {string}
+ */
+ blockLevelList: '|body|hr|p|div|h1|h2|h3|h4|h5|h6|address|pre|form|' +
+ 'table|tbody|thead|tfoot|th|tr|td|li|ol|ul|blockquote|center|',
+
+ /**
+ * List of elements that do not allow children separated by bars (|)
+ *
+ * @param {Node} node
+ * @return {bool}
+ * @since 1.4.5
+ */
+ canHaveChildren: function (node) {
+ // 1 = Element
+ // 9 = Document
+ // 11 = Document Fragment
+ if (!/11?|9/.test(node.nodeType)) {
+ return false;
+ }
+
+ // List of empty HTML tags separated by bar (|) character.
+ // Source: http://www.w3.org/TR/html4/index/elements.html
+ // Source: http://www.w3.org/TR/html5/syntax.html#void-elements
+ return ('|iframe|area|base|basefont|br|col|frame|hr|img|input|wbr' +
+ '|isindex|link|meta|param|command|embed|keygen|source|track|' +
+ 'object|').indexOf('|' + node.nodeName.toLowerCase() + '|') < 0;
+ },
+
+ /**
+ * Checks if an element is inline
+ *
+ * @return {bool}
+ */
+ isInline: function (elm, includeCodeAsBlock) {
+ var tagName,
+ nodeType = (elm || {}).nodeType || 3;
+
+ if (nodeType !== 1) {
+ return nodeType === 3;
+ }
+
+ tagName = elm.tagName.toLowerCase();
+
+ if (tagName === 'code') {
+ return !includeCodeAsBlock;
+ }
+
+ return dom.blockLevelList.indexOf('|' + tagName + '|') < 0;
+ },
+
+ /**
+ * Copys the CSS from 1 node to another. Only copies CSS defined on the element e.g. style attr. Detects if the browser is iOS Needed to fix iOS specific bugs/ ')[0].contentEditable;
+
+ // Check if the contenteditable attribute is supported
+ if (editableAttr === undef || editableAttr === 'inherit') {
+ return false;
+ }
+
+ // I think blackberry supports contentEditable or will at least
+ // give a valid value for the contentEditable detection above
+ // so it isn't included in the below tests.
+
+ // I hate having to do UA sniffing but some mobile browsers say they
+ // support contentediable when it isn't usable, i.e. you can't enter
+ // text.
+ // This is the only way I can think of to detect them which is also how
+ // every other editor I've seen deals with this issue.
+
+ // Exclude Opera mobile and mini
+ isUnsupported = /Opera Mobi|Opera Mini/i.test(USER_AGENT);
+
+ if (/Android/i.test(USER_AGENT)) {
+ isUnsupported = true;
+
+ if (/Safari/.test(USER_AGENT)) {
+ // Android browser 534+ supports content editable
+ // This also matches Chrome which supports content editable too
+ match = /Safari\/(\d+)/.exec(USER_AGENT);
+ isUnsupported = (!match || !match[1] ? true : match[1] < 534);
+ }
+ }
+
+ // The current version of Amazon Silk supports it, older versions didn't
+ // As it uses webkit like Android, assume it's the same and started
+ // working at versions >= 534
+ if (/ Silk\//i.test(USER_AGENT)) {
+ match = /AppleWebKit\/(\d+)/.exec(USER_AGENT);
+ isUnsupported = (!match || !match[1] ? true : match[1] < 534);
+ }
+
+ // iOS 5+ supports content editable
+ if (exports.ios) {
+ // Block any version <= 4_x(_x)
+ isUnsupported = /OS [0-4](_\d)+ like Mac/i.test(USER_AGENT);
+ }
+
+ // FireFox does support WYSIWYG on mobiles so override
+ // any previous value if using FF
+ if (/Firefox/i.test(USER_AGENT)) {
+ isUnsupported = false;
+ }
+
+ if (/OneBrowser/i.test(USER_AGENT)) {
+ isUnsupported = false;
+ }
+
+ // UCBrowser works but doesn't give a unique user agent
+ if (navigator.vendor === 'UCWEB') {
+ isUnsupported = false;
+ }
+
+ return !isUnsupported;
+ }());
+ }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+
+
+/***/ },
+/* 7 */
+/***/ function(module, exports, __webpack_require__) {
+
+ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports) {
+ 'use strict';
+
+ var VALID_SCHEME_REGEX =
+ /^(?:https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(?:\/\/)/i;
+
+ /**
+ * Escapes a string so it's safe to use in regex
+ *
+ * @param {String} str
+ * @return {String}
+ * @name regex
+ */
+ exports.regex = function (str) {
+ return str.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');
+ };
+
+ /**
+ * Escapes all HTML entities in a string
+ *
+ * If noQuotes is set to false, all single and double
+ * quotes will also be escaped
+ *
+ * @param {String} str
+ * @param {Boolean} [noQuotes=false]
+ * @return {String}
+ * @name entities
+ * @since 1.4.1
+ */
+ exports.entities = function (str, noQuotes) {
+ if (!str) {
+ return str;
+ }
+
+ var replacements = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ ' ': ' ',
+ '\r\n': '\n',
+ '\r': '\n',
+ '\n': ' 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...}));
'
+ };
+
+ if (noQuotes !== false) {
+ replacements['"'] = '"';
+ replacements['\''] = ''';
+ replacements['`'] = '`';
+ }
+
+ str = str.replace(/ {2}|\r\n|[&<>\r\n'"`]/g, function (match) {
+ return replacements[match] || match;
+ });
+
+ return str;
+ };
+
+ /**
+ * Escape URI scheme.
+ *
+ * Appends the current URL to a url if it has a scheme that is not:
+ *
+ * http
+ * https
+ * sftp
+ * ftp
+ * mailto
+ * spotify
+ * skype
+ * ssh
+ * teamspeak
+ * tel
+ * //
+ *
+ * **IMPORTANT**: This does not escape any HTML in a url, for
+ * that use the escape.entities() method.
+ *
+ * @param {String} url
+ * @return {String}
+ * @name escapeUriScheme
+ * @memberOf jQuery.sceditor
+ * @since 1.4.5
+ */
+ exports.uriScheme = function (url) {
+ /*jshint maxlen:false*/
+ var path,
+ // If there is a : before a / then it has a scheme
+ hasScheme = /^[^\/]*:/i,
+ location = window.location;
+
+ // Has no scheme or a valid scheme
+ if ((!url || !hasScheme.test(url)) || VALID_SCHEME_REGEX.test(url)) {
+ return url;
+ }
+
+ path = location.pathname.split('/');
+ path.pop();
+
+ return location.protocol + '//' +
+ location.host +
+ path.join('/') + '/' +
+ url;
+ };
+ }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+
+
+/***/ },
+/* 8 */
+/***/ function(module, exports, __webpack_require__) {
+
+ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function () {
+ 'use strict';
+
+ /**
+ * HTML templates used by the editor and default commands
+ * @type {Object}
+ * @private
+ */
+ var _templates = {
+ html:
+ '' +
+ '' +
+ '',
+
+ fontOpt: '{font}',
+
+ sizeOpt: '{size}',
+
+ pastetext:
+ '
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 += '
';
+
+ 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(
+ '';
+
+ for (col = 0; col < cols; col++) {
+ html += ' ';
+ }
+
+ html += '' +
+ (IE_BR_FIX ? '' : ' ';
+ }
+
+ html += '
') +
+ '',
+ (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('
');
+ }
+
+ // 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('
' + 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: '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 theSets 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]
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 = $('' + (IE_VER ? '' : '
') + '
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); + + // Lastor
Binds a handler to the specified events
+ * + *This function only binds to a limited list of
+ * supported events.
+ * The supported events are:
+ *
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 = $('', $wysiwygDoc[0]) + .appendTo($wysiwygDoc.find('head'))[0]; + } + + if (typeof css !== 'string') { + return inlineCss.styleSheet ? + inlineCss.styleSheet.cssText : inlineCss.innerHTML; + } + + if (inlineCss.styleSheet) { + inlineCss.styleSheet.cssText = css; + } else { + inlineCss.innerHTML = css; + } + + return base; + }; + + /** + * Handles the keydown event, used for shortcuts + * @private + */ + handleKeyDown = function (e) { + var shortcut = [], + SHIFT_KEYS = { + '`': '~', + '1': '!', + '2': '@', + '3': '#', + '4': '$', + '5': '%', + '6': '^', + '7': '&', + '8': '*', + '9': '(', + '0': ')', + '-': '_', + '=': '+', + ';': ': ', + '\'': '"', + ',': '<', + '.': '>', + '/': '?', + '\\': '|', + '[': '{', + ']': '}' + }, + SPECIAL_KEYS = { + 8: 'backspace', + 9: 'tab', + 13: 'enter', + 19: 'pause', + 20: 'capslock', + 27: 'esc', + 32: 'space', + 33: 'pageup', + 34: 'pagedown', + 35: 'end', + 36: 'home', + 37: 'left', + 38: 'up', + 39: 'right', + 40: 'down', + 45: 'insert', + 46: 'del', + 91: 'win', + 92: 'win', + 93: 'select', + 96: '0', + 97: '1', + 98: '2', + 99: '3', + 100: '4', + 101: '5', + 102: '6', + 103: '7', + 104: '8', + 105: '9', + 106: '*', + 107: '+', + 109: '-', + 110: '.', + 111: '/', + 112: 'f1', + 113: 'f2', + 114: 'f3', + 115: 'f4', + 116: 'f5', + 117: 'f6', + 118: 'f7', + 119: 'f8', + 120: 'f9', + 121: 'f10', + 122: 'f11', + 123: 'f12', + 144: 'numlock', + 145: 'scrolllock', + 186: ';', + 187: '=', + 188: ',', + 189: '-', + 190: '.', + 191: '/', + 192: '`', + 219: '[', + 220: '\\', + 221: ']', + 222: '\'' + }, + NUMPAD_SHIFT_KEYS = { + 109: '-', + 110: 'del', + 111: '/', + 96: '0', + 97: '1', + 98: '2', + 99: '3', + 100: '4', + 101: '5', + 102: '6', + 103: '7', + 104: '8', + 105: '9' + }, + which = e.which, + character = SPECIAL_KEYS[which] || + String.fromCharCode(which).toLowerCase(); + + if (e.ctrlKey || e.metaKey) { + shortcut.push('ctrl'); + } + + if (e.altKey) { + shortcut.push('alt'); + } + + if (e.shiftKey) { + shortcut.push('shift'); + + if (NUMPAD_SHIFT_KEYS[which]) { + character = NUMPAD_SHIFT_KEYS[which]; + } else if (SHIFT_KEYS[character]) { + character = SHIFT_KEYS[character]; + } + } + + // Shift is 16, ctrl is 17 and alt is 18 + if (character && (which < 16 || which > 18)) { + shortcut.push(character); + } + + shortcut = shortcut.join('+'); + if (shortcutHandlers[shortcut]) { + return shortcutHandlers[shortcut].call(base); + } + }; + + /** + * Adds a shortcut handler to the editor + * @param {String} shortcut + * @param {String|Function} cmd + * @return {jQuery.sceditor} + */ + base.addShortcut = function (shortcut, cmd) { + shortcut = shortcut.toLowerCase(); + + if (typeof cmd === 'string') { + shortcutHandlers[shortcut] = function () { + handleCommand( + toolbarButtons[cmd], + base.commands[cmd] + ); + + return false; + }; + } else { + shortcutHandlers[shortcut] = cmd; + } + + return base; + }; + + /** + * Removes a shortcut handler + * @param {String} shortcut + * @return {jQuery.sceditor} + */ + base.removeShortcut = function (shortcut) { + delete shortcutHandlers[shortcut.toLowerCase()]; + + return base; + }; + + /** + * Handles the backspace key press + * + * Will remove block styling like quotes/code ect if at the start. + * @private + */ + handleBackSpace = function (e) { + var node, offset, tmpRange, range, parent; + + // 8 is the backspace key + if (options.disableBlockRemove || e.which !== 8 || + !(range = rangeHelper.selectedRange())) { + return; + } + + if (!globalWin.getSelection) { + node = range.parentElement(); + tmpRange = $wysiwygDoc[0].selection.createRange(); + + // Select the entire parent and set the end + // as start of the current range + tmpRange.moveToElementText(node); + tmpRange.setEndPoint('EndToStart', range); + + // Number of characters selected is the start offset + // relative to the parent node + offset = tmpRange.text.length; + } else { + node = range.startContainer; + offset = range.startOffset; + } + + if (offset !== 0 || !(parent = currentStyledBlockNode())) { + return; + } + + while (node !== parent) { + while (node.previousSibling) { + node = node.previousSibling; + + // Everything but empty text nodes before the cursor + // should prevent the style from being removed + if (node.nodeType !== 3 || node.nodeValue) { + return; + } + } + + if (!(node = node.parentNode)) { + return; + } + } + + if (!parent || $(parent).is('body')) { + return; + } + + // The backspace was pressed at the start of + // the container so clear the style + base.clearBlockFormatting(parent); + return false; + }; + + /** + * Gets the first styled block node that contains the cursor + * @return {HTMLElement} + */ + currentStyledBlockNode = function () { + var block = currentBlockNode; + + while (!dom.hasStyling(block) || dom.isInline(block, true)) { + if (!(block = block.parentNode) || $(block).is('body')) { + return; + } + } + + return block; + }; + + /** + * Clears the formatting of the passed block element. + * + * If block is false, if will clear the styling of the first + * block level element that contains the cursor. + * @param {HTMLElement} block + * @since 1.4.4 + */ + base.clearBlockFormatting = function (block) { + block = block || currentStyledBlockNode(); + + if (!block || $(block).is('body')) { + return base; + } + + rangeHelper.saveRange(); + + block.className = ''; + lastRange = null; + + $(block).attr('style', ''); + + if (!$(block).is('p,div,td')) { + dom.convertElement(block, 'p'); + } + + rangeHelper.restoreRange(); + return base; + }; + + /** + * Triggers the valueChanged signal if there is + * a plugin that handles it. + * + * If rangeHelper.saveRange() has already been + * called, then saveRange should be set to false + * to prevent the range being saved twice. + * + * @since 1.4.5 + * @param {Boolean} saveRange If to call rangeHelper.saveRange(). + * @private + */ + triggerValueChanged = function (saveRange) { + if (!pluginManager || + (!pluginManager.hasHandler('valuechangedEvent') && + !triggerValueChanged.hasHandler)) { + return; + } + + var currentHtml, + sourceMode = base.sourceMode(), + hasSelection = !sourceMode && rangeHelper.hasSelection(); + + // Don't need to save the range if sceditor-start-marker + // is present as the range is already saved + saveRange = saveRange !== false && + !$wysiwygDoc[0].getElementById('sceditor-start-marker'); + + // Clear any current timeout as it's now been triggered + if (valueChangedKeyUp.timer) { + clearTimeout(valueChangedKeyUp.timer); + valueChangedKeyUp.timer = false; + } + + if (hasSelection && saveRange) { + rangeHelper.saveRange(); + } + + currentHtml = sourceMode ? + $sourceEditor.val() : + $wysiwygBody.html(); + + // Only trigger if something has actually changed. + if (currentHtml !== triggerValueChanged.lastHtmlValue) { + triggerValueChanged.lastHtmlValue = currentHtml; + + $editorContainer.trigger($.Event('valuechanged', { + rawValue: sourceMode ? base.val() : currentHtml + })); + } + + if (hasSelection && saveRange) { + rangeHelper.removeMarkers(); + } + }; + + /** + * Should be called whenever there is a blur event + * @private + */ + valueChangedBlur = function () { + if (valueChangedKeyUp.timer) { + triggerValueChanged(); + } + }; + + /** + * Should be called whenever there is a keypress event + * @param {Event} e The keypress event + * @private + */ + valueChangedKeyUp = function (e) { + var which = e.which, + lastChar = valueChangedKeyUp.lastChar, + lastWasSpace = (lastChar === 13 || lastChar === 32), + lastWasDelete = (lastChar === 8 || lastChar === 46); + + valueChangedKeyUp.lastChar = which; + + // 13 = return & 32 = space + if (which === 13 || which === 32) { + if (!lastWasSpace) { + triggerValueChanged(); + } else { + valueChangedKeyUp.triggerNextChar = true; + } + // 8 = backspace & 46 = del + } else if (which === 8 || which === 46) { + if (!lastWasDelete) { + triggerValueChanged(); + } else { + valueChangedKeyUp.triggerNextChar = true; + } + } else if (valueChangedKeyUp.triggerNextChar) { + triggerValueChanged(); + valueChangedKeyUp.triggerNextChar = false; + } + + // Clear the previous timeout and set a new one. + if (valueChangedKeyUp.timer) { + clearTimeout(valueChangedKeyUp.timer); + } + + // Trigger the event 1.5s after the last keypress if space + // isn't pressed. This might need to be lowered, will need + // to look into what the slowest average Chars Per Min is. + valueChangedKeyUp.timer = setTimeout(function () { + triggerValueChanged(); + }, 1500); + }; + + autoUpdate = function () { + if (!autoUpdateCanceled) { + base.updateOriginal(); + } + + autoUpdateCanceled = false; + }; + + // run the initializer + init(); + }; + + + /** + * Map containing the loaded SCEditor locales + * @type {Object} + * @name locale + * @memberOf jQuery.sceditor + */ + SCEditor.locale = {}; + + + /** + * Static command helper class + * @class command + * @name jQuery.sceditor.command + */ + SCEditor.command = + /** @lends jQuery.sceditor.command */ + { + /** + * Gets a command + * + * @param {String} name + * @return {Object|null} + * @since v1.3.5 + */ + get: function (name) { + return SCEditor.commands[name] || null; + }, + + /** + *Adds a command to the editor or updates an existing + * command if a command with the specified name already exists.
+ * + *Once a command is add it can be included in the toolbar by + * adding it's name to the toolbar option in the constructor. It + * can also be executed manually by calling + * {@link jQuery.sceditor.execCommand}
+ * + * @example + * SCEditor.command.set("hello", + * { + * exec: function () { + * alert("Hello World!"); + * } + * }); + * + * @param {String} name + * @param {Object} cmd + * @return {this|false} Returns false if name or cmd is false + * @since v1.3.5 + */ + set: function (name, cmd) { + if (!name || !cmd) { + return false; + } + + // merge any existing command properties + cmd = $.extend(SCEditor.commands[name] || {}, cmd); + + cmd.remove = function () { + SCEditor.command.remove(name); + }; + + SCEditor.commands[name] = cmd; + return this; + }, + + /** + * Removes a command + * + * @param {String} name + * @return {this} + * @since v1.3.5 + */ + remove: function (name) { + if (SCEditor.commands[name]) { + delete SCEditor.commands[name]; + } + + return this; + } + }; + + return SCEditor; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 3 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function () { + 'use strict'; + + var plugins = {}; + + /** + * Plugin Manager class + * @class PluginManager + * @name PluginManager + */ + var PluginManager = function (thisObj) { + /** + * Alias of this + * + * @private + * @type {Object} + */ + var base = this; + + /** + * Array of all currently registered plugins + * + * @type {Array} + * @private + */ + var registeredPlugins = []; + + + /** + * Changes a signals name from "name" into "signalName". + * + * @param {String} signal + * @return {String} + * @private + */ + var formatSignalName = function (signal) { + return 'signal' + signal.charAt(0).toUpperCase() + signal.slice(1); + }; + + /** + * Calls handlers for a signal + * + * @see call() + * @see callOnlyFirst() + * @param {Array} args + * @param {Boolean} returnAtFirst + * @return {Mixed} + * @private + */ + var callHandlers = function (args, returnAtFirst) { + args = [].slice.call(args); + + var idx, ret, + signal = formatSignalName(args.shift()); + + for (idx = 0; idx < registeredPlugins.length; idx++) { + if (signal in registeredPlugins[idx]) { + ret = registeredPlugins[idx][signal].apply(thisObj, args); + + if (returnAtFirst) { + return ret; + } + } + } + }; + + /** + * Calls all handlers for the passed signal + * + * @param {String} signal + * @param {...String} args + * @return {Void} + * @function + * @name call + * @memberOf PluginManager.prototype + */ + base.call = function () { + callHandlers(arguments, false); + }; + + /** + * Calls the first handler for a signal, and returns the + * + * @param {String} signal + * @param {...String} args + * @return {Mixed} The result of calling the handler + * @function + * @name callOnlyFirst + * @memberOf PluginManager.prototype + */ + base.callOnlyFirst = function () { + return callHandlers(arguments, true); + }; + + /** + * Checks if a signal has a handler + * + * @param {String} signal + * @return {Boolean} + * @function + * @name hasHandler + * @memberOf PluginManager.prototype + */ + base.hasHandler = function (signal) { + var i = registeredPlugins.length; + signal = formatSignalName(signal); + + while (i--) { + if (signal in registeredPlugins[i]) { + return true; + } + } + + return false; + }; + + /** + * Checks if the plugin exists in plugins + * + * @param {String} plugin + * @return {Boolean} + * @function + * @name exists + * @memberOf PluginManager.prototype + */ + base.exists = function (plugin) { + if (plugin in plugins) { + plugin = plugins[plugin]; + + return typeof plugin === 'function' && + typeof plugin.prototype === 'object'; + } + + return false; + }; + + /** + * Checks if the passed plugin is currently registered. + * + * @param {String} plugin + * @return {Boolean} + * @function + * @name isRegistered + * @memberOf PluginManager.prototype + */ + base.isRegistered = function (plugin) { + if (base.exists(plugin)) { + var idx = registeredPlugins.length; + + while (idx--) { + if (registeredPlugins[idx] instanceof plugins[plugin]) { + return true; + } + } + } + + return false; + }; + + /** + * Registers a plugin to receive signals + * + * @param {String} plugin + * @return {Boolean} + * @function + * @name register + * @memberOf PluginManager.prototype + */ + base.register = function (plugin) { + if (!base.exists(plugin) || base.isRegistered(plugin)) { + return false; + } + + plugin = new plugins[plugin](); + registeredPlugins.push(plugin); + + if ('init' in plugin) { + plugin.init.call(thisObj); + } + + return true; + }; + + /** + * Deregisters a plugin. + * + * @param {String} plugin + * @return {Boolean} + * @function + * @name deregister + * @memberOf PluginManager.prototype + */ + base.deregister = function (plugin) { + var removedPlugin, + pluginIdx = registeredPlugins.length, + removed = false; + + if (!base.isRegistered(plugin)) { + return removed; + } + + while (pluginIdx--) { + if (registeredPlugins[pluginIdx] instanceof plugins[plugin]) { + removedPlugin = registeredPlugins.splice(pluginIdx, 1)[0]; + removed = true; + + if ('destroy' in removedPlugin) { + removedPlugin.destroy.call(thisObj); + } + } + } + + return removed; + }; + + /** + * Clears all plugins and removes the owner reference. + * + * Calling any functions on this object after calling + * destroy will cause a JS error. + * + * @name destroy + * @memberOf PluginManager.prototype + */ + base.destroy = function () { + var i = registeredPlugins.length; + + while (i--) { + if ('destroy' in registeredPlugins[i]) { + registeredPlugins[i].destroy.call(thisObj); + } + } + + registeredPlugins = []; + thisObj = null; + }; + }; + + PluginManager.plugins = plugins; + + return PluginManager; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var dom = __webpack_require__(5); + var escape = __webpack_require__(7); + var browser = __webpack_require__(6); + + 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; + + + var _nodeToHtml = function (node) { + return $('', node.ownerDocument).append(node).html(); + }; + + /** + * Gets the text, start/end node and offset for + * length chars left or right of the passed node + * at the specified offset. + * + * @param {Node} node + * @param {Number} offset + * @param {Boolean} isLeft + * @param {Number} length + * @return {Object} + * @private + */ + var outerText = function (range, isLeft, length) { + var nodeValue, remaining, start, end, node, + text = '', + next = range.startContainer, + offset = range.startOffset; + + // Handle cases where node is a paragraph and offset + // refers to the index of a text node. + // 3 = text node + if (next && next.nodeType !== 3) { + next = next.childNodes[offset]; + offset = 0; + } + + start = end = offset; + + while (length > text.length && next && next.nodeType === 3) { + nodeValue = next.nodeValue; + remaining = length - text.length; + + // If not the first node, start and end should be at their + // max values as will be updated when getting the text + if (node) { + end = nodeValue.length; + start = 0; + } + + node = next; + + if (isLeft) { + start = Math.max(end - remaining, 0); + offset = start; + + text = nodeValue.substr(start, end - start) + text; + next = node.previousSibling; + } else { + end = Math.min(remaining, nodeValue.length); + offset = start + end; + + text += nodeValue.substr(start, end); + next = node.nextSibling; + } + } + + return { + node: node || next, + offset: offset, + text: text + }; + }; + + var RangeHelper = function (w, d) { + var _createMarker, _isOwner, _prepareInput, + doc = d || w.contentDocument || w.document, + win = w, + isW3C = !!w.getSelection, + startMarker = 'sceditor-start-marker', + endMarker = 'sceditor-end-marker', + CHARACTER = 'character', // Used to improve minification + base = this; + + /** + *
Inserts HTML into the current range replacing any selected + * text.
+ * + *If endHTML is specified the selected contents will be put between + * html and endHTML. If there is nothing selected html and endHTML are + * just concatenate together.
+ * + * @param {string} html + * @param {string} endHTML + * @return False on fail + * @function + * @name insertHTML + * @memberOf RangeHelper.prototype + */ + base.insertHTML = function (html, endHTML) { + var node, div, + range = base.selectedRange(); + + if (!range) { + return false; + } + + if (isW3C) { + if (endHTML) { + html += base.selectedHtml() + endHTML; + } + + div = doc.createElement('p'); + node = doc.createDocumentFragment(); + div.innerHTML = html; + + while (div.firstChild) { + node.appendChild(div.firstChild); + } + + base.insertNode(node); + } else { + range.pasteHTML(_prepareInput(html, endHTML, true)); + base.restoreRange(); + } + }; + + /** + * Prepares HTML to be inserted by adding a zero width space + * if the last child is empty and adding the range start/end + * markers to the last child. + * + * @param {Node|string} node + * @param {Node|string} endNode + * @param {boolean} returnHtml + * @return {Node|string} + * @private + */ + _prepareInput = function (node, endNode, returnHtml) { + var lastChild, $lastChild, + div = doc.createElement('div'), + $div = $(div); + + if (typeof node === 'string') { + if (endNode) { + node += base.selectedHtml() + endNode; + } + + $div.html(node); + } else { + $div.append(node); + + if (endNode) { + $div + .append(base.selectedRange().extractContents()) + .append(endNode); + } + } + + if (!(lastChild = div.lastChild)) { + return; + } + + while (!dom.isInline(lastChild.lastChild, true)) { + lastChild = lastChild.lastChild; + } + + if (dom.canHaveChildren(lastChild)) { + $lastChild = $(lastChild); + + // IE <= 8 and Webkit won't allow the cursor to be placed + // inside an empty tag, so add a zero width space to it. + if (!lastChild.lastChild) { + $lastChild.append('\u200B'); + } + } + + // Needed so IE <= 8 can place the cursor after emoticons and images + if (IE_VER && IE_VER < 9 && $(lastChild).is('img')) { + $div.append('\u200B'); + } + + base.removeMarkers(); + + // Append marks to last child so when restored cursor will be in + // the right place + ($lastChild || $div) + .append(_createMarker(startMarker)) + .append(_createMarker(endMarker)); + + if (returnHtml) { + return $div.html(); + } + + return $(doc.createDocumentFragment()).append($div.contents())[0]; + }; + + /** + *The same as insertHTML except with DOM nodes instead
+ * + *Warning: the nodes must belong to the + * document they are being inserted into. Some browsers + * will throw exceptions if they don't.
+ * + * @param {Node} node + * @param {Node} endNode + * @return False on fail + * @function + * @name insertNode + * @memberOf RangeHelper.prototype + */ + base.insertNode = function (node, endNode) { + if (isW3C) { + var input = _prepareInput(node, endNode), + range = base.selectedRange(), + parent = range.commonAncestorContainer; + + if (!input) { + return false; + } + + range.deleteContents(); + + // FF allowsClones the selected Range
+ * + *IE <= 8 will return a TextRange, all other browsers + * will return a Range object.
+ * + * @return {Range|TextRange} + * @function + * @name cloneSelected + * @memberOf RangeHelper.prototype + */ + base.cloneSelected = function () { + var range = base.selectedRange(); + + if (range) { + return isW3C ? range.cloneRange() : range.duplicate(); + } + }; + + /** + *Gets the selected Range
+ * + *IE <= 8 will return a TextRange, all other browsers + * will return a Range object.
+ * + * @return {Range|TextRange} + * @function + * @name selectedRange + * @memberOf RangeHelper.prototype + */ + base.selectedRange = function () { + var range, firstChild, + sel = isW3C ? win.getSelection() : doc.selection; + + if (!sel) { + return; + } + + // When creating a new range, set the start to the first child + // element of the body element to avoid errors in FF. + if (sel.getRangeAt && sel.rangeCount <= 0) { + firstChild = doc.body; + while (firstChild.firstChild) { + firstChild = firstChild.firstChild; + } + + range = doc.createRange(); + // Must be setStartBefore otherwise it can cause infinite + // loops with lists in WebKit. See issue 442 + range.setStartBefore(firstChild); + + sel.addRange(range); + } + + if (isW3C && sel.rangeCount > 0) { + range = sel.getRangeAt(0); + } + + if (!isW3C && sel.type !== 'Control') { + range = sel.createRange(); + } + + // IE fix to make sure only return selections that + // are part of the WYSIWYG iframe + return _isOwner(range) ? range : null; + }; + + /** + * Checks if an IE TextRange range belongs to + * this document or not. + * + * Returns true if the range isn't an IE range or + * if the range is null. + * + * @private + */ + _isOwner = function (range) { + var parent; + + if (range && !isW3C) { + parent = range.parentElement(); + } + + // IE fix to make sure only return selections + // that are part of the WYSIWYG iframe + return parent ? + parent.ownerDocument === doc : + true; + }; + + /** + * Gets if there is currently a selection + * + * @return {boolean} + * @function + * @name hasSelection + * @since 1.4.4 + * @memberOf RangeHelper.prototype + */ + base.hasSelection = function () { + var sel = isW3C ? win.getSelection() : doc.selection; + + if (isW3C || !sel) { + return sel && sel.rangeCount > 0; + } + + return sel.type !== 'None' && _isOwner(sel.createRange()); + }; + + /** + * Gets the currently selected HTML + * + * @return {string} + * @function + * @name selectedHtml + * @memberOf RangeHelper.prototype + */ + base.selectedHtml = function () { + var div, + range = base.selectedRange(); + + if (range) { + + // IE9+ and all other browsers + if (isW3C) { + div = doc.createElement('p'); + div.appendChild(range.cloneContents()); + + return div.innerHTML; + // IE < 9 + } else if (range.text !== '' && range.htmlText) { + return range.htmlText; + } + } + + return ''; + }; + + /** + * Gets the parent node of the selected contents in the range + * + * @return {HTMLElement} + * @function + * @name parentNode + * @memberOf RangeHelper.prototype + */ + base.parentNode = function () { + var range = base.selectedRange(); + + if (range) { + return range.parentElement ? + range.parentElement() : + range.commonAncestorContainer; + } + }; + + /** + * Gets the first block level parent of the selected + * contents of the range. + * + * @return {HTMLElement} + * @function + * @name getFirstBlockParent + * @memberOf RangeHelper.prototype + */ + /** + * Gets the first block level parent of the selected + * contents of the range. + * + * @param {Node} n The element to get the first block level parent from + * @return {HTMLElement} + * @function + * @name getFirstBlockParent^2 + * @since 1.4.1 + * @memberOf RangeHelper.prototype + */ + base.getFirstBlockParent = function (n) { + var func = function (node) { + if (!dom.isInline(node, true)) { + return node; + } + + node = node ? node.parentNode : null; + + return node ? func(node) : node; + }; + + return func(n || base.parentNode()); + }; + + /** + * Inserts a node at either the start or end of the current selection + * + * @param {Bool} start + * @param {Node} node + * @function + * @name insertNodeAt + * @memberOf RangeHelper.prototype + */ + base.insertNodeAt = function (start, node) { + var currentRange = base.selectedRange(), + range = base.cloneSelected(); + + if (!range) { + return false; + } + + range.collapse(start); + + if (isW3C) { + range.insertNode(node); + } else { + range.pasteHTML(_nodeToHtml(node)); + } + + // Reselect the current range. + // Fixes issue with Chrome losing the selection. Issue#82 + base.selectRange(currentRange); + }; + + /** + * Creates a marker node + * + * @param {string} id + * @return {Node} + * @private + */ + _createMarker = function (id) { + base.removeMarker(id); + + var marker = doc.createElement('span'); + marker.id = id; + marker.style.lineHeight = '0'; + marker.style.display = 'none'; + marker.className = 'sceditor-selection sceditor-ignore'; + marker.innerHTML = ' '; + + return marker; + }; + + /** + * Inserts start/end markers for the current selection + * which can be used by restoreRange to re-select the + * range. + * + * @memberOf RangeHelper.prototype + * @function + * @name insertMarkers + */ + base.insertMarkers = function () { + base.insertNodeAt(true, _createMarker(startMarker)); + base.insertNodeAt(false, _createMarker(endMarker)); + }; + + /** + * Gets the marker with the specified ID + * + * @param {string} id + * @return {Node} + * @function + * @name getMarker + * @memberOf RangeHelper.prototype + */ + base.getMarker = function (id) { + return doc.getElementById(id); + }; + + /** + * Removes the marker with the specified ID + * + * @param {string} id + * @function + * @name removeMarker + * @memberOf RangeHelper.prototype + */ + base.removeMarker = function (id) { + var marker = base.getMarker(id); + + if (marker) { + marker.parentNode.removeChild(marker); + } + }; + + /** + * Removes the start/end markers + * + * @function + * @name removeMarkers + * @memberOf RangeHelper.prototype + */ + base.removeMarkers = function () { + base.removeMarker(startMarker); + base.removeMarker(endMarker); + }; + + /** + * Saves the current range location. Alias of insertMarkers() + * + * @function + * @name saveRage + * @memberOf RangeHelper.prototype + */ + base.saveRange = function () { + base.insertMarkers(); + }; + + /** + * Select the specified range + * + * @param {Range|TextRange} range + * @function + * @name selectRange + * @memberOf RangeHelper.prototype + */ + base.selectRange = function (range) { + if (isW3C) { + var lastChild; + var sel = win.getSelection(); + var container = range.endContainer; + + // 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 && range.collapsed && container && + !dom.isInline(container, true)) { + + lastChild = container.lastChild; + while (lastChild && $(lastChild).is('.sceditor-ignore')) { + lastChild = lastChild.previousSibling; + } + + if ($(lastChild).is('br')) { + var rng = doc.createRange(); + rng.setEndAfter(lastChild); + rng.collapse(false); + + if (base.compare(range, rng)) { + range.setStartBefore(lastChild); + range.collapse(true); + } + } + } + + if (sel) { + base.clear(); + sel.addRange(range); + } + } else { + range.select(); + } + }; + + /** + * Restores the last range saved by saveRange() or insertMarkers() + * + * @function + * @name restoreRange + * @memberOf RangeHelper.prototype + */ + base.restoreRange = function () { + var marker, isCollapsed, previousSibling, + range = base.selectedRange(), + start = base.getMarker(startMarker), + end = base.getMarker(endMarker); + + if (!start || !end || !range) { + return false; + } + + isCollapsed = start.nextSibling === end; + + if (!isW3C) { + range = doc.body.createTextRange(); + marker = doc.body.createTextRange(); + + // IE < 9 cannot set focus after a BR so need to insert + // a dummy char after it to allow the cursor to be placed + previousSibling = start.previousSibling; + if (start.nextSibling === end && (!previousSibling || + !dom.isInline(previousSibling, true) || + $(previousSibling).is('br'))) { + $(start).before('\u200B'); + } + + marker.moveToElementText(start); + range.setEndPoint('StartToStart', marker); + range.moveStart(CHARACTER, 0); + + marker.moveToElementText(end); + range.setEndPoint('EndToStart', marker); + range.moveEnd(CHARACTER, 0); + } else { + range = doc.createRange(); + + range.setStartBefore(start); + range.setEndAfter(end); + } + + if (isCollapsed) { + range.collapse(true); + } + + base.selectRange(range); + base.removeMarkers(); + }; + + /** + * Selects the text left and right of the current selection + * + * @param {int} left + * @param {int} right + * @since 1.4.3 + * @function + * @name selectOuterText + * @memberOf RangeHelper.prototype + */ + base.selectOuterText = function (left, right) { + var start, end, + range = base.cloneSelected(); + + if (!range) { + return false; + } + + range.collapse(false); + + if (!isW3C) { + range.moveStart(CHARACTER, 0 - left); + range.moveEnd(CHARACTER, right); + } else { + start = outerText(range, true, left); + end = outerText(range, false, right); + + range.setStart(start.node, start.offset); + range.setEnd(end.node, end.offset); + } + + base.selectRange(range); + }; + + /** + * Gets the text left or right of the current selection + * + * @param {boolean} before + * @param {number} length + * @since 1.4.3 + * @function + * @name selectOuterText + * @memberOf RangeHelper.prototype + */ + base.getOuterText = function (before, length) { + var range = base.cloneSelected(); + + if (!range) { + return ''; + } + + range.collapse(!before); + + if (!isW3C) { + if (before) { + range.moveStart(CHARACTER, 0 - length); + } else { + range.moveEnd(CHARACTER, length); + } + + return range.text; + } + + return outerText(range, before, length).text; + }; + + /** + * Replaces keywords with values based on the current caret position + * + * @param {Array} keywords + * @param {boolean} includeAfter If to include the text after the + * current caret position or just + * text before + * @param {boolean} keywordsSorted If the keywords array is pre + * sorted shortest to longest + * @param {number} longestKeyword Length of the longest keyword + * @param {boolean} requireWhitespace If the key must be surrounded + * by whitespace + * @param {string} keypressChar If this is being called from + * a keypress event, this should be + * set to the pressed character + * @return {boolean} + * @function + * @name replaceKeyword + * @memberOf RangeHelper.prototype + */ + /*jshint maxparams: false*/ + base.replaceKeyword = function ( + keywords, + includeAfter, + keywordsSorted, + longestKeyword, + requireWhitespace, + keypressChar + ) { + if (!keywordsSorted) { + keywords.sort(function (a, b) { + return a[0].length - b[0].length; + }); + } + + var outerText, matchPos, startIndex, leftLen, + charsLeft, keyword, keywordLen, + whitespaceRegex = '[\\s\xA0\u2002\u2003\u2009]', + keywordIdx = keywords.length, + whitespaceLen = requireWhitespace ? 1 : 0, + maxKeyLen = longestKeyword || + keywords[keywordIdx - 1][0].length; + + if (requireWhitespace) { + // requireWhitespace doesn't work with textRanges as they + // select text on the other side of elements causing + // space-img-key to match when it shouldn't. + if (!isW3C) { + return false; + } + + maxKeyLen++; + } + + keypressChar = keypressChar || ''; + outerText = base.getOuterText(true, maxKeyLen); + leftLen = outerText.length; + outerText += keypressChar; + + if (includeAfter) { + outerText += base.getOuterText(false, maxKeyLen); + } + + while (keywordIdx--) { + keyword = keywords[keywordIdx][0]; + keywordLen = keyword.length; + startIndex = Math.max(0, leftLen - keywordLen - whitespaceLen); + + if (requireWhitespace) { + matchPos = outerText + .substr(startIndex) + .search(new RegExp( + '(?:' + whitespaceRegex + ')' + + escape.regex(keyword) + + '(?=' + whitespaceRegex + ')' + )); + } else { + matchPos = outerText.indexOf(keyword, startIndex); + } + + if (matchPos > -1) { + // Add the length of the text that was removed by substr() + // when matching and also add 1 for the whitespace + if (requireWhitespace) { + matchPos += startIndex + 1; + } + + // Make sure the match is between before and + // after, not just entirely in one side or the other + if (matchPos <= leftLen && + matchPos + keywordLen + whitespaceLen >= leftLen) { + charsLeft = leftLen - matchPos; + + // If the keypress char is white space then it should + // not be replaced, only chars that are part of the + // key should be replaced. + base.selectOuterText( + charsLeft, + keywordLen - charsLeft - + (/^\S/.test(keypressChar) ? 1 : 0) + ); + + base.insertHTML(keywords[keywordIdx][1]); + return true; + } + } + } + + return false; + }; + + /** + * Compares two ranges. + * + * If rangeB is undefined it will be set to + * the current selected range + * + * @param {Range|TextRange} rangeA + * @param {Range|TextRange} rangeB + * @return {boolean} + */ + base.compare = function (rangeA, rangeB) { + var END_TO_END = isW3C ? Range.END_TO_END : 'EndToEnd', + START_TO_START = isW3C ? Range.START_TO_START : 'StartToStart', + comparePoints = isW3C ? + 'compareBoundaryPoints' : + 'compareEndPoints'; + + if (!rangeB) { + rangeB = base.selectedRange(); + } + + if (!rangeA || !rangeB) { + return !rangeA && !rangeB; + } + + return _isOwner(rangeA) && _isOwner(rangeB) && + rangeA[comparePoints](END_TO_END, rangeB) === 0 && + rangeA[comparePoints](START_TO_START, rangeB) === 0; + }; + + /** + * Removes any current selection + * + * @since 1.4.6 + */ + base.clear = function () { + var sel = isW3C ? win.getSelection() : doc.selection; + + if (sel) { + if (sel.removeAllRanges) { + sel.removeAllRanges(); + } else if (sel.empty) { + sel.empty(); + } + } + }; + }; + + return RangeHelper; + }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); + + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require) { + 'use strict'; + + var $ = __webpack_require__(1); + var browser = __webpack_require__(6); + + var _propertyNameCache = {}; + + var dom = { + /** + * Loop all child nodes of the passed node + * + * The function should accept 1 parameter being the node. + * If the function returns false the loop will be exited. + * + * @param {HTMLElement} node + * @param {Function} func Callback which is called with every + * child node as the first argument. + * @param {bool} innermostFirst If the innermost node should be passed + * to the function before it's parents. + * @param {bool} siblingsOnly If to only traverse the nodes siblings + * @param {bool} reverse If to traverse the nodes in reverse + */ + /*jshint maxparams: false*/ + traverse: function (node, func, innermostFirst, siblingsOnly, reverse) { + if (node) { + node = reverse ? node.lastChild : node.firstChild; + + while (node) { + var next = reverse ? + node.previousSibling : + node.nextSibling; + + if ( + (!innermostFirst && func(node) === false) || + (!siblingsOnly && dom.traverse( + node, func, innermostFirst, siblingsOnly, reverse + ) === false) || + (innermostFirst && func(node) === false) + ) { + return false; + } + + // move to next child + node = next; + } + } + }, + + /** + * Like traverse but loops in reverse + * @see traverse + */ + rTraverse: function (node, func, innermostFirst, siblingsOnly) { + this.traverse(node, func, innermostFirst, siblingsOnly, true); + }, + + /** + * Parses HTML + * + * @param {String} html + * @param {Document} context + * @since 1.4.4 + * @return {Array} + */ + parseHTML: function (html, context) { + var ret = [], + tmp = (context || document).createElement('div'); + + tmp.innerHTML = html; + + $.merge(ret, tmp.childNodes); + + return ret; + }, + + /** + * Checks if an element has any styling. + * + * It has styling if it is not a plain or
+ * if it has a class, style attribute or data.
+ *
+ * @param {HTMLElement} elm
+ * @return {Boolean}
+ * @since 1.4.4
+ */
+ hasStyling: function (elm) {
+ var $elm = $(elm);
+
+ return elm && (!$elm.is('p,div') || elm.className ||
+ $elm.attr('style') || !$.isEmptyObject($elm.data()));
+ },
+
+ /**
+ * Converts an element from one type to another.
+ *
+ * For example it can convert the element to
+ *
+ * @param {HTMLElement} oldElm
+ * @param {String} toTagName
+ * @return {HTMLElement}
+ * @since 1.4.4
+ */
+ convertElement: function (oldElm, toTagName) {
+ var child, attr,
+ oldAttrs = oldElm.attributes,
+ attrsIdx = oldAttrs.length,
+ newElm = oldElm.ownerDocument.createElement(toTagName);
+
+ while (attrsIdx--) {
+ attr = oldAttrs[attrsIdx];
+
+ // IE < 8 returns all possible attributes instead of just
+ // the specified ones so have to check it is specified.
+ if (!browser.ie || attr.specified) {
+ // IE < 8 doesn't return the CSS for the style attribute
+ // so must copy it manually
+ if (browser.ie < 8 && /style/i.test(attr.name)) {
+ dom.copyCSS(oldElm, newElm);
+ } else {
+ // Some browsers parse invalid attributes names like
+ // 'size"2' which throw an exception when set, just
+ // ignore these.
+ try {
+ newElm.setAttribute(attr.name, attr.value);
+ } catch (ex) {}
+ }
+ }
+ }
+
+ while ((child = oldElm.firstChild)) {
+ newElm.appendChild(child);
+ }
+
+ oldElm.parentNode.replaceChild(newElm, oldElm);
+
+ return newElm;
+ },
+
+ /**
+ * List of block level elements separated by bars (|)
+ * @type {string}
+ */
+ blockLevelList: '|body|hr|p|div|h1|h2|h3|h4|h5|h6|address|pre|form|' +
+ 'table|tbody|thead|tfoot|th|tr|td|li|ol|ul|blockquote|center|',
+
+ /**
+ * List of elements that do not allow children separated by bars (|)
+ *
+ * @param {Node} node
+ * @return {bool}
+ * @since 1.4.5
+ */
+ canHaveChildren: function (node) {
+ // 1 = Element
+ // 9 = Document
+ // 11 = Document Fragment
+ if (!/11?|9/.test(node.nodeType)) {
+ return false;
+ }
+
+ // List of empty HTML tags separated by bar (|) character.
+ // Source: http://www.w3.org/TR/html4/index/elements.html
+ // Source: http://www.w3.org/TR/html5/syntax.html#void-elements
+ return ('|iframe|area|base|basefont|br|col|frame|hr|img|input|wbr' +
+ '|isindex|link|meta|param|command|embed|keygen|source|track|' +
+ 'object|').indexOf('|' + node.nodeName.toLowerCase() + '|') < 0;
+ },
+
+ /**
+ * Checks if an element is inline
+ *
+ * @return {bool}
+ */
+ isInline: function (elm, includeCodeAsBlock) {
+ var tagName,
+ nodeType = (elm || {}).nodeType || 3;
+
+ if (nodeType !== 1) {
+ return nodeType === 3;
+ }
+
+ tagName = elm.tagName.toLowerCase();
+
+ if (tagName === 'code') {
+ return !includeCodeAsBlock;
+ }
+
+ return dom.blockLevelList.indexOf('|' + tagName + '|') < 0;
+ },
+
+ /**
+ * Copys the CSS from 1 node to another. Only copies CSS defined on the element e.g. style attr. Detects if the browser is iOS Needed to fix iOS specific bugs/ ')[0].contentEditable;
+
+ // Check if the contenteditable attribute is supported
+ if (editableAttr === undef || editableAttr === 'inherit') {
+ return false;
+ }
+
+ // I think blackberry supports contentEditable or will at least
+ // give a valid value for the contentEditable detection above
+ // so it isn't included in the below tests.
+
+ // I hate having to do UA sniffing but some mobile browsers say they
+ // support contentediable when it isn't usable, i.e. you can't enter
+ // text.
+ // This is the only way I can think of to detect them which is also how
+ // every other editor I've seen deals with this issue.
+
+ // Exclude Opera mobile and mini
+ isUnsupported = /Opera Mobi|Opera Mini/i.test(USER_AGENT);
+
+ if (/Android/i.test(USER_AGENT)) {
+ isUnsupported = true;
+
+ if (/Safari/.test(USER_AGENT)) {
+ // Android browser 534+ supports content editable
+ // This also matches Chrome which supports content editable too
+ match = /Safari\/(\d+)/.exec(USER_AGENT);
+ isUnsupported = (!match || !match[1] ? true : match[1] < 534);
+ }
+ }
+
+ // The current version of Amazon Silk supports it, older versions didn't
+ // As it uses webkit like Android, assume it's the same and started
+ // working at versions >= 534
+ if (/ Silk\//i.test(USER_AGENT)) {
+ match = /AppleWebKit\/(\d+)/.exec(USER_AGENT);
+ isUnsupported = (!match || !match[1] ? true : match[1] < 534);
+ }
+
+ // iOS 5+ supports content editable
+ if (exports.ios) {
+ // Block any version <= 4_x(_x)
+ isUnsupported = /OS [0-4](_\d)+ like Mac/i.test(USER_AGENT);
+ }
+
+ // FireFox does support WYSIWYG on mobiles so override
+ // any previous value if using FF
+ if (/Firefox/i.test(USER_AGENT)) {
+ isUnsupported = false;
+ }
+
+ if (/OneBrowser/i.test(USER_AGENT)) {
+ isUnsupported = false;
+ }
+
+ // UCBrowser works but doesn't give a unique user agent
+ if (navigator.vendor === 'UCWEB') {
+ isUnsupported = false;
+ }
+
+ return !isUnsupported;
+ }());
+ }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+
+
+/***/ },
+/* 7 */
+/***/ function(module, exports, __webpack_require__) {
+
+ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports) {
+ 'use strict';
+
+ var VALID_SCHEME_REGEX =
+ /^(?:https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(?:\/\/)/i;
+
+ /**
+ * Escapes a string so it's safe to use in regex
+ *
+ * @param {String} str
+ * @return {String}
+ * @name regex
+ */
+ exports.regex = function (str) {
+ return str.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');
+ };
+
+ /**
+ * Escapes all HTML entities in a string
+ *
+ * If noQuotes is set to false, all single and double
+ * quotes will also be escaped
+ *
+ * @param {String} str
+ * @param {Boolean} [noQuotes=false]
+ * @return {String}
+ * @name entities
+ * @since 1.4.1
+ */
+ exports.entities = function (str, noQuotes) {
+ if (!str) {
+ return str;
+ }
+
+ var replacements = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ ' ': ' ',
+ '\r\n': '\n',
+ '\r': '\n',
+ '\n': ' 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...})); Sets the width and/or height of the editor. If width or height is not numeric it is ignored. 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. 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. 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. 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: Would cause the cursor to be placed: 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). 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. 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. 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 ' + (IE_VER ? '' : ' Gets the current node that contains the selection/caret in
+ * WYSIWYG mode. Will be null in sourceMode or if there is no selection. 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. or Binds a handler to the specified events This function only binds to a limited list of
+ * supported events. The events param should be a string containing the event(s)
+ * to bind this handler to. If multiple, they should be separated
+ * by spaces. Adds a handler to the node changed event. Happens whenever the node containing the selection/caret
+ * changes in WYSIWYG mode. Adds a handler to the selection changed event Happens whenever the selection changes in WYSIWYG mode. 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 Adds a command to the editor or updates an existing
+ * command if a command with the specified name already exists. Once a command is add it can be included in the toolbar by
+ * adding it's name to the toolbar option in the constructor. It
+ * can also be executed manually by calling
+ * {@link jQuery.sceditor.execCommand} ', node.ownerDocument).append(node).html();
+ };
+
+ /**
+ * Gets the text, start/end node and offset for
+ * length chars left or right of the passed node
+ * at the specified offset.
+ *
+ * @param {Node} node
+ * @param {Number} offset
+ * @param {Boolean} isLeft
+ * @param {Number} length
+ * @return {Object}
+ * @private
+ */
+ var outerText = function (range, isLeft, length) {
+ var nodeValue, remaining, start, end, node,
+ text = '',
+ next = range.startContainer,
+ offset = range.startOffset;
+
+ // Handle cases where node is a paragraph and offset
+ // refers to the index of a text node.
+ // 3 = text node
+ if (next && next.nodeType !== 3) {
+ next = next.childNodes[offset];
+ offset = 0;
+ }
+
+ start = end = offset;
+
+ while (length > text.length && next && next.nodeType === 3) {
+ nodeValue = next.nodeValue;
+ remaining = length - text.length;
+
+ // If not the first node, start and end should be at their
+ // max values as will be updated when getting the text
+ if (node) {
+ end = nodeValue.length;
+ start = 0;
+ }
+
+ node = next;
+
+ if (isLeft) {
+ start = Math.max(end - remaining, 0);
+ offset = start;
+
+ text = nodeValue.substr(start, end - start) + text;
+ next = node.previousSibling;
+ } else {
+ end = Math.min(remaining, nodeValue.length);
+ offset = start + end;
+
+ text += nodeValue.substr(start, end);
+ next = node.nextSibling;
+ }
+ }
+
+ return {
+ node: node || next,
+ offset: offset,
+ text: text
+ };
+ };
+
+ var RangeHelper = function (w, d) {
+ var _createMarker, _isOwner, _prepareInput,
+ doc = d || w.contentDocument || w.document,
+ win = w,
+ isW3C = !!w.getSelection,
+ startMarker = 'sceditor-start-marker',
+ endMarker = 'sceditor-end-marker',
+ CHARACTER = 'character', // Used to improve minification
+ base = this;
+
+ /**
+ * Inserts HTML into the current range replacing any selected
+ * text. If endHTML is specified the selected contents will be put between
+ * html and endHTML. If there is nothing selected html and endHTML are
+ * just concatenate together. The same as insertHTML except with DOM nodes instead Warning: the nodes must belong to the
+ * document they are being inserted into. Some browsers
+ * will throw exceptions if they don't. Clones the selected Range IE <= 8 will return a TextRange, all other browsers
+ * will return a Range object. Gets the selected Range IE <= 8 will return a TextRange, all other browsers
+ * will return a Range object. or
+ * if it has a class, style attribute or data.
+ *
+ * @param {HTMLElement} elm
+ * @return {Boolean}
+ * @since 1.4.4
+ */
+ hasStyling: function (elm) {
+ var $elm = $(elm);
+
+ return elm && (!$elm.is('p,div') || elm.className ||
+ $elm.attr('style') || !$.isEmptyObject($elm.data()));
+ },
+
+ /**
+ * Converts an element from one type to another.
+ *
+ * For example it can convert the element to
+ *
+ * @param {HTMLElement} oldElm
+ * @param {String} toTagName
+ * @return {HTMLElement}
+ * @since 1.4.4
+ */
+ convertElement: function (oldElm, toTagName) {
+ var child, attr,
+ oldAttrs = oldElm.attributes,
+ attrsIdx = oldAttrs.length,
+ newElm = oldElm.ownerDocument.createElement(toTagName);
+
+ while (attrsIdx--) {
+ attr = oldAttrs[attrsIdx];
+
+ // IE < 8 returns all possible attributes instead of just
+ // the specified ones so have to check it is specified.
+ if (!browser.ie || attr.specified) {
+ // IE < 8 doesn't return the CSS for the style attribute
+ // so must copy it manually
+ if (browser.ie < 8 && /style/i.test(attr.name)) {
+ dom.copyCSS(oldElm, newElm);
+ } else {
+ // Some browsers parse invalid attributes names like
+ // 'size"2' which throw an exception when set, just
+ // ignore these.
+ try {
+ newElm.setAttribute(attr.name, attr.value);
+ } catch (ex) {}
+ }
+ }
+ }
+
+ while ((child = oldElm.firstChild)) {
+ newElm.appendChild(child);
+ }
+
+ oldElm.parentNode.replaceChild(newElm, oldElm);
+
+ return newElm;
+ },
+
+ /**
+ * List of block level elements separated by bars (|)
+ * @type {string}
+ */
+ blockLevelList: '|body|hr|p|div|h1|h2|h3|h4|h5|h6|address|pre|form|' +
+ 'table|tbody|thead|tfoot|th|tr|td|li|ol|ul|blockquote|center|',
+
+ /**
+ * List of elements that do not allow children separated by bars (|)
+ *
+ * @param {Node} node
+ * @return {bool}
+ * @since 1.4.5
+ */
+ canHaveChildren: function (node) {
+ // 1 = Element
+ // 9 = Document
+ // 11 = Document Fragment
+ if (!/11?|9/.test(node.nodeType)) {
+ return false;
+ }
+
+ // List of empty HTML tags separated by bar (|) character.
+ // Source: http://www.w3.org/TR/html4/index/elements.html
+ // Source: http://www.w3.org/TR/html5/syntax.html#void-elements
+ return ('|iframe|area|base|basefont|br|col|frame|hr|img|input|wbr' +
+ '|isindex|link|meta|param|command|embed|keygen|source|track|' +
+ 'object|').indexOf('|' + node.nodeName.toLowerCase() + '|') < 0;
+ },
+
+ /**
+ * Checks if an element is inline
+ *
+ * @return {bool}
+ */
+ isInline: function (elm, includeCodeAsBlock) {
+ var tagName,
+ nodeType = (elm || {}).nodeType || 3;
+
+ if (nodeType !== 1) {
+ return nodeType === 3;
+ }
+
+ tagName = elm.tagName.toLowerCase();
+
+ if (tagName === 'code') {
+ return !includeCodeAsBlock;
+ }
+
+ return dom.blockLevelList.indexOf('|' + tagName + '|') < 0;
+ },
+
+ /**
+ * Copys the CSS from 1 node to another. Only copies CSS defined on the element e.g. style attr. Detects if the browser is iOS Needed to fix iOS specific bugs/ ')[0].contentEditable;
+
+ // Check if the contenteditable attribute is supported
+ if (editableAttr === undef || editableAttr === 'inherit') {
+ return false;
+ }
+
+ // I think blackberry supports contentEditable or will at least
+ // give a valid value for the contentEditable detection above
+ // so it isn't included in the below tests.
+
+ // I hate having to do UA sniffing but some mobile browsers say they
+ // support contentediable when it isn't usable, i.e. you can't enter
+ // text.
+ // This is the only way I can think of to detect them which is also how
+ // every other editor I've seen deals with this issue.
+
+ // Exclude Opera mobile and mini
+ isUnsupported = /Opera Mobi|Opera Mini/i.test(USER_AGENT);
+
+ if (/Android/i.test(USER_AGENT)) {
+ isUnsupported = true;
+
+ if (/Safari/.test(USER_AGENT)) {
+ // Android browser 534+ supports content editable
+ // This also matches Chrome which supports content editable too
+ match = /Safari\/(\d+)/.exec(USER_AGENT);
+ isUnsupported = (!match || !match[1] ? true : match[1] < 534);
+ }
+ }
+
+ // The current version of Amazon Silk supports it, older versions didn't
+ // As it uses webkit like Android, assume it's the same and started
+ // working at versions >= 534
+ if (/ Silk\//i.test(USER_AGENT)) {
+ match = /AppleWebKit\/(\d+)/.exec(USER_AGENT);
+ isUnsupported = (!match || !match[1] ? true : match[1] < 534);
+ }
+
+ // iOS 5+ supports content editable
+ if (exports.ios) {
+ // Block any version <= 4_x(_x)
+ isUnsupported = /OS [0-4](_\d)+ like Mac/i.test(USER_AGENT);
+ }
+
+ // FireFox does support WYSIWYG on mobiles so override
+ // any previous value if using FF
+ if (/Firefox/i.test(USER_AGENT)) {
+ isUnsupported = false;
+ }
+
+ if (/OneBrowser/i.test(USER_AGENT)) {
+ isUnsupported = false;
+ }
+
+ // UCBrowser works but doesn't give a unique user agent
+ if (navigator.vendor === 'UCWEB') {
+ isUnsupported = false;
+ }
+
+ return !isUnsupported;
+ }());
+ }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+
+
+/***/ },
+/* 7 */
+/***/ function(module, exports, __webpack_require__) {
+
+ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function (require, exports) {
+ 'use strict';
+
+ var VALID_SCHEME_REGEX =
+ /^(?:https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(?:\/\/)/i;
+
+ /**
+ * Escapes a string so it's safe to use in regex
+ *
+ * @param {String} str
+ * @return {String}
+ * @name regex
+ */
+ exports.regex = function (str) {
+ return str.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');
+ };
+
+ /**
+ * Escapes all HTML entities in a string
+ *
+ * If noQuotes is set to false, all single and double
+ * quotes will also be escaped
+ *
+ * @param {String} str
+ * @param {Boolean} [noQuotes=false]
+ * @return {String}
+ * @name entities
+ * @since 1.4.1
+ */
+ exports.entities = function (str, noQuotes) {
+ if (!str) {
+ return str;
+ }
+
+ var replacements = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ ' ': ' ',
+ '\r\n': '\n',
+ '\r': '\n',
+ '\n': ' 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...})); ', 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:
+ * Adds a BBCode to the parser or updates an existing
+ * BBCode if a BBCode with the specified name already exists. ', 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 00000000..c95ef4ac
Binary files /dev/null and b/js/sceditor/development/themes/famfamfam.png differ
diff --git a/js/sceditor/development/themes/modern.css b/js/sceditor/development/themes/modern.css
new file mode 100644
index 00000000..00fe57f4
--- /dev/null
+++ b/js/sceditor/development/themes/modern.css
@@ -0,0 +1,578 @@
+/**
+ * Modern theme
+ *
+ * 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 #999;
+}
+.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 {
+ background: #ccc;
+ background: linear-gradient(to bottom, #cccccc 0%, #b2b2b2 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#b2b2b2', GradientType=0);
+}
+.ie9 div.sceditor-toolbar {
+ filter: none;
+ background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2NjY2NjYyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNiMmIyYjIiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+);
+}
+div.sceditor-group {
+ display: inline;
+ background: transparent;
+ margin: 0;
+ padding: 0;
+ border: 0;
+}
+.sceditor-button {
+ padding: 4px;
+ margin: 2px 1px 2px 3px;
+ height: 16px;
+ border-radius: 12px;
+ background-clip: padding-box;
+}
+.sceditor-button:hover,
+.sceditor-button.active,
+.sceditor-button.active:hover {
+ box-shadow: none;
+}
+.sceditor-button:hover {
+ background: #fff;
+ background: rgba(255, 255, 255, 0.75);
+ margin: 1px 0 1px 2px;
+ border: 1px solid #eee;
+}
+.sceditor-button.disabled:hover {
+ margin: 2px 1px 2px 3px;
+ border: 0;
+}
+.sceditor-button.active {
+ background: #b1b1b1;
+ background: rgba(0, 0, 0, 0.1);
+ margin: 1px 0 1px 2px;
+ border: 1px solid #999;
+}
+.sceditor-button.active:hover {
+ background: #fff;
+ background: rgba(255, 255, 255, 0.25);
+}
+.sceditor-button:active,
+.sceditor-button.active:active {
+ margin: 1px 0 1px 2px;
+ border: 1px solid #999;
+ box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.5);
+}
+.sceditor-button div {
+ margin: 0;
+}
diff --git a/js/sceditor/development/themes/monocons.css b/js/sceditor/development/themes/monocons.css
new file mode 100644
index 00000000..f955835c
--- /dev/null
+++ b/js/sceditor/development/themes/monocons.css
@@ -0,0 +1,643 @@
+/**
+ * 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
+ */
+@font-face {
+ font-family: 'Monocons';
+ src: url('monocons//monocons.eot');
+ src: url('monocons//monocons.eot?#iefix') format('embedded-opentype'), url('monocons//monocons.ttf') format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+.sceditor-button div:before,
+div.sceditor-grip {
+ font-family: 'Monocons';
+ font-size: 16px;
+ speak: none;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+}
+.sceditor-button-youtube div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e000');
+}
+.sceditor-button-unlink div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e001');
+}
+.sceditor-button-underline div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e002');
+}
+.sceditor-button-time div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e003');
+}
+.sceditor-button-table div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e004');
+}
+.sceditor-button-superscript div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e005');
+}
+.sceditor-button-subscript div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e006');
+}
+.sceditor-button-strike div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e007');
+}
+.sceditor-button-source div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e008');
+}
+.sceditor-button-size div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e009');
+}
+.sceditor-button-rtl div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e00a');
+}
+.sceditor-button-right div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e00b');
+}
+.sceditor-button-removeformat div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e00c');
+}
+.sceditor-button-quote div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e00d');
+}
+.sceditor-button-print div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e00e');
+}
+.sceditor-button-pastetext div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e00f');
+}
+.sceditor-button-paste div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e010');
+}
+.sceditor-button-orderedlist div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e011');
+}
+.sceditor-button-maximize div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e012');
+}
+.sceditor-button-ltr div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e013');
+}
+.sceditor-button-link div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e014');
+}
+.sceditor-button-left div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e015');
+}
+.sceditor-button-justify div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e016');
+}
+.sceditor-button-italic div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e017');
+}
+.sceditor-button-image div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e018');
+}
+.sceditor-button-horizontalrule div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e019');
+}
+.sceditor-button-format div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e01c');
+}
+.sceditor-button-font div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e01d');
+}
+.sceditor-button-emoticon div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e01e');
+}
+.sceditor-button-email div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e01f');
+}
+.sceditor-button-bold div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e020');
+}
+.sceditor-button-date div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e021');
+}
+.sceditor-button-cut div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e022');
+}
+.sceditor-button-copy div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e023');
+}
+.sceditor-button-color div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e024');
+}
+.sceditor-button-code div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e025');
+}
+.sceditor-button-center div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e026');
+}
+.sceditor-button-bulletlist div {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e027');
+}
+div.sceditor-grip {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e01b');
+}
+.rtl div.sceditor-grip {
+ *zoom: expression(this.runtimeStyle['zoom'] = '1', this.innerHTML = '\e01a');
+}
+.sceditor-button-youtube div:before {
+ content: "\e000";
+}
+.sceditor-button-unlink div:before {
+ content: "\e001";
+}
+.sceditor-button-underline div:before {
+ content: "\e002";
+}
+.sceditor-button-time div:before {
+ content: "\e003";
+}
+.sceditor-button-table div:before {
+ content: "\e004";
+}
+.sceditor-button-superscript div:before {
+ content: "\e005";
+}
+.sceditor-button-subscript div:before {
+ content: "\e006";
+}
+.sceditor-button-strike div:before {
+ content: "\e007";
+}
+.sceditor-button-source div:before {
+ content: "\e008";
+}
+.sceditor-button-size div:before {
+ content: "\e009";
+}
+.sceditor-button-rtl div:before {
+ content: "\e00a";
+}
+.sceditor-button-right div:before {
+ content: "\e00b";
+}
+.sceditor-button-removeformat div:before {
+ content: "\e00c";
+}
+.sceditor-button-quote div:before {
+ content: "\e00d";
+}
+.sceditor-button-print div:before {
+ content: "\e00e";
+}
+.sceditor-button-pastetext div:before {
+ content: "\e00f";
+}
+.sceditor-button-paste div:before {
+ content: "\e010";
+}
+.sceditor-button-orderedlist div:before {
+ content: "\e011";
+}
+.sceditor-button-maximize div:before {
+ content: "\e012";
+}
+.sceditor-button-ltr div:before {
+ content: "\e013";
+}
+.sceditor-button-link div:before {
+ content: "\e014";
+}
+.sceditor-button-left div:before {
+ content: "\e015";
+}
+.sceditor-button-justify div:before {
+ content: "\e016";
+}
+.sceditor-button-italic div:before {
+ content: "\e017";
+}
+.sceditor-button-image div:before {
+ content: "\e018";
+}
+.sceditor-button-horizontalrule div:before {
+ content: "\e019";
+}
+.sceditor-button-format div:before {
+ content: "\e01c";
+}
+.sceditor-button-font div:before {
+ content: "\e01d";
+}
+.sceditor-button-emoticon div:before {
+ content: "\e01e";
+}
+.sceditor-button-email div:before {
+ content: "\e01f";
+}
+.sceditor-button-bold div:before {
+ content: "\e020";
+}
+.sceditor-button-date div:before {
+ content: "\e021";
+}
+.sceditor-button-cut div:before {
+ content: "\e022";
+}
+.sceditor-button-copy div:before {
+ content: "\e023";
+}
+.sceditor-button-color div:before {
+ content: "\e024";
+}
+.sceditor-button-code div:before {
+ content: "\e025";
+}
+.sceditor-button-center div:before {
+ content: "\e026";
+}
+.sceditor-button-bulletlist div:before {
+ content: "\e027";
+}
+div.sceditor-grip:before {
+ content: "\e01b";
+}
+.rtl div.sceditor-grip:before {
+ content: "\e01a";
+}
+/**
+ * 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;
+}
+.ie7 .sceditor-button div,
+.ie6 .sceditor-button div {
+ font-family: 'Monocons';
+ overflow: visible;
+ font-size: 16px;
+ line-height: 1;
+ text-indent: 0;
+}
+div.sceditor-grip {
+ height: 16px;
+ width: 16px;
+}
+.sceditor-button div:before,
+div.sceditor-grip:before {
+ text-indent: 0;
+ line-height: 17px;
+ width: 16px;
+ height: 16px;
+ display: block;
+ color: #333;
+ text-shadow: 0 1px #fff;
+}
diff --git a/js/sceditor/development/themes/monocons/monocons.eot b/js/sceditor/development/themes/monocons/monocons.eot
new file mode 100644
index 00000000..1db65477
Binary files /dev/null and b/js/sceditor/development/themes/monocons/monocons.eot differ
diff --git a/js/sceditor/development/themes/monocons/monocons.ttf b/js/sceditor/development/themes/monocons/monocons.ttf
new file mode 100644
index 00000000..d100abdf
Binary files /dev/null and b/js/sceditor/development/themes/monocons/monocons.ttf differ
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 00000000..58a07677
Binary files /dev/null and b/js/sceditor/emoticons/alien.png differ
diff --git a/js/sceditor/emoticons/angel.png b/js/sceditor/emoticons/angel.png
new file mode 100644
index 00000000..4792225c
Binary files /dev/null and b/js/sceditor/emoticons/angel.png differ
diff --git a/js/sceditor/emoticons/angry.png b/js/sceditor/emoticons/angry.png
new file mode 100644
index 00000000..7bec8e4b
Binary files /dev/null and b/js/sceditor/emoticons/angry.png differ
diff --git a/js/sceditor/emoticons/blink.png b/js/sceditor/emoticons/blink.png
new file mode 100644
index 00000000..ff529f12
Binary files /dev/null and b/js/sceditor/emoticons/blink.png differ
diff --git a/js/sceditor/emoticons/blush.png b/js/sceditor/emoticons/blush.png
new file mode 100644
index 00000000..8ff7d1db
Binary files /dev/null and b/js/sceditor/emoticons/blush.png differ
diff --git a/js/sceditor/emoticons/cheerful.png b/js/sceditor/emoticons/cheerful.png
new file mode 100644
index 00000000..c7c5cb84
Binary files /dev/null and b/js/sceditor/emoticons/cheerful.png differ
diff --git a/js/sceditor/emoticons/cool.png b/js/sceditor/emoticons/cool.png
new file mode 100644
index 00000000..d21c5445
Binary files /dev/null and b/js/sceditor/emoticons/cool.png differ
diff --git a/js/sceditor/emoticons/credits.txt b/js/sceditor/emoticons/credits.txt
new file mode 100644
index 00000000..2ffdaeb2
--- /dev/null
+++ b/js/sceditor/emoticons/credits.txt
@@ -0,0 +1,9 @@
+Presenting, Nomicons: The Full Monty :o
+
+Credits:
+Oscar Gruno, aka Nominell v. 2.0 -> 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 00000000..58ee08f8
Binary files /dev/null and b/js/sceditor/emoticons/cwy.png differ
diff --git a/js/sceditor/emoticons/devil.png b/js/sceditor/emoticons/devil.png
new file mode 100644
index 00000000..7d8226a2
Binary files /dev/null and b/js/sceditor/emoticons/devil.png differ
diff --git a/js/sceditor/emoticons/dizzy.png b/js/sceditor/emoticons/dizzy.png
new file mode 100644
index 00000000..82184642
Binary files /dev/null and b/js/sceditor/emoticons/dizzy.png differ
diff --git a/js/sceditor/emoticons/ermm.png b/js/sceditor/emoticons/ermm.png
new file mode 100644
index 00000000..122c10f4
Binary files /dev/null and b/js/sceditor/emoticons/ermm.png differ
diff --git a/js/sceditor/emoticons/face.png b/js/sceditor/emoticons/face.png
new file mode 100644
index 00000000..04ad4b7a
Binary files /dev/null and b/js/sceditor/emoticons/face.png differ
diff --git a/js/sceditor/emoticons/getlost.png b/js/sceditor/emoticons/getlost.png
new file mode 100644
index 00000000..ac87dcea
Binary files /dev/null and b/js/sceditor/emoticons/getlost.png differ
diff --git a/js/sceditor/emoticons/grin.png b/js/sceditor/emoticons/grin.png
new file mode 100644
index 00000000..69cf5a3b
Binary files /dev/null and b/js/sceditor/emoticons/grin.png differ
diff --git a/js/sceditor/emoticons/happy.png b/js/sceditor/emoticons/happy.png
new file mode 100644
index 00000000..54b91316
Binary files /dev/null and b/js/sceditor/emoticons/happy.png differ
diff --git a/js/sceditor/emoticons/heart.png b/js/sceditor/emoticons/heart.png
new file mode 100644
index 00000000..451058d6
Binary files /dev/null and b/js/sceditor/emoticons/heart.png differ
diff --git a/js/sceditor/emoticons/kissing.png b/js/sceditor/emoticons/kissing.png
new file mode 100644
index 00000000..28d77524
Binary files /dev/null and b/js/sceditor/emoticons/kissing.png differ
diff --git a/js/sceditor/emoticons/laughing.png b/js/sceditor/emoticons/laughing.png
new file mode 100644
index 00000000..d65f35ec
Binary files /dev/null and b/js/sceditor/emoticons/laughing.png differ
diff --git a/js/sceditor/emoticons/ninja.png b/js/sceditor/emoticons/ninja.png
new file mode 100644
index 00000000..952f8119
Binary files /dev/null and b/js/sceditor/emoticons/ninja.png differ
diff --git a/js/sceditor/emoticons/pinch.png b/js/sceditor/emoticons/pinch.png
new file mode 100644
index 00000000..f6f6e53b
Binary files /dev/null and b/js/sceditor/emoticons/pinch.png differ
diff --git a/js/sceditor/emoticons/pouty.png b/js/sceditor/emoticons/pouty.png
new file mode 100644
index 00000000..f3cef70f
Binary files /dev/null and b/js/sceditor/emoticons/pouty.png differ
diff --git a/js/sceditor/emoticons/sad.png b/js/sceditor/emoticons/sad.png
new file mode 100644
index 00000000..d08666e2
Binary files /dev/null and b/js/sceditor/emoticons/sad.png differ
diff --git a/js/sceditor/emoticons/shocked.png b/js/sceditor/emoticons/shocked.png
new file mode 100644
index 00000000..f3dfb11f
Binary files /dev/null and b/js/sceditor/emoticons/shocked.png differ
diff --git a/js/sceditor/emoticons/sick.png b/js/sceditor/emoticons/sick.png
new file mode 100644
index 00000000..3a473815
Binary files /dev/null and b/js/sceditor/emoticons/sick.png differ
diff --git a/js/sceditor/emoticons/sideways.png b/js/sceditor/emoticons/sideways.png
new file mode 100644
index 00000000..b3dd09ab
Binary files /dev/null and b/js/sceditor/emoticons/sideways.png differ
diff --git a/js/sceditor/emoticons/silly.png b/js/sceditor/emoticons/silly.png
new file mode 100644
index 00000000..d4497d9a
Binary files /dev/null and b/js/sceditor/emoticons/silly.png differ
diff --git a/js/sceditor/emoticons/sleeping.png b/js/sceditor/emoticons/sleeping.png
new file mode 100644
index 00000000..2b97a803
Binary files /dev/null and b/js/sceditor/emoticons/sleeping.png differ
diff --git a/js/sceditor/emoticons/smile.png b/js/sceditor/emoticons/smile.png
new file mode 100644
index 00000000..c11821e8
Binary files /dev/null and b/js/sceditor/emoticons/smile.png differ
diff --git a/js/sceditor/emoticons/tongue.png b/js/sceditor/emoticons/tongue.png
new file mode 100644
index 00000000..73da3e34
Binary files /dev/null and b/js/sceditor/emoticons/tongue.png differ
diff --git a/js/sceditor/emoticons/unsure.png b/js/sceditor/emoticons/unsure.png
new file mode 100644
index 00000000..87c75997
Binary files /dev/null and b/js/sceditor/emoticons/unsure.png differ
diff --git a/js/sceditor/emoticons/w00t.png b/js/sceditor/emoticons/w00t.png
new file mode 100644
index 00000000..fa08831b
Binary files /dev/null and b/js/sceditor/emoticons/w00t.png differ
diff --git a/js/sceditor/emoticons/wassat.png b/js/sceditor/emoticons/wassat.png
new file mode 100644
index 00000000..201733b0
Binary files /dev/null and b/js/sceditor/emoticons/wassat.png differ
diff --git a/js/sceditor/emoticons/whistling.png b/js/sceditor/emoticons/whistling.png
new file mode 100644
index 00000000..3940f0d8
Binary files /dev/null and b/js/sceditor/emoticons/whistling.png differ
diff --git a/js/sceditor/emoticons/wink.png b/js/sceditor/emoticons/wink.png
new file mode 100644
index 00000000..3d1a9cc0
Binary files /dev/null and b/js/sceditor/emoticons/wink.png differ
diff --git a/js/sceditor/emoticons/wub.png b/js/sceditor/emoticons/wub.png
new file mode 100644
index 00000000..d5faa2b6
Binary files /dev/null and b/js/sceditor/emoticons/wub.png differ
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 is licensed under the MIT "+(n?"":" ')[0].contentEditable;return g!==f&&"inherit"!==g&&(c=/Opera Mobi|Opera Mini/i.test(e),/Android/i.test(e)&&(c=!0,/Safari/.test(e)&&(a=/Safari\/(\d+)/.exec(e),c=!a||!a[1]||a[1]<534)),/ Silk\//i.test(e)&&(a=/AppleWebKit\/(\d+)/.exec(e),c=!a||!a[1]||a[1]<534),b.ios&&(c=/OS [0-4](_\d)+ like Mac/i.test(e)),/Firefox/i.test(e)&&(c=!1),/OneBrowser/i.test(e)&&(c=!1),"UCWEB"===navigator.vendor&&(c=!1),!c)}()}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a,b){"use strict";var c=/^(?:https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(?:\/\/)/i;b.regex=function(a){return a.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")},b.entities=function(a,b){if(!a)return a;var c={"&":"&","<":"<",">":">"," ":" ","\r\n":"\n","\r":"\n","\n":" "+(n?"":" ')[0].contentEditable;return g!==f&&"inherit"!==g&&(c=/Opera Mobi|Opera Mini/i.test(e),/Android/i.test(e)&&(c=!0,/Safari/.test(e)&&(a=/Safari\/(\d+)/.exec(e),c=!a||!a[1]||a[1]<534)),/ Silk\//i.test(e)&&(a=/AppleWebKit\/(\d+)/.exec(e),c=!a||!a[1]||a[1]<534),b.ios&&(c=/OS [0-4](_\d)+ like Mac/i.test(e)),/Firefox/i.test(e)&&(c=!1),/OneBrowser/i.test(e)&&(c=!1),"UCWEB"===navigator.vendor&&(c=!1),!c)}()}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a,b){"use strict";var c=/^(?:https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(?:\/\/)/i;b.regex=function(a){return a.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")},b.entities=function(a,b){if(!a)return a;var c={"&":"&","<":"<",">":">"," ":" ","\r\n":"\n","\r":"\n","\n":" "+(n?"":" ')[0].contentEditable;return g!==f&&"inherit"!==g&&(c=/Opera Mobi|Opera Mini/i.test(e),/Android/i.test(e)&&(c=!0,/Safari/.test(e)&&(a=/Safari\/(\d+)/.exec(e),c=!a||!a[1]||a[1]<534)),/ Silk\//i.test(e)&&(a=/AppleWebKit\/(\d+)/.exec(e),c=!a||!a[1]||a[1]<534),b.ios&&(c=/OS [0-4](_\d)+ like Mac/i.test(e)),/Firefox/i.test(e)&&(c=!1),/OneBrowser/i.test(e)&&(c=!1),"UCWEB"===navigator.vendor&&(c=!1),!c)}()}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(a,b){"use strict";var c=/^(?:https?|s?ftp|mailto|spotify|skype|ssh|teamspeak|tel):|(?:\/\/)/i;b.regex=function(a){return a.replace(/([\-.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")},b.entities=function(a,b){if(!a)return a;var c={"&":"&","<":"<",">":">"," ":" ","\r\n":"\n","\r":"\n","\n":" ",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=o
'
+ };
+
+ if (noQuotes !== false) {
+ replacements['"'] = '"';
+ replacements['\''] = ''';
+ replacements['`'] = '`';
+ }
+
+ str = str.replace(/ {2}|\r\n|[&<>\r\n'"`]/g, function (match) {
+ return replacements[match] || match;
+ });
+
+ return str;
+ };
+
+ /**
+ * Escape URI scheme.
+ *
+ * Appends the current URL to a url if it has a scheme that is not:
+ *
+ * http
+ * https
+ * sftp
+ * ftp
+ * mailto
+ * spotify
+ * skype
+ * ssh
+ * teamspeak
+ * tel
+ * //
+ *
+ * **IMPORTANT**: This does not escape any HTML in a url, for
+ * that use the escape.entities() method.
+ *
+ * @param {String} url
+ * @return {String}
+ * @name escapeUriScheme
+ * @memberOf jQuery.sceditor
+ * @since 1.4.5
+ */
+ exports.uriScheme = function (url) {
+ /*jshint maxlen:false*/
+ var path,
+ // If there is a : before a / then it has a scheme
+ hasScheme = /^[^\/]*:/i,
+ location = window.location;
+
+ // Has no scheme or a valid scheme
+ if ((!url || !hasScheme.test(url)) || VALID_SCHEME_REGEX.test(url)) {
+ return url;
+ }
+
+ path = location.pathname.split('/');
+ path.pop();
+
+ return location.protocol + '//' +
+ location.host +
+ path.join('/') + '/' +
+ url;
+ };
+ }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+
+
+/***/ },
+/* 8 */
+/***/ function(module, exports, __webpack_require__) {
+
+ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function () {
+ 'use strict';
+
+ /**
+ * HTML templates used by the editor and default commands
+ * @type {Object}
+ * @private
+ */
+ var _templates = {
+ html:
+ '' +
+ '' +
+ '',
+
+ fontOpt: '{font}',
+
+ sizeOpt: '{size}',
+
+ pastetext:
+ '
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 += '
';
+
+ 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(
+ '';
+
+ for (col = 0; col < cols; col++) {
+ html += ' ';
+ }
+
+ html += '' +
+ (IE_BR_FIX ? '' : ' ';
+ }
+
+ html += '
') +
+ '',
+ (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}
+ */
+ /**
+ *
+ *
+ * '[b]', '[/b]'
+ *
+ * [b]Selected text|[/b]
') + '
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
' : '';
+ 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);
+ };
+
+ /**
+ *
+ * The supported events are:
+ *
+ *
+ *
+ *
+ *
+ * When the current node containing the selection changes
+ * in WYSIWYG mode
to be selected but inserting a node
+ // into
will cause it not to be displayed so must
+ // insert before the
in FF.
+ // 3 = TextNode
+ if (parent && parent.nodeType !== 3 &&
+ !dom.canHaveChildren(parent)) {
+ parent.parentNode.insertBefore(input, parent);
+ } else {
+ range.insertNode(input);
+ }
+
+ base.restoreRange();
+ } else {
+ base.insertHTML(
+ _nodeToHtml(node),
+ endNode ? _nodeToHtml(endNode) : null
+ );
+ }
+ };
+
+ /**
+ *
'
+ };
+
+ if (noQuotes !== false) {
+ replacements['"'] = '"';
+ replacements['\''] = ''';
+ replacements['`'] = '`';
+ }
+
+ str = str.replace(/ {2}|\r\n|[&<>\r\n'"`]/g, function (match) {
+ return replacements[match] || match;
+ });
+
+ return str;
+ };
+
+ /**
+ * Escape URI scheme.
+ *
+ * Appends the current URL to a url if it has a scheme that is not:
+ *
+ * http
+ * https
+ * sftp
+ * ftp
+ * mailto
+ * spotify
+ * skype
+ * ssh
+ * teamspeak
+ * tel
+ * //
+ *
+ * **IMPORTANT**: This does not escape any HTML in a url, for
+ * that use the escape.entities() method.
+ *
+ * @param {String} url
+ * @return {String}
+ * @name escapeUriScheme
+ * @memberOf jQuery.sceditor
+ * @since 1.4.5
+ */
+ exports.uriScheme = function (url) {
+ /*jshint maxlen:false*/
+ var path,
+ // If there is a : before a / then it has a scheme
+ hasScheme = /^[^\/]*:/i,
+ location = window.location;
+
+ // Has no scheme or a valid scheme
+ if ((!url || !hasScheme.test(url)) || VALID_SCHEME_REGEX.test(url)) {
+ return url;
+ }
+
+ path = location.pathname.split('/');
+ path.pop();
+
+ return location.protocol + '//' +
+ location.host +
+ path.join('/') + '/' +
+ url;
+ };
+ }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
+
+
+/***/ },
+/* 8 */
+/***/ function(module, exports, __webpack_require__) {
+
+ var __WEBPACK_AMD_DEFINE_RESULT__;!(__WEBPACK_AMD_DEFINE_RESULT__ = function () {
+ 'use strict';
+
+ /**
+ * HTML templates used by the editor and default commands
+ * @type {Object}
+ * @private
+ */
+ var _templates = {
+ html:
+ '' +
+ '' +
+ '',
+
+ fontOpt: '{font}',
+
+ sizeOpt: '{size}',
+
+ pastetext:
+ '
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 += '
';
+
+ 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(
+ '';
+
+ for (col = 0; col < cols; col++) {
+ html += ' ';
+ }
+
+ html += '' +
+ (IE_BR_FIX ? '' : ' ';
+ }
+
+ html += '
') +
+ '',
+ (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: [
+ '
'
+ ]
+ },
+ orderedlist: {
+ txtExec: [
+ '
'
+ ]
+ },
+ 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: [
+ '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('
');
+ }
+
+ // 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('{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}
'
+ },
+ 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: '
'
+ ]
+ },
+ orderedlist: {
+ txtExec: [
+ '
'
+ ]
+ },
+ 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: [
+ ' 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
")+"
")),!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('',v[0]).appendTo(v.find("head"))[0]),"string"!=typeof a?I.styleSheet?I.styleSheet.cssText:I.innerHTML:(I.styleSheet?I.styleSheet.cssText=a:I.innerHTML=a,ua)},$=function(a){var b=[],c={"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|","[":"{","]":"}"},d={8:"backspace",9:"tab",13:"enter",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",91:"win",92:"win",93:"select",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scrolllock",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},e={109:"-",110:"del",111:"/",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"},f=a.which,g=d[f]||String.fromCharCode(f).toLowerCase();if((a.ctrlKey||a.metaKey)&&b.push("ctrl"),a.altKey&&b.push("alt"),a.shiftKey&&(b.push("shift"),e[f]?g=e[f]:c[g]&&(g=c[g])),g&&(f<16||f>18)&&b.push(g),b=b.join("+"),Aa[b])return Aa[b].call(ua)},ua.addShortcut=function(a,b){return a=a.toLowerCase(),"string"==typeof b?Aa[a]=function(){return M(Ca[b],ua.commands[b]),!1}:Aa[a]=b,ua},ua.removeShortcut=function(a){return delete Aa[a.toLowerCase()],ua},_=function(a){var d,e,f,g,h;if(!c.disableBlockRemove&&8===a.which&&(g=B.selectedRange())&&(j.getSelection?(d=g.startContainer,e=g.startOffset):(d=g.parentElement(),f=v[0].selection.createRange(),f.moveToElementText(d),f.setEndPoint("EndToStart",g),e=f.text.length),0===e&&(h=pa()))){for(;d!==h;){for(;d.previousSibling;)if(d=d.previousSibling,3!==d.nodeType||d.nodeValue)return;if(!(d=d.parentNode))return}if(h&&!b(h).is("body"))return ua.clearBlockFormatting(h),!1}},pa=function(){for(var a=E;!f.hasStyling(a)||f.isInline(a,!0);)if(!(a=a.parentNode)||b(a).is("body"))return;return a},ua.clearBlockFormatting=function(a){return a=a||pa(),!a||b(a).is("body")?ua:(B.saveRange(),a.className="",z=null,b(a).attr("style",""),b(a).is("p,div,td")||f.convertElement(a,"p"),B.restoreRange(),ua)},qa=function(a){if(C&&(C.hasHandler("valuechangedEvent")||qa.hasHandler)){var c,d=ua.sourceMode(),e=!d&&B.hasSelection();a=a!==!1&&!v[0].getElementById("sceditor-start-marker"),sa.timer&&(clearTimeout(sa.timer),sa.timer=!1),e&&a&&B.saveRange(),c=d?w.val():u.html(),c!==qa.lastHtmlValue&&(qa.lastHtmlValue=c,q.trigger(b.Event("valuechanged",{rawValue:d?ua.val():c}))),e&&a&&B.removeMarkers()}},ra=function(){sa.timer&&qa()},sa=function(a){var b=a.which,c=sa.lastChar,d=13===c||32===c,e=8===c||46===c;sa.lastChar=b,13===b||32===b?d?sa.triggerNextChar=!0:qa():8===b||46===b?e?sa.triggerNextChar=!0:qa():sa.triggerNextChar&&(qa(),sa.triggerNextChar=!1),sa.timer&&clearTimeout(sa.timer),sa.timer=setTimeout(function(){qa()},1500)},ta=function(){J||ua.updateOriginal(),J=!1},K()};return p.locale={},p.command={get:function(a){return p.commands[a]||null},set:function(a,c){return!(!a||!c)&&(c=b.extend(p.commands[a]||{},c),c.remove=function(){p.command.remove(a)},p.commands[a]=c,this)},remove:function(a){return p.commands[a]&&delete p.commands[a],this}},p}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(){"use strict";var a={},b=function(b){var c=this,d=[],e=function(a){return"signal"+a.charAt(0).toUpperCase()+a.slice(1)},f=function(a,c){a=[].slice.call(a);var f,g,h=e(a.shift());for(f=0;f
"};return b!==!1&&(c['"']=""",c["'"]="'",c["`"]="`"),a=a.replace(/ {2}|\r\n|[&<>\r\n'"`]/g,function(a){return c[a]||a})},b.uriScheme=function(a){var b,d=/^[^\/]*:/i,e=window.location;return a&&d.test(a)&&!c.test(a)?(b=e.pathname.split("/"),b.pop(),e.protocol+"//"+e.host+b.join("/")+"/"+a):a}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(){"use strict";var a={html:'',fontOpt:'{font}',sizeOpt:'{size}',pastetext:'
";if(!(g<1||h<1)){for(d=0;d
",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("
")+"";i+=""}i+="",(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=o
"),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("
"),b.length||s.push("
"),s.push("{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}
"},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:'
")+"
")),!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('',v[0]).appendTo(v.find("head"))[0]),"string"!=typeof a?I.styleSheet?I.styleSheet.cssText:I.innerHTML:(I.styleSheet?I.styleSheet.cssText=a:I.innerHTML=a,ua)},$=function(a){var b=[],c={"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|","[":"{","]":"}"},d={8:"backspace",9:"tab",13:"enter",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",91:"win",92:"win",93:"select",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scrolllock",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},e={109:"-",110:"del",111:"/",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"},f=a.which,g=d[f]||String.fromCharCode(f).toLowerCase();if((a.ctrlKey||a.metaKey)&&b.push("ctrl"),a.altKey&&b.push("alt"),a.shiftKey&&(b.push("shift"),e[f]?g=e[f]:c[g]&&(g=c[g])),g&&(f<16||f>18)&&b.push(g),b=b.join("+"),Aa[b])return Aa[b].call(ua)},ua.addShortcut=function(a,b){return a=a.toLowerCase(),"string"==typeof b?Aa[a]=function(){return M(Ca[b],ua.commands[b]),!1}:Aa[a]=b,ua},ua.removeShortcut=function(a){return delete Aa[a.toLowerCase()],ua},_=function(a){var d,e,f,g,h;if(!c.disableBlockRemove&&8===a.which&&(g=B.selectedRange())&&(j.getSelection?(d=g.startContainer,e=g.startOffset):(d=g.parentElement(),f=v[0].selection.createRange(),f.moveToElementText(d),f.setEndPoint("EndToStart",g),e=f.text.length),0===e&&(h=pa()))){for(;d!==h;){for(;d.previousSibling;)if(d=d.previousSibling,3!==d.nodeType||d.nodeValue)return;if(!(d=d.parentNode))return}if(h&&!b(h).is("body"))return ua.clearBlockFormatting(h),!1}},pa=function(){for(var a=E;!f.hasStyling(a)||f.isInline(a,!0);)if(!(a=a.parentNode)||b(a).is("body"))return;return a},ua.clearBlockFormatting=function(a){return a=a||pa(),!a||b(a).is("body")?ua:(B.saveRange(),a.className="",z=null,b(a).attr("style",""),b(a).is("p,div,td")||f.convertElement(a,"p"),B.restoreRange(),ua)},qa=function(a){if(C&&(C.hasHandler("valuechangedEvent")||qa.hasHandler)){var c,d=ua.sourceMode(),e=!d&&B.hasSelection();a=a!==!1&&!v[0].getElementById("sceditor-start-marker"),sa.timer&&(clearTimeout(sa.timer),sa.timer=!1),e&&a&&B.saveRange(),c=d?w.val():u.html(),c!==qa.lastHtmlValue&&(qa.lastHtmlValue=c,q.trigger(b.Event("valuechanged",{rawValue:d?ua.val():c}))),e&&a&&B.removeMarkers()}},ra=function(){sa.timer&&qa()},sa=function(a){var b=a.which,c=sa.lastChar,d=13===c||32===c,e=8===c||46===c;sa.lastChar=b,13===b||32===b?d?sa.triggerNextChar=!0:qa():8===b||46===b?e?sa.triggerNextChar=!0:qa():sa.triggerNextChar&&(qa(),sa.triggerNextChar=!1),sa.timer&&clearTimeout(sa.timer),sa.timer=setTimeout(function(){qa()},1500)},ta=function(){J||ua.updateOriginal(),J=!1},K()};return p.locale={},p.command={get:function(a){return p.commands[a]||null},set:function(a,c){return!(!a||!c)&&(c=b.extend(p.commands[a]||{},c),c.remove=function(){p.command.remove(a)},p.commands[a]=c,this)},remove:function(a){return p.commands[a]&&delete p.commands[a],this}},p}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(){"use strict";var a={},b=function(b){var c=this,d=[],e=function(a){return"signal"+a.charAt(0).toUpperCase()+a.slice(1)},f=function(a,c){a=[].slice.call(a);var f,g,h=e(a.shift());for(f=0;f
"};return b!==!1&&(c['"']=""",c["'"]="'",c["`"]="`"),a=a.replace(/ {2}|\r\n|[&<>\r\n'"`]/g,function(a){return c[a]||a})},b.uriScheme=function(a){var b,d=/^[^\/]*:/i,e=window.location;return a&&d.test(a)&&!c.test(a)?(b=e.pathname.split("/"),b.pop(),e.protocol+"//"+e.host+b.join("/")+"/"+a):a}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(){"use strict";var a={html:'',fontOpt:'{font}',sizeOpt:'{size}',pastetext:'
";if(!(g<1||h<1)){for(d=0;d
",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("
")+"";i+=""}i+="",(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&&h
")+"
")),!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('',v[0]).appendTo(v.find("head"))[0]),"string"!=typeof a?I.styleSheet?I.styleSheet.cssText:I.innerHTML:(I.styleSheet?I.styleSheet.cssText=a:I.innerHTML=a,ua)},$=function(a){var b=[],c={"`":"~",1:"!",2:"@",3:"#",4:"$",5:"%",6:"^",7:"&",8:"*",9:"(",0:")","-":"_","=":"+",";":": ","'":'"',",":"<",".":">","/":"?","\\":"|","[":"{","]":"}"},d={8:"backspace",9:"tab",13:"enter",19:"pause",20:"capslock",27:"esc",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down",45:"insert",46:"del",91:"win",92:"win",93:"select",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9",106:"*",107:"+",109:"-",110:".",111:"/",112:"f1",113:"f2",114:"f3",115:"f4",116:"f5",117:"f6",118:"f7",119:"f8",120:"f9",121:"f10",122:"f11",123:"f12",144:"numlock",145:"scrolllock",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},e={109:"-",110:"del",111:"/",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"},f=a.which,g=d[f]||String.fromCharCode(f).toLowerCase();if((a.ctrlKey||a.metaKey)&&b.push("ctrl"),a.altKey&&b.push("alt"),a.shiftKey&&(b.push("shift"),e[f]?g=e[f]:c[g]&&(g=c[g])),g&&(f<16||f>18)&&b.push(g),b=b.join("+"),Aa[b])return Aa[b].call(ua)},ua.addShortcut=function(a,b){return a=a.toLowerCase(),"string"==typeof b?Aa[a]=function(){return M(Ca[b],ua.commands[b]),!1}:Aa[a]=b,ua},ua.removeShortcut=function(a){return delete Aa[a.toLowerCase()],ua},_=function(a){var d,e,f,g,h;if(!c.disableBlockRemove&&8===a.which&&(g=B.selectedRange())&&(j.getSelection?(d=g.startContainer,e=g.startOffset):(d=g.parentElement(),f=v[0].selection.createRange(),f.moveToElementText(d),f.setEndPoint("EndToStart",g),e=f.text.length),0===e&&(h=pa()))){for(;d!==h;){for(;d.previousSibling;)if(d=d.previousSibling,3!==d.nodeType||d.nodeValue)return;if(!(d=d.parentNode))return}if(h&&!b(h).is("body"))return ua.clearBlockFormatting(h),!1}},pa=function(){for(var a=E;!f.hasStyling(a)||f.isInline(a,!0);)if(!(a=a.parentNode)||b(a).is("body"))return;return a},ua.clearBlockFormatting=function(a){return a=a||pa(),!a||b(a).is("body")?ua:(B.saveRange(),a.className="",z=null,b(a).attr("style",""),b(a).is("p,div,td")||f.convertElement(a,"p"),B.restoreRange(),ua)},qa=function(a){if(C&&(C.hasHandler("valuechangedEvent")||qa.hasHandler)){var c,d=ua.sourceMode(),e=!d&&B.hasSelection();a=a!==!1&&!v[0].getElementById("sceditor-start-marker"),sa.timer&&(clearTimeout(sa.timer),sa.timer=!1),e&&a&&B.saveRange(),c=d?w.val():u.html(),c!==qa.lastHtmlValue&&(qa.lastHtmlValue=c,q.trigger(b.Event("valuechanged",{rawValue:d?ua.val():c}))),e&&a&&B.removeMarkers()}},ra=function(){sa.timer&&qa()},sa=function(a){var b=a.which,c=sa.lastChar,d=13===c||32===c,e=8===c||46===c;sa.lastChar=b,13===b||32===b?d?sa.triggerNextChar=!0:qa():8===b||46===b?e?sa.triggerNextChar=!0:qa():sa.triggerNextChar&&(qa(),sa.triggerNextChar=!1),sa.timer&&clearTimeout(sa.timer),sa.timer=setTimeout(function(){qa()},1500)},ta=function(){J||ua.updateOriginal(),J=!1},K()};return p.locale={},p.command={get:function(a){return p.commands[a]||null},set:function(a,c){return!(!a||!c)&&(c=b.extend(p.commands[a]||{},c),c.remove=function(){p.command.remove(a)},p.commands[a]=c,this)},remove:function(a){return p.commands[a]&&delete p.commands[a],this}},p}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(){"use strict";var a={},b=function(b){var c=this,d=[],e=function(a){return"signal"+a.charAt(0).toUpperCase()+a.slice(1)},f=function(a,c){a=[].slice.call(a);var f,g,h=e(a.shift());for(f=0;f
"};return b!==!1&&(c['"']=""",c["'"]="'",c["`"]="`"),a=a.replace(/ {2}|\r\n|[&<>\r\n'"`]/g,function(a){return c[a]||a})},b.uriScheme=function(a){var b,d=/^[^\/]*:/i,e=window.location;return a&&d.test(a)&&!c.test(a)?(b=e.pathname.split("/"),b.pop(),e.protocol+"//"+e.host+b.join("/")+"/"+a):a}}.call(b,c,b,a),!(void 0!==d&&(a.exports=d))},function(a,b,c){var d;d=function(){"use strict";var a={html:'',fontOpt:'{font}',sizeOpt:'{size}',pastetext:'
";if(!(g<1||h<1)){for(d=0;d
",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("
")+"";i+=""}i+="",(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:['
"]},orderedlist:{txtExec:["
"]},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:['
"),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("
"),b.length||s.push("
"),s.push("
"+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:'"," |
","
"]},image:{txtExec:function(a,b){var c=prompt(this._("Enter the image URL:"),b);c&&this.insertText('",""]},youtube:{txtExec:function(a){var c=this;b.command.get("youtube")._dropDown(c,a,function(a){c.insertText('')})}},rtl:{txtExec:['
",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 00000000..c95ef4ac Binary files /dev/null and b/js/sceditor/minified/themes/famfamfam.png differ diff --git a/js/sceditor/minified/themes/modern.min.css b/js/sceditor/minified/themes/modern.min.css new file mode 100644 index 00000000..170040d8 --- /dev/null +++ b/js/sceditor/minified/themes/modern.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;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{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:active{background:#fff}.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 #999}.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{background:#ccc;background:linear-gradient(to bottom,#ccc 0,#b2b2b2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#b2b2b2', GradientType=0)}.ie9 div.sceditor-toolbar{-webkit-filter:none;filter:none;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2NjY2NjYyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNiMmIyYjIiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}div.sceditor-group{display:inline;background:0 0;margin:0;padding:0;border:0}.sceditor-button{padding:4px;margin:2px 1px 2px 3px;height:16px;border-radius:12px;background-clip:padding-box}.sceditor-button.active,.sceditor-button.active:hover,.sceditor-button:hover{box-shadow:none}.sceditor-button:hover{background:#fff;background:rgba(255,255,255,.75);margin:1px 0 1px 2px;border:1px solid #eee}.sceditor-button.disabled:hover{margin:2px 1px 2px 3px;border:0}.sceditor-button.active{background:#b1b1b1;background:rgba(0,0,0,.1);margin:1px 0 1px 2px;border:1px solid #999}.sceditor-button.active:hover{background:#fff;background:rgba(255,255,255,.25)}.sceditor-button.active:active,.sceditor-button:active{margin:1px 0 1px 2px;border:1px solid #999;box-shadow:inset 0 0 4px rgba(0,0,0,.5)}.sceditor-button div{margin:0} \ No newline at end of file diff --git a/js/sceditor/minified/themes/monocons.min.css b/js/sceditor/minified/themes/monocons.min.css new file mode 100644 index 00000000..4d024b68 --- /dev/null +++ b/js/sceditor/minified/themes/monocons.min.css @@ -0,0 +1 @@ +@font-face{font-family:Monocons;src:url(monocons//monocons.eot);src:url(monocons//monocons.eot?#iefix) format('embedded-opentype'),url(monocons//monocons.ttf) format('truetype');font-weight:400;font-style:normal}.sceditor-button div:before,div.sceditor-grip{font-family:Monocons;font-size:16px;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased}.sceditor-button-youtube div:before{content:"\e000"}.sceditor-button-unlink div:before{content:"\e001"}.sceditor-button-underline div:before{content:"\e002"}.sceditor-button-time div:before{content:"\e003"}.sceditor-button-table div:before{content:"\e004"}.sceditor-button-superscript div:before{content:"\e005"}.sceditor-button-subscript div:before{content:"\e006"}.sceditor-button-strike div:before{content:"\e007"}.sceditor-button-source div:before{content:"\e008"}.sceditor-button-size div:before{content:"\e009"}.sceditor-button-rtl div:before{content:"\e00a"}.sceditor-button-right div:before{content:"\e00b"}.sceditor-button-removeformat div:before{content:"\e00c"}.sceditor-button-quote div:before{content:"\e00d"}.sceditor-button-print div:before{content:"\e00e"}.sceditor-button-pastetext div:before{content:"\e00f"}.sceditor-button-paste div:before{content:"\e010"}.sceditor-button-orderedlist div:before{content:"\e011"}.sceditor-button-maximize div:before{content:"\e012"}.sceditor-button-ltr div:before{content:"\e013"}.sceditor-button-link div:before{content:"\e014"}.sceditor-button-left div:before{content:"\e015"}.sceditor-button-justify div:before{content:"\e016"}.sceditor-button-italic div:before{content:"\e017"}.sceditor-button-image div:before{content:"\e018"}.sceditor-button-horizontalrule div:before{content:"\e019"}.sceditor-button-format div:before{content:"\e01c"}.sceditor-button-font div:before{content:"\e01d"}.sceditor-button-emoticon div:before{content:"\e01e"}.sceditor-button-email div:before{content:"\e01f"}.sceditor-button-bold div:before{content:"\e020"}.sceditor-button-date div:before{content:"\e021"}.sceditor-button-cut div:before{content:"\e022"}.sceditor-button-copy div:before{content:"\e023"}.sceditor-button-color div:before{content:"\e024"}.sceditor-button-code div:before{content:"\e025"}.sceditor-button-center div:before{content:"\e026"}.sceditor-button-bulletlist div:before{content:"\e027"}div.sceditor-grip:before{content:"\e01b"}.rtl div.sceditor-grip:before{content:"\e01a"}.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;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}.ie6 .sceditor-button div,.ie7 .sceditor-button div{font-family:Monocons;overflow:visible;font-size:16px;line-height:1;text-indent:0}div.sceditor-grip{height:16px;width:16px}.sceditor-button div:before,div.sceditor-grip:before{text-indent:0;line-height:17px;width:16px;height:16px;display:block;color:#333;text-shadow:0 1px #fff} \ No newline at end of file diff --git a/js/sceditor/minified/themes/monocons/monocons.eot b/js/sceditor/minified/themes/monocons/monocons.eot new file mode 100644 index 00000000..1db65477 Binary files /dev/null and b/js/sceditor/minified/themes/monocons/monocons.eot differ diff --git a/js/sceditor/minified/themes/monocons/monocons.ttf b/js/sceditor/minified/themes/monocons/monocons.ttf new file mode 100644 index 00000000..d100abdf Binary files /dev/null and b/js/sceditor/minified/themes/monocons/monocons.ttf differ 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 00000000..c95ef4ac Binary files /dev/null and b/stylesheets/sceditor/themes/famfamfam.png differ diff --git a/stylesheets/sceditor/themes/modern.min.css b/stylesheets/sceditor/themes/modern.min.css new file mode 100644 index 00000000..170040d8 --- /dev/null +++ b/stylesheets/sceditor/themes/modern.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;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{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:active{background:#fff}.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 #999}.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{background:#ccc;background:linear-gradient(to bottom,#ccc 0,#b2b2b2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#b2b2b2', GradientType=0)}.ie9 div.sceditor-toolbar{-webkit-filter:none;filter:none;background:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2NjY2NjYyIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNiMmIyYjIiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+)}div.sceditor-group{display:inline;background:0 0;margin:0;padding:0;border:0}.sceditor-button{padding:4px;margin:2px 1px 2px 3px;height:16px;border-radius:12px;background-clip:padding-box}.sceditor-button.active,.sceditor-button.active:hover,.sceditor-button:hover{box-shadow:none}.sceditor-button:hover{background:#fff;background:rgba(255,255,255,.75);margin:1px 0 1px 2px;border:1px solid #eee}.sceditor-button.disabled:hover{margin:2px 1px 2px 3px;border:0}.sceditor-button.active{background:#b1b1b1;background:rgba(0,0,0,.1);margin:1px 0 1px 2px;border:1px solid #999}.sceditor-button.active:hover{background:#fff;background:rgba(255,255,255,.25)}.sceditor-button.active:active,.sceditor-button:active{margin:1px 0 1px 2px;border:1px solid #999;box-shadow:inset 0 0 4px rgba(0,0,0,.5)}.sceditor-button div{margin:0} \ No newline at end of file diff --git a/stylesheets/sceditor/themes/monocons.min.css b/stylesheets/sceditor/themes/monocons.min.css new file mode 100644 index 00000000..4d024b68 --- /dev/null +++ b/stylesheets/sceditor/themes/monocons.min.css @@ -0,0 +1 @@ +@font-face{font-family:Monocons;src:url(monocons//monocons.eot);src:url(monocons//monocons.eot?#iefix) format('embedded-opentype'),url(monocons//monocons.ttf) format('truetype');font-weight:400;font-style:normal}.sceditor-button div:before,div.sceditor-grip{font-family:Monocons;font-size:16px;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased}.sceditor-button-youtube div:before{content:"\e000"}.sceditor-button-unlink div:before{content:"\e001"}.sceditor-button-underline div:before{content:"\e002"}.sceditor-button-time div:before{content:"\e003"}.sceditor-button-table div:before{content:"\e004"}.sceditor-button-superscript div:before{content:"\e005"}.sceditor-button-subscript div:before{content:"\e006"}.sceditor-button-strike div:before{content:"\e007"}.sceditor-button-source div:before{content:"\e008"}.sceditor-button-size div:before{content:"\e009"}.sceditor-button-rtl div:before{content:"\e00a"}.sceditor-button-right div:before{content:"\e00b"}.sceditor-button-removeformat div:before{content:"\e00c"}.sceditor-button-quote div:before{content:"\e00d"}.sceditor-button-print div:before{content:"\e00e"}.sceditor-button-pastetext div:before{content:"\e00f"}.sceditor-button-paste div:before{content:"\e010"}.sceditor-button-orderedlist div:before{content:"\e011"}.sceditor-button-maximize div:before{content:"\e012"}.sceditor-button-ltr div:before{content:"\e013"}.sceditor-button-link div:before{content:"\e014"}.sceditor-button-left div:before{content:"\e015"}.sceditor-button-justify div:before{content:"\e016"}.sceditor-button-italic div:before{content:"\e017"}.sceditor-button-image div:before{content:"\e018"}.sceditor-button-horizontalrule div:before{content:"\e019"}.sceditor-button-format div:before{content:"\e01c"}.sceditor-button-font div:before{content:"\e01d"}.sceditor-button-emoticon div:before{content:"\e01e"}.sceditor-button-email div:before{content:"\e01f"}.sceditor-button-bold div:before{content:"\e020"}.sceditor-button-date div:before{content:"\e021"}.sceditor-button-cut div:before{content:"\e022"}.sceditor-button-copy div:before{content:"\e023"}.sceditor-button-color div:before{content:"\e024"}.sceditor-button-code div:before{content:"\e025"}.sceditor-button-center div:before{content:"\e026"}.sceditor-button-bulletlist div:before{content:"\e027"}div.sceditor-grip:before{content:"\e01b"}.rtl div.sceditor-grip:before{content:"\e01a"}.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;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}.ie6 .sceditor-button div,.ie7 .sceditor-button div{font-family:Monocons;overflow:visible;font-size:16px;line-height:1;text-indent:0}div.sceditor-grip{height:16px;width:16px}.sceditor-button div:before,div.sceditor-grip:before{text-indent:0;line-height:17px;width:16px;height:16px;display:block;color:#333;text-shadow:0 1px #fff} \ No newline at end of file diff --git a/stylesheets/sceditor/themes/monocons/monocons.eot b/stylesheets/sceditor/themes/monocons/monocons.eot new file mode 100644 index 00000000..1db65477 Binary files /dev/null and b/stylesheets/sceditor/themes/monocons/monocons.eot differ diff --git a/stylesheets/sceditor/themes/monocons/monocons.ttf b/stylesheets/sceditor/themes/monocons/monocons.ttf new file mode 100644 index 00000000..d100abdf Binary files /dev/null and b/stylesheets/sceditor/themes/monocons/monocons.ttf differ 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;} + +