Merge branch 'temp8' into temp8-remove-bootstrap-datepicker

This commit is contained in:
Mads Rasmussen
2018-11-26 13:57:52 +01:00
79 changed files with 1832 additions and 6705 deletions
@@ -1,4 +1,6 @@
namespace Umbraco.Core.Configuration
using System;
namespace Umbraco.Core.Configuration
{
/// <summary>
/// Contains general settings information for the entire Umbraco instance based on information from web.config appsettings
@@ -24,6 +26,8 @@
/// <remarks>
/// Defaults to ~/App_Data/umbraco.config
/// </remarks>
//fixme - remove
[Obsolete("This should not be used, need to remove the content xml cache")]
string ContentXmlFile { get; }
/// <summary>
-16
View File
@@ -35,11 +35,7 @@ namespace Umbraco.Core.IO
private object _wkfsObject;
private MediaFileSystem _mediaFileSystem;
//fixme - is this needed to be a managed file system? seems irrelevant since it won't ever be moved and is only used in one place in code
private IFileSystem _javascriptLibraryFileSystem;
#region Constructor
// DI wants a public ctor
@@ -129,16 +125,6 @@ namespace Umbraco.Core.IO
}
}
//fixme - is this needed to be a managed file system? seems irrelevant since it won't ever be moved and is only used in one place in code
internal IFileSystem JavaScriptLibraryFileSystem
{
get
{
if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems();
return _javascriptLibraryFileSystem;
}
}
private void EnsureWellKnownFileSystems()
{
LazyInitializer.EnsureInitialized(ref _wkfsObject, ref _wkfsInitialized, ref _wkfsLock, CreateWellKnownFileSystems);
@@ -154,7 +140,6 @@ namespace Umbraco.Core.IO
var scriptsFileSystem = new PhysicalFileSystem(SystemDirectories.Scripts);
var masterPagesFileSystem = new PhysicalFileSystem(SystemDirectories.Masterpages);
var mvcViewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews);
var javaScriptLibraryFileSystem = new PhysicalFileSystem(SystemDirectories.JavaScriptLibrary);
_macroPartialFileSystem = new ShadowWrapper(macroPartialFileSystem, "Views/MacroPartials", () => IsScoped());
_partialViewsFileSystem = new ShadowWrapper(partialViewsFileSystem, "Views/Partials", () => IsScoped());
@@ -162,7 +147,6 @@ namespace Umbraco.Core.IO
_scriptsFileSystem = new ShadowWrapper(scriptsFileSystem, "scripts", () => IsScoped());
_masterPagesFileSystem = new ShadowWrapper(masterPagesFileSystem, "masterpages", () => IsScoped());
_mvcViewsFileSystem = new ShadowWrapper(mvcViewsFileSystem, "Views", () => IsScoped());
_javascriptLibraryFileSystem = new ShadowWrapper(javaScriptLibraryFileSystem, "Lib", () => IsScoped());
// filesystems obtained from GetFileSystemProvider are already wrapped and do not need to be wrapped again
_mediaFileSystem = GetFileSystemProvider<MediaFileSystem>();
+13 -18
View File
@@ -8,24 +8,20 @@ namespace Umbraco.Core.IO
{
public static string Bin => "~/bin";
public static string Config => IOHelper.ReturnPath("umbracoConfigDirectory", "~/config");
public static string Config => "~/config";
public static string Css => IOHelper.ReturnPath("umbracoCssDirectory", "~/css");
public static string Data => "~/App_Data";
public static string Data => IOHelper.ReturnPath("umbracoStorageDirectory", "~/App_Data");
public static string Install => "~/install";
public static string Install => IOHelper.ReturnPath("umbracoInstallPath", "~/install");
//fixme: remove this
[Obsolete("Master pages are obsolete and code should be removed")]
public static string Masterpages => "~/masterpages";
//TODO: Consider removing this
public static string Masterpages => IOHelper.ReturnPath("umbracoMasterPagesPath", "~/masterpages");
//NOTE: this is not configurable and shouldn't need to be
public static string AppCode => "~/App_Code";
//NOTE: this is not configurable and shouldn't need to be
public static string AppPlugins => "~/App_Plugins";
//NOTE: this is not configurable and shouldn't need to be
public static string MvcViews => "~/Views";
public static string PartialViews => MvcViews + "/Partials/";
@@ -36,21 +32,20 @@ namespace Umbraco.Core.IO
public static string Scripts => IOHelper.ReturnPath("umbracoScriptsPath", "~/scripts");
public static string StyleSheets => IOHelper.ReturnPath("umbracoStylesheetsPath", "~/css");
public static string Css => IOHelper.ReturnPath("umbracoCssPath", "~/css");
public static string Umbraco => IOHelper.ReturnPath("umbracoPath", "~/umbraco");
//TODO: Consider removing this
public static string UserControls => IOHelper.ReturnPath("umbracoUsercontrolsPath", "~/usercontrols");
//fixme: remove this
[Obsolete("Usercontrols are obsolete and code should be removed")]
public static string UserControls => "~/usercontrols";
[Obsolete("Only used by legacy load balancing which is obsolete and should be removed")]
public static string WebServices => IOHelper.ReturnPath("umbracoWebservicesPath", Umbraco.EnsureEndsWith("/") + "webservices");
//by default the packages folder should exist in the data folder
public static string Packages => IOHelper.ReturnPath("umbracoPackagesPath", Data + IOHelper.DirSepChar + "packages");
public static string Packages => Data + IOHelper.DirSepChar + "packages";
public static string Preview => IOHelper.ReturnPath("umbracoPreviewPath", Data + IOHelper.DirSepChar + "preview");
public static string JavaScriptLibrary => IOHelper.ReturnPath("umbracoJavaScriptLibraryPath", Umbraco + IOHelper.DirSepChar + "lib");
public static string Preview => Data + IOHelper.DirSepChar + "preview";
private static string _root;
+1 -1
View File
@@ -540,7 +540,7 @@ namespace Umbraco.Core
public static string StripHtml(this string text)
{
const string pattern = @"<(.|\n)*?>";
return Regex.Replace(text, pattern, String.Empty);
return Regex.Replace(text, pattern, string.Empty);
}
/// <summary>
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Web.Services;
using Umbraco.Core.IO;
@@ -8,6 +9,7 @@ namespace Umbraco.Core.Sync
/// The client Soap service for making distrubuted cache calls between servers
/// </summary>
[WebServiceBinding(Name = "CacheRefresherSoap", Namespace = "http://umbraco.org/webservices/")]
[Obsolete("Legacy load balancing is obsolete and should be removed")]
internal class ServerSyncWebServiceClient : System.Web.Services.Protocols.SoapHttpClientProtocol
{
+1 -13
View File
@@ -13,7 +13,6 @@ using Umbraco.Core.Persistence;
using Umbraco.Core.Runtime;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Stubs;
using Umbraco.Examine;
using Umbraco.Web;
namespace Umbraco.Tests.Runtimes
@@ -61,23 +60,13 @@ namespace Umbraco.Tests.Runtimes
{
protected override IRuntime GetRuntime()
{
return new TestRuntime(this);
return new TestRuntime();
}
//// don't register anything against AppDomain
//protected override void ConfigureUnhandledException(ILogger logger)
//{ }
}
// test runtime
public class TestRuntime : CoreRuntime
{
public TestRuntime(UmbracoApplicationBase umbracoApplication)
: base()
{
_umbracoApplication = umbracoApplication;
}
// the application's logger is created by the application
// through GetLogger, that custom application can override
protected override ILogger GetLogger()
@@ -118,7 +107,6 @@ namespace Umbraco.Tests.Runtimes
}
private MainDom _mainDom;
private readonly UmbracoApplicationBase _umbracoApplication;
public override void Boot(ServiceContainer container)
{
+1 -18
View File
@@ -253,24 +253,6 @@ gulp.task('dependencies', function () {
"src": ["./node_modules/clipboard/dist/clipboard.min.js"],
"base": "./node_modules/clipboard/dist"
},
{
"name": "codemirror",
"src": [
"./node_modules/codemirror/lib/codemirror.js",
"./node_modules/codemirror/lib/codemirror.css",
"./node_modules/codemirror/mode/css/css.js",
"./node_modules/codemirror/mode/javascript/javascript.js",
"./node_modules/codemirror/mode/xml/xml.js",
"./node_modules/codemirror/mode/htmlmixed/htmlmixed.js",
"./node_modules/codemirror/addon/search/*",
"./node_modules/codemirror/addon/edit/*",
"./node_modules/codemirror/addon/selection/*",
"./node_modules/codemirror/addon/dialog/*"
],
"base": "./node_modules/codemirror"
},
{
"name": "jsdiff",
"src": ["./node_modules/diff/dist/diff.min.js"],
@@ -359,6 +341,7 @@ gulp.task('dependencies', function () {
"src": [
"./node_modules/tinymce/tinymce.min.js",
"./node_modules/tinymce/plugins/**",
"./node_modules/tinymce/skins/**",
"./node_modules/tinymce/themes/**"
],
"base": "./node_modules/tinymce"
@@ -1,22 +0,0 @@
The MIT License
Copyright (c) 2011 Jeff Pickhardt
Modified from the Python CodeMirror mode, Copyright (c) 2010 Timothy Farrell
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.
@@ -1,727 +0,0 @@
<!doctype html>
<html>
<head>
<title>CodeMirror: Razor mode</title>
<link rel="stylesheet" href="../../lib/codemirror.css">
<script src="../../lib/codemirror.js"></script>
<script src="razor.js"></script>
<style>.CodeMirror {border-top: 1px solid silver; border-bottom: 1px solid silver;}</style>
<link rel="stylesheet" href="../../doc/docs.css">
</head>
<body>
<h1>CodeMirror: Razor mode</h1>
<form><textarea id="code" name="code">
# CoffeeScript mode for CodeMirror
# Copyright (c) 2011 Jeff Pickhardt, released under
# the MIT License.
#
# Modified from the Python CodeMirror mode, which also is
# under the MIT License Copyright (c) 2010 Timothy Farrell.
#
# The following script, Underscore.coffee, is used to
# demonstrate CoffeeScript mode for CodeMirror.
#
# To download CoffeeScript mode for CodeMirror, go to:
# https://github.com/pickhardt/coffeescript-codemirror-mode
# **Underscore.coffee
# (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.**
# Underscore is freely distributable under the terms of the
# [MIT license](http://en.wikipedia.org/wiki/MIT_License).
# Portions of Underscore are inspired by or borrowed from
# [Prototype.js](http://prototypejs.org/api), Oliver Steele's
# [Functional](http://osteele.com), and John Resig's
# [Micro-Templating](http://ejohn.org).
# For all details and documentation:
# http://documentcloud.github.com/underscore/
# Baseline setup
# --------------
# Establish the root object, `window` in the browser, or `global` on the server.
root = this
# Save the previous value of the `_` variable.
previousUnderscore = root._
### Multiline
comment
###
# Establish the object that gets thrown to break out of a loop iteration.
# `StopIteration` is SOP on Mozilla.
breaker = if typeof(StopIteration) is 'undefined' then '__break__' else StopIteration
#### Docco style single line comment (title)
# Helper function to escape **RegExp** contents, because JS doesn't have one.
escapeRegExp = (string) -> string.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1')
# Save bytes in the minified (but not gzipped) version:
ArrayProto = Array.prototype
ObjProto = Object.prototype
# Create quick reference variables for speed access to core prototypes.
slice = ArrayProto.slice
unshift = ArrayProto.unshift
toString = ObjProto.toString
hasOwnProperty = ObjProto.hasOwnProperty
propertyIsEnumerable = ObjProto.propertyIsEnumerable
# All **ECMA5** native implementations we hope to use are declared here.
nativeForEach = ArrayProto.forEach
nativeMap = ArrayProto.map
nativeReduce = ArrayProto.reduce
nativeReduceRight = ArrayProto.reduceRight
nativeFilter = ArrayProto.filter
nativeEvery = ArrayProto.every
nativeSome = ArrayProto.some
nativeIndexOf = ArrayProto.indexOf
nativeLastIndexOf = ArrayProto.lastIndexOf
nativeIsArray = Array.isArray
nativeKeys = Object.keys
# Create a safe reference to the Underscore object for use below.
_ = (obj) -> new wrapper(obj)
# Export the Underscore object for **CommonJS**.
if typeof(exports) != 'undefined' then exports._ = _
# Export Underscore to global scope.
root._ = _
# Current version.
_.VERSION = '1.1.0'
# Collection Functions
# --------------------
# The cornerstone, an **each** implementation.
# Handles objects implementing **forEach**, arrays, and raw objects.
_.each = (obj, iterator, context) ->
try
if nativeForEach and obj.forEach is nativeForEach
obj.forEach iterator, context
else if _.isNumber obj.length
iterator.call context, obj[i], i, obj for i in [0...obj.length]
else
iterator.call context, val, key, obj for own key, val of obj
catch e
throw e if e isnt breaker
obj
# Return the results of applying the iterator to each element. Use JavaScript
# 1.6's version of **map**, if possible.
_.map = (obj, iterator, context) ->
return obj.map(iterator, context) if nativeMap and obj.map is nativeMap
results = []
_.each obj, (value, index, list) ->
results.push iterator.call context, value, index, list
results
# **Reduce** builds up a single result from a list of values. Also known as
# **inject**, or **foldl**. Uses JavaScript 1.8's version of **reduce**, if possible.
_.reduce = (obj, iterator, memo, context) ->
if nativeReduce and obj.reduce is nativeReduce
iterator = _.bind iterator, context if context
return obj.reduce iterator, memo
_.each obj, (value, index, list) ->
memo = iterator.call context, memo, value, index, list
memo
# The right-associative version of **reduce**, also known as **foldr**. Uses
# JavaScript 1.8's version of **reduceRight**, if available.
_.reduceRight = (obj, iterator, memo, context) ->
if nativeReduceRight and obj.reduceRight is nativeReduceRight
iterator = _.bind iterator, context if context
return obj.reduceRight iterator, memo
reversed = _.clone(_.toArray(obj)).reverse()
_.reduce reversed, iterator, memo, context
# Return the first value which passes a truth test.
_.detect = (obj, iterator, context) ->
result = null
_.each obj, (value, index, list) ->
if iterator.call context, value, index, list
result = value
_.breakLoop()
result
# Return all the elements that pass a truth test. Use JavaScript 1.6's
# **filter**, if it exists.
_.filter = (obj, iterator, context) ->
return obj.filter iterator, context if nativeFilter and obj.filter is nativeFilter
results = []
_.each obj, (value, index, list) ->
results.push value if iterator.call context, value, index, list
results
# Return all the elements for which a truth test fails.
_.reject = (obj, iterator, context) ->
results = []
_.each obj, (value, index, list) ->
results.push value if not iterator.call context, value, index, list
results
# Determine whether all of the elements match a truth test. Delegate to
# JavaScript 1.6's **every**, if it is present.
_.every = (obj, iterator, context) ->
iterator ||= _.identity
return obj.every iterator, context if nativeEvery and obj.every is nativeEvery
result = true
_.each obj, (value, index, list) ->
_.breakLoop() unless (result = result and iterator.call(context, value, index, list))
result
# Determine if at least one element in the object matches a truth test. Use
# JavaScript 1.6's **some**, if it exists.
_.some = (obj, iterator, context) ->
iterator ||= _.identity
return obj.some iterator, context if nativeSome and obj.some is nativeSome
result = false
_.each obj, (value, index, list) ->
_.breakLoop() if (result = iterator.call(context, value, index, list))
result
# Determine if a given value is included in the array or object,
# based on `===`.
_.include = (obj, target) ->
return _.indexOf(obj, target) isnt -1 if nativeIndexOf and obj.indexOf is nativeIndexOf
return true for own key, val of obj when val is target
false
# Invoke a method with arguments on every item in a collection.
_.invoke = (obj, method) ->
args = _.rest arguments, 2
(if method then val[method] else val).apply(val, args) for val in obj
# Convenience version of a common use case of **map**: fetching a property.
_.pluck = (obj, key) ->
_.map(obj, (val) -> val[key])
# Return the maximum item or (item-based computation).
_.max = (obj, iterator, context) ->
return Math.max.apply(Math, obj) if not iterator and _.isArray(obj)
result = computed: -Infinity
_.each obj, (value, index, list) ->
computed = if iterator then iterator.call(context, value, index, list) else value
computed >= result.computed and (result = {value: value, computed: computed})
result.value
# Return the minimum element (or element-based computation).
_.min = (obj, iterator, context) ->
return Math.min.apply(Math, obj) if not iterator and _.isArray(obj)
result = computed: Infinity
_.each obj, (value, index, list) ->
computed = if iterator then iterator.call(context, value, index, list) else value
computed < result.computed and (result = {value: value, computed: computed})
result.value
# Sort the object's values by a criterion produced by an iterator.
_.sortBy = (obj, iterator, context) ->
_.pluck(((_.map obj, (value, index, list) ->
{value: value, criteria: iterator.call(context, value, index, list)}
).sort((left, right) ->
a = left.criteria; b = right.criteria
if a < b then -1 else if a > b then 1 else 0
)), 'value')
# Use a comparator function to figure out at what index an object should
# be inserted so as to maintain order. Uses binary search.
_.sortedIndex = (array, obj, iterator) ->
iterator ||= _.identity
low = 0
high = array.length
while low < high
mid = (low + high) >> 1
if iterator(array[mid]) < iterator(obj) then low = mid + 1 else high = mid
low
# Convert anything iterable into a real, live array.
_.toArray = (iterable) ->
return [] if (!iterable)
return iterable.toArray() if (iterable.toArray)
return iterable if (_.isArray(iterable))
return slice.call(iterable) if (_.isArguments(iterable))
_.values(iterable)
# Return the number of elements in an object.
_.size = (obj) -> _.toArray(obj).length
# Array Functions
# ---------------
# Get the first element of an array. Passing `n` will return the first N
# values in the array. Aliased as **head**. The `guard` check allows it to work
# with **map**.
_.first = (array, n, guard) ->
if n and not guard then slice.call(array, 0, n) else array[0]
# Returns everything but the first entry of the array. Aliased as **tail**.
# Especially useful on the arguments object. Passing an `index` will return
# the rest of the values in the array from that index onward. The `guard`
# check allows it to work with **map**.
_.rest = (array, index, guard) ->
slice.call(array, if _.isUndefined(index) or guard then 1 else index)
# Get the last element of an array.
_.last = (array) -> array[array.length - 1]
# Trim out all falsy values from an array.
_.compact = (array) -> item for item in array when item
# Return a completely flattened version of an array.
_.flatten = (array) ->
_.reduce array, (memo, value) ->
return memo.concat(_.flatten(value)) if _.isArray value
memo.push value
memo
, []
# Return a version of the array that does not contain the specified value(s).
_.without = (array) ->
values = _.rest arguments
val for val in _.toArray(array) when not _.include values, val
# Produce a duplicate-free version of the array. If the array has already
# been sorted, you have the option of using a faster algorithm.
_.uniq = (array, isSorted) ->
memo = []
for el, i in _.toArray array
memo.push el if i is 0 || (if isSorted is true then _.last(memo) isnt el else not _.include(memo, el))
memo
# Produce an array that contains every item shared between all the
# passed-in arrays.
_.intersect = (array) ->
rest = _.rest arguments
_.select _.uniq(array), (item) ->
_.all rest, (other) ->
_.indexOf(other, item) >= 0
# Zip together multiple lists into a single array -- elements that share
# an index go together.
_.zip = ->
length = _.max _.pluck arguments, 'length'
results = new Array length
for i in [0...length]
results[i] = _.pluck arguments, String i
results
# If the browser doesn't supply us with **indexOf** (I'm looking at you, MSIE),
# we need this function. Return the position of the first occurrence of an
# item in an array, or -1 if the item is not included in the array.
_.indexOf = (array, item) ->
return array.indexOf item if nativeIndexOf and array.indexOf is nativeIndexOf
i = 0; l = array.length
while l - i
if array[i] is item then return i else i++
-1
# Provide JavaScript 1.6's **lastIndexOf**, delegating to the native function,
# if possible.
_.lastIndexOf = (array, item) ->
return array.lastIndexOf(item) if nativeLastIndexOf and array.lastIndexOf is nativeLastIndexOf
i = array.length
while i
if array[i] is item then return i else i--
-1
# Generate an integer Array containing an arithmetic progression. A port of
# [the native Python **range** function](http://docs.python.org/library/functions.html#range).
_.range = (start, stop, step) ->
a = arguments
solo = a.length <= 1
i = start = if solo then 0 else a[0]
stop = if solo then a[0] else a[1]
step = a[2] or 1
len = Math.ceil((stop - start) / step)
return [] if len <= 0
range = new Array len
idx = 0
loop
return range if (if step > 0 then i - stop else stop - i) >= 0
range[idx] = i
idx++
i+= step
# Function Functions
# ------------------
# Create a function bound to a given object (assigning `this`, and arguments,
# optionally). Binding with arguments is also known as **curry**.
_.bind = (func, obj) ->
args = _.rest arguments, 2
-> func.apply obj or root, args.concat arguments
# Bind all of an object's methods to that object. Useful for ensuring that
# all callbacks defined on an object belong to it.
_.bindAll = (obj) ->
funcs = if arguments.length > 1 then _.rest(arguments) else _.functions(obj)
_.each funcs, (f) -> obj[f] = _.bind obj[f], obj
obj
# Delays a function for the given number of milliseconds, and then calls
# it with the arguments supplied.
_.delay = (func, wait) ->
args = _.rest arguments, 2
setTimeout((-> func.apply(func, args)), wait)
# Memoize an expensive function by storing its results.
_.memoize = (func, hasher) ->
memo = {}
hasher or= _.identity
->
key = hasher.apply this, arguments
return memo[key] if key of memo
memo[key] = func.apply this, arguments
# Defers a function, scheduling it to run after the current call stack has
# cleared.
_.defer = (func) ->
_.delay.apply _, [func, 1].concat _.rest arguments
# Returns the first function passed as an argument to the second,
# allowing you to adjust arguments, run code before and after, and
# conditionally execute the original function.
_.wrap = (func, wrapper) ->
-> wrapper.apply wrapper, [func].concat arguments
# Returns a function that is the composition of a list of functions, each
# consuming the return value of the function that follows.
_.compose = ->
funcs = arguments
->
args = arguments
for i in [funcs.length - 1..0] by -1
args = [funcs[i].apply(this, args)]
args[0]
# Object Functions
# ----------------
# Retrieve the names of an object's properties.
_.keys = nativeKeys or (obj) ->
return _.range 0, obj.length if _.isArray(obj)
key for key, val of obj
# Retrieve the values of an object's properties.
_.values = (obj) ->
_.map obj, _.identity
# Return a sorted list of the function names available in Underscore.
_.functions = (obj) ->
_.filter(_.keys(obj), (key) -> _.isFunction(obj[key])).sort()
# Extend a given object with all of the properties in a source object.
_.extend = (obj) ->
for source in _.rest(arguments)
obj[key] = val for key, val of source
obj
# Create a (shallow-cloned) duplicate of an object.
_.clone = (obj) ->
return obj.slice 0 if _.isArray obj
_.extend {}, obj
# Invokes interceptor with the obj, and then returns obj.
# The primary purpose of this method is to "tap into" a method chain,
# in order to perform operations on intermediate results within
the chain.
_.tap = (obj, interceptor) ->
interceptor obj
obj
# Perform a deep comparison to check if two objects are equal.
_.isEqual = (a, b) ->
# Check object identity.
return true if a is b
# Different types?
atype = typeof(a); btype = typeof(b)
return false if atype isnt btype
# Basic equality test (watch out for coercions).
return true if `a == b`
# One is falsy and the other truthy.
return false if (!a and b) or (a and !b)
# One of them implements an `isEqual()`?
return a.isEqual(b) if a.isEqual
# Check dates' integer values.
return a.getTime() is b.getTime() if _.isDate(a) and _.isDate(b)
# Both are NaN?
return false if _.isNaN(a) and _.isNaN(b)
# Compare regular expressions.
if _.isRegExp(a) and _.isRegExp(b)
return a.source is b.source and
a.global is b.global and
a.ignoreCase is b.ignoreCase and
a.multiline is b.multiline
# If a is not an object by this point, we can't handle it.
return false if atype isnt 'object'
# Check for different array lengths before comparing contents.
return false if a.length and (a.length isnt b.length)
# Nothing else worked, deep compare the contents.
aKeys = _.keys(a); bKeys = _.keys(b)
# Different object sizes?
return false if aKeys.length isnt bKeys.length
# Recursive comparison of contents.
return false for key, val of a when !(key of b) or !_.isEqual(val, b[key])
true
# Is a given array or object empty?
_.isEmpty = (obj) ->
return obj.length is 0 if _.isArray(obj) or _.isString(obj)
return false for own key of obj
true
# Is a given value a DOM element?
_.isElement = (obj) -> obj and obj.nodeType is 1
# Is a given value an array?
_.isArray = nativeIsArray or (obj) -> !!(obj and obj.concat and obj.unshift and not obj.callee)
# Is a given variable an arguments object?
_.isArguments = (obj) -> obj and obj.callee
# Is the given value a function?
_.isFunction = (obj) -> !!(obj and obj.constructor and obj.call and obj.apply)
# Is the given value a string?
_.isString = (obj) -> !!(obj is '' or (obj and obj.charCodeAt and obj.substr))
# Is a given value a number?
_.isNumber = (obj) -> (obj is +obj) or toString.call(obj) is '[object Number]'
# Is a given value a boolean?
_.isBoolean = (obj) -> obj is true or obj is false
# Is a given value a Date?
_.isDate = (obj) -> !!(obj and obj.getTimezoneOffset and obj.setUTCFullYear)
# Is the given value a regular expression?
_.isRegExp = (obj) -> !!(obj and obj.exec and (obj.ignoreCase or obj.ignoreCase is false))
# Is the given value NaN -- this one is interesting. `NaN != NaN`, and
# `isNaN(undefined) == true`, so we make sure it's a number first.
_.isNaN = (obj) -> _.isNumber(obj) and window.isNaN(obj)
# Is a given value equal to null?
_.isNull = (obj) -> obj is null
# Is a given variable undefined?
_.isUndefined = (obj) -> typeof obj is 'undefined'
# Utility Functions
# -----------------
# Run Underscore.js in noConflict mode, returning the `_` variable to its
# previous owner. Returns a reference to the Underscore object.
_.noConflict = ->
root._ = previousUnderscore
this
# Keep the identity function around for default iterators.
_.identity = (value) -> value
# Run a function `n` times.
_.times = (n, iterator, context) ->
iterator.call context, i for i in [0...n]
# Break out of the middle of an iteration.
_.breakLoop = -> throw breaker
# Add your own custom functions to the Underscore object, ensuring that
# they're correctly added to the OOP wrapper as well.
_.mixin = (obj) ->
for name in _.functions(obj)
addToWrapper name, _[name] = obj[name]
# Generate a unique integer id (unique within the entire client session).
# Useful for temporary DOM ids.
idCounter = 0
_.uniqueId = (prefix) ->
(prefix or '') + idCounter++
# By default, Underscore uses **ERB**-style template delimiters, change the
# following template settings to use alternative delimiters.
_.templateSettings = {
start: '<%'
end: '%>'
interpolate: /<%=(.+?)%>/g
}
# JavaScript templating a-la **ERB**, pilfered from John Resig's
# *Secrets of the JavaScript Ninja*, page 83.
# Single-quote fix from Rick Strahl.
# With alterations for arbitrary delimiters, and to preserve whitespace.
_.template = (str, data) ->
c = _.templateSettings
endMatch = new RegExp("'(?=[^"+c.end.substr(0, 1)+"]*"+escapeRegExp(c.end)+")","g")
fn = new Function 'obj',
'var p=[],print=function(){p.push.apply(p,arguments);};' +
'with(obj||{}){p.push(\'' +
str.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
.replace(/\t/g, '\\t')
.replace(endMatch,"")
.split("'").join("\\'")
.split("").join("'")
.replace(c.interpolate, "',$1,'")
.split(c.start).join("');")
.split(c.end).join("p.push('") +
"');}return p.join('');"
if data then fn(data) else fn
# Aliases
# -------
_.forEach = _.each
_.foldl = _.inject = _.reduce
_.foldr = _.reduceRight
_.select = _.filter
_.all = _.every
_.any = _.some
_.contains = _.include
_.head = _.first
_.tail = _.rest
_.methods = _.functions
# Setup the OOP Wrapper
# ---------------------
# If Underscore is called as a function, it returns a wrapped object that
# can be used OO-style. This wrapper holds altered versions of all the
# underscore functions. Wrapped objects may be chained.
wrapper = (obj) ->
this._wrapped = obj
this
# Helper function to continue chaining intermediate results.
result = (obj, chain) ->
if chain then _(obj).chain() else obj
# A method to easily add functions to the OOP wrapper.
addToWrapper = (name, func) ->
wrapper.prototype[name] = ->
args = _.toArray arguments
unshift.call args, this._wrapped
result func.apply(_, args), this._chain
# Add all ofthe Underscore functions to the wrapper object.
_.mixin _
# Add all mutator Array functions to the wrapper.
_.each ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], (name) ->
method = Array.prototype[name]
wrapper.prototype[name] = ->
method.apply(this._wrapped, arguments)
result(this._wrapped, this._chain)
# Add all accessor Array functions to the wrapper.
_.each ['concat', 'join', 'slice'], (name) ->
method = Array.prototype[name]
wrapper.prototype[name] = ->
result(method.apply(this._wrapped, arguments), this._chain)
# Start chaining a wrapped Underscore object.
wrapper::chain = ->
this._chain = true
this
# Extracts the result from a wrapped and chained object.
wrapper::value = -> this._wrapped
</textarea></form>
<script>
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
</script>
<p><strong>MIME types defined:</strong> <code>text/x-coffeescript</code>.</p>
<p>The CoffeeScript mode was written by Jeff Pickhardt (<a href="LICENSE">license</a>).</p>
</body>
</html>
@@ -1,254 +0,0 @@
CodeMirror.defineMode("razor", function(config, parserConfig) {
var indentUnit = config.indentUnit,
keywords = words("abstract as base break case catch checked class const continue" +
" default delegate do else enum event explicit extern finally fixed for" +
" foreach goto if implicit in interface internal is lock namespace new" +
" operator out override params private protected public readonly ref return sealed" +
" sizeof stackalloc static struct switch this throw try typeof unchecked" +
" unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
" global group into join let orderby partial remove select set value var yield"),
builtin = words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" +
" Guid Int16 Int32 Int64 Library Model Object SByte Single String TimeSpan UInt16 UInt32" +
" UInt64 bool byte char decimal double short int long object" +
" sbyte float string ushort uint ulong"),
blockKeywords = words("catch class do else finally for foreach if struct switch try while"),
atoms = words("true false null"),
hooks = parserConfig.hooks || {},
multiLineStrings = parserConfig.multiLineStrings;
var isOperatorChar = /[+\-*&%=<>!?|\/]/;
var curPunc;
function tokenBase(stream, state) {
var ch = stream.next();
if (hooks[ch]) {
var result = hooks[ch](stream, state);
if (result !== false) return result;
}
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
curPunc = ch;
return null;
}
if (/\d/.test(ch)) {
stream.eatWhile(/[\w\.]/);
return "number";
}
if (ch == "@") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
return "at";
}
if (isOperatorChar.test(ch)) {
stream.eatWhile(isOperatorChar);
return "operator";
}
stream.eatWhile(/[\w\$_]/);
var cur = stream.current();
if (keywords.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
return "keyword";
}
if (builtin.propertyIsEnumerable(cur)) {
if (blockKeywords.propertyIsEnumerable(cur)) curPunc = "newstatement";
return "builtin";
}
if (atoms.propertyIsEnumerable(cur)) return "atom";
return "variable";
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped) {end = true; break;}
escaped = !escaped && next == "\\";
}
if (end || !(escaped || multiLineStrings))
state.tokenize = null;
return "string";
};
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "@" && maybeEnd) {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}
function Context(indented, column, type, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type) {
return state.context = new Context(state.indented, col, type, null, state.context);
}
function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}
function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
// Interface
return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", false),
indented: 0,
startOfLine: true
};
},
token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) return null;
curPunc = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment" || style == "meta") return style;
if (ctx.align == null) ctx.align = true;
if ((curPunc == ";" || curPunc == ":") && ctx.type == "statement") popContext(state);
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (ctx.type == "}" || ctx.type == "top" || (ctx.type == "statement" && curPunc == "newstatement"))
pushContext(state, stream.column(), "statement");
state.startOfLine = false;
return style;
},
indent: function(state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null) return 0;
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
var closing = firstChar == ctx.type;
if (ctx.type == "statement") return ctx.indented + (firstChar == "{" ? 0 : indentUnit);
else if (ctx.align) return ctx.column + (closing ? 0 : 1);
else return ctx.indented + (closing ? 0 : indentUnit);
},
electricChars: "{}"
};
});
(function() {
function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
var cKeywords = "auto if break int case long char register continue return default short do sizeof " +
"double static else struct entry switch extern typedef float union for unsigned " +
"goto while enum void const signed volatile";
function cppHook(stream, state) {
if (!state.startOfLine) return false;
stream.skipToEnd();
return "meta";
}
// C#-style strings where "" escapes a quote.
function tokenAtString(stream, state) {
var next;
while ((next = stream.next()) != null) {
if (next == '"' && !stream.eat('"')) {
state.tokenize = null;
break;
}
}
return "string";
}
function mimes(ms, mode) {
for (var i = 0; i < ms.length; ++i) CodeMirror.defineMIME(ms[i], mode);
}
/*
mimes(["text/x-csrc", "text/x-c", "text/x-chdr"], {
name: "clike",
keywords: words(cKeywords),
blockKeywords: words("case do else for if switch while struct"),
atoms: words("null"),
hooks: {"#": cppHook}
});
mimes(["text/x-c++src", "text/x-c++hdr"], {
name: "clike",
keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try bool explicit new " +
"static_cast typeid catch operator template typename class friend private " +
"this using const_cast inline public throw virtual delete mutable protected " +
"wchar_t"),
blockKeywords: words("catch class do else finally for if struct switch try while"),
atoms: words("true false null"),
hooks: {"#": cppHook}
});*/
CodeMirror.defineMIME("text/x-razor", {
name: "razor",
keywords: words("abstract as base break case catch checked class const continue" +
" default delegate do else enum event explicit extern finally fixed for" +
" foreach goto if implicit in interface internal is lock namespace new" +
" operator out override params private protected public readonly ref return sealed" +
" sizeof stackalloc static struct switch this throw try typeof unchecked" +
" unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
" global group into join let orderby partial remove select set value var yield"),
blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
builtin: words("Boolean Byte Char DateTime DateTimeOffset Decimal Double" +
" Guid Int16 Int32 Int64 Object SByte Single String TimeSpan UInt16 UInt32" +
" UInt64 bool byte char decimal double short int long object" +
" sbyte float string ushort uint ulong"),
atoms: words("true false null"),
hooks: {
"@": function(stream, state) {
if (stream.eat('"')) {
state.tokenize = tokenAtString;
return tokenAtString(stream, state);
}
stream.eatWhile(/[\w\$_]/);
return "meta";
}
}
});
}());
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,8 +0,0 @@
tinymce.addI18n('en',{
'HTML source code': 'HTML source code',
'Start search': 'Start search',
'Find next': 'Find next',
'Find previous': 'Find previous',
'Replace': 'Replace',
'Replace all': 'Replace all'
});
@@ -1,24 +0,0 @@
tinymce.PluginManager.requireLangPack("codemirror");
tinymce.PluginManager.add("codemirror", function(a, c) {
function b() {
a.focus();
a.selection.collapse(!0);
a.selection.setContent('<span class="CmCaReT" style="display:none">&#0;</span>');
var b = a.windowManager.open({
title: "Source code", url: c + "/source.html", width: a.getParam("code_dialog_width", 600), height: a.getParam("code_dialog_height", Math.min(tinymce.DOM.getViewPort().h - 200, 500)), resizable: !0, maximizable: !0,
buttons: [
{
text: "Ok", subtype: "primary",
onclick: function() {
document.querySelectorAll(".mce-container-body>iframe")[0].contentWindow.submit();
b.close()
}
}, { text: "Cancel", onclick: "close" }
]
})
}
a.addButton("codemirror",
{ title: "Source code", icon: "code", onclick: b });
a.addMenuItem("codemirror", { icon: "code", text: "Source code", context: "tools", onclick: b })
});
@@ -1,255 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<script>
/**
* source.html
*
* Copyright 2013-2014 Web Power, www.webpower.nl
* @author Arjan Haverkamp
*/
// Global vars:
var tinymce, // Reference to TinyMCE
editor, // Reference to TinyMCE editor
codemirror, // CodeMirror instance
chr = 0, // Unused utf-8 character, placeholder for cursor
isMac = /macintosh|mac os/i.test(navigator.userAgent),
CMsettings; // CodeMirror settings
function inArray(key, arr)
{
"use strict";
arr = '|' + arr.join('|') + '|';
return arr.indexOf('|'+key+'|') != -1;
}
(function()
{// Initialise (before load)
"use strict";
tinymce = parent.tinymce;
editor = tinymce.activeEditor;
var i, userSettings = editor.settings.codemirror ? (typeof editor.settings.codemirror === 'object') ? editor.settings.codemirror : JSON.parse(editor.settings.codemirror) : {};
CMsettings = {
path: userSettings.path || 'CodeMirror',
indentOnInit: userSettings.indentOnInit || false,
config: {// Default config
mode: 'htmlmixed',
lineNumbers: true,
lineWrapping: true,
indentUnit: 2,
tabSize: 2,
matchBrackets: true,
styleActiveLine: true,
// CodeMirror v2
onChange: function(inst) {
inst.isDirty = true;
},
}, // CodeMirror v4 commented out below.
jsFiles: [// Default JS files
'lib/codemirror.js',
'addon/edit/matchbrackets.js',
'addon/search/match-highlighter.js',
'mode/xml/xml.js',
'mode/javascript/javascript.js',
'mode/css/css.js',
'mode/htmlmixed/htmlmixed.js',
'addon/dialog/dialog.js',
'addon/search/searchcursor.js',
'addon/search/search.js',
'addon/selection/active-line.js'
],
cssFiles: [// Default CSS files
'lib/codemirror.css',
'addon/dialog/dialog.css'
]
};
// Merge config
for (i in userSettings.config) {
CMsettings.config[i] = userSettings.config[i];
}
// Merge jsFiles
for (i in userSettings.jsFiles) {
if (!inArray(userSettings.jsFiles[i], CMsettings.jsFiles)) {
CMsettings.jsFiles.push(userSettings.jsFiles[i]);
}
}
// Merge cssFiles
for (i in userSettings.cssFiles) {
if (!inArray(userSettings.cssFiles[i], CMsettings.cssFiles)) {
CMsettings.cssFiles.push(userSettings.cssFiles[i]);
}
}
// Add trailing slash to path
if (!/\/$/.test(CMsettings.path)) {
CMsettings.path += '/';
}
// Write stylesheets
for (i = 0; i < CMsettings.cssFiles.length; i++) {
document.write('<li'+'nk rel="stylesheet" type="text/css" href="' + CMsettings.path + CMsettings.cssFiles[i] + '" />');
}
// Write JS source files
for (i = 0; i < CMsettings.jsFiles.length; i++) {
document.write('<scr'+'ipt type="text/javascript" src="' + CMsettings.path + CMsettings.jsFiles[i] + '"></scr'+'ipt>');
}
window.onload = start;
}());
function start()
{// Initialise (on load)
"use strict";
if (typeof(window.CodeMirror) !== 'function') {
alert('CodeMirror not found in "' + CMsettings.path + '", aborting...');
return;
}
// Create legend for keyboard shortcuts for find & replace:
var head = parent.document.querySelectorAll('.mce-foot')[0],
div = parent.document.createElement('div'),
td1 = '<td style="font-size:11px;font-family:courier;font-weight:bold;text-align:right;padding-right: 1em;">',
td2 = '<td style="font-size:11px;padding-right: 1em;">';
div.innerHTML = '<table cellspacing="0" cellpadding="0" style="border-spacing:4px"><tbody>' +
'<tr><tr><td style="font-size:11px;font-family:courier;font-weight:bold;text-align:right;padding-right: 1em;">Ctrl-F</td>' +
'<td style="font-size:11px;padding-right: 1em;">Start search</td>' +
'<td style="font-size:11px;font-family:courier;font-weight:bold;text-align:right;padding-right: 1em;">Ctrl-G</td>' +
'<td style="font-size:11px;padding-right: 1em;">Find next</td></tr>' +
'<tr><td style="font-size:11px;font-family:courier;font-weight:bold;text-align:right;padding-right: 1em;">Shift-Ctrl-F</td>' +
'<td style="font-size:11px;padding-right: 1em;">Find previous</td>' +
'<td style="font-size:11px;font-family:courier;font-weight:bold;text-align:right;padding-right: 1em;">Shift-Ctrl-F</td>' +
'<td style="font-size:11px;padding-right: 1em;">Replace</td></tr>' +
'<tr><td style="font-size:11px;font-family:courier;font-weight:bold;text-align:right;padding-right: 1em;">Shift-Ctrl-R</td>' +
'<td style="font-size:11px;padding-right: 1em;">Replace all</td><td></td><td></td></tr>'+
'</tbody></table>';
div.style.position = 'absolute';
div.style.left = '1em';
div.style.bottom = '.5em';
head.appendChild(div);
// Set CodeMirror cursor to same position as cursor was in TinyMCE:
var html = editor.getContent({source_view: true});
html = html.replace(/<span\s+class="CmCaReT"([^>]*)>([^<]*)<\/span>/gm, String.fromCharCode(chr));
editor.dom.remove(editor.dom.select('.CmCaReT'));
html = html.replace(/(<div class=".*?umb-macro-holder.*?mceNonEditable.*?"><!-- <\?UMBRACO_MACRO macroAlias="(.*?)".*?\/> --> *<ins>)[\s\S]*?(<\/ins> *<\/div>)/ig, "$1Macro alias: <strong>$2</strong>$3");
//CodeMirror v4
CodeMirror.defineInitHook(function(inst)
{
// Move cursor to correct position:
inst.focus();
var cursor = inst.getSearchCursor(String.fromCharCode(chr), false);
if (cursor.findNext()) {
inst.setCursor(cursor.to());
cursor.replace('');
}
// Indent all code, if so requested:
if (editor.settings.codemirror.indentOnInit) {
var last = inst.lineCount();
inst.operation(function() {
for (var i = 0; i < last; ++i) {
inst.indentLine(i);
}
});
}
});
CMsettings.config.value = html;
// Instantiante CodeMirror:
codemirror = CodeMirror(document.body, CMsettings.config);
codemirror.isDirty = false;
/*codemirror.on('change', function(inst) { // CodeMirror v4
inst.isDirty = true;
});*/
}
function findDepth(haystack, needle)
{
"use strict";
var idx = haystack.indexOf(needle), depth = 0, x;
for (x = idx; x >= 0; x--) {
switch(haystack.charAt(x)) {
case '<': depth--; break;
case '>': depth++; break;
}
}
return depth;
}
// This function is called by plugin.js, when user clicks 'Ok' button
function submit()
{
"use strict";
var cc = '&#x0;', isDirty = codemirror.isDirty, doc = codemirror; // CodeMirror v4 doc = codemirror.doc
if (doc.getSelection() != "") { // CodeMirror v4 if(doc.somethingSelected()) {
// Clear selection:
doc.setCursor(doc.getCursor());
}
// Insert cursor placeholder (&#x0;)
doc.replaceSelection(cc);
var pos = codemirror.getCursor(),
curLineHTML = doc.getLine(pos.line);
if (findDepth(curLineHTML, cc) !== 0) {
// Cursor is inside a <tag>, don't set cursor:
curLineHTML = curLineHTML.replace(cc, '');
doc.getLineHandle(pos.line).text = curLineHTML;
}
// Submit HTML to TinyMCE:
editor.setContent(codemirror.getValue().replace(cc, '<span class="CmCaReT">&nbsp;</span>'));
editor.isNotDirty = !isDirty;
if (isDirty) {
editor.nodeChanged();
}
// Set cursor:
var el = editor.dom.select('span.CmCaReT')[0];
if (el) {
editor.selection.scrollIntoView(el);
editor.selection.setCursorLocation(el,0);
editor.dom.remove(el);
}
}
</script>
<style type="text/css">
html,body,.CodeMirror-scroll {
height: 100%;
}
body {
margin: 0;
}
.CodeMirror {
height: 100%;
font-size: 12px;
line-height: 18px;
}
.CodeMirror-activeline-background {
background: #e8f2ff !important;
}
</style>
</head>
<body></body>
</html>
@@ -1,99 +0,0 @@
body.mce-content-body {
background-color: #fff;
font-family: Verdana,Arial,Helvetica,sans-serif;
font-size: 14px;
line-height: 1.5em;
scrollbar-3dlight-color: #f0f0ee;
scrollbar-arrow-color: #676662;
scrollbar-base-color: #f0f0ee;
scrollbar-darkshadow-color: #ddd;
scrollbar-face-color: #e0e0dd;
scrollbar-highlight-color: #f0f0ee;
scrollbar-shadow-color: #f0f0ee;
scrollbar-track-color: #f5f5f5;
}
td, th {
font-family: Verdana,Arial,Helvetica,sans-serif;
font-size: 11px;
}
.mce-object {
border: 1px dotted #3a3a3a;
background: #d5d5d5 url(img/object.gif) no-repeat center;
}
.mce-pagebreak {
cursor: default;
display: block;
border: 0;
width: 100%;
height: 5px;
border: 1px dashed #666;
margin-top: 15px;
}
.mce-item-anchor {
cursor: default;
display: inline-block;
-webkit-user-select: all;
-webkit-user-modify: read-only;
-moz-user-select: all;
-moz-user-modify: read-only;
width: 9px!important;
height: 9px!important;
border: 1px dotted #3a3a3a;
background: #d5d5d5 url(img/anchor.gif) no-repeat center;
}
.mce-nbsp {
background: #AAA;
}
hr {
cursor: default;
}
.mce-match-marker {
background: green;
color: #fff;
}
.mce-spellchecker-word {
background: url(img/wline.gif) repeat-x bottom left;
cursor: default;
}
.mce-item-table, .mce-item-table td, .mce-item-table th, .mce-item-table caption {
border: 1px dashed #BBB;
}
td.mce-item-selected, th.mce-item-selected {
background-color: #39f!important;
}
.mce-edit-focus {
outline: 1px dotted #333;
}
/* TINYMCE Macro styles*/
.mce-content-body .umb-macro-holder
{
border: 3px dotted orange;
padding: 7px;
display:block;
margin:3px;
}
/* loader for macro loading in tinymce*/
.mce-content-body .umb-macro-holder.loading {
background: url(img/loader.gif) right no-repeat;
-moz-background-size: 18px;
-o-background-size: 18px;
-webkit-background-size: 18px;
background-size: 18px;
background-position-x: 99%;
}
/* TINYMCE IMAGE RESIZING LIMITS */
#mceResizeHandlen, #mceResizeHandles, #mceResizeHandlee, #mceResizeHandlew{display: none !important; visibility: hidden !important;}
@@ -1 +0,0 @@
Icons are generated and provided by the http://icomoon.io service.
@@ -1,63 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="tinymce-small" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe000;" glyph-name="save" d="M960 80v591.938l-223.938 224.062h-592.062c-44.182 0-80-35.816-80-80v-736c0-44.184 35.818-80 80-80h736c44.184 0 80 35.816 80 80zM576 768h64v-192h-64v192zM704 128h-384v255.882c0.034 0.042 0.076 0.082 0.116 0.118h383.77c0.040-0.036 0.082-0.076 0.116-0.118l-0.002-255.882zM832 128h-64v256c0 35.2-28.8 64-64 64h-384c-35.2 0-64-28.8-64-64v-256h-64v640h64v-192c0-35.2 28.8-64 64-64h320c35.2 0 64 28.8 64 64v171.010l128-128.072v-490.938z" />
<glyph unicode="&#xe001;" glyph-name="newdocument" d="M850.746 717.254l-133.492 133.49c-24.888 24.892-74.054 45.256-109.254 45.256h-416c-35.2 0-64-28.8-64-64v-768c0-35.2 28.8-64 64-64h640c35.2 0 64 28.8 64 64v544c0 35.2-20.366 84.364-45.254 109.254zM805.49 672.002c6.792-6.796 13.792-19.162 18.894-32.002h-184.384v184.386c12.84-5.1 25.204-12.1 32-18.896l133.49-133.488zM831.884 64h-639.77c-0.040 0.034-0.082 0.076-0.114 0.116v767.77c0.034 0.040 0.076 0.082 0.114 0.114h383.886v-256h256v-511.884c-0.034-0.040-0.076-0.082-0.116-0.116z" />
<glyph unicode="&#xe002;" glyph-name="fullpage" d="M1024 367.542v160.916l-159.144 15.914c-8.186 30.042-20.088 58.548-35.21 84.98l104.596 127.838-113.052 113.050-127.836-104.596c-26.434 15.124-54.942 27.026-84.982 35.208l-15.914 159.148h-160.916l-15.914-159.146c-30.042-8.186-58.548-20.086-84.98-35.208l-127.838 104.594-113.050-113.050 104.596-127.836c-15.124-26.432-27.026-54.94-35.21-84.98l-159.146-15.916v-160.916l159.146-15.914c8.186-30.042 20.086-58.548 35.21-84.982l-104.596-127.836 113.048-113.048 127.838 104.596c26.432-15.124 54.94-27.028 84.98-35.21l15.916-159.148h160.916l15.914 159.144c30.042 8.186 58.548 20.088 84.982 35.21l127.836-104.596 113.048 113.048-104.596 127.836c15.124 26.434 27.028 54.942 35.21 84.98l159.148 15.92zM704 384l-128-128h-128l-128 128v128l128 128h128l128-128v-128z" />
<glyph unicode="&#xe003;" glyph-name="alignleft" d="M64 768h896v-128h-896zM64 384h896v-128h-896zM64 576h576v-128h-576zM64 192h576v-128h-576z" />
<glyph unicode="&#xe004;" glyph-name="aligncenter" d="M64 768h896v-128h-896zM64 384h896v-128h-896zM256 576h512v-128h-512zM256 192h512v-128h-512z" />
<glyph unicode="&#xe005;" glyph-name="alignright" d="M64 768h896v-128h-896zM64 384h896v-128h-896zM384 576h576v-128h-576zM384 192h576v-128h-576z" />
<glyph unicode="&#xe006;" glyph-name="alignjustify" d="M64 768h896v-128h-896zM64 384h896v-128h-896zM64 576h896v-128h-896zM64 192h896v-128h-896z" />
<glyph unicode="&#xe007;" glyph-name="cut" d="M864.408 289.868c-46.47 46.47-106.938 68.004-161.082 62.806l-63.326 63.326 192 192c0 0 128 128 0 256l-320-320-320 320c-128-128 0-256 0-256l192-192-63.326-63.326c-54.144 5.198-114.61-16.338-161.080-62.806-74.98-74.98-85.112-186.418-22.626-248.9 62.482-62.482 173.92-52.354 248.9 22.626 46.47 46.468 68.002 106.938 62.806 161.080l63.326 63.326 63.328-63.328c-5.196-54.144 16.336-114.61 62.806-161.078 74.978-74.98 186.418-85.112 248.898-22.626 62.488 62.482 52.356 173.918-22.624 248.9zM353.124 201.422c-2.212-24.332-15.020-49.826-35.14-69.946-22.212-22.214-51.080-35.476-77.218-35.476-10.524 0-25.298 2.228-35.916 12.848-21.406 21.404-17.376 73.132 22.626 113.136 22.212 22.214 51.080 35.476 77.218 35.476 10.524 0 25.298-2.228 35.916-12.848 13.112-13.11 13.47-32.688 12.514-43.19zM512 352c-35.346 0-64 28.654-64 64s28.654 64 64 64 64-28.654 64-64-28.654-64-64-64zM819.152 108.848c-10.62-10.62-25.392-12.848-35.916-12.848-26.138 0-55.006 13.262-77.218 35.476-20.122 20.12-32.928 45.614-35.138 69.946-0.958 10.502-0.6 30.080 12.514 43.192 10.618 10.622 25.39 12.848 35.916 12.848 26.136 0 55.006-13.262 77.216-35.474 40.004-40.008 44.032-91.736 22.626-113.14z" />
<glyph unicode="&#xe008;" glyph-name="paste" d="M704 576v160c0 17.6-14.4 32-32 32h-160v64c0 35.2-28.8 64-64 64h-128c-35.204 0-64-28.8-64-64v-64h-160c-17.602 0-32-14.4-32-32v-512c0-17.6 14.398-32 32-32h224v-192h384l192 192v384h-192zM320 831.886c0.034 0.038 0.072 0.078 0.114 0.114h127.768c0.042-0.036 0.082-0.076 0.118-0.114v-63.886h-128v63.886zM192 640v64h384v-64h-384zM704 90.51v101.49h101.49l-101.49-101.49zM832 256h-192v-192h-256v448h448v-256z" />
<glyph unicode="&#xe009;" glyph-name="searchreplace" d="M888 576h-56v256h64v64h-320v-64h64v-256h-256v256h64v64h-320v-64h64v-256h-56c-39.6 0-72-32.4-72-72v-432c0-39.6 32.4-72 72-72h240c39.6 0 72 32.4 72 72v312h128v-312c0-39.6 32.4-72 72-72h240c39.6 0 72 32.4 72 72v432c0 39.6-32.4 72-72 72zM348 64h-184c-19.8 0-36 14.4-36 32s16.2 32 36 32h184c19.8 0 36-14.4 36-32s-16.2-32-36-32zM544 448h-64c-17.6 0-32 14.4-32 32s14.4 32 32 32h64c17.6 0 32-14.4 32-32s-14.4-32-32-32zM860 64h-184c-19.8 0-36 14.4-36 32s16.2 32 36 32h184c19.8 0 36-14.4 36-32s-16.2-32-36-32z" />
<glyph unicode="&#xe00a;" glyph-name="bullist" d="M384 832h576v-128h-576zM384 512h576v-128h-576zM384 192h576v-128h-576zM128 768c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64zM128 448c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64zM128 128c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64z" />
<glyph unicode="&#xe00b;" glyph-name="numlist" d="M384 832h576v-128h-576zM384 512h576v-128h-576zM384 192h576v-128h-576zM320 430v146h-64v320h-128v-64h64v-256h-64v-64h128v-50l-128-60v-146h128v-64h-128v-64h128v-64h-128v-64h192v320h-128v50z" />
<glyph unicode="&#xe00c;" glyph-name="indent" d="M64 768h896v-128h-896zM384 384h576v-128h-576zM384 576h576v-128h-576zM64 192h896v-128h-896zM64 576l224-160-224-160z" />
<glyph unicode="&#xe00d;" glyph-name="outdent" d="M64 768h896v-128h-896zM64 384h576v-128h-576zM64 576h576v-128h-576zM64 192h896v-128h-896zM960 576l-224-160 224-160z" />
<glyph unicode="&#xe00e;" glyph-name="blockquote" d="M256.428 535.274c105.8 0 191.572-91.17 191.572-203.638 0-112.464-85.772-203.636-191.572-203.636-105.802 0-191.572 91.17-191.572 203.636l-0.856 29.092c0 224.93 171.54 407.272 383.144 407.272v-116.364c-73.1 0-141.826-30.26-193.516-85.204-9.954-10.578-19.034-21.834-27.224-33.656 9.784 1.64 19.806 2.498 30.024 2.498zM768.428 535.274c105.8 0 191.572-91.17 191.572-203.638 0-112.464-85.772-203.636-191.572-203.636-105.802 0-191.572 91.17-191.572 203.636l-0.856 29.092c0 224.93 171.54 407.272 383.144 407.272v-116.364c-73.1 0-141.826-30.26-193.516-85.204-9.956-10.578-19.036-21.834-27.224-33.656 9.784 1.64 19.806 2.498 30.024 2.498z" />
<glyph unicode="&#xe00f;" glyph-name="undo" d="M704 0c59 199 134.906 455.266-256 446.096v-222.096l-336.002 336 336.002 336v-217.326c468.092 12.2 544-358.674 256-678.674z" />
<glyph unicode="&#xe010;" glyph-name="redo" d="M576 678.674v217.326l336.002-336-336.002-336v222.096c-390.906 9.17-315-247.096-256-446.096-288 320-212.092 690.874 256 678.674z" />
<glyph unicode="&#xe011;" glyph-name="unlink" d="M927.274 729.784l-133.49 133.488c-21.104 21.104-49.232 32.728-79.198 32.728s-58.094-11.624-79.196-32.726l-165.492-165.49c-43.668-43.668-43.668-114.724 0-158.392l2.746-2.746 67.882 67.882-2.746 2.746c-6.132 6.132-6.132 16.494 0 22.626l165.492 165.492c4.010 4.008 8.808 4.608 11.312 4.608s7.302-0.598 11.312-4.61l133.49-133.488c6.132-6.134 6.132-16.498 0.002-22.628l-165.494-165.494c-4.008-4.008-8.806-4.608-11.31-4.608s-7.302 0.6-11.312 4.612l-2.746 2.746-67.88-67.884 2.742-2.742c21.106-21.108 49.23-32.728 79.2-32.728s58.094 11.624 79.196 32.726l165.494 165.492c43.662 43.666 43.662 114.72-0.004 158.39zM551.356 359.356l-67.882-67.882 2.746-2.746c4.008-4.008 4.61-8.806 4.61-11.31 0-2.506-0.598-7.302-4.606-11.314l-165.494-165.49c-4.010-4.010-8.81-4.61-11.314-4.61s-7.304 0.6-11.314 4.61l-133.492 133.486c-4.010 4.010-4.61 8.81-4.61 11.314s0.598 7.3 4.61 11.312l165.49 165.488c4.010 4.012 8.81 4.612 11.314 4.612s7.304-0.6 11.314-4.612l2.746-2.742 67.882 67.88-2.746 2.746c-21.104 21.104-49.23 32.726-79.196 32.726s-58.092-11.624-79.196-32.726l-165.488-165.486c-21.106-21.104-32.73-49.234-32.73-79.198s11.624-58.094 32.726-79.198l133.49-133.49c21.106-21.102 49.232-32.726 79.198-32.726s58.092 11.624 79.196 32.726l165.494 165.492c21.104 21.104 32.722 49.23 32.722 79.196s-11.624 58.094-32.726 79.196l-2.744 2.746zM352 250c-9.724 0-19.45 3.71-26.87 11.128-14.84 14.84-14.84 38.898 0 53.738l320 320c14.84 14.84 38.896 14.84 53.736 0 14.844-14.84 14.844-38.9 0-53.74l-320-320c-7.416-7.416-17.142-11.126-26.866-11.126z" />
<glyph unicode="&#xe012;" glyph-name="link" d="M927.274 729.784l-133.49 133.488c-21.104 21.104-49.232 32.728-79.198 32.728s-58.094-11.624-79.196-32.726l-165.492-165.49c-43.668-43.668-43.668-114.724 0-158.392l2.746-2.746 67.882 67.882-2.746 2.746c-6.132 6.132-6.132 16.494 0 22.626l165.492 165.492c4.010 4.008 8.808 4.608 11.312 4.608s7.302-0.598 11.312-4.61l133.49-133.488c6.132-6.134 6.132-16.498 0.002-22.628l-165.494-165.494c-4.008-4.008-8.806-4.608-11.31-4.608s-7.302 0.6-11.312 4.612l-2.746 2.746-67.88-67.884 2.742-2.742c21.106-21.108 49.23-32.728 79.2-32.728s58.094 11.624 79.196 32.726l165.494 165.492c43.662 43.666 43.662 114.72-0.004 158.39zM551.356 359.356l-67.882-67.882 2.746-2.746c4.008-4.008 4.61-8.806 4.61-11.31 0-2.506-0.598-7.302-4.606-11.314l-165.494-165.49c-4.010-4.010-8.81-4.61-11.314-4.61s-7.304 0.6-11.314 4.61l-133.492 133.486c-4.010 4.010-4.61 8.81-4.61 11.314s0.598 7.3 4.61 11.312l165.49 165.488c4.010 4.012 8.81 4.612 11.314 4.612s7.304-0.6 11.314-4.612l2.746-2.742 67.882 67.88-2.746 2.746c-21.104 21.104-49.23 32.726-79.196 32.726s-58.092-11.624-79.196-32.726l-165.488-165.486c-21.106-21.104-32.73-49.234-32.73-79.198s11.624-58.094 32.726-79.198l133.49-133.49c21.106-21.102 49.232-32.726 79.198-32.726s58.092 11.624 79.196 32.726l165.494 165.492c21.104 21.104 32.722 49.23 32.722 79.196s-11.624 58.094-32.726 79.196l-2.744 2.746zM800 122c-9.724 0-19.45 3.708-26.87 11.13l-128 127.998c-14.844 14.84-14.844 38.898 0 53.738 14.84 14.844 38.896 14.844 53.736 0l128-128c14.844-14.84 14.844-38.896 0-53.736-7.416-7.422-17.142-11.13-26.866-11.13zM608 0c-17.674 0-32 14.326-32 32v128c0 17.674 14.326 32 32 32s32-14.326 32-32v-128c0-17.674-14.326-32-32-32zM928 320h-128c-17.674 0-32 14.326-32 32s14.326 32 32 32h128c17.674 0 32-14.326 32-32s-14.326-32-32-32zM224 774c9.724 0 19.45-3.708 26.87-11.13l128-128c14.842-14.84 14.842-38.898 0-53.738-14.84-14.844-38.898-14.844-53.738 0l-128 128c-14.842 14.84-14.842 38.898 0 53.738 7.418 7.422 17.144 11.13 26.868 11.13zM416 896c17.674 0 32-14.326 32-32v-128c0-17.674-14.326-32-32-32s-32 14.326-32 32v128c0 17.674 14.326 32 32 32zM96 576h128c17.674 0 32-14.326 32-32s-14.326-32-32-32h-128c-17.674 0-32 14.326-32 32s14.326 32 32 32z" />
<glyph unicode="&#xe013;" glyph-name="bookmark" d="M256 896v-896l256 256 256-256v896h-512zM704 170.51l-192 192-192-192v661.49h384v-661.49z" />
<glyph unicode="&#xe014;" glyph-name="image" d="M896 832h-768c-35.2 0-64-28.8-64-64v-640c0-35.2 28.8-64 64-64h768c35.2 0 64 28.8 64 64v640c0 35.2-28.8 64-64 64zM896 128.116c-0.012-0.014-0.030-0.028-0.042-0.042l-191.958 319.926-160-128-224 288-191.968-479.916c-0.010 0.010-0.022 0.022-0.032 0.032v639.77c0.034 0.040 0.076 0.082 0.114 0.114h767.77c0.040-0.034 0.082-0.076 0.116-0.116v-639.768zM640 608c0-53.019 42.981-96 96-96s96 42.981 96 96c0 53.019-42.981 96-96 96s-96-42.981-96-96z" />
<glyph unicode="&#xe015;" glyph-name="media" d="M896 832h-768c-35.2 0-64-28.8-64-64v-640c0-35.2 28.8-64 64-64h768c35.2 0 64 28.8 64 64v640c0 35.2-28.8 64-64 64zM256 128h-128v128h128v-128zM256 384h-128v128h128v-128zM256 640h-128v128h128v-128zM704 128h-384v640h384v-640zM896 128h-128v128h128v-128zM896 384h-128v128h128v-128zM896 640h-128v128h128v-128zM384 640v-384l288 192z" />
<glyph unicode="&#xe016;" glyph-name="help" d="M448 256h128v-128h-128v128zM704 704c35.346 0 64-28.654 64-64v-166l-228-154h-92v64l192 128v64h-320v128h384zM512 896c-119.666 0-232.166-46.6-316.784-131.216-84.614-84.618-131.216-197.118-131.216-316.784 0-119.664 46.602-232.168 131.216-316.784 84.618-84.616 197.118-131.216 316.784-131.216 119.664 0 232.168 46.6 316.784 131.216s131.216 197.12 131.216 316.784c0 119.666-46.6 232.166-131.216 316.784-84.616 84.616-197.12 131.216-316.784 131.216z" />
<glyph unicode="&#xe017;" glyph-name="code" d="M416 256l-192 192 192 192-64 64-256-256 256-256zM672 704l-64-64 192-192-192-192 64-64 256 256z" />
<glyph unicode="&#xe018;" glyph-name="insertdatetime" d="M77.798 655.376l81.414-50.882c50.802 81.114 128.788 143.454 221.208 174.246l-30.366 91.094c-113.748-37.898-209.728-114.626-272.256-214.458zM673.946 869.834l-30.366-91.094c92.422-30.792 170.404-93.132 221.208-174.248l81.412 50.882c-62.526 99.834-158.506 176.562-272.254 214.46zM607.974 255.992c-4.808 0-9.692 1.090-14.286 3.386l-145.688 72.844v211.778c0 17.672 14.328 32 32 32s32-14.328 32-32v-172.222l110.31-55.156c15.806-7.902 22.214-27.124 14.31-42.932-5.604-11.214-16.908-17.696-28.646-17.698zM512 768c-212.078 0-384-171.922-384-384s171.922-384 384-384c212.078 0 384 171.922 384 384s-171.922 384-384 384zM512 96c-159.058 0-288 128.942-288 288s128.942 288 288 288c159.058 0 288-128.942 288-288s-128.942-288-288-288z" />
<glyph unicode="&#xe019;" glyph-name="preview" d="M64 504.254c45.318 49.92 97.162 92.36 153.272 125.124 90.332 52.744 192.246 80.622 294.728 80.622 102.48 0 204.396-27.878 294.726-80.624 56.112-32.764 107.956-75.204 153.274-125.124v117.432c-33.010 28.118-68.124 53.14-104.868 74.594-105.006 61.314-223.658 93.722-343.132 93.722s-238.128-32.408-343.134-93.72c-36.742-21.454-71.856-46.478-104.866-74.596v-117.43zM512 640c-183.196 0-345.838-100.556-448-256 102.162-155.448 264.804-256 448-256s345.838 100.552 448 256c-102.162 155.444-264.804 256-448 256zM512 448c0-35.346-28.654-64-64-64s-64 28.654-64 64c0 35.348 28.654 64 64 64s64-28.652 64-64zM728.066 263.338c-67.434-39.374-140.128-59.338-216.066-59.338s-148.632 19.964-216.066 59.338c-51.554 30.104-98.616 71.31-138.114 120.662 39.498 49.35 86.56 90.558 138.116 120.66 13.276 7.752 26.758 14.74 40.426 20.982-10.512-23.742-16.362-50.008-16.362-77.642 0-106.040 85.962-192 192-192 106.040 0 192 85.96 192 192 0 27.634-5.85 53.9-16.36 77.642 13.668-6.244 27.15-13.23 40.426-20.982 51.554-30.102 98.616-71.31 138.116-120.66-39.498-49.352-86.56-90.558-138.116-120.662z" />
<glyph unicode="&#xe01a;" glyph-name="forecolor" d="M651.168 676.166c-24.612 81.962-28.876 91.834-107.168 91.834h-64c-79.618 0-82.664-10.152-108.418-96 0-0.002 0-0.002-0.002-0.004l-143.998-479.996h113.636l57.6 192h226.366l57.6-192h113.63l-145.246 484.166zM437.218 512l38.4 136c10.086 33.618 36.38 30 36.38 30s26.294 3.618 36.38-30h0.004l38.4-136h-149.564z" />
<glyph unicode="&#xe01b;" glyph-name="table" d="M64 768v-704h896v704h-896zM384 320v128h256v-128h-256zM640 256v-128h-256v128h256zM640 640v-128h-256v128h256zM320 640v-128h-192v128h192zM128 448h192v-128h-192v128zM704 448h192v-128h-192v128zM704 512v128h192v-128h-192zM128 256h192v-128h-192v128zM704 128v128h192v-128h-192z" />
<glyph unicode="&#xe01c;" glyph-name="hr" d="M64 512h896v-128h-896z" />
<glyph unicode="&#xe01d;" glyph-name="removeformat" d="M64 192h512v-128h-512v128zM768 768h-220.558l-183.766-512h-132.288l183.762 512h-223.15v128h576v-128zM929.774 64l-129.774 129.774-129.774-129.774-62.226 62.226 129.774 129.774-129.774 129.774 62.226 62.226 129.774-129.774 129.774 129.774 62.226-62.226-129.774-129.774 129.774-129.774-62.226-62.226z" />
<glyph unicode="&#xe01e;" glyph-name="subscript" d="M768 50v-50h128v-64h-192v146l128 60v50h-128v64h192v-146zM676 704h-136l-188-188-188 188h-136l256-256-256-256h136l188 188 188-188h136l-256 256z" />
<glyph unicode="&#xe01f;" glyph-name="superscript" d="M768 754v-50h128v-64h-192v146l128 60v50h-128v64h192v-146zM676 704h-136l-188-188-188 188h-136l256-256-256-256h136l188 188 188-188h136l-256 256z" />
<glyph unicode="&#xe020;" glyph-name="charmap" d="M704 128v37.004c151.348 61.628 256 193.82 256 346.996 0 212.078-200.576 384-448 384s-448-171.922-448-384c0-153.176 104.654-285.368 256-346.996v-37.004h-192l-64 96v-224h320v222.812c-100.9 51.362-170.666 161.54-170.666 289.188 0 176.732 133.718 320 298.666 320s298.666-143.268 298.666-320c0-127.648-69.766-237.826-170.666-289.188v-222.812h320v224l-64-96h-192z" />
<glyph unicode="&#xe021;" glyph-name="emoticons" d="M512 820c99.366 0 192.782-38.694 263.042-108.956s108.958-163.678 108.958-263.044-38.696-192.782-108.958-263.042-163.676-108.958-263.042-108.958-192.782 38.696-263.044 108.958-108.956 163.676-108.956 263.042 38.694 192.782 108.956 263.044 163.678 108.956 263.044 108.956zM512 896c-247.424 0-448-200.576-448-448s200.576-448 448-448 448 200.576 448 448-200.576 448-448 448v0zM320 576c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64zM576 576c0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64s-64-28.654-64-64zM512 304c-101.84 0-192.56 36.874-251.166 94.328 23.126-117.608 126.778-206.328 251.166-206.328s228.040 88.72 251.168 206.328c-58.608-57.454-149.328-94.328-251.168-94.328z" />
<glyph unicode="&#xe022;" glyph-name="print" d="M256 832h512v-128h-512v128zM896 640h-768c-35.2 0-64-28.8-64-64v-256c0-35.2 28.796-64 64-64h128v-192h512v192h128c35.2 0 64 28.8 64 64v256c0 35.2-28.8 64-64 64zM704 128h-384v256h384v-256zM910.4 544c0-25.626-20.774-46.4-46.398-46.4s-46.402 20.774-46.402 46.4 20.778 46.4 46.402 46.4c25.626 0 46.398-20.774 46.398-46.4z" />
<glyph unicode="&#xe023;" glyph-name="fullscreen" d="M480 576l-192 192 128 128h-352v-352l128 128 192-192zM640 480l192 192 128-128v352h-352l128-128-192-192zM544 320l192-192-128-128h352v352l-128-128-192 192zM384 416l-192-192-128 128v-352h352l-128 128 192 192z" />
<glyph unicode="&#xe024;" glyph-name="spellcheck" d="M960 832v64h-192c-35.202 0-64-28.8-64-64v-320c0-15.856 5.858-30.402 15.496-41.614l-303.496-260.386-142 148-82-70 224-288 416 448h128v64h-192v320h192zM256 448h64v384c0 35.2-28.8 64-64 64h-128c-35.2 0-64-28.8-64-64v-384h64v192h128v-192zM128 704v128h128v-128h-128zM640 512v96c0 35.2-8.8 64-44 64 35.2 0 44 28.8 44 64v96c0 35.2-28.8 64-64 64h-192v-448h192c35.2 0 64 28.8 64 64zM448 832h128v-128h-128v128zM448 640h128v-128h-128v128z" />
<glyph unicode="&#xe025;" glyph-name="nonbreaking" d="M448 448h-128v128h128v128h128v-128h128v-128h-128v-128h-128v128zM960 384v-320h-896v320h128v-192h640v192h128z" />
<glyph unicode="&#xe026;" glyph-name="template" d="M512 576h128v-64h-128zM512 192h128v-64h-128zM576 384h128v-64h-128zM768 384v-192h-64v-64h128v256zM384 384h128v-64h-128zM320 192h128v-64h-128zM320 576h128v-64h-128zM192 768v-256h64v192h64v64zM704 512h128v256h-64v-192h-64zM64 896v-896h896v896h-896zM896 64h-768v768h768v-768zM192 384v-256h64v192h64v64zM576 768h128v-64h-128zM384 768h128v-64h-128z" />
<glyph unicode="&#xe027;" glyph-name="pagebreak" d="M816 896l16-384h-640l16 384h32l16-320h512l16 320h32zM208 0l-16 320h640l-16-320h-32l-16 256h-512l-16-256h-32zM64 448h128v-64h-128zM256 448h128v-64h-128zM448 448h128v-64h-128zM640 448h128v-64h-128zM832 448h128v-64h-128z" />
<glyph unicode="&#xe028;" glyph-name="restoredraft" d="M576 896c247.424 0 448-200.576 448-448s-200.576-448-448-448v96c94.024 0 182.418 36.614 248.902 103.098s103.098 154.878 103.098 248.902c0 94.022-36.614 182.418-103.098 248.902s-154.878 103.098-248.902 103.098c-94.022 0-182.418-36.614-248.902-103.098-51.14-51.138-84.582-115.246-97.306-184.902h186.208l-224-256-224 256h164.57c31.060 217.102 217.738 384 443.43 384zM768 512v-128h-256v320h128v-192z" />
<glyph unicode="&#xe02a;" glyph-name="bold" d="M625.442 465.818c48.074 38.15 78.558 94.856 78.558 158.182 0 114.876-100.29 208-224 208h-224v-768h288c123.712 0 224 93.124 224 208 0 88.196-59.118 163.562-142.558 193.818zM384 656c0 26.51 21.49 48 48 48h67.204c42.414 0 76.796-42.98 76.796-96s-34.382-96-76.796-96h-115.204v144zM547.2 192h-115.2c-26.51 0-48 21.49-48 48v144h163.2c42.418 0 76.8-42.98 76.8-96s-34.382-96-76.8-96z" />
<glyph unicode="&#xe02b;" glyph-name="italic" d="M832 832v-64h-144l-256-640h144v-64h-448v64h144l256 640h-144v64h448z" />
<glyph unicode="&#xe02c;" glyph-name="underline" d="M192 128h576v-64h-576v64zM640 832v-384c0-31.312-14.7-61.624-41.39-85.352-30.942-27.502-73.068-42.648-118.61-42.648-45.544 0-87.668 15.146-118.608 42.648-26.692 23.728-41.392 54.040-41.392 85.352v384h-128v-384c0-141.382 128.942-256 288-256s288 114.618 288 256v384h-128z" />
<glyph unicode="&#xe02d;" glyph-name="strikethrough" d="M960 448h-265.876c-50.078 35.42-114.43 54.86-182.124 54.86-89.206 0-164.572 50.242-164.572 109.712s75.366 109.714 164.572 109.714c75.058 0 140.308-35.576 159.12-82.286h113.016c-7.93 50.644-37.58 97.968-84.058 132.826-50.88 38.16-117.676 59.174-188.078 59.174-70.404 0-137.196-21.014-188.074-59.174-54.788-41.090-86.212-99.502-86.212-160.254s31.424-119.164 86.212-160.254c1.956-1.466 3.942-2.898 5.946-4.316h-265.872v-64h512.532c58.208-17.106 100.042-56.27 100.042-100.572 0-59.468-75.368-109.71-164.572-109.71-75.060 0-140.308 35.574-159.118 82.286h-113.016c7.93-50.64 37.582-97.968 84.060-132.826 50.876-38.164 117.668-59.18 188.072-59.18 70.402 0 137.198 21.016 188.074 59.174 54.79 41.090 86.208 99.502 86.208 160.254 0 35.298-10.654 69.792-30.294 100.572h204.012v64z" />
<glyph unicode="&#xe02e;" glyph-name="visualchars" d="M384 832c-123.712 0-224-100.288-224-224s100.288-224 224-224v-320h128v640h64v-640h128v640h128v128h-448z" />
<glyph unicode="&#xe02f;" glyph-name="ltr" d="M448 832c-123.712 0-224-100.288-224-224s100.288-224 224-224v-320h128v640h64v-640h128v640h128v128h-448zM64 64l224 192-224 192z" />
<glyph unicode="&#xe030;" glyph-name="rtl" d="M320 832c-123.712 0-224-100.288-224-224s100.288-224 224-224v-320h128v640h64v-640h128v640h128v128h-448zM960 448l-224-192 224-192z" />
<glyph unicode="&#xe031;" glyph-name="copy" d="M832 640h-192v64l-192 192h-384v-704h384v-192h576v448l-192 192zM832 549.49l101.49-101.49h-101.49v101.49zM448 805.49l101.49-101.49h-101.49v101.49zM128 832h256v-192h192v-384h-448v576zM960 64h-448v128h128v384h128v-192h192v-320z" />
<glyph unicode="&#xe032;" glyph-name="resize" d="M768 704h64v-64h-64zM640 576h64v-64h-64zM640 448h64v-64h-64zM640 320h64v-64h-64zM512 448h64v-64h-64zM512 320h64v-64h-64zM384 320h64v-64h-64zM768 576h64v-64h-64zM768 448h64v-64h-64zM768 320h64v-64h-64zM768 192h64v-64h-64zM640 192h64v-64h-64zM512 192h64v-64h-64zM384 192h64v-64h-64zM256 192h64v-64h-64z" />
<glyph unicode="&#xe034;" glyph-name="browse" d="M928 832h-416l-32 64h-352l-64-128h896zM840.34 256h87.66l32 448h-896l64-640h356.080c-104.882 37.776-180.080 138.266-180.080 256 0 149.982 122.018 272 272 272 149.98 0 272-122.018 272-272 0-21.678-2.622-43.15-7.66-64zM874.996 110.25l-134.496 110.692c17.454 28.922 27.5 62.814 27.5 99.058 0 106.040-85.96 192-192 192s-192-85.96-192-192 85.96-192 192-192c36.244 0 70.138 10.046 99.058 27.5l110.692-134.496c22.962-26.678 62.118-28.14 87.006-3.252l5.492 5.492c24.888 24.888 23.426 64.044-3.252 87.006zM576 196c-68.484 0-124 55.516-124 124s55.516 124 124 124 124-55.516 124-124-55.516-124-124-124z" />
<glyph unicode="&#xe035;" glyph-name="pastetext" d="M704 576v160c0 17.6-14.4 32-32 32h-160v64c0 35.2-28.8 64-64 64h-128c-35.204 0-64-28.8-64-64v-64h-160c-17.602 0-32-14.4-32-32v-512c0-17.6 14.398-32 32-32h224v-192h576v576h-192zM320 831.886c0.034 0.038 0.072 0.078 0.114 0.114h127.768c0.042-0.036 0.082-0.076 0.118-0.114v-63.886h-128v63.886zM192 640v64h384v-64h-384zM832 64h-448v448h448v-448zM448 448v-128h32l32 64h64v-192h-48v-64h160v64h-48v192h64l32-64h32v128z" />
<glyph unicode="&#xe603;" glyph-name="codesample" d="M200.015 577.994v103.994c0 43.077 34.919 77.997 77.997 77.997h26v103.994h-26c-100.51 0-181.991-81.481-181.991-181.991v-103.994c0-43.077-34.919-77.997-77.997-77.997h-26v-103.994h26c43.077 0 77.997-34.919 77.997-77.997v-103.994c0-100.509 81.481-181.991 181.991-181.991h26v103.994h-26c-43.077 0-77.997 34.919-77.997 77.997v103.994c0 50.927-20.928 96.961-54.642 129.994 33.714 33.032 54.642 79.065 54.642 129.994zM823.985 577.994v103.994c0 43.077-34.919 77.997-77.997 77.997h-26v103.994h26c100.509 0 181.991-81.481 181.991-181.991v-103.994c0-43.077 34.919-77.997 77.997-77.997h26v-103.994h-26c-43.077 0-77.997-34.919-77.997-77.997v-103.994c0-100.509-81.482-181.991-181.991-181.991h-26v103.994h26c43.077 0 77.997 34.919 77.997 77.997v103.994c0 50.927 20.928 96.961 54.642 129.994-33.714 33.032-54.642 79.065-54.642 129.994zM615.997 603.277c0-57.435-46.56-103.994-103.994-103.994s-103.994 46.56-103.994 103.994c0 57.435 46.56 103.994 103.994 103.994s103.994-46.56 103.994-103.994zM512 448.717c-57.435 0-103.994-46.56-103.994-103.994 0-55.841 26-100.107 105.747-103.875-23.715-33.413-59.437-46.608-105.747-50.94v-61.747c0 0 207.991-18.144 207.991 216.561-0.202 57.437-46.56 103.996-103.994 103.996z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 24 KiB

@@ -1,131 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="tinymce" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe000;" glyph-name="save" d="M896 960h-896v-1024h1024v896l-128 128zM512 832h128v-256h-128v256zM896 64h-768v768h64v-320h576v320h74.978l53.022-53.018v-714.982z" />
<glyph unicode="&#xe001;" glyph-name="newdocument" d="M903.432 760.57l-142.864 142.862c-31.112 31.112-92.568 56.568-136.568 56.568h-480c-44 0-80-36-80-80v-864c0-44 36-80 80-80h736c44 0 80 36 80 80v608c0 44-25.456 105.458-56.568 136.57zM858.178 715.314c3.13-3.13 6.25-6.974 9.28-11.314h-163.458v163.456c4.34-3.030 8.184-6.15 11.314-9.28l142.864-142.862zM896 16c0-8.672-7.328-16-16-16h-736c-8.672 0-16 7.328-16 16v864c0 8.672 7.328 16 16 16h480c4.832 0 10.254-0.61 16-1.704v-254.296h254.296c1.094-5.746 1.704-11.166 1.704-16v-608z" />
<glyph unicode="&#xe002;" glyph-name="fullpage" d="M1024 367.542v160.916l-159.144 15.914c-8.186 30.042-20.088 58.548-35.21 84.98l104.596 127.838-113.052 113.050-127.836-104.596c-26.434 15.124-54.942 27.026-84.982 35.208l-15.914 159.148h-160.916l-15.914-159.146c-30.042-8.186-58.548-20.086-84.98-35.208l-127.838 104.594-113.050-113.050 104.596-127.836c-15.124-26.432-27.026-54.94-35.21-84.98l-159.146-15.916v-160.916l159.146-15.914c8.186-30.042 20.086-58.548 35.21-84.982l-104.596-127.836 113.048-113.048 127.838 104.596c26.432-15.124 54.94-27.028 84.98-35.21l15.916-159.148h160.916l15.914 159.144c30.042 8.186 58.548 20.088 84.982 35.21l127.836-104.596 113.048 113.048-104.596 127.836c15.124 26.434 27.028 54.942 35.21 84.98l159.148 15.92zM704 384l-128-128h-128l-128 128v128l128 128h128l128-128v-128z" />
<glyph unicode="&#xe003;" glyph-name="alignleft" d="M0 896h1024v-128h-1024zM0 704h640v-128h-640zM0 320h640v-128h-640zM0 512h1024v-128h-1024zM0 128h1024v-128h-1024z" />
<glyph unicode="&#xe004;" glyph-name="aligncenter" d="M0 896h1024v-128h-1024zM192 704h640v-128h-640zM192 320h640v-128h-640zM0 512h1024v-128h-1024zM0 128h1024v-128h-1024z" />
<glyph unicode="&#xe005;" glyph-name="alignright" d="M0 896h1024v-128h-1024zM384 704h640v-128h-640zM384 320h640v-128h-640zM0 512h1024v-128h-1024zM0 128h1024v-128h-1024z" />
<glyph unicode="&#xe006;" glyph-name="alignjustify" d="M0 896h1024v-128h-1024zM0 704h1024v-128h-1024zM0 512h1024v-128h-1024zM0 320h1024v-128h-1024zM0 128h1024v-128h-1024z" />
<glyph unicode="&#xe007;" glyph-name="cut" d="M890.774 250.846c-45.654 45.556-103.728 69.072-157.946 69.072h-29.112l-63.904 64.008 255.62 256.038c63.904 64.010 63.904 192.028 0 256.038l-383.43-384.056-383.432 384.054c-63.904-64.008-63.904-192.028 0-256.038l255.622-256.034-63.906-64.008h-29.114c-54.22 0-112.292-23.518-157.948-69.076-81.622-81.442-92.65-202.484-24.63-270.35 29.97-29.902 70.288-44.494 112.996-44.494 54.216 0 112.29 23.514 157.946 69.072 53.584 53.464 76.742 124 67.084 185.348l65.384 65.488 65.376-65.488c-9.656-61.348 13.506-131.882 67.084-185.348 45.662-45.558 103.732-69.072 157.948-69.072 42.708 0 83.024 14.592 112.994 44.496 68.020 67.866 56.988 188.908-24.632 270.35zM353.024 114.462c-7.698-17.882-19.010-34.346-33.626-48.926-14.636-14.604-31.172-25.918-49.148-33.624-16.132-6.916-32.96-10.568-48.662-10.568-15.146 0-36.612 3.402-52.862 19.612-16.136 16.104-19.52 37.318-19.52 52.288 0 15.542 3.642 32.21 10.526 48.212 7.7 17.884 19.014 34.346 33.626 48.926 14.634 14.606 31.172 25.914 49.15 33.624 16.134 6.914 32.96 10.568 48.664 10.568 15.146 0 36.612-3.4 52.858-19.614 16.134-16.098 19.522-37.316 19.522-52.284 0.002-15.542-3.638-32.216-10.528-48.214zM512.004 293.404c-49.914 0-90.376 40.532-90.376 90.526 0 49.992 40.462 90.52 90.376 90.52s90.372-40.528 90.372-90.52c0-49.998-40.46-90.526-90.372-90.526zM855.272 40.958c-16.248-16.208-37.712-19.612-52.86-19.612-15.704 0-32.53 3.652-48.666 10.568-17.972 7.706-34.508 19.020-49.142 33.624-14.614 14.58-25.926 31.042-33.626 48.926-6.886 15.998-10.526 32.672-10.526 48.212 0 14.966 3.384 36.188 19.52 52.286 16.246 16.208 37.712 19.614 52.86 19.614 15.7 0 32.53-3.654 48.66-10.568 17.978-7.708 34.516-19.018 49.15-33.624 14.61-14.58 25.924-31.042 33.626-48.926 6.884-15.998 10.526-32.67 10.526-48.212-0.002-14.97-3.39-36.186-19.522-52.288z" />
<glyph unicode="&#xe008;" glyph-name="paste" d="M832 640v160c0 17.6-14.4 32-32 32h-224v64c0 35.2-28.8 64-64 64h-128c-35.204 0-64-28.8-64-64v-64h-224c-17.602 0-32-14.4-32-32v-640c0-17.6 14.398-32 32-32h288v-192h448l192 192v512h-192zM384 895.886c0.034 0.038 0.072 0.078 0.114 0.114h127.768c0.042-0.036 0.082-0.076 0.118-0.114v-63.886h-128v63.886zM192 704v64h512v-64h-512zM832 26.51v101.49h101.49l-101.49-101.49zM960 192h-192v-192h-320v576h512v-384z" />
<glyph unicode="&#xe009;" glyph-name="searchreplace" d="M64 960h384v-64h-384zM576 960h384v-64h-384zM952 640h-56v256h-256v-256h-256v256h-256v-256h-56c-39.6 0-72-32.4-72-72v-560c0-39.6 32.4-72 72-72h304c39.6 0 72 32.4 72 72v376h128v-376c0-39.6 32.4-72 72-72h304c39.6 0 72 32.4 72 72v560c0 39.6-32.4 72-72 72zM348 0h-248c-19.8 0-36 14.4-36 32s16.2 32 36 32h248c19.8 0 36-14.4 36-32s-16.2-32-36-32zM544 448h-64c-17.6 0-32 14.4-32 32s14.4 32 32 32h64c17.6 0 32-14.4 32-32s-14.4-32-32-32zM924 0h-248c-19.8 0-36 14.4-36 32s16.2 32 36 32h248c19.8 0 36-14.4 36-32s-16.2-32-36-32z" />
<glyph unicode="&#xe00a;" glyph-name="bullist" d="M384 896h640v-128h-640v128zM384 512h640v-128h-640v128zM384 128h640v-128h-640v128zM0 832c0 70.692 57.308 128 128 128s128-57.308 128-128c0-70.692-57.308-128-128-128s-128 57.308-128 128zM0 448c0 70.692 57.308 128 128 128s128-57.308 128-128c0-70.692-57.308-128-128-128s-128 57.308-128 128zM0 64c0 70.692 57.308 128 128 128s128-57.308 128-128c0-70.692-57.308-128-128-128s-128 57.308-128 128z" />
<glyph unicode="&#xe00b;" glyph-name="numlist" d="M384 128h640v-128h-640zM384 512h640v-128h-640zM384 896h640v-128h-640zM192 960v-256h-64v192h-64v64zM128 434v-50h128v-64h-192v146l128 60v50h-128v64h192v-146zM256 256v-320h-192v64h128v64h-128v64h128v64h-128v64z" />
<glyph unicode="&#xe00c;" glyph-name="indent" d="M0 896h1024v-128h-1024zM384 704h640v-128h-640zM384 512h640v-128h-640zM384 320h640v-128h-640zM0 128h1024v-128h-1024zM0 256v384l256-192z" />
<glyph unicode="&#xe00d;" glyph-name="outdent" d="M0 896h1024v-128h-1024zM384 704h640v-128h-640zM384 512h640v-128h-640zM384 320h640v-128h-640zM0 128h1024v-128h-1024zM256 640v-384l-256 192z" />
<glyph unicode="&#xe00e;" glyph-name="blockquote" d="M225 512c123.712 0 224-100.29 224-224 0-123.712-100.288-224-224-224s-224 100.288-224 224l-1 32c0 247.424 200.576 448 448 448v-128c-85.474 0-165.834-33.286-226.274-93.726-11.634-11.636-22.252-24.016-31.83-37.020 11.438 1.8 23.16 2.746 35.104 2.746zM801 512c123.71 0 224-100.29 224-224 0-123.712-100.29-224-224-224s-224 100.288-224 224l-1 32c0 247.424 200.576 448 448 448v-128c-85.474 0-165.834-33.286-226.274-93.726-11.636-11.636-22.254-24.016-31.832-37.020 11.44 1.8 23.16 2.746 35.106 2.746z" />
<glyph unicode="&#xe00f;" glyph-name="undo" d="M761.862-64c113.726 206.032 132.888 520.306-313.862 509.824v-253.824l-384 384 384 384v-248.372c534.962 13.942 594.57-472.214 313.862-775.628z" />
<glyph unicode="&#xe010;" glyph-name="redo" d="M576 711.628v248.372l384-384-384-384v253.824c-446.75 10.482-427.588-303.792-313.86-509.824-280.712 303.414-221.1 789.57 313.86 775.628z" />
<glyph unicode="&#xe011;" glyph-name="link" d="M320 256c17.6-17.6 47.274-16.726 65.942 1.942l316.118 316.116c18.668 18.668 19.54 48.342 1.94 65.942s-47.274 16.726-65.942-1.942l-316.116-316.116c-18.668-18.668-19.542-48.342-1.942-65.942zM476.888 284.888c4.56-9.050 6.99-19.16 6.99-29.696 0-17.616-6.744-34.060-18.992-46.308l-163.382-163.382c-12.248-12.248-28.694-18.992-46.308-18.992s-34.060 6.744-46.308 18.992l-99.382 99.382c-12.248 12.248-18.992 28.694-18.992 46.308s6.744 34.060 18.992 46.308l163.382 163.382c12.248 12.248 28.694 18.994 46.308 18.994 10.536 0 20.644-2.43 29.696-6.99l65.338 65.338c-27.87 21.41-61.44 32.16-95.034 32.16-39.986 0-79.972-15.166-110.308-45.502l-163.382-163.382c-60.67-60.67-60.67-159.948 0-220.618l99.382-99.382c30.334-30.332 70.32-45.5 110.306-45.5 39.988 0 79.974 15.168 110.308 45.502l163.382 163.382c55.82 55.82 60.238 144.298 13.344 205.344l-65.34-65.34zM978.498 815.116l-99.382 99.382c-30.334 30.336-70.32 45.502-110.308 45.502-39.986 0-79.972-15.166-110.308-45.502l-163.382-163.382c-55.82-55.82-60.238-144.298-13.342-205.342l65.338 65.34c-4.558 9.050-6.988 19.16-6.988 29.694 0 17.616 6.744 34.060 18.992 46.308l163.382 163.382c12.248 12.248 28.694 18.994 46.308 18.994s34.060-6.746 46.308-18.994l99.382-99.382c12.248-12.248 18.992-28.694 18.992-46.308s-6.744-34.060-18.992-46.308l-163.382-163.382c-12.248-12.248-28.694-18.992-46.308-18.992-10.536 0-20.644 2.43-29.696 6.99l-65.338-65.338c27.872-21.41 61.44-32.16 95.034-32.16 39.988 0 79.974 15.168 110.308 45.502l163.382 163.382c60.67 60.666 60.67 159.944 0 220.614z" />
<glyph unicode="&#xe012;" glyph-name="unlink" d="M476.888 284.886c4.56-9.048 6.99-19.158 6.99-29.696 0-17.616-6.744-34.058-18.992-46.308l-163.38-163.38c-12.248-12.248-28.696-18.992-46.308-18.992s-34.060 6.744-46.308 18.992l-99.38 99.38c-12.248 12.25-18.992 28.696-18.992 46.308s6.744 34.060 18.992 46.308l163.38 163.382c12.248 12.246 28.696 18.992 46.308 18.992 10.538 0 20.644-2.43 29.696-6.988l65.338 65.336c-27.87 21.41-61.44 32.16-95.034 32.16-39.986 0-79.972-15.166-110.308-45.502l-163.38-163.382c-60.67-60.67-60.67-159.95 0-220.618l99.38-99.382c30.334-30.332 70.32-45.5 110.306-45.5 39.988 0 79.974 15.168 110.308 45.502l163.38 163.38c55.82 55.82 60.238 144.298 13.344 205.346l-65.34-65.338zM978.496 815.116l-99.38 99.382c-30.334 30.336-70.32 45.502-110.308 45.502-39.986 0-79.97-15.166-110.306-45.502l-163.382-163.382c-55.82-55.82-60.238-144.298-13.342-205.342l65.338 65.34c-4.558 9.050-6.988 19.16-6.988 29.694 0 17.616 6.744 34.060 18.992 46.308l163.382 163.382c12.246 12.248 28.694 18.994 46.306 18.994 17.616 0 34.060-6.746 46.308-18.994l99.38-99.382c12.248-12.248 18.992-28.694 18.992-46.308s-6.744-34.060-18.992-46.308l-163.38-163.382c-12.248-12.248-28.694-18.992-46.308-18.992-10.536 0-20.644 2.43-29.696 6.99l-65.338-65.338c27.872-21.41 61.44-32.16 95.034-32.16 39.988 0 79.974 15.168 110.308 45.504l163.38 163.38c60.672 60.666 60.672 159.944 0 220.614zM233.368 681.376l-191.994 191.994 45.256 45.256 191.994-191.994zM384 960h64v-192h-64zM0 576h192v-64h-192zM790.632 214.624l191.996-191.996-45.256-45.256-191.996 191.996zM576 128h64v-192h-64zM832 384h192v-64h-192z" />
<glyph unicode="&#xe013;" glyph-name="anchor" d="M192 960v-1024l320 320 320-320v1024h-640zM768 90.51l-256 256-256-256v805.49h512v-805.49z" />
<glyph unicode="&#xe014;" glyph-name="image" d="M0 832v-832h1024v832h-1024zM960 64h-896v704h896v-704zM704 608c0 53.019 42.981 96 96 96s96-42.981 96-96c0-53.019-42.981-96-96-96s-96 42.981-96 96zM896 128h-768l192 512 256-320 128 96z" />
<glyph unicode="&#xe015;" glyph-name="media" d="M0 832v-768h1024v768h-1024zM192 128h-128v128h128v-128zM192 384h-128v128h128v-128zM192 640h-128v128h128v-128zM768 128h-512v640h512v-640zM960 128h-128v128h128v-128zM960 384h-128v128h128v-128zM960 640h-128v128h128v-128zM384 640v-384l256 192z" />
<glyph unicode="&#xe016;" glyph-name="help" d="M448 256h128v-128h-128zM704 704c35.346 0 64-28.654 64-64v-192l-192-128h-128v64l192 128v64h-320v128h384zM512 864c-111.118 0-215.584-43.272-294.156-121.844s-121.844-183.038-121.844-294.156c0-111.118 43.272-215.584 121.844-294.156s183.038-121.844 294.156-121.844c111.118 0 215.584 43.272 294.156 121.844s121.844 183.038 121.844 294.156c0 111.118-43.272 215.584-121.844 294.156s-183.038 121.844-294.156 121.844zM512 960v0c282.77 0 512-229.23 512-512s-229.23-512-512-512c-282.77 0-512 229.23-512 512s229.23 512 512 512z" />
<glyph unicode="&#xe017;" glyph-name="code" d="M320 704l-256-256 256-256h128l-256 256 256 256zM704 704h-128l256-256-256-256h128l256 256z" />
<glyph unicode="&#xe018;" glyph-name="inserttime" d="M512 768c-212.076 0-384-171.922-384-384s171.922-384 384-384c212.074 0 384 171.922 384 384s-171.926 384-384 384zM715.644 180.354c-54.392-54.396-126.716-84.354-203.644-84.354s-149.25 29.958-203.646 84.354c-54.396 54.394-84.354 126.718-84.354 203.646s29.958 149.25 84.354 203.646c54.396 54.396 126.718 84.354 203.646 84.354s149.252-29.958 203.642-84.354c54.402-54.396 84.358-126.718 84.358-203.646s-29.958-149.252-84.356-203.646zM325.93 756.138l-42.94 85.878c-98.874-49.536-179.47-130.132-229.006-229.008l85.876-42.94c40.248 80.336 105.732 145.822 186.070 186.070zM884.134 570.070l85.878 42.938c-49.532 98.876-130.126 179.472-229.004 229.008l-42.944-85.878c80.338-40.248 145.824-105.732 186.070-186.068zM512 576h-64v-192c0-10.11 4.7-19.11 12.022-24.972l-0.012-0.016 160-128 39.976 49.976-147.986 118.39v176.622z" />
<glyph unicode="&#xe019;" glyph-name="preview" d="M512 640c-209.368 0-395.244-100.556-512-256 116.756-155.446 302.632-256 512-256s395.244 100.554 512 256c-116.756 155.444-302.632 256-512 256zM448 512c35.346 0 64-28.654 64-64s-28.654-64-64-64-64 28.654-64 64 28.654 64 64 64zM773.616 254.704c-39.648-20.258-81.652-35.862-124.846-46.376-44.488-10.836-90.502-16.328-136.77-16.328-46.266 0-92.282 5.492-136.768 16.324-43.194 10.518-85.198 26.122-124.846 46.376-63.020 32.202-120.222 76.41-167.64 129.298 47.418 52.888 104.62 97.1 167.64 129.298 32.336 16.522 66.242 29.946 101.082 40.040-19.888-30.242-31.468-66.434-31.468-105.336 0-106.040 85.962-192 192-192s192 85.96 192 192c0 38.902-11.582 75.094-31.466 105.34 34.838-10.096 68.744-23.52 101.082-40.042 63.022-32.198 120.218-76.408 167.638-129.298-47.42-52.886-104.618-97.1-167.638-129.296zM860.918 716.278c-108.72 55.554-226.112 83.722-348.918 83.722s-240.198-28.168-348.918-83.722c-58.772-30.032-113.732-67.904-163.082-112.076v-109.206c55.338 58.566 120.694 107.754 192.194 144.29 99.62 50.904 207.218 76.714 319.806 76.714s220.186-25.81 319.804-76.716c71.502-36.536 136.858-85.724 192.196-144.29v109.206c-49.35 44.174-104.308 82.046-163.082 112.078z" />
<glyph unicode="&#xe01a;" glyph-name="forecolor" d="M322.018 128l57.6 192h264.764l57.6-192h113.632l-191.996 640h-223.236l-192-640h113.636zM475.618 640h72.764l57.6-192h-187.964l57.6 192z" />
<glyph unicode="&#xe01b;" glyph-name="table" d="M0 896v-896h1024v896h-1024zM384 320v192h256v-192h-256zM640 256v-192h-256v192h256zM640 768v-192h-256v192h256zM320 768v-192h-256v192h256zM64 512h256v-192h-256v192zM704 512h256v-192h-256v192zM704 576v192h256v-192h-256zM64 256h256v-192h-256v192zM704 64v192h256v-192h-256z" />
<glyph unicode="&#xe01c;" glyph-name="hr" d="M0 512h1024v-128h-1024z" />
<glyph unicode="&#xe01d;" glyph-name="removeformat" d="M0 64h576v-128h-576zM192 960h704v-128h-704zM277.388 128l204.688 784.164 123.85-32.328-196.25-751.836zM929.774-64l-129.774 129.774-129.774-129.774-62.226 62.226 129.774 129.774-129.774 129.774 62.226 62.226 129.774-129.774 129.774 129.774 62.226-62.226-129.774-129.774 129.774-129.774z" />
<glyph unicode="&#xe01e;" glyph-name="sub" d="M768 50v-50h128v-64h-192v146l128 60v50h-128v64h192v-146zM676 704h-136l-188-188-188 188h-136l256-256-256-256h136l188 188 188-188h136l-256 256z" />
<glyph unicode="&#xe01f;" glyph-name="sup" d="M768 754v-50h128v-64h-192v146l128 60v50h-128v64h192v-146zM676 704h-136l-188-188-188 188h-136l256-256-256-256h136l188 188 188-188h136l-256 256z" />
<glyph unicode="&#xe020;" glyph-name="charmap" d="M704 64h256l64 128v-256h-384v214.214c131.112 56.484 224 197.162 224 361.786 0 214.432-157.598 382.266-352 382.266-194.406 0-352-167.832-352-382.266 0-164.624 92.886-305.302 224-361.786v-214.214h-384v256l64-128h256v32.59c-187.63 66.46-320 227.402-320 415.41 0 247.424 229.23 448 512 448s512-200.576 512-448c0-188.008-132.37-348.95-320-415.41v-32.59z" />
<glyph unicode="&#xe021;" glyph-name="emoticons" d="M512 960c-282.77 0-512-229.228-512-512 0-282.77 229.228-512 512-512 282.77 0 512 229.23 512 512 0 282.772-229.23 512-512 512zM512 16c-238.586 0-432 193.412-432 432 0 238.586 193.414 432 432 432 238.59 0 432-193.414 432-432 0-238.588-193.41-432-432-432zM384 640c0-35.346-28.654-64-64-64s-64 28.654-64 64 28.654 64 64 64 64-28.654 64-64zM768 640c0-35.346-28.652-64-64-64s-64 28.654-64 64 28.652 64 64 64 64-28.654 64-64zM512 308c141.074 0 262.688 57.532 318.462 123.192-20.872-171.22-156.288-303.192-318.462-303.192-162.118 0-297.498 132.026-318.444 303.168 55.786-65.646 177.386-123.168 318.444-123.168z" />
<glyph unicode="&#xe022;" glyph-name="print" d="M256 896h512v-128h-512zM960 704h-896c-35.2 0-64-28.8-64-64v-320c0-35.2 28.796-64 64-64h192v-256h512v256h192c35.2 0 64 28.8 64 64v320c0 35.2-28.8 64-64 64zM704 64h-384v320h384v-320zM974.4 608c0-25.626-20.774-46.4-46.398-46.4-25.626 0-46.402 20.774-46.402 46.4s20.776 46.4 46.402 46.4c25.626 0 46.398-20.774 46.398-46.4z" />
<glyph unicode="&#xe023;" glyph-name="fullscreen" d="M1024 960v-384l-138.26 138.26-212-212-107.48 107.48 212 212-138.26 138.26zM245.74 821.74l212-212-107.48-107.48-212 212-138.26-138.26v384h384zM885.74 181.74l138.26 138.26v-384h-384l138.26 138.26-212 212 107.48 107.48zM457.74 286.26l-212-212 138.26-138.26h-384v384l138.26-138.26 212 212z" />
<glyph unicode="&#xe024;" glyph-name="spellchecker" d="M128 704h128v-192h64v384c0 35.2-28.8 64-64 64h-128c-35.2 0-64-28.8-64-64v-384h64v192zM128 896h128v-128h-128v128zM960 896v64h-192c-35.202 0-64-28.8-64-64v-320c0-35.2 28.798-64 64-64h192v64h-192v320h192zM640 800v96c0 35.2-28.8 64-64 64h-192v-448h192c35.2 0 64 28.8 64 64v96c0 35.2-8.8 64-44 64 35.2 0 44 28.8 44 64zM576 576h-128v128h128v-128zM576 768h-128v128h128v-128zM832 384l-416-448-224 288 82 70 142-148 352 302z" />
<glyph unicode="&#xe025;" glyph-name="nonbreaking" d="M448 384h-192v128h192v192h128v-192h192v-128h-192v-192h-128zM1024 320v-384h-1024v384h128v-256h768v256z" />
<glyph unicode="&#xe026;" glyph-name="template" d="M384 768h128v-64h-128zM576 768h128v-64h-128zM896 768v-256h-192v64h128v128h-64v64zM320 576h128v-64h-128zM512 576h128v-64h-128zM192 704v-128h64v-64h-128v256h192v-64zM384 384h128v-64h-128zM576 384h128v-64h-128zM896 384v-256h-192v64h128v128h-64v64zM320 192h128v-64h-128zM512 192h128v-64h-128zM192 320v-128h64v-64h-128v256h192v-64zM960 896h-896v-896h896v896zM1024 960v0-1024h-1024v1024h1024z" />
<glyph unicode="&#xe027;" glyph-name="pagebreak" d="M0 448h128v-64h-128zM192 448h192v-64h-192zM448 448h128v-64h-128zM640 448h192v-64h-192zM896 448h128v-64h-128zM880 960l16-448h-768l16 448h32l16-384h640l16 384zM144-64l-16 384h768l-16-384h-32l-16 320h-640l-16-320z" />
<glyph unicode="&#xe028;" glyph-name="restoredraft" d="M576 896c247.424 0 448-200.576 448-448s-200.576-448-448-448v96c94.024 0 182.418 36.614 248.902 103.098s103.098 154.878 103.098 248.902c0 94.022-36.614 182.418-103.098 248.902s-154.878 103.098-248.902 103.098c-94.022 0-182.418-36.614-248.902-103.098-51.14-51.138-84.582-115.246-97.306-184.902h186.208l-224-256-224 256h164.57c31.060 217.102 217.738 384 443.43 384zM768 512v-128h-256v320h128v-192z" />
<glyph unicode="&#xe02a;" glyph-name="bold" d="M707.88 475.348c37.498 44.542 60.12 102.008 60.12 164.652 0 141.16-114.842 256-256 256h-320v-896h384c141.158 0 256 114.842 256 256 0 92.956-49.798 174.496-124.12 219.348zM384 768h101.5c55.968 0 101.5-57.42 101.5-128s-45.532-128-101.5-128h-101.5v256zM543 128h-159v256h159c58.45 0 106-57.42 106-128s-47.55-128-106-128z" />
<glyph unicode="&#xe02b;" glyph-name="italic" d="M896 896v-64h-128l-320-768h128v-64h-448v64h128l320 768h-128v64z" />
<glyph unicode="&#xe02c;" glyph-name="underline" d="M704 896h128v-416c0-159.058-143.268-288-320-288-176.73 0-320 128.942-320 288v416h128v-416c0-40.166 18.238-78.704 51.354-108.506 36.896-33.204 86.846-51.494 140.646-51.494s103.75 18.29 140.646 51.494c33.116 29.802 51.354 68.34 51.354 108.506v416zM192 128h640v-128h-640z" />
<glyph unicode="&#xe02d;" glyph-name="strikethrough" d="M731.42 442.964c63.92-47.938 100.58-116.086 100.58-186.964s-36.66-139.026-100.58-186.964c-59.358-44.518-137.284-69.036-219.42-69.036-82.138 0-160.062 24.518-219.42 69.036-63.92 47.938-100.58 116.086-100.58 186.964h128c0-69.382 87.926-128 192-128s192 58.618 192 128c0 69.382-87.926 128-192 128-82.138 0-160.062 24.518-219.42 69.036-63.92 47.94-100.58 116.086-100.58 186.964s36.66 139.024 100.58 186.964c59.358 44.518 137.282 69.036 219.42 69.036 82.136 0 160.062-24.518 219.42-69.036 63.92-47.94 100.58-116.086 100.58-186.964h-128c0 69.382-87.926 128-192 128s-192-58.618-192-128c0-69.382 87.926-128 192-128 82.136 0 160.062-24.518 219.42-69.036zM0 448h1024v-64h-1024z" />
<glyph unicode="&#xe02e;" glyph-name="visualchars" d="M384 896h512v-128h-128v-768h-128v768h-128v-768h-128v448c-123.712 0-224 100.288-224 224s100.288 224 224 224z" />
<glyph unicode="&#xe02f;" glyph-name="ltr" d="M448 896h512v-128h-128v-768h-128v768h-128v-768h-128v448c-123.712 0-224 100.288-224 224s100.288 224 224 224zM64 512l256-224-256-224z" />
<glyph unicode="&#xe030;" glyph-name="rtl" d="M256 896h512v-128h-128v-768h-128v768h-128v-768h-128v448c-123.712 0-224 100.288-224 224s100.288 224 224 224zM960 64l-256 224 256 224z" />
<glyph unicode="&#xe031;" glyph-name="copy" d="M832 704h-192v64l-192 192h-448v-768h384v-256h640v576l-192 192zM832 613.49l101.49-101.49h-101.49v101.49zM448 869.49l101.49-101.49h-101.49v101.49zM64 896h320v-192h192v-448h-512v640zM960 0h-512v192h192v448h128v-192h192v-448z" />
<glyph unicode="&#xe032;" glyph-name="resize" d="M768 704h64v-64h-64zM640 576h64v-64h-64zM640 448h64v-64h-64zM640 320h64v-64h-64zM512 448h64v-64h-64zM512 320h64v-64h-64zM384 320h64v-64h-64zM768 576h64v-64h-64zM768 448h64v-64h-64zM768 320h64v-64h-64zM768 192h64v-64h-64zM640 192h64v-64h-64zM512 192h64v-64h-64zM384 192h64v-64h-64zM256 192h64v-64h-64z" />
<glyph unicode="&#xe033;" glyph-name="checkbox" d="M128 416l288-288 480 480-128 128-352-352-160 160z" />
<glyph unicode="&#xe034;" glyph-name="browse" d="M928 832h-416l-32 64h-352l-64-128h896zM904.34 256h74.86l44.8 448h-1024l64-640h484.080c-104.882 37.776-180.080 138.266-180.080 256 0 149.982 122.018 272 272 272 149.98 0 272-122.018 272-272 0-21.678-2.622-43.15-7.66-64zM1002.996 46.25l-198.496 174.692c17.454 28.92 27.5 62.814 27.5 99.058 0 106.040-85.96 192-192 192s-192-85.96-192-192 85.96-192 192-192c36.244 0 70.138 10.046 99.058 27.5l174.692-198.496c22.962-26.678 62.118-28.14 87.006-3.252l5.492 5.492c24.888 24.888 23.426 64.044-3.252 87.006zM640 196c-68.484 0-124 55.516-124 124s55.516 124 124 124 124-55.516 124-124-55.516-124-124-124z" />
<glyph unicode="&#xe035;" glyph-name="pastetext" d="M512 448v-128h32l32 64h64v-256h-48v-64h224v64h-48v256h64l32-64h32v128zM832 640v160c0 17.6-14.4 32-32 32h-224v64c0 35.2-28.8 64-64 64h-128c-35.204 0-64-28.8-64-64v-64h-224c-17.602 0-32-14.4-32-32v-640c0-17.6 14.398-32 32-32h288v-192h640v704h-192zM384 895.886c0.034 0.038 0.072 0.078 0.114 0.114h127.768c0.042-0.036 0.082-0.076 0.118-0.114v-63.886h-128v63.886zM192 704v64h512v-64h-512zM960 0h-512v576h512v-576z" />
<glyph unicode="&#xe600;" glyph-name="gamma" d="M483.2 320l-147.2 336c-9.6 25.6-19.2 44.8-25.6 54.4s-16 12.8-25.6 12.8c-16 0-25.6-3.2-28.8-3.2v70.4c9.6 6.4 25.6 6.4 38.4 9.6 32 0 57.6-6.4 73.6-22.4 6.4-6.4 12.8-16 19.2-25.6 6.4-12.8 12.8-25.6 16-41.6l121.6-291.2 150.4 371.2h92.8l-198.4-470.4v-224h-86.4v224zM0 960v-1024h1024v1024h-1024zM960 0h-896v896h896v-896z" />
<glyph unicode="&#xe601;" glyph-name="orientation" d="M627.2 80h-579.2v396.8h579.2v-396.8zM553.6 406.4h-435.2v-256h435.2v256zM259.2 732.8c176 176 457.6 176 633.6 0s176-457.6 0-633.6c-121.6-121.6-297.6-160-454.4-108.8 121.6-28.8 262.4 9.6 361.6 108.8 150.4 150.4 160 384 22.4 521.6-121.6 121.6-320 128-470.4 19.2l86.4-86.4-294.4-22.4 22.4 294.4 92.8-92.8z" />
<glyph unicode="&#xe602;" glyph-name="invert" d="M892.8-22.4l-89.6 89.6c-70.4-80-172.8-131.2-288-131.2-208 0-380.8 166.4-384 377.6 0 0 0 0 0 0 0 3.2 0 3.2 0 6.4s0 3.2 0 6.4v0c0 0 0 0 0 3.2 0 0 0 3.2 0 3.2 3.2 105.6 48 211.2 105.6 304l-192 192 44.8 44.8 182.4-182.4c0 0 0 0 0 0l569.6-569.6c0 0 0 0 0 0l99.2-99.2-48-44.8zM896 326.4c0 0 0 0 0 0 0 3.2 0 6.4 0 6.4-9.6 316.8-384 627.2-384 627.2s-108.8-89.6-208-220.8l70.4-70.4c6.4 9.6 16 22.4 22.4 32 41.6 51.2 83.2 96 115.2 128v0c32-32 73.6-76.8 115.2-128 108.8-137.6 169.6-265.6 172.8-371.2 0 0 0-3.2 0-3.2v0 0c0-3.2 0-3.2 0-6.4s0-3.2 0-3.2v0 0c0-22.4-3.2-41.6-9.6-64l76.8-76.8c16 41.6 28.8 89.6 28.8 137.6 0 0 0 0 0 0 0 3.2 0 3.2 0 6.4s0 3.2 0 6.4z" />
<glyph unicode="&#xe603;" glyph-name="codesample" d="M199.995 578.002v104.002c0 43.078 34.923 78.001 78.001 78.001h26v104.002h-26c-100.518 0-182.003-81.485-182.003-182.003v-104.002c0-43.078-34.923-78.001-78.001-78.001h-26v-104.002h26c43.078 0 78.001-34.923 78.001-78.001v-104.002c0-100.515 81.485-182.003 182.003-182.003h26v104.002h-26c-43.078 0-78.001 34.923-78.001 78.001v104.002c0 50.931-20.928 96.966-54.646 130.002 33.716 33.036 54.646 79.072 54.646 130.002zM824.005 578.002v104.002c0 43.078-34.923 78.001-78.001 78.001h-26v104.002h26c100.515 0 182.003-81.485 182.003-182.003v-104.002c0-43.078 34.923-78.001 78.001-78.001h26v-104.002h-26c-43.078 0-78.001-34.923-78.001-78.001v-104.002c0-100.515-81.488-182.003-182.003-182.003h-26v104.002h26c43.078 0 78.001 34.923 78.001 78.001v104.002c0 50.931 20.928 96.966 54.646 130.002-33.716 33.036-54.646 79.072-54.646 130.002zM616.002 603.285c0-57.439-46.562-104.002-104.002-104.002s-104.002 46.562-104.002 104.002c0 57.439 46.562 104.002 104.002 104.002s104.002-46.562 104.002-104.002zM512 448.717c-57.439 0-104.002-46.562-104.002-104.002 0-55.845 26-100.115 105.752-103.88-23.719-33.417-59.441-46.612-105.752-50.944v-61.751c0 0 208.003-18.144 208.003 216.577-0.202 57.441-46.56 104.004-104.002 104.004z" />
<glyph unicode="&#xe604;" glyph-name="tablerowprops" d="M0 896v-896h1024v896h-1024zM640 256v-192h-256v192h256zM640 768v-192h-256v192h256zM320 768v-192h-256v192h256zM704 576v192h256v-192h-256zM64 256h256v-192h-256v192zM704 64v192h256v-192h-256z" />
<glyph unicode="&#xe605;" glyph-name="tablecellprops" d="M0 896v-896h1024v896h-1024zM640 256v-192h-256v192h256zM640 768v-192h-256v192h256zM320 768v-192h-256v192h256zM64 512h256v-192h-256v192zM704 512h256v-192h-256v192zM704 576v192h256v-192h-256zM64 256h256v-192h-256v192zM704 64v192h256v-192h-256z" />
<glyph unicode="&#xe606;" glyph-name="table2" d="M0 896v-832h1024v832h-1024zM320 128h-256v192h256v-192zM320 384h-256v192h256v-192zM640 128h-256v192h256v-192zM640 384h-256v192h256v-192zM960 128h-256v192h256v-192zM960 384h-256v192h256v-192zM960 640h-896v192h896v-192z" />
<glyph unicode="&#xe607;" glyph-name="tablemergecells" d="M0 896v-896h1024v896h-1024zM384 64v448h576v-448h-576zM640 768v-192h-256v192h256zM320 768v-192h-256v192h256zM64 512h256v-192h-256v192zM704 576v192h256v-192h-256zM64 256h256v-192h-256v192z" />
<glyph unicode="&#xe608;" glyph-name="tableinsertcolbefore" d="M320 188.8v182.4h-182.4v89.6h182.4v182.4h86.4v-182.4h185.6v-89.6h-185.6v-182.4zM0 896v-896h1024v896h-1024zM640 64h-576v704h576v-704zM960 64h-256v192h256v-192zM960 320h-256v192h256v-192zM960 576h-256v192h256v-192z" />
<glyph unicode="&#xe609;" glyph-name="tableinsertcolafter" d="M704 643.2v-182.4h182.4v-89.6h-182.4v-182.4h-86.4v182.4h-185.6v89.6h185.6v182.4zM0 896v-896h1024v896h-1024zM320 64h-256v192h256v-192zM320 320h-256v192h256v-192zM320 576h-256v192h256v-192zM960 64h-576v704h576v-704z" />
<glyph unicode="&#xe60a;" glyph-name="tableinsertrowbefore" d="M691.2 508.8h-144v-144h-70.4v144h-144v67.2h144v144h70.4v-144h144zM0 896v-896h1024v896h-1024zM320 64h-256v192h256v-192zM640 64h-256v192h256v-192zM960 64h-256v192h256v-192zM960 316.8h-896v451.2h896v-451.2z" />
<glyph unicode="&#xe60b;" glyph-name="tableinsertrowafter" d="M332.8 323.2h144v144h70.4v-144h144v-67.2h-144v-144h-70.4v144h-144zM0 896v-896h1024v896h-1024zM384 768h256v-192h-256v192zM64 768h256v-192h-256v192zM960 64h-896v451.2h896v-451.2zM960 576h-256v192h256v-192z" />
<glyph unicode="&#xe60d;" glyph-name="tablesplitcells" d="M0 896v-896h1024v896h-1024zM384 768h256v-192h-256v192zM320 64h-256v192h256v-192zM320 320h-256v192h256v-192zM320 576h-256v192h256v-192zM960 64h-576v448h576v-448zM960 576h-256v192h256v-192zM864 156.8l-60.8-60.8-131.2 131.2-131.2-131.2-60.8 60.8 131.2 131.2-131.2 131.2 60.8 60.8 131.2-131.2 131.2 131.2 60.8-60.8-131.2-131.2z" />
<glyph unicode="&#xe60e;" glyph-name="tabledelete" d="M0 896h1024v-896h-1024v896zM60.8 768v-704h899.2v704h-899.2zM809.6 211.2l-96-96-204.8 204.8-204.8-204.8-96 96 204.8 204.8-204.8 204.8 96 96 204.8-204.8 204.8 204.8 96-96-204.8-204.8z" />
<glyph unicode="&#xe62a;" glyph-name="tableleftheader" d="M0 896v-832h1024v832h-1024zM640 128h-256v192h256v-192zM640 384h-256v192h256v-192zM640 640h-256v192h256v-192zM960 128h-256v192h256v-192zM960 384h-256v192h256v-192zM960 640h-256v192h256v-192z" />
<glyph unicode="&#xe62b;" glyph-name="tabletopheader" d="M0 896v-832h1024v832h-1024zM320 128h-256v192h256v-192zM320 384h-256v192h256v-192zM640 128h-256v192h256v-192zM640 384h-256v192h256v-192zM960 128h-256v192h256v-192zM960 384h-256v192h256v-192z" />
<glyph unicode="&#xe800;" glyph-name="tabledeleterow" d="M886.4 572.8l-156.8-156.8 160-160-76.8-76.8-160 160-156.8-156.8-76.8 73.6 160 160-163.2 163.2 76.8 76.8 163.2-163.2 156.8 156.8 73.6-76.8zM0 896v-896h1024v896h-1024zM960 576h-22.4l-64-64h86.4v-192h-89.6l64-64h25.6v-192h-896v192h310.4l64 64h-374.4v192h371.2l-64 64h-307.2v192h896v-192z" />
<glyph unicode="&#xe801;" glyph-name="tabledeletecol" d="M320 499.2l64-64v-12.8l-64-64v140.8zM640 422.4l64-64v137.6l-64-64v-9.6zM1024 896v-896h-1024v896h1024zM960 768h-256v-51.2l-12.8 12.8-51.2-51.2v89.6h-256v-89.6l-51.2 51.2-12.8-12.8v51.2h-256v-704h256v118.4l35.2-35.2 28.8 28.8v-115.2h256v115.2l48-48 16 16v-83.2h256v707.2zM672 662.4l-156.8-156.8-163.2 163.2-76.8-76.8 163.2-163.2-156.8-156.8 76.8-76.8 156.8 156.8 160-160 76.8 76.8-160 160 156.8 156.8-76.8 76.8z" />
<glyph unicode="&#xe900;" glyph-name="a11y" d="M960 704v64l-448-128-448 128v-64l320-128v-256l-128-448h64l192 448 192-448h64l-128 448v256zM416 800q0 40 28 68t68 28 68-28 28-68-28-68-68-28-68 28-28 68z" />
<glyph unicode="&#xe901;" glyph-name="toc" d="M0 896h128v-128h-128v128zM192 896h832v-128h-832v128zM192 704h128v-128h-128v128zM384 704h640v-128h-640v128zM384 512h128v-128h-128v128zM576 512h448v-128h-448v128zM0 320h128v-128h-128v128zM192 320h832v-128h-832v128zM192 128h128v-128h-128v128zM384 128h640v-128h-640v128z" />
<glyph unicode="&#xe902;" glyph-name="fill" d="M521.6 915.2l-67.2-67.2-86.4 86.4-86.4-86.4 86.4-86.4-368-368 432-432 518.4 518.4-428.8 435.2zM435.2 134.4l-262.4 262.4 35.2 35.2 576 51.2-348.8-348.8zM953.6 409.6c-6.4-6.4-16-16-28.8-32-28.8-32-41.6-64-41.6-89.6v0 0 0 0 0 0 0c0-16 6.4-35.2 22.4-48 12.8-12.8 32-22.4 48-22.4s35.2 6.4 48 22.4 22.4 32 22.4 48v0 0 0 0 0 0 0c0 25.6-12.8 54.4-41.6 89.6-9.6 16-22.4 25.6-28.8 32v0z" />
<glyph unicode="&#xe903;" glyph-name="borderwidth" d="M0 265.6h1024v-128h-1024v128zM0 32h1024v-64h-1024v64zM0 566.4h1024v-192h-1024v192zM0 928h1024v-256h-1024v256z" />
<glyph unicode="&#xe904;" glyph-name="line" d="M739.2 627.2l-502.4-502.4h-185.6v185.6l502.4 502.4 185.6-185.6zM803.2 688l-185.6 185.6 67.2 67.2c22.4 22.4 54.4 22.4 76.8 0l108.8-108.8c22.4-22.4 22.4-54.4 0-76.8l-67.2-67.2zM41.6 48h940.8v-112h-940.8v112z" />
<glyph unicode="&#xe905;" glyph-name="count" d="M0 480h1024v-64h-1024v64zM304 912v-339.2h-67.2v272h-67.2v67.2zM444.8 694.4v-54.4h134.4v-67.2h-201.6v153.6l134.4 64v54.4h-134.4v67.2h201.6v-153.6zM854.4 912v-339.2h-204.8v67.2h137.6v67.2h-137.6v70.4h137.6v67.2h-137.6v67.2zM115.2 166.4c3.2 57.6 38.4 83.2 108.8 83.2 38.4 0 67.2-9.6 86.4-25.6s25.6-35.2 25.6-70.4v-112c0-25.6 0-28.8 9.6-41.6h-73.6c-3.2 9.6-3.2 9.6-6.4 19.2-22.4-19.2-41.6-25.6-70.4-25.6-54.4 0-89.6 32-89.6 76.8s28.8 70.4 99.2 80l38.4 6.4c16 3.2 22.4 6.4 22.4 16 0 12.8-12.8 22.4-38.4 22.4s-41.6-9.6-44.8-28.8h-67.2zM262.4 115.2c-6.4-3.2-12.8-6.4-25.6-6.4l-25.6-6.4c-25.6-6.4-38.4-16-38.4-28.8 0-16 12.8-25.6 35.2-25.6s41.6 9.6 54.4 32v35.2zM390.4 336h73.6v-112c22.4 16 41.6 22.4 67.2 22.4 64 0 105.6-51.2 105.6-124.8 0-76.8-44.8-134.4-108.8-134.4-32 0-48 9.6-67.2 35.2v-28.8h-70.4v342.4zM460.8 121.6c0-41.6 22.4-70.4 51.2-70.4s51.2 28.8 51.2 70.4c0 44.8-19.2 70.4-51.2 70.4-28.8 0-51.2-28.8-51.2-70.4zM851.2 153.6c-3.2 22.4-19.2 35.2-44.8 35.2-32 0-51.2-25.6-51.2-70.4 0-48 19.2-73.6 51.2-73.6 25.6 0 41.6 12.8 44.8 41.6l70.4-3.2c-9.6-60.8-54.4-96-118.4-96-73.6 0-121.6 51.2-121.6 128 0 80 48 131.2 124.8 131.2 64 0 108.8-35.2 112-96h-67.2z" />
<glyph unicode="&#xe906;" glyph-name="reload" d="M889.68 793.68c-93.608 102.216-228.154 166.32-377.68 166.32-282.77 0-512-229.23-512-512h96c0 229.75 186.25 416 416 416 123.020 0 233.542-53.418 309.696-138.306l-149.696-149.694h352v352l-134.32-134.32zM928 448c0-229.75-186.25-416-416-416-123.020 0-233.542 53.418-309.694 138.306l149.694 149.694h-352v-352l134.32 134.32c93.608-102.216 228.154-166.32 377.68-166.32 282.77 0 512 229.23 512 512h-96z" />
<glyph unicode="&#xe907;" glyph-name="translate" d="M553.6 304l-118.4 118.4c80 89.6 137.6 195.2 172.8 304h137.6v92.8h-326.4v92.8h-92.8v-92.8h-326.4v-92.8h518.4c-32-89.6-80-176-147.2-249.6-44.8 48-80 99.2-108.8 156.8h-92.8c35.2-76.8 80-147.2 137.6-211.2l-236.8-233.6 67.2-67.2 233.6 233.6 144-144c3.2 0 38.4 92.8 38.4 92.8zM816 540.8h-92.8l-208-560h92.8l51.2 140.8h220.8l51.2-140.8h92.8l-208 560zM691.2 214.4l76.8 201.6 76.8-201.6h-153.6z" />
<glyph unicode="&#xe908;" glyph-name="drag" d="M576 896h128v-128h-128v128zM576 640h128v-128h-128v128zM320 640h128v-128h-128v128zM576 384h128v-128h-128v128zM320 384h128v-128h-128v128zM320 128h128v-128h-128v128zM576 128h128v-128h-128v128zM320 896h128v-128h-128v128z" />
<glyph unicode="&#xe90b;" glyph-name="home" d="M1024 369.556l-512 397.426-512-397.428v162.038l512 397.426 512-397.428zM896 384v-384h-256v256h-256v-256h-256v384l384 288z" />
<glyph unicode="&#xe911;" glyph-name="books" d="M576.234 670.73l242.712 81.432 203.584-606.784-242.712-81.432zM0 64h256v704h-256v-704zM64 640h128v-64h-128v64zM320 64h256v704h-256v-704zM384 640h128v-64h-128v64z" />
<glyph unicode="&#xe914;" glyph-name="upload" d="M839.432 760.57c27.492-27.492 50.554-78.672 55.552-120.57h-318.984v318.984c41.898-4.998 93.076-28.060 120.568-55.552l142.864-142.862zM512 576v384h-368c-44 0-80-36-80-80v-864c0-44 36-80 80-80h672c44 0 80 36 80 80v560h-384zM576 192v-192h-192v192h-160l256 256 256-256h-160z" />
<glyph unicode="&#xe915;" glyph-name="editimage" d="M768 416v-352h-640v640h352l128 128h-512c-52.8 0-96-43.2-96-96v-704c0-52.8 43.2-96 96-96h704c52.798 0 96 43.2 96 96v512l-128-128zM864 960l-608-608v-160h160l608 608c0 96-64 160-160 160zM416 320l-48 48 480 480 48-48-480-480z" />
<glyph unicode="&#xe91c;" glyph-name="bubble" d="M928 896h-832c-52.8 0-96-43.2-96-96v-512c0-52.8 43.2-96 96-96h160v-256l307.2 256h364.8c52.8 0 96 43.2 96 96v512c0 52.8-43.2 96-96 96zM896 320h-379.142l-196.858-174.714v174.714h-192v448h768v-448z" />
<glyph unicode="&#xe91d;" glyph-name="user" d="M622.826 257.264c-22.11 3.518-22.614 64.314-22.614 64.314s64.968 64.316 79.128 150.802c38.090 0 61.618 91.946 23.522 124.296 1.59 34.054 48.96 267.324-190.862 267.324s-192.45-233.27-190.864-267.324c-38.094-32.35-14.57-124.296 23.522-124.296 14.158-86.486 79.128-150.802 79.128-150.802s-0.504-60.796-22.614-64.314c-71.22-11.332-337.172-128.634-337.172-257.264h896c0 128.63-265.952 245.932-337.174 257.264z" />
<glyph unicode="&#xe926;" glyph-name="lock" d="M592 512h-16v192c0 105.87-86.13 192-192 192h-128c-105.87 0-192-86.13-192-192v-192h-16c-26.4 0-48-21.6-48-48v-480c0-26.4 21.6-48 48-48h544c26.4 0 48 21.6 48 48v480c0 26.4-21.6 48-48 48zM192 704c0 35.29 28.71 64 64 64h128c35.29 0 64-28.71 64-64v-192h-256v192z" />
<glyph unicode="&#xe927;" glyph-name="unlock" d="M768 896c105.87 0 192-86.13 192-192v-192h-128v192c0 35.29-28.71 64-64 64h-128c-35.29 0-64-28.71-64-64v-192h16c26.4 0 48-21.6 48-48v-480c0-26.4-21.6-48-48-48h-544c-26.4 0-48 21.6-48 48v480c0 26.4 21.6 48 48 48h400v192c0 105.87 86.13 192 192 192h128z" />
<glyph unicode="&#xe928;" glyph-name="settings" d="M448 832v16c0 26.4-21.6 48-48 48h-160c-26.4 0-48-21.6-48-48v-16h-192v-128h192v-16c0-26.4 21.6-48 48-48h160c26.4 0 48 21.6 48 48v16h576v128h-576zM256 704v128h128v-128h-128zM832 528c0 26.4-21.6 48-48 48h-160c-26.4 0-48-21.6-48-48v-16h-576v-128h576v-16c0-26.4 21.6-48 48-48h160c26.4 0 48 21.6 48 48v16h192v128h-192v16zM640 384v128h128v-128h-128zM448 208c0 26.4-21.6 48-48 48h-160c-26.4 0-48-21.6-48-48v-16h-192v-128h192v-16c0-26.4 21.6-48 48-48h160c26.4 0 48 21.6 48 48v16h576v128h-576v16zM256 64v128h128v-128h-128z" />
<glyph unicode="&#xe92a;" glyph-name="remove2" d="M192-64h640l64 704h-768zM640 832v128h-256v-128h-320v-192l64 64h768l64-64v192h-320zM576 832h-128v64h128v-64z" />
<glyph unicode="&#xe92d;" glyph-name="menu" d="M384 896h256v-256h-256zM384 576h256v-256h-256zM384 256h256v-256h-256z" />
<glyph unicode="&#xe930;" glyph-name="warning" d="M1009.956 44.24l-437.074 871.112c-16.742 29.766-38.812 44.648-60.882 44.648s-44.14-14.882-60.884-44.648l-437.074-871.112c-33.486-59.532-5-108.24 63.304-108.24h869.308c68.302 0 96.792 48.708 63.302 108.24zM512 64c-35.346 0-64 28.654-64 64 0 35.348 28.654 64 64 64 35.348 0 64-28.652 64-64 0-35.346-28.652-64-64-64zM556 256h-88l-20 256c0 35.346 28.654 64 64 64s64-28.654 64-64l-20-256z" />
<glyph unicode="&#xe931;" glyph-name="question" d="M448 256h128v-128h-128zM704 704c35.346 0 64-28.654 64-64v-192l-192-128h-128v64l192 128v64h-320v128h384zM512 864c-111.118 0-215.584-43.272-294.156-121.844s-121.844-183.038-121.844-294.156c0-111.118 43.272-215.584 121.844-294.156s183.038-121.844 294.156-121.844c111.118 0 215.584 43.272 294.156 121.844s121.844 183.038 121.844 294.156c0 111.118-43.272 215.584-121.844 294.156s-183.038 121.844-294.156 121.844zM512 960v0c282.77 0 512-229.23 512-512s-229.23-512-512-512c-282.77 0-512 229.23-512 512s229.23 512 512 512z" />
<glyph unicode="&#xe932;" glyph-name="pluscircle" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512 64c-212.078 0-384 171.922-384 384s171.922 384 384 384c212.078 0 384-171.922 384-384s-171.922-384-384-384zM768 384h-192v-192h-128v192h-192v128h192v192h128v-192h192z" />
<glyph unicode="&#xe933;" glyph-name="info" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM448 768h128v-128h-128v128zM640 128h-256v64h64v256h-64v64h192v-320h64v-64z" />
<glyph unicode="&#xe934;" glyph-name="notice" d="M1024 224l-288 736h-448l-288-288v-448l288-288h448l288 288v448l-288 288zM576 128h-128v128h128v-128zM576 384h-128v384h128v-384z" />
<glyph unicode="&#xe935;" glyph-name="drop" d="M864.626 486.838c-65.754 183.44-205.11 348.15-352.626 473.162-147.516-125.012-286.87-289.722-352.626-473.162-40.664-113.436-44.682-236.562 12.584-345.4 65.846-125.14 198.632-205.438 340.042-205.438s274.196 80.298 340.040 205.44c57.27 108.838 53.25 231.962 12.586 345.398zM738.764 201.044c-43.802-83.252-132.812-137.044-226.764-137.044-55.12 0-108.524 18.536-152.112 50.652 13.242-1.724 26.632-2.652 40.112-2.652 117.426 0 228.668 67.214 283.402 171.242 44.878 85.292 40.978 173.848 23.882 244.338 14.558-28.15 26.906-56.198 36.848-83.932 22.606-63.062 40.024-156.34-5.368-242.604z" />
<glyph unicode="&#xe939;" glyph-name="minus" d="M0 544v-192c0-17.672 14.328-32 32-32h960c17.672 0 32 14.328 32 32v192c0 17.672-14.328 32-32 32h-960c-17.672 0-32-14.328-32-32z" />
<glyph unicode="&#xe93a;" glyph-name="plus" d="M992 576h-352v352c0 17.672-14.328 32-32 32h-192c-17.672 0-32-14.328-32-32v-352h-352c-17.672 0-32-14.328-32-32v-192c0-17.672 14.328-32 32-32h352v-352c0-17.672 14.328-32 32-32h192c17.672 0 32 14.328 32 32v352h352c17.672 0 32 14.328 32 32v192c0 17.672-14.328 32-32 32z" />
<glyph unicode="&#xe93b;" glyph-name="arrowup" d="M0 320l192-192 320 320 320-320 192 192-511.998 512z" />
<glyph unicode="&#xe93c;" glyph-name="arrowright" d="M384 960l-192-192 320-320-320-320 192-192 512 512z" />
<glyph unicode="&#xe93d;" glyph-name="arrowdown" d="M1024 576l-192 192-320-320-320 320-192-192 512-511.998z" />
<glyph unicode="&#xe93f;" glyph-name="arrowup2" d="M768 320l-256 256-256-256z" />
<glyph unicode="&#xe940;" glyph-name="arrowdown2" d="M256 576l256-256 256 256z" />
<glyph unicode="&#xe941;" glyph-name="menu2" d="M256 704l256-256 256 256zM255.996 384.004l256-256 256 256z" />
<glyph unicode="&#xe961;" glyph-name="newtab" d="M704 384l128 128v-512h-768v768h512l-128-128h-256v-512h512zM960 896v-352l-130.744 130.744-354.746-354.744h-90.51v90.512l354.744 354.744-130.744 130.744z" />
<glyph unicode="&#xeaa8;" glyph-name="rotateleft" d="M607.998 831.986c-212.070 0-383.986-171.916-383.986-383.986h-191.994l246.848-246.848 246.848 246.848h-191.994c0 151.478 122.798 274.276 274.276 274.276 151.48 0 274.276-122.798 274.276-274.276 0-151.48-122.796-274.276-274.276-274.276v-109.71c212.070 0 383.986 171.916 383.986 383.986s-171.916 383.986-383.986 383.986z" />
<glyph unicode="&#xeaa9;" glyph-name="rotateright" d="M416.002 831.986c212.070 0 383.986-171.916 383.986-383.986h191.994l-246.848-246.848-246.848 246.848h191.994c0 151.478-122.798 274.276-274.276 274.276-151.48 0-274.276-122.798-274.276-274.276 0-151.48 122.796-274.276 274.276-274.276v-109.71c-212.070 0-383.986 171.916-383.986 383.986s171.916 383.986 383.986 383.986z" />
<glyph unicode="&#xeaaa;" glyph-name="flipv" d="M0 576h1024v384zM1024 0v384h-1024z" />
<glyph unicode="&#xeaac;" glyph-name="fliph" d="M576 960v-1024h384zM0-64h384v1024z" />
<glyph unicode="&#xeb35;" glyph-name="zoomin" d="M992.262 88.604l-242.552 206.294c-25.074 22.566-51.89 32.926-73.552 31.926 57.256 67.068 91.842 154.078 91.842 249.176 0 212.078-171.922 384-384 384-212.076 0-384-171.922-384-384s171.922-384 384-384c95.098 0 182.108 34.586 249.176 91.844-1-21.662 9.36-48.478 31.926-73.552l206.294-242.552c35.322-39.246 93.022-42.554 128.22-7.356s31.892 92.898-7.354 128.22zM384 320c-141.384 0-256 114.616-256 256s114.616 256 256 256 256-114.616 256-256-114.614-256-256-256zM448 768h-128v-128h-128v-128h128v-128h128v128h128v128h-128z" />
<glyph unicode="&#xeb36;" glyph-name="zoomout" d="M992.262 88.604l-242.552 206.294c-25.074 22.566-51.89 32.926-73.552 31.926 57.256 67.068 91.842 154.078 91.842 249.176 0 212.078-171.922 384-384 384-212.076 0-384-171.922-384-384s171.922-384 384-384c95.098 0 182.108 34.586 249.176 91.844-1-21.662 9.36-48.478 31.926-73.552l206.294-242.552c35.322-39.246 93.022-42.554 128.22-7.356s31.892 92.898-7.354 128.22zM384 320c-141.384 0-256 114.616-256 256s114.616 256 256 256 256-114.616 256-256-114.614-256-256-256zM192 640h384v-128h-384z" />
<glyph unicode="&#xeba7;" glyph-name="sharpen" d="M768 832h-512l-256-256 512-576 512 576-256 256zM512 181.334v2.666h-2.37l-14.222 16h16.592v16h-30.814l-14.222 16h45.036v16h-59.258l-14.222 16h73.48v16h-87.704l-14.222 16h101.926v16h-116.148l-14.222 16h130.37v16h-144.592l-14.222 16h158.814v16h-173.038l-14.222 16h187.26v16h-201.482l-14.222 16h215.704v16h-229.926l-14.222 16h244.148v16h-258.372l-14.222 16h272.594v16h-286.816l-14.222 16h301.038v16h-315.26l-14.222 16h329.482v16h-343.706l-7.344 8.262 139.072 139.072h211.978v-3.334h215.314l16-16h-231.314v-16h247.314l16-16h-263.314v-16h279.314l16-16h-295.314v-16h311.314l16-16h-327.314v-16h343.312l7.738-7.738-351.050-394.928z" />
<glyph unicode="&#xec6a;" glyph-name="options" d="M64 768h896v-192h-896zM64 512h896v-192h-896zM64 256h896v-192h-896z" />
<glyph unicode="&#xeccc;" glyph-name="sun" d="M512 128c35.346 0 64-28.654 64-64v-64c0-35.346-28.654-64-64-64s-64 28.654-64 64v64c0 35.346 28.654 64 64 64zM512 768c-35.346 0-64 28.654-64 64v64c0 35.346 28.654 64 64 64s64-28.654 64-64v-64c0-35.346-28.654-64-64-64zM960 512c35.346 0 64-28.654 64-64s-28.654-64-64-64h-64c-35.348 0-64 28.654-64 64s28.652 64 64 64h64zM192 448c0-35.346-28.654-64-64-64h-64c-35.346 0-64 28.654-64 64s28.654 64 64 64h64c35.346 0 64-28.654 64-64zM828.784 221.726l45.256-45.258c24.992-24.99 24.992-65.516 0-90.508-24.994-24.992-65.518-24.992-90.51 0l-45.256 45.256c-24.992 24.99-24.992 65.516 0 90.51 24.994 24.992 65.518 24.992 90.51 0zM195.216 674.274l-45.256 45.256c-24.994 24.994-24.994 65.516 0 90.51s65.516 24.994 90.51 0l45.256-45.256c24.994-24.994 24.994-65.516 0-90.51s-65.516-24.994-90.51 0zM828.784 674.274c-24.992-24.992-65.516-24.992-90.51 0-24.992 24.994-24.992 65.516 0 90.51l45.256 45.254c24.992 24.994 65.516 24.994 90.51 0 24.992-24.994 24.992-65.516 0-90.51l-45.256-45.254zM195.216 221.726c24.992 24.992 65.518 24.992 90.508 0 24.994-24.994 24.994-65.52 0-90.51l-45.254-45.256c-24.994-24.992-65.516-24.992-90.51 0s-24.994 65.518 0 90.508l45.256 45.258zM512 704c-141.384 0-256-114.616-256-256 0-141.382 114.616-256 256-256 141.382 0 256 114.618 256 256 0 141.384-114.616 256-256 256zM512 288c-88.366 0-160 71.634-160 160s71.634 160 160 160 160-71.634 160-160-71.634-160-160-160z" />
<glyph unicode="&#xeccd;" glyph-name="moon" d="M715.812 895.52c-60.25 34.784-124.618 55.904-189.572 64.48 122.936-160.082 144.768-384.762 37.574-570.42-107.2-185.67-312.688-279.112-512.788-252.68 39.898-51.958 90.376-97.146 150.628-131.934 245.908-141.974 560.37-57.72 702.344 188.198 141.988 245.924 57.732 560.372-188.186 702.356z" />
<glyph unicode="&#xecd4;" glyph-name="contrast" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM128 448c0 212.078 171.922 384 384 384v-768c-212.078 0-384 171.922-384 384z" />
<glyph unicode="&#xed6a;" glyph-name="remove22" d="M893.254 738.746l-90.508 90.508-290.746-290.744-290.746 290.744-90.508-90.506 290.746-290.748-290.746-290.746 90.508-90.508 290.746 290.746 290.746-290.746 90.508 90.51-290.744 290.744z" />
<glyph unicode="&#xedc0;" glyph-name="arrowleft" d="M672-64l192 192-320 320 320 320-192 192-512-512z" />
<glyph unicode="&#xedf9;" glyph-name="resize2" d="M0 896v-384c0-35.346 28.654-64 64-64s64 28.654 64 64v229.488l677.488-677.488h-229.488c-35.346 0-64-28.652-64-64 0-35.346 28.654-64 64-64h384c35.346 0 64 28.654 64 64v384c0 35.348-28.654 64-64 64s-64-28.652-64-64v-229.488l-677.488 677.488h229.488c35.346 0 64 28.654 64 64s-28.652 64-64 64h-384c-35.346 0-64-28.654-64-64z" />
<glyph unicode="&#xee78;" glyph-name="crop" d="M832 704l192 192-64 64-192-192h-448v192h-128v-192h-192v-128h192v-512h512v-192h128v192h192v128h-192v448zM320 640h320l-320-320v320zM384 256l320 320v-320h-320z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 B

File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
tinymce.ThemeManager.add("modern",function(e){function t(){function t(t){var r,i=[];if(t)return c(t.split(/[ ,]/),function(t){function n(){var n=e.selection;"bullist"==o&&n.selectorChanged("ul > li",function(e,n){for(var r,i=n.parents.length;i--&&(r=n.parents[i].nodeName,"OL"!=r&&"UL"!=r););t.active("UL"==r)}),"numlist"==o&&n.selectorChanged("ol > li",function(e,n){for(var r,i=n.parents.length;i--&&(r=n.parents[i].nodeName,"OL"!=r&&"UL"!=r););t.active("OL"==r)}),t.settings.stateSelector&&n.selectorChanged(t.settings.stateSelector,function(e){t.active(e)},!0),t.settings.disabledStateSelector&&n.selectorChanged(t.settings.disabledStateSelector,function(e){t.disabled(e)})}var o;"|"==t?r=null:l.has(t)?(t={type:t},s.toolbar_items_size&&(t.size=s.toolbar_items_size),i.push(t),r=null):(r||(r={type:"buttongroup",items:[]},i.push(r)),e.buttons[t]&&(o=t,t=e.buttons[o],t.type=t.type||"button",s.toolbar_items_size&&(t.size=s.toolbar_items_size),t=l.create(t),r.items.push(t),e.initialized?n():e.on("init",n)))}),n.push({type:"toolbar",layout:"flow",items:i}),!0}for(var n=[],r=1;10>r&&t(s["toolbar"+r]);r++);return n.length||t(s.toolbar||f),n}function n(){function t(t){var n;return"|"==t?{text:"|"}:n=e.menuItems[t]}function n(n){var r,i,o,a;if(s.menu?(i=s.menu[n],a=!0):i=d[n],i){r={text:i.title},o=[],c((i.items||"").split(/[ ,]/),function(e){var n=t(e);n&&o.push(t(e))}),a||c(e.menuItems,function(e){e.context==n&&("before"==e.separator&&o.push({text:"|"}),e.prependToContext?o.unshift(e):o.push(e),"after"==e.separator&&o.push({text:"|"}))});for(var l=0;o.length>l;l++)"|"==o[l].text&&(0===l||l==o.length-1)&&o.splice(l,1);if(r.menu=o,!r.menu.length)return null}return r}var r=[],i=s.menubar?tinymce.makeMap(s.menubar,/[ ,]/):!1;for(var o in d)(!i||i[o])&&(o=n(o),o&&r.push(o));return r}function r(t){function n(e){var n=t.find(e)[0];n&&n.focus()}e.shortcuts.add("Alt+F9","",function(){n("menubar")}),e.shortcuts.add("Alt+F10","",function(){n("toolbar")}),e.shortcuts.add("Alt+F11","",function(){n("elementpath")}),t.on("cancel",function(){e.focus()})}function i(){function i(){if(f&&f.visible()){var t=u.getPos(e.getBody());f.moveTo(t.x,t.y-f.layoutRect().h)}}function o(){f&&(f.show(),i(),u.addClass(e.getBody(),"mce-edit-focus"))}function c(){f&&(f.hide(),u.removeClass(e.getBody(),"mce-edit-focus"),document.activeElement&&-1==document.activeElement.className.indexOf("mce-content-body")&&u.setStyle(document.body,"padding-top",0))}function d(){return f?(f.visible()||o(),void 0):(f=a.panel=l.create({type:"floatpanel",classes:"tinymce tinymce-inline",layout:"flex",direction:"column",autohide:!1,autofix:!0,border:1,items:[s.menubar===!1?null:{type:"menubar",border:"0 0 1 0",items:n()},{type:"panel",name:"toolbar",layout:"stack",items:t()}]}),f.renderTo(document.body).reflow(),r(f),o(),e.on("nodeChange",i),e.on("activate",o),e.on("deactivate",c),void 0)}var f;return s.content_editable=!0,e.on("focus",d),e.on("blur",c),e.on("remove",function(){f.remove(),f=null}),{}}function o(i){var o;return o=a.panel=l.create({type:"panel",classes:"tinymce",style:"visibility: hidden",layout:"stack",border:1,items:[s.menubar===!1?null:{type:"menubar",border:"0 0 1 0",items:n()},{type:"panel",layout:"stack",items:t()},{type:"panel",name:"iframe",layout:"stack",classes:"edit-area",html:"",border:"1 0 0 0"}]}),s.statusbar!==!1&&o.add({type:"panel",name:"statusbar",classes:"statusbar",layout:"flow",border:"1 0 0 0",items:[{type:"elementpath"},s.resize!==!1?{type:"resizehandle",editor:e}:null]}),o.renderBefore(i.targetNode).reflow(),s.width&&tinymce.DOM.setStyle(o.getEl(),"width",s.width),e.on("remove",function(){o.remove(),o=null}),r(o),{iframeContainer:o.find("#iframe")[0].getEl(),editorContainer:o.getEl()}}var a=this,s=e.settings,l=tinymce.ui.Factory,c=tinymce.each,u=tinymce.DOM,d={file:{title:"File",items:"newdocument"},edit:{title:"Edit",items:"undo redo | cut copy paste | selectall"},insert:{title:"Insert",items:"|"},view:{title:"View",items:"visualaid |"},format:{title:"Format",items:"bold italic underline strikethrough superscript subscript | formats | removeformat"},table:{title:"Table"},tools:{title:"Tools"}},f="undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image";a.renderUI=function(t){var n=s.skin!==!1?s.skin||"lightgray":!1;return n&&(tinymce.Env.ie&&7>=tinymce.Env.ie?tinymce.DOM.loadCSS(tinymce.baseURL+"/skins/"+n+"/skin.ie7.min.css"):tinymce.DOM.loadCSS(tinymce.baseURL+"/skins/"+n+"/skin.min.css"),e.contentCSS.push(tinymce.baseURL+"/skins/"+n+"/content.min.css")),e.on("ProgressState",function(e){a.throbber=a.throbber||new tinymce.ui.Throbber(a.panel.getEl("body")),e.state?a.throbber.show(e.time):a.throbber.hide()}),s.inline?i(t):o(t)}});
File diff suppressed because it is too large Load Diff
+1 -3
View File
@@ -21,7 +21,6 @@
"animejs": "2.2.0",
"bootstrap-social": "4.8.0",
"clipboard": "2.0.0",
"codemirror": "5.3.0",
"diff": "3.4.0",
"flatpickr": "4.5.2",
"font-awesome": "4.7.0",
@@ -33,9 +32,8 @@
"lazyload-js": "1.0.0",
"moment": "2.10.6",
"ng-file-upload": "12.2.13",
"npm": "^6.4.1",
"signalr": "2.3.0",
"tinymce": "4.7.13",
"tinymce": "4.8.3",
"typeahead.js": "0.10.5",
"underscore": "1.9.1"
},
@@ -1,407 +1,156 @@
angular.module("umbraco.directives")
.directive('gridRte', function (tinyMceService, stylesheetResource, angularHelper, assetsService, $q, $timeout, eventsService) {
.directive('gridRte', function (tinyMceService, angularHelper, assetsService, $q, $timeout, eventsService) {
return {
scope: {
uniqueId: '=',
value: '=',
onClick: '&',
onFocus: '&',
onBlur: '&',
configuration:"=",
onMediaPickerClick: "=",
onEmbedClick: "=",
onMacroPickerClick: "=",
onLinkPickerClick: "="
configuration: "="
},
template: "<textarea ng-model=\"value\" rows=\"10\" class=\"mceNoEditor\" style=\"overflow:hidden\" id=\"{{uniqueId}}\"></textarea>",
templateUrl: 'views/components/grid/grid-rte.html',
replace: true,
link: function (scope, element, attrs) {
var initTiny = function () {
//TODO: A lot of the code below should be shared between the grid rte and the normal rte
//we always fetch the default one, and then override parts with our own
tinyMceService.configuration().then(function (tinyMceConfig) {
var promises = [];
//queue file loading
if (typeof (tinymce) === "undefined") {
promises.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", scope));
}
var toolbar = ["code", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "umbembeddialog"];
if (scope.configuration && scope.configuration.toolbar) {
toolbar = scope.configuration.toolbar;
}
//config value from general tinymce.config file
var validElements = tinyMceConfig.validElements;
var fallbackStyles = [{title: "Page header", block: "h2"}, {title: "Section header", block: "h3"}, {title: "Paragraph header", block: "h4"}, {title: "Normal", block: "p"}, {title: "Quote", block: "blockquote"}, {title: "Code", block: "code"}];
//stores a reference to the editor
var tinyMceEditor = null;
//These are absolutely required in order for the macros to render inline
//we put these as extended elements because they get merged on top of the normal allowed elements by tiny mce
var extendedValidElements = "@[id|class|style],-div[id|dir|class|align|style],ins[datetime|cite],-ul[class|style],-li[class|style],-h1[id|dir|class|align|style],-h2[id|dir|class|align|style],-h3[id|dir|class|align|style],-h4[id|dir|class|align|style],-h5[id|dir|class|align|style],-h6[id|style|dir|class|align],span[id|class|style]";
promises.push(tinyMceService.getTinyMceEditorConfig({
htmlId: scope.uniqueId,
stylesheets: scope.configuration ? scope.configuration.stylesheets : null,
toolbar: toolbar
}));
var invalidElements = tinyMceConfig.inValidElements;
var plugins = _.map(tinyMceConfig.plugins, function (plugin) {
if (plugin.useOnFrontend) {
return plugin.name;
}
}).join(" ") + " autoresize";
// pin toolbar to top of screen if we have focus and it scrolls off the screen
function pinToolbar() {
tinyMceService.pinToolbar(tinyMceEditor);
}
//config value on the data type
var toolbar = ["code", "styleselect", "bold", "italic", "alignleft", "aligncenter", "alignright", "bullist", "numlist", "link", "umbmediapicker", "umbembeddialog"].join(" | ");
var stylesheets = [];
// unpin toolbar to top of screen
function unpinToolbar() {
tinyMceService.unpinToolbar(tinyMceEditor);
}
var styleFormats = [];
var requests = [];
$q.all(promises).then(function (result) {
//queue file loading
if (typeof (tinymce) === "undefined") {
requests.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", scope));
}
var tinyMceEditorConfig = result[promises.length - 1];
tinyMceEditorConfig.setup = function (editor) {
if(scope.configuration && scope.configuration.toolbar){
toolbar = scope.configuration.toolbar.join(' | ');
}
//set the reference
tinyMceEditor = editor;
//initialize the standard editor functionality for Umbraco
tinyMceService.initializeEditor({
editor: editor,
value: scope.value,
currentForm: angularHelper.getCurrentForm(scope)
});
if(scope.configuration && scope.configuration.stylesheets){
angular.forEach(scope.configuration.stylesheets, function(stylesheet, key){
//custom initialization for this editor within the grid
editor.on('init', function (e) {
stylesheets.push(Umbraco.Sys.ServerVariables.umbracoSettings.cssPath + "/" + stylesheet + ".css");
requests.push(stylesheetResource.getRulesByName(stylesheet).then(function (rules) {
angular.forEach(rules, function (rule) {
var r = {};
var split = "";
r.title = rule.name;
if (rule.selector[0] === ".") {
r.inline = "span";
r.classes = rule.selector.substring(1);
}else if (rule.selector[0] === "#") {
//Even though this will render in the style drop down, it will not actually be applied
// to the elements, don't think TinyMCE even supports this and it doesn't really make much sense
// since only one element can have one id.
r.inline = "span";
r.attributes = { id: rule.selector.substring(1) };
}else if (rule.selector[0] !== "." && rule.selector.indexOf(".") > -1) {
split = rule.selector.split(".");
r.block = split[0];
r.classes = rule.selector.substring(rule.selector.indexOf(".") + 1).replace(".", " ");
}else if (rule.selector[0] !== "#" && rule.selector.indexOf("#") > -1) {
split = rule.selector.split("#");
r.block = split[0];
r.classes = rule.selector.substring(rule.selector.indexOf("#") + 1);
}else {
r.block = rule.selector;
}
styleFormats.push(r);
});
}));
});
}else{
stylesheets.push("views/propertyeditors/grid/config/grid.default.rtestyles.css");
styleFormats = fallbackStyles;
}
//force overflow to hidden to prevent no needed scroll
editor.getBody().style.overflow = "hidden";
//stores a reference to the editor
var tinyMceEditor = null;
$q.all(requests).then(function () {
var uniqueId = scope.uniqueId;
//create a baseline Config to exten upon
var baseLineConfigObj = {
mode: "exact",
skin: "umbraco",
plugins: plugins,
valid_elements: validElements,
invalid_elements: invalidElements,
extended_valid_elements: extendedValidElements,
menubar: false,
statusbar: false,
relative_urls: false,
toolbar: toolbar,
content_css: stylesheets,
style_formats: styleFormats,
autoresize_bottom_margin: 0,
//see http://archive.tinymce.com/wiki.php/Configuration:cache_suffix
cache_suffix: "?umb__rnd=" + Umbraco.Sys.ServerVariables.application.cacheBuster
};
if (tinyMceConfig.customConfig) {
//if there is some custom config, we need to see if the string value of each item might actually be json and if so, we need to
// convert it to json instead of having it as a string since this is what tinymce requires
for (var i in tinyMceConfig.customConfig) {
var val = tinyMceConfig.customConfig[i];
if (val) {
val = val.toString().trim();
if (val.detectIsJson()) {
try {
tinyMceConfig.customConfig[i] = JSON.parse(val);
//now we need to check if this custom config key is defined in our baseline, if it is we don't want to
//overwrite the baseline config item if it is an array, we want to concat the items in the array, otherwise
//if it's an object it will overwrite the baseline
if (angular.isArray(baseLineConfigObj[i]) && angular.isArray(tinyMceConfig.customConfig[i])) {
//concat it and below this concat'd array will overwrite the baseline in angular.extend
tinyMceConfig.customConfig[i] = baseLineConfigObj[i].concat(tinyMceConfig.customConfig[i]);
}
}
catch (e) {
//cannot parse, we'll just leave it
}
}
}
if (val === "true") {
tinyMceConfig.customConfig[i] = true;
}
if (val === "false") {
tinyMceConfig.customConfig[i] = false;
}
$timeout(function () {
if (scope.value === null) {
editor.focus();
}
angular.extend(baseLineConfigObj, tinyMceConfig.customConfig);
}
//set all the things that user configs should not be able to override
baseLineConfigObj.elements = uniqueId;
baseLineConfigObj.setup = function (editor) {
//set the reference
tinyMceEditor = editor;
//enable browser based spell checking
editor.on('init', function (e) {
editor.getBody().setAttribute('spellcheck', true);
//force overflow to hidden to prevent no needed scroll
editor.getBody().style.overflow = "hidden";
$timeout(function(){
if(scope.value === null){
editor.focus();
}
}, 400);
});
// pin toolbar to top of screen if we have focus and it scrolls off the screen
var pinToolbar = function () {
var _toolbar = $(editor.editorContainer).find(".mce-toolbar");
var toolbarHeight = _toolbar.height();
var _tinyMce = $(editor.editorContainer);
var tinyMceRect = _tinyMce[0].getBoundingClientRect();
var tinyMceTop = tinyMceRect.top;
var tinyMceBottom = tinyMceRect.bottom;
var tinyMceWidth = tinyMceRect.width;
var _tinyMceEditArea = _tinyMce.find(".mce-edit-area");
// set padding in top of mce so the content does not "jump" up
_tinyMceEditArea.css("padding-top", toolbarHeight);
if (tinyMceTop < 160 && ((160 + toolbarHeight) < tinyMceBottom)) {
_toolbar
.css("visibility", "visible")
.css("position", "fixed")
.css("top", "160px")
.css("margin-top", "0")
.css("width", tinyMceWidth);
} else {
_toolbar
.css("visibility", "visible")
.css("position", "absolute")
.css("top", "auto")
.css("margin-top", "0")
.css("width", tinyMceWidth);
}
};
// unpin toolbar to top of screen
var unpinToolbar = function() {
var _toolbar = $(editor.editorContainer).find(".mce-toolbar");
var _tinyMce = $(editor.editorContainer);
var _tinyMceEditArea = _tinyMce.find(".mce-edit-area");
// reset padding in top of mce so the content does not "jump" up
_tinyMceEditArea.css("padding-top", "0");
_toolbar.css("position", "static");
};
//when we leave the editor (maybe)
editor.on('blur', function (e) {
editor.save();
angularHelper.safeApply(scope, function () {
scope.value = editor.getContent();
var _toolbar = $(editor.editorContainer)
.find(".mce-toolbar");
if(scope.onBlur){
scope.onBlur();
}
unpinToolbar();
$('.umb-panel-body').off('scroll', pinToolbar);
});
});
// Focus on editor
editor.on('focus', function (e) {
angularHelper.safeApply(scope, function () {
if(scope.onFocus){
scope.onFocus();
}
pinToolbar();
$('.umb-panel-body').on('scroll', pinToolbar);
});
});
// Click on editor
editor.on('click', function (e) {
angularHelper.safeApply(scope, function () {
if(scope.onClick){
scope.onClick();
}
pinToolbar();
$('.umb-panel-body').on('scroll', pinToolbar);
});
});
//when buttons modify content
editor.on('ExecCommand', function (e) {
editor.save();
angularHelper.safeApply(scope, function () {
scope.value = editor.getContent();
});
});
// Update model on keypress
editor.on('KeyUp', function (e) {
editor.save();
angularHelper.safeApply(scope, function () {
scope.value = editor.getContent();
});
});
// Update model on change, i.e. copy/pasted text, plugins altering content
editor.on('SetContent', function (e) {
if (!e.initial) {
editor.save();
angularHelper.safeApply(scope, function () {
scope.value = editor.getContent();
});
}
});
editor.on('ObjectResized', function (e) {
var qs = "?width=" + e.width + "&height=" + e.height;
var srcAttr = $(e.target).attr("src");
var path = srcAttr.split("?")[0];
$(e.target).attr("data-mce-src", path + qs);
});
//Create the insert link plugin
tinyMceService.createLinkPicker(editor, scope, function(currentTarget, anchorElement){
if(scope.onLinkPickerClick) {
scope.onLinkPickerClick(editor, currentTarget, anchorElement);
}
});
//Create the insert media plugin
tinyMceService.createMediaPicker(editor, scope, function(currentTarget, userData){
if(scope.onMediaPickerClick) {
scope.onMediaPickerClick(editor, currentTarget, userData);
}
});
//Create the embedded plugin
tinyMceService.createInsertEmbeddedMedia(editor, scope, function(){
if(scope.onEmbedClick) {
scope.onEmbedClick(editor);
}
});
//Create the insert macro plugin
tinyMceService.createInsertMacro(editor, scope, function(dialogData){
if(scope.onMacroPickerClick) {
scope.onMacroPickerClick(editor, dialogData);
}
});
};
/** Loads in the editor */
function loadTinyMce() {
//we need to add a timeout here, to force a redraw so TinyMCE can find
//the elements needed
$timeout(function () {
tinymce.DOM.events.domLoaded = true;
tinymce.init(baseLineConfigObj);
}, 150, false);
}
loadTinyMce();
//here we declare a special method which will be called whenever the value has changed from the server
//this is instead of doing a watch on the model.value = faster
//scope.model.onValueChanged = function (newVal, oldVal) {
// //update the display val again if it has changed from the server;
// tinyMceEditor.setContent(newVal, { format: 'raw' });
// //we need to manually fire this event since it is only ever fired based on loading from the DOM, this
// // is required for our plugins listening to this event to execute
// tinyMceEditor.fire('LoadContent', null);
//};
var tabShownListener = eventsService.on("app.tabChange", function (e, args) {
var tabId = args.id;
var myTabId = element.closest(".umb-tab-pane").attr("rel");
if (String(tabId) === myTabId) {
//the tab has been shown, trigger the mceAutoResize (as it could have timed out before the tab was shown)
if (tinyMceEditor !== undefined && tinyMceEditor != null) {
tinyMceEditor.execCommand('mceAutoResize', false, null, null);
}
}
});
//listen for formSubmitting event (the result is callback used to remove the event subscription)
var formSubmittingListener = scope.$on("formSubmitting", function () {
//TODO: Here we should parse out the macro rendered content so we can save on a lot of bytes in data xfer
// we do parse it out on the server side but would be nice to do that on the client side before as well.
scope.value = tinyMceEditor ? tinyMceEditor.getContent() : null;
});
//when the element is disposed we need to unsubscribe!
// NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom
// element might still be there even after the modal has been hidden.
scope.$on('$destroy', function () {
formSubmittingListener();
eventsService.unsubscribe(tabShownListener);
if (tinyMceEditor !== undefined && tinyMceEditor != null) {
tinyMceEditor.destroy()
}
});
}, 400);
});
//TODO: Perhaps we should pin the toolbar for the rte always, regardless of if it's in the grid or not?
// this would mean moving this code into the tinyMceService.initializeEditor
//when we leave the editor (maybe)
editor.on('blur', function (e) {
angularHelper.safeApply(scope, function () {
unpinToolbar();
$('.umb-panel-body').off('scroll', pinToolbar);
});
});
// Focus on editor
editor.on('focus', function (e) {
angularHelper.safeApply(scope, function () {
pinToolbar();
$('.umb-panel-body').on('scroll', pinToolbar);
});
});
// Click on editor
editor.on('click', function (e) {
angularHelper.safeApply(scope, function () {
pinToolbar();
$('.umb-panel-body').on('scroll', pinToolbar);
});
});
};
/** Loads in the editor */
function loadTinyMce() {
//we need to add a timeout here, to force a redraw so TinyMCE can find
//the elements needed
$timeout(function () {
tinymce.DOM.events.domLoaded = true;
tinymce.init(tinyMceEditorConfig);
}, 150, false);
}
loadTinyMce();
//TODO: This should probably be in place for all RTE, not just for the grid, which means
// this code can live in tinyMceService.initializeEditor
var tabShownListener = eventsService.on("app.tabChange", function (e, args) {
var tabId = args.id;
var myTabId = element.closest(".umb-tab-pane").attr("rel");
if (String(tabId) === myTabId) {
//the tab has been shown, trigger the mceAutoResize (as it could have timed out before the tab was shown)
if (tinyMceEditor !== undefined && tinyMceEditor != null) {
tinyMceEditor.execCommand('mceAutoResize', false, null, null);
}
}
});
};
//listen for formSubmitting event (the result is callback used to remove the event subscription)
var formSubmittingListener = scope.$on("formSubmitting", function () {
scope.value = tinyMceEditor ? tinyMceEditor.getContent() : null;
});
initTiny();
//when the element is disposed we need to unsubscribe!
// NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom
// element might still be there even after the modal has been hidden.
scope.$on('$destroy', function () {
formSubmittingListener();
eventsService.unsubscribe(tabShownListener);
//ensure we unbind this in case the blur doesn't fire above
$('.umb-panel-body').off('scroll', pinToolbar);
if (tinyMceEditor !== undefined && tinyMceEditor != null) {
tinyMceEditor.destroy()
}
});
});
}
};
File diff suppressed because one or more lines are too long
@@ -23,7 +23,7 @@
* </pre>
**/
function contentResource($q, $http, $routeParams, umbDataFormatter, umbRequestHelper) {
function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
/** internal method process the saving of data and post processing the result */
function saveContentItem(content, action, files, restApiUrl, showNotifications) {
@@ -607,10 +607,7 @@ function contentResource($q, $http, $routeParams, umbDataFormatter, umbRequestHe
else if (options.orderDirection === "desc") {
options.orderDirection = "Descending";
}
if (!options.cultureName) {
// must send a culture to the content API to handle variant data correctly
options.cultureName = $routeParams.mculture;
}
//converts the value to a js bool
function toBool(v) {
if (angular.isNumber(v)) {
@@ -6,7 +6,7 @@
* @description
* Some angular helper/extension methods
*/
function angularHelper($log, $q) {
function angularHelper($q) {
return {
/**
@@ -13,7 +13,7 @@
* Section navigation and search, and maintain their state for the entire application lifetime
*
*/
function navigationService($rootScope, $routeParams, $location, $q, $timeout, $injector, eventsService, umbModelMapper, treeService, appState) {
function navigationService($routeParams, $location, $q, $timeout, $injector, eventsService, umbModelMapper, treeService, appState) {
//the promise that will be resolved when the navigation is ready
var navReadyPromise = $q.defer();
@@ -311,7 +311,6 @@ function navigationService($rootScope, $routeParams, $location, $q, $timeout, $i
* @param {String} args.tree the tree alias to sync to
* @param {Array} args.path the path to sync the tree to
* @param {Boolean} args.forceReload optional, specifies whether to force reload the node data from the server even if it already exists in the tree currently
* @param {Boolean} args.activate optional, specifies whether to set the synced node to be the active node, this will default to true if not specified
*/
syncTree: function (args) {
if (!args) {
@@ -332,6 +331,8 @@ function navigationService($rootScope, $routeParams, $location, $q, $timeout, $i
/**
Internal method that should ONLY be used by the legacy API wrapper, the legacy API used to
have to set an active tree and then sync, the new API does this in one method by using syncTree
TODO: Delete this if not required
*/
_syncPath: function(path, forceReload) {
return navReadyPromise.promise.then(function () {
File diff suppressed because it is too large Load Diff
@@ -113,16 +113,6 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
return treeInitPromise.promise;
}
//TODO: Remove this, this is not healthy
// Put the navigation service on this scope so we can use it's methods/properties in the view.
// IMPORTANT: all properties assigned to this scope are generally available on the scope object on dialogs since
// when we create a dialog we pass in this scope to be used for the dialog's scope instead of creating a new one.
$scope.nav = navigationService;
// TODO: Remove this, this is not healthy
// it is less than ideal to be passing in the navigationController scope to something else to be used as it's scope,
// this is going to lead to problems/confusion. I really don't think passing scope's around is very good practice.
$rootScope.nav = navigationService;
//set up our scope vars
$scope.showContextMenuDialog = false;
$scope.showContextMenu = false;
@@ -147,7 +137,8 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
navigationService.showSearch();
});
$scope.selectedId = navigationService.currentId;
////TODO: remove this it's not a thing
//$scope.selectedId = navigationService.currentId;
var evts = [];
@@ -180,7 +171,7 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
}
}));
//Listen for section state changes
//Listen for tree state changes
evts.push(eventsService.on("appState.treeState.changed", function (e, args) {
if (args.key === "currentRootNode") {
@@ -197,15 +188,18 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar
//Listen for section state changes
evts.push(eventsService.on("appState.sectionState.changed", function (e, args) {
//section changed
if (args.key === "currentSection" && $scope.currentSection != args.value) {
$scope.currentSection = args.value;
//load the tree
configureTreeAndLanguages();
$scope.treeApi.load({ section: $scope.currentSection, customTreeParams: $scope.customTreeParams, cacheKey: $scope.treeCacheKey });
//before loading the main tree we need to ensure that the nav is ready
navigationService.waitForNavReady().then(() => {
$scope.currentSection = args.value;
//load the tree
configureTreeAndLanguages();
$scope.treeApi.load({ section: $scope.currentSection, customTreeParams: $scope.customTreeParams, cacheKey: $scope.treeCacheKey });
});
}
//show/hide search results
if (args.key === "showSearchResults") {
$scope.showSearchResults = args.value;
@@ -57,6 +57,7 @@
// Application wide styles (refactor is WIP)
@import "application/grid.less";
@import "rte.less";
@import "application/shadows.less";
@import "application/animations.less";
@@ -102,44 +102,6 @@
}
}
/* CODEMIRROR DATATYPE */
div.umb-codeeditor {
border: 1px solid @gray-8;
}
div.umb-codeeditor .umb-el-wrap {
padding: 0;
}
div.umb-codeeditor .umb-btn-toolbar {
padding: 0;
margin: 0;
border-bottom: @gray-8 1px solid;
background: @gray-10;
}
//
// RTE
// --------------------------------------------------
.umb-rte {
position: relative;
.-loading {
position: absolute;
}
}
.mce-tinymce{border: 1px solid @gray-8 !important; border-radius: 0 !important;}
.mce-panel{background: @gray-10 !important; border-color: @gray-8 !important;}
.mce-btn-group, .mce-btn{border: none !important; background: none !important;}
.mce-ico{font-size: 12px !important; color: @gray-1 !important;}
/* Special case to support helviticons for the tiny mce button controls */
.mce-ico.mce-i-custom[class^="icon-"],
.mce-ico.mce-i-custom[class*=" icon-"] {
font-family: icomoon;
font-size:16px !important;
}
/* pre-value editor */
.rte-editor-preval .control-group .controls > div > label .mce-ico { line-height: 20px; }
//
@@ -0,0 +1,77 @@
// Styles for the RTE, the whole stylesheet is used in Tiny and these are specific to it's content
// -------------------------
.umb-rte {
position: relative;
.-loading {
position: absolute;
}
}
.umb-rte .mce-tinymce {
box-shadow: none;
}
.umb-rte .umb-rte-editor{
min-height: 100px;
}
.umb-rte .mce-content-body {
background-color: @white;
line-height: 1.5em;
border: 1px solid @gray-8;
padding:10px;
}
/* loader for macro loading in tinymce*/
.umb-rte .mce-content-body .umb-macro-holder.loading {
background: url(img/loader.gif) right no-repeat;
background-size: 18px;
background-position-x: 99%;
}
.umb-rte .mce-container {
box-sizing: border-box;
}
/* make sure the menu wraps */
.umb-rte .mce-top-part.mce-container div {
white-space: normal;
}
.umb-rte .mce-tinymce .mce-edit-area {
border: 1px solid @gray-8 !important;
border-radius: 0px !important;
}
/*
.mce-panel {
background: @gray-10 !important;
border-color: @gray-8 !important;
}
.mce-btn-group, .mce-btn {
border: none !important;
background: none !important;
}
*/
.mce-ico {
font-size: 12px !important;
/*color: @gray-1 !important;*/
}
/* Special case to support helviticons for the tiny mce button controls */
.mce-ico.mce-i-custom[class^="icon-"],
.mce-ico.mce-i-custom[class*=" icon-"] {
font-family: icomoon;
font-size: 16px !important;
}
/* pre-value editor */
.rte-editor-preval .control-group .controls > div > label .mce-ico {
line-height: 20px;
}
@@ -0,0 +1,3 @@
<div class="umb-rte">
<div id="{{uniqueId}}"></div>
</div>
@@ -1,7 +1,7 @@
<ul class="umb-tree" ng-class="{'hide-options': hideoptions === 'true'}">
<li ng-if="!tree.root.containsGroups">
<div class="umb-tree-root" data-element="tree-root" ng-class="getNodeCssClass(tree.root)" ng-hide="hideheader" on-right-click="altSelect(tree.root, $event)">
<div class="umb-tree-root" data-element="tree-root" ng-class="getNodeCssClass(tree.root)" ng-hide="hideheader === 'true'" on-right-click="altSelect(tree.root, $event)">
<h5>
<a ng-href="#/{{section}}" ng-click="select(tree.root, $event)" class="umb-tree-root-link" data-element="tree-root-link">
<i ng-if="enablecheckboxes === 'true'" ng-class="selectEnabledNodeClass(tree.root)"></i>
@@ -25,7 +25,8 @@
<!-- REPEAT for each group in the tree -->
<li ng-if="tree.root.containsGroups"
ng-repeat="group in tree.root.children">
<div class="umb-tree-root" data-element="tree-root" ng-class="getNodeCssClass(group)" ng-hide="hideheader" on-right-click="altSelect(group, $event)">
<div class="umb-tree-root" data-element="tree-root" ng-class="getNodeCssClass(group)" ng-hide="hideheader === 'true'" on-right-click="altSelect(group, $event)">
<h5>
<a ng-href="#/{{section}}" ng-click="select(group, $event)" class="umb-tree-root-link" data-element="tree-root-link">
<i ng-if="enablecheckboxes === 'true'" ng-class="selectEnabledNodeClass(group)"></i>
@@ -48,7 +48,9 @@
contentResource.sort(args)
.then(function(){
navigationService.syncTree({ tree: "content", path: $scope.currentNode.path, forceReload: true, activate: false });
navigationService.syncTree({ tree: "content", path: $scope.currentNode.path, forceReload: true })
.then(() => navigationService.reloadNode($scope.currentNode));
vm.saveButtonState = "success";
}, function(error) {
vm.error = error;
@@ -48,7 +48,9 @@
mediaResource.sort(args)
.then(function(){
navigationService.syncTree({ tree: "media", path: $scope.currentNode.path, forceReload: true, activate: false });
navigationService.syncTree({ tree: "media", path: $scope.currentNode.path, forceReload: true })
.then(() => navigationService.reloadNode($scope.currentNode));
vm.saveButtonState = "success";
}, function(error) {
vm.error = error;
@@ -84,4 +86,4 @@
}
angular.module("umbraco").controller("Umbraco.Editors.Media.SortController", MediaSortController);
})();
})();
@@ -1,15 +0,0 @@
body.mce-content-body {
background: transparent !important;
overflow-x:hidden !important;
padding-bottom: 10px !important;
/*margin:0px;*/
}
p {
margin: 0 0 10px;
}
.button {
display: inline-block;
border-radius:4px;
}
@@ -1,75 +1,8 @@
(function() {
"use strict";
function GridRichTextEditorController($scope, tinyMceService, macroService, editorState, editorService) {
function GridRichTextEditorController() {
var vm = this;
vm.openLinkPicker = openLinkPicker;
vm.openMediaPicker = openMediaPicker;
vm.openMacroPicker = openMacroPicker;
vm.openEmbed = openEmbed;
function openLinkPicker(editor, currentTarget, anchorElement) {
var linkPicker = {
currentTarget: currentTarget,
anchors: tinyMceService.getAnchorNames(JSON.stringify(editorState.current.properties)),
submit: function(model) {
tinyMceService.insertLinkInEditor(editor, model.target, anchorElement);
editorService.close();
},
close: function() {
editorService.close();
}
};
editorService.linkPicker(linkPicker);
}
function openMediaPicker(editor, currentTarget, userData) {
var mediaPicker = {
currentTarget: currentTarget,
onlyImages: true,
showDetails: true,
startNodeId: userData.startMediaIds.length !== 1 ? -1 : userData.startMediaIds[0],
submit: function(model) {
tinyMceService.insertMediaInEditor(editor, model.selectedImages[0]);
editorService.close();
},
close: function() {
editorService.close();
}
};
editorService.mediaPicker(mediaPicker);
}
function openEmbed(editor) {
var embed = {
submit: function(model) {
tinyMceService.insertEmbeddedMediaInEditor(editor, model.embed.preview);
editorService.close();
},
close: function() {
editorService.close();
}
};
editorService.embed(embed);
}
function openMacroPicker(editor, dialogData) {
var macroPicker = {
dialogData: dialogData,
submit: function(model) {
var macroObject = macroService.collectValueData(model.selectedMacro, model.macroParams, dialogData.renderingEngine);
tinyMceService.insertMacroInEditor(editor, macroObject, $scope);
editorService.close();
},
close: function() {
editorService.close();
}
};
editorService.macroPicker(macroPicker);
}
}
angular.module("umbraco").controller("Umbraco.PropertyEditors.Grid.RichTextEditorController", GridRichTextEditorController);
@@ -1,14 +1,9 @@
<div ng-controller="Umbraco.PropertyEditors.Grid.RichTextEditorController as vm">
<div
grid-rte
<grid-rte
configuration="model.config.rte"
value="control.value"
unique-id="control.$uniqueId"
on-link-picker-click="vm.openLinkPicker"
on-media-picker-click="vm.openMediaPicker"
on-embed-click="vm.openEmbed"
on-macro-picker-click="vm.openMacroPicker">
</div>
unique-id="control.$uniqueId">
</grid-rte>
</div>
@@ -0,0 +1,61 @@
(function () {
"use strict";
function CodeEditorController($scope, localizationService) {
var vm = this;
vm.submit = submit;
vm.close = close;
vm.aceOption = {};
vm.aceOption = {
mode: "razor",
theme: "chrome",
showPrintMargin: false,
advanced: {
fontSize: "14px",
enableSnippets: false, //The Razor mode snippets are awful (Need a way to override these)
enableBasicAutocompletion: true,
enableLiveAutocompletion: false
},
onLoad: function(aceEditor) {
vm.aceEditor = aceEditor;
}
}
vm.template = {};
vm.template.content = $scope.model.content;
//////////
function onInit() {
// set default title
if(!$scope.model.title) {
// TODO localize
$scope.model.title = "Edit source code";
}
}
function submit(model) {
// refresh the model
model.content = vm.aceEditor.getValue();
if($scope.model.submit) {
$scope.model.submit(model);
}
}
function close() {
if($scope.model.close) {
$scope.model.close();
}
}
onInit();
}
angular.module("umbraco").controller("Umbraco.PropertyEditors.RTECodeEditorController", CodeEditorController);
})();
@@ -0,0 +1,41 @@
<div ng-controller="Umbraco.PropertyEditors.RTECodeEditorController as vm">
<umb-editor-view>
<umb-editor-header
name="model.title"
name-locked="true"
hide-alias="true"
hide-icon="true"
hide-description="true">
</umb-editor-header>
<umb-editor-container>
<div
data-element="code-editor"
auto-scale="85"
umb-ace-editor="vm.aceOption"
model="vm.template.content">
</div>
</umb-editor-container>
<umb-editor-footer>
<umb-editor-footer-content-right>
<umb-button
type="button"
button-style="link"
label-key="general_close"
action="vm.close()">
</umb-button>
<umb-button
type="button"
button-style="success"
label-key="general_submit"
action="vm.submit(model)">
</umb-button>
</umb-editor-footer-content-right>
</umb-editor-footer>
</umb-editor-view>
</div>
@@ -1,380 +1,69 @@
angular.module("umbraco")
.controller("Umbraco.PropertyEditors.RTEController",
function ($scope, $q, $locale, assetsService, $timeout, tinyMceService, angularHelper, stylesheetResource, macroService, editorState, editorService) {
function ($scope, $q, assetsService, $timeout, tinyMceService, angularHelper, editorService, macroService, editorState) {
$scope.isLoading = true;
//TODO: A lot of the code below should be shared between the grid rte and the normal rte
//To id the html textarea we need to use the datetime ticks because we can have multiple rte's per a single property alias
// because now we have to support having 2x (maybe more at some stage) content editors being displayed at once. This is because
// we have this mini content editor panel that can be launched with MNTP.
var d = new Date();
var n = d.getTime();
$scope.textAreaHtmlId = $scope.model.alias + "_" + n + "_rte";
$scope.isLoading = true;
var alreadyDirty = false;
function syncContent(editor){
editor.save();
//stop watching before we update the value
stopWatch();
angularHelper.safeApply($scope, function () {
$scope.model.value = editor.getContent();
});
//re-watch the value
startWatch(editor);
if (!alreadyDirty) {
//make the form dirty manually so that the track changes works, setting our model doesn't trigger
// the angular bits because tinymce replaces the textarea.
var currForm = angularHelper.getCurrentForm($scope);
currForm.$setDirty();
alreadyDirty = true;
}
}
var unwatch = null;
/**
* Starts a watch on the model value so that we can update TinyMCE if the model changes behind the scenes or from the server
* @param {any} editor
*/
function startWatch(editor) {
unwatch = $scope.$watch("model.value", function (newVal, oldVal) {
if (newVal !== oldVal) {
//update the display val again if it has changed from the server;
//uses an empty string in the editor when the value is null
editor.setContent(newVal || "", { format: 'raw' });
//we need to manually fire this event since it is only ever fired based on loading from the DOM, this
// is required for our plugins listening to this event to execute
editor.fire('LoadContent', null);
}
});
}
/** Stops the watch on model.value which is done anytime we are manually updating the model.value */
function stopWatch() {
if (unwatch) {
unwatch();
}
}
tinyMceService.configuration().then(function (tinyMceConfig) {
//config value from general tinymce.config file
var validElements = tinyMceConfig.validElements;
//These are absolutely required in order for the macros to render inline
//we put these as extended elements because they get merged on top of the normal allowed elements by tiny mce
var extendedValidElements = "@[id|class|style],-div[id|dir|class|align|style],ins[datetime|cite],-ul[class|style],-li[class|style],span[id|class|style]";
var invalidElements = tinyMceConfig.inValidElements;
var plugins = _.map(tinyMceConfig.plugins, function (plugin) {
if (plugin.useOnFrontend) {
return plugin.name;
}
}).join(" ");
//To id the html textarea we need to use the datetime ticks because we can have multiple rte's per a single property alias
// because now we have to support having 2x (maybe more at some stage) content editors being displayed at once. This is because
// we have this mini content editor panel that can be launched with MNTP.
var d = new Date();
var n = d.getTime();
$scope.textAreaHtmlId = $scope.model.alias + "_" + n + "_rte";
var editorConfig = $scope.model.config.editor;
if (!editorConfig || angular.isString(editorConfig)) {
editorConfig = tinyMceService.defaultPrevalues();
}
//config value on the data type
var toolbar = editorConfig.toolbar.join(" | ");
var stylesheets = [];
var styleFormats = [];
var requests = [];
var promises = [];
if (!editorConfig.maxImageSize && editorConfig.maxImageSize != 0) {
editorConfig.maxImageSize = tinyMceService.defaultPrevalues().maxImageSize;
}
//queue file loading
if (typeof tinymce === "undefined") { // Don't reload tinymce if already loaded
requests.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", $scope));
promises.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", $scope));
}
//queue rules loading
angular.forEach(editorConfig.stylesheets, function (val, key) {
stylesheets.push(Umbraco.Sys.ServerVariables.umbracoSettings.cssPath + "/" + val + ".css?" + new Date().getTime());
requests.push(stylesheetResource.getRulesByName(val).then(function (rules) {
angular.forEach(rules, function (rule) {
var r = {};
r.title = rule.name;
if (rule.selector[0] == ".") {
r.inline = "span";
r.classes = rule.selector.substring(1);
}
else if (rule.selector[0] == "#") {
r.inline = "span";
r.attributes = { id: rule.selector.substring(1) };
}
else if (rule.selector[0] != "." && rule.selector.indexOf(".") > -1) {
var split = rule.selector.split(".");
r.block = split[0];
r.classes = rule.selector.substring(rule.selector.indexOf(".") + 1).replace(".", " ");
}
else if (rule.selector[0] != "#" && rule.selector.indexOf("#") > -1) {
var split = rule.selector.split("#");
r.block = split[0];
r.classes = rule.selector.substring(rule.selector.indexOf("#") + 1);
}
else {
r.block = rule.selector;
}
styleFormats.push(r);
});
}));
});
//stores a reference to the editor
var tinyMceEditor = null;
// these languages are available for localization
var availableLanguages = [
'da',
'de',
'en',
'en_us',
'fi',
'fr',
'he',
'it',
'ja',
'nl',
'no',
'pl',
'pt',
'ru',
'sv',
'zh'
];
//define fallback language
var language = 'en_us';
//get locale from angular and match tinymce format. Angular localization is always in the format of ru-ru, de-de, en-gb, etc.
//wheras tinymce is in the format of ru, de, en, en_us, etc.
var localeId = $locale.id.replace('-', '_');
//try matching the language using full locale format
var languageMatch = _.find(availableLanguages, function(o) { return o === localeId; });
//if no matches, try matching using only the language
if (languageMatch === undefined) {
var localeParts = localeId.split('_');
languageMatch = _.find(availableLanguages, function(o) { return o === localeParts[0]; });
}
//if a match was found - set the language
if (languageMatch !== undefined) {
language = languageMatch;
}
promises.push(tinyMceService.getTinyMceEditorConfig({
htmlId: $scope.textAreaHtmlId,
stylesheets: editorConfig.stylesheets,
toolbar: editorConfig.toolbar,
mode: editorConfig.mode
}));
//wait for queue to end
$q.all(requests).then(function () {
$q.all(promises).then(function (result) {
var standardConfig = result[promises.length - 1];
//create a baseline Config to exten upon
var baseLineConfigObj = {
mode: "exact",
skin: "umbraco",
plugins: plugins,
valid_elements: validElements,
invalid_elements: invalidElements,
extended_valid_elements: extendedValidElements,
menubar: false,
statusbar: false,
relative_urls: false,
height: editorConfig.dimensions.height,
width: editorConfig.dimensions.width,
maxImageSize: editorConfig.maxImageSize,
toolbar: toolbar,
content_css: stylesheets,
style_formats: styleFormats,
language: language,
//see http://archive.tinymce.com/wiki.php/Configuration:cache_suffix
cache_suffix: "?umb__rnd=" + Umbraco.Sys.ServerVariables.application.cacheBuster
maxImageSize: editorConfig.maxImageSize
};
if (tinyMceConfig.customConfig) {
angular.extend(baseLineConfigObj, standardConfig);
//if there is some custom config, we need to see if the string value of each item might actually be json and if so, we need to
// convert it to json instead of having it as a string since this is what tinymce requires
for (var i in tinyMceConfig.customConfig) {
var val = tinyMceConfig.customConfig[i];
if (val) {
val = val.toString().trim();
if (val.detectIsJson()) {
try {
tinyMceConfig.customConfig[i] = JSON.parse(val);
//now we need to check if this custom config key is defined in our baseline, if it is we don't want to
//overwrite the baseline config item if it is an array, we want to concat the items in the array, otherwise
//if it's an object it will overwrite the baseline
if (angular.isArray(baseLineConfigObj[i]) && angular.isArray(tinyMceConfig.customConfig[i])) {
//concat it and below this concat'd array will overwrite the baseline in angular.extend
tinyMceConfig.customConfig[i] = baseLineConfigObj[i].concat(tinyMceConfig.customConfig[i]);
}
}
catch (e) {
//cannot parse, we'll just leave it
}
}
if (val === "true") {
tinyMceConfig.customConfig[i] = true;
}
if (val === "false") {
tinyMceConfig.customConfig[i] = false;
}
}
}
angular.extend(baseLineConfigObj, tinyMceConfig.customConfig);
}
//set all the things that user configs should not be able to override
baseLineConfigObj.elements = $scope.textAreaHtmlId; //this is the exact textarea id to replace!
baseLineConfigObj.setup = function (editor) {
//set the reference
tinyMceEditor = editor;
//enable browser based spell checking
editor.on('init', function (e) {
editor.getBody().setAttribute('spellcheck', true);
//initialize the standard editor functionality for Umbraco
tinyMceService.initializeEditor({
editor: editor,
value: $scope.model.value,
currentForm: angularHelper.getCurrentForm($scope)
});
//We need to listen on multiple things here because of the nature of tinymce, it doesn't
//fire events when you think!
//The change event doesn't fire when content changes, only when cursor points are changed and undo points
//are created. the blur event doesn't fire if you insert content into the editor with a button and then
//press save.
//We have a couple of options, one is to do a set timeout and check for isDirty on the editor, or we can
//listen to both change and blur and also on our own 'saving' event. I think this will be best because a
//timer might end up using unwanted cpu and we'd still have to listen to our saving event in case they clicked
//save before the timeout elapsed.
//TODO: We need to re-enable something like this to ensure the track changes is working with tinymce
// so we can detect if the form is dirty or not, Per has some better events to use as this one triggers
// even if you just enter/exit with mouse cursuor which doesn't really mean it's changed.
// see: http://issues.umbraco.org/issue/U4-4485
//var alreadyDirty = false;
//editor.on('change', function (e) {
// angularHelper.safeApply($scope, function () {
// $scope.model.value = editor.getContent();
// if (!alreadyDirty) {
// //make the form dirty manually so that the track changes works, setting our model doesn't trigger
// // the angular bits because tinymce replaces the textarea.
// var currForm = angularHelper.getCurrentForm($scope);
// currForm.$setDirty();
// alreadyDirty = true;
// }
// });
//});
//when we leave the editor (maybe)
editor.on('blur', function (e) {
editor.save();
angularHelper.safeApply($scope, function () {
$scope.model.value = editor.getContent();
});
});
//when buttons modify content
editor.on('ExecCommand', function (e) {
syncContent(editor);
});
// Update model on keypress
editor.on('KeyUp', function (e) {
syncContent(editor);
});
// Update model on change, i.e. copy/pasted text, plugins altering content
editor.on('SetContent', function (e) {
if (!e.initial) {
syncContent(editor);
}
});
editor.on('ObjectResized', function (e) {
var qs = "?width=" + e.width + "&height=" + e.height + "&mode=max";
var srcAttr = $(e.target).attr("src");
var path = srcAttr.split("?")[0];
$(e.target).attr("data-mce-src", path + qs);
syncContent(editor);
});
tinyMceService.createLinkPicker(editor, $scope, function(currentTarget, anchorElement) {
var linkPicker = {
currentTarget: currentTarget,
anchors: tinyMceService.getAnchorNames(JSON.stringify(editorState.current.properties)),
submit: function(model) {
tinyMceService.insertLinkInEditor(editor, model.target, anchorElement);
editorService.close();
},
close: function() {
editorService.close();
}
};
editorService.linkPicker(linkPicker);
});
//Create the insert media plugin
tinyMceService.createMediaPicker(editor, $scope, function(currentTarget, userData){
var mediaPicker = {
currentTarget: currentTarget,
onlyImages: true,
showDetails: true,
disableFolderSelect: true,
startNodeId: userData.startMediaIds.length !== 1 ? -1 : userData.startMediaIds[0],
startNodeIsVirtual: userData.startMediaIds.length !== 1,
submit: function(model) {
tinyMceService.insertMediaInEditor(editor, model.selectedImages[0]);
editorService.close();
},
close: function() {
editorService.close();
}
};
editorService.mediaPicker(mediaPicker);
});
//Create the embedded plugin
tinyMceService.createInsertEmbeddedMedia(editor, $scope, function() {
var embed = {
submit: function(model) {
tinyMceService.insertEmbeddedMediaInEditor(editor, model.embed.preview);
editorService.close();
},
close: function() {
editorService.close();
}
};
editorService.embed(embed);
});
//Create the insert macro plugin
tinyMceService.createInsertMacro(editor, $scope, function(dialogData) {
var macroPicker = {
dialogData: dialogData,
submit: function(model) {
var macroObject = macroService.collectValueData(model.selectedMacro, model.macroParams, dialogData.renderingEngine);
tinyMceService.insertMacroInEditor(editor, macroObject, $scope);
editorService.close();
},
close: function() {
editorService.close();
}
};
editorService.macroPicker(macroPicker);
});
startWatch(editor);
};
/** Loads in the editor */
function loadTinyMce() {
@@ -390,11 +79,9 @@ angular.module("umbraco")
}
loadTinyMce();
//listen for formSubmitting event (the result is callback used to remove the event subscription)
var unsubscribe = $scope.$on("formSubmitting", function () {
//TODO: Here we should parse out the macro rendered content so we can save on a lot of bytes in data xfer
// we do parse it out on the server side but would be nice to do that on the client side before as well.
if (tinyMceEditor !== undefined && tinyMceEditor != null && !$scope.isLoading) {
$scope.model.value = tinyMceEditor.getContent();
}
@@ -405,12 +92,11 @@ angular.module("umbraco")
// element might still be there even after the modal has been hidden.
$scope.$on('$destroy', function () {
unsubscribe();
if (tinyMceEditor !== undefined && tinyMceEditor != null) {
tinyMceEditor.destroy()
}
if (tinyMceEditor !== undefined && tinyMceEditor != null) {
tinyMceEditor.destroy()
}
});
});
});
});
});
});
@@ -1,9 +1,6 @@
<div ng-controller="Umbraco.PropertyEditors.RTEController" class="umb-property-editor umb-rte">
<div class="-loading" ng-if="isLoading"><localize key="general_loading">Loading</localize>...</div>
<textarea
ng-style="{ visibility : isLoading ? 'hidden' : 'visible'}"
ng-model="model.value"
rows="10"
id="{{textAreaHtmlId}}">
</textarea>
<div ng-style="{ visibility : isLoading ? 'hidden' : 'visible'}"
id="{{textAreaHtmlId}}" class="umb-rte-editor"></div>
</div>
@@ -19,13 +19,16 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
if (!$scope.model.value.maxImageSize && $scope.model.value.maxImageSize != 0) {
$scope.model.value.maxImageSize = cfg.maxImageSize;
}
if (!$scope.model.value.mode) {
$scope.model.value.mode = "classic";
}
tinyMceService.configuration().then(function(config){
$scope.tinyMceConfig = config;
// extend commands with properties for font-icon and if it is a custom command
$scope.tinyMceConfig.commands = _.map($scope.tinyMceConfig.commands, function (obj) {
var icon = getFontIcon(obj.frontEndCommand);
var icon = getFontIcon(obj.alias);
return angular.extend(obj, {
fontIcon: icon.name,
isCustom: icon.isCustom
@@ -46,17 +49,17 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
};
$scope.selectCommand = function(command){
var index = $scope.model.value.toolbar.indexOf(command.frontEndCommand);
var index = $scope.model.value.toolbar.indexOf(command.alias);
if(command.selected && index === -1){
$scope.model.value.toolbar.push(command.frontEndCommand);
$scope.model.value.toolbar.push(command.alias);
}else if(index >= 0){
$scope.model.value.toolbar.splice(index, 1);
}
};
$scope.selectStylesheet = function (css) {
var index = $scope.model.value.stylesheets.indexOf(css.name);
if(css.selected && index === -1){
@@ -65,13 +68,13 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
$scope.model.value.stylesheets.splice(index, 1);
}
};
// map properties for specific commands
function getFontIcon(alias) {
var icon = { name: alias, isCustom: false };
switch (alias) {
case "codemirror":
case "ace":
icon.name = "code";
icon.isCustom = false;
break;
@@ -107,8 +110,8 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController",
var unsubscribe = $scope.$on("formSubmitting", function (ev, args) {
var commands = _.where($scope.tinyMceConfig.commands, {selected: true});
$scope.model.value.toolbar = _.pluck(commands, "frontEndCommand");
$scope.model.value.toolbar = _.pluck(commands, "alias");
});
// when the scope is destroyed we need to unsubscribe
@@ -1,32 +1,32 @@
<div ng-controller="Umbraco.PrevalueEditors.RteController" class="rte-editor-preval">
<umb-control-group label="Toolbar" hide-label="false">
<div ng-repeat="cmd in tinyMceConfig.commands">
<umb-control-group label="Toolbar" hide-label="false">
<div ng-repeat="cmd in tinyMceConfig.commands">
<label>
<input type="checkbox"
ng-checked="selected(cmd, cmd.frontEndCommand, model.value.toolbar)"
ng-model="cmd.selected"
ng-change="selectCommand(cmd)" />
<input type="checkbox"
ng-checked="selected(cmd, cmd.alias, model.value.toolbar)"
ng-model="cmd.selected"
ng-change="selectCommand(cmd)" />
<!--<img ng-src="{{cmd.icon}}" />-->
<!--<img ng-src="{{cmd.icon}}" />-->
<i class="mce-ico" ng-class="(cmd.isCustom ? ' mce-i-custom ' : ' mce-i-') + cmd.fontIcon"></i>
{{cmd.name}}
</label>
</div>
</umb-control-group>
</div>
</umb-control-group>
<umb-control-group label="Stylesheets" hide-label="0">
<div ng-repeat="css in stylesheets">
<umb-control-group label="Stylesheets" hide-label="0">
<div ng-repeat="css in stylesheets">
<label>
<input type="checkbox"
ng-checked="selected(css, css.name, model.value.stylesheets)"
ng-model="css.selected"
ng-change="selectStylesheet(css)" />
{{css.name}}
<input type="checkbox"
ng-checked="selected(css, css.name, model.value.stylesheets)"
ng-model="css.selected"
ng-change="selectStylesheet(css)" />
{{css.name}}
</label>
</div>
</umb-control-group>
</div>
</umb-control-group>
<umb-control-group label="Dimensions" description="Width x Height">
<div class="vertical-align-items">
@@ -38,6 +38,15 @@
<umb-control-group label="Maximum size for inserted images" description="0 to disable resizing">
<div class="vertical-align-items">
<input type="number" min="0" ng-model="model.value.maxImageSize" class="umb-property-editor-tiny" placeholder="Width/Height" /> Pixels
</div>
</div>
</umb-control-group>
</div>
<umb-control-group label="Mode" description="Select mode">
<div class="vertical-align-items">
<select ng-model="model.value.mode">
<option value="classic">Classic</option> <!-- Theme:modern & inline:false-->
<option value="distraction-free">Distraction Free</option> <!-- Theme:inlite & inline:true -->
</select>
</div>
</umb-control-group>
</div>
@@ -1,245 +1,55 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Any changes to this file requires the application (umbraco) to restart -->
<!-- This can be done by touching the web.config or recycling the application pool -->
<?xml version="1.0" encoding="utf-8"?>
<tinymceConfig>
<commands>
<command>
<umbracoAlias>code</umbracoAlias>
<name>Code</name>
<icon>images/editor/code.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="code">code</tinyMceCommand>
<priority>1</priority>
</command>
<command>
<umbracoAlias>codemirror</umbracoAlias>
<name>Code mirror</name>
<icon>images/editor/code.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="codemirror">codemirror</tinyMceCommand>
<priority>1</priority>
</command>
<command>
<umbracoAlias>removeformat</umbracoAlias>
<name>Remove format</name>
<icon>images/editor/removeformat.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="removeformat">removeformat</tinyMceCommand>
<priority>2</priority>
</command>
<command>
<umbracoAlias>undo</umbracoAlias>
<name>Undo</name>
<icon>images/editor/undo.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="undo">undo</tinyMceCommand>
<priority>11</priority>
</command>
<command>
<umbracoAlias>redo</umbracoAlias>
<name>Redo</name>
<icon>images/editor/redo.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="redo">redo</tinyMceCommand>
<priority>12</priority>
</command>
<command>
<umbracoAlias>cut</umbracoAlias>
<name>Cut</name>
<icon>images/editor/cut.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="cut">cut</tinyMceCommand>
<priority>13</priority>
</command>
<command>
<umbracoAlias>copy</umbracoAlias>
<name>Copy</name>
<icon>images/editor/copy.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="copy">copy</tinyMceCommand>
<priority>14</priority>
</command>
<command>
<umbracoAlias>paste</umbracoAlias>
<name>Paste</name>
<icon>images/editor/paste.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="paste">paste</tinyMceCommand>
<priority>15</priority>
</command>
<command>
<umbracoAlias>styleselect</umbracoAlias>
<name>Style select</name>
<icon>images/editor/showStyles.png</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="styleselect">styleselect</tinyMceCommand>
<priority>20</priority>
</command>
<command>
<umbracoAlias>bold</umbracoAlias>
<name>Bold</name>
<icon>images/editor/bold.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="bold">bold</tinyMceCommand>
<priority>21</priority>
</command>
<command>
<umbracoAlias>italic</umbracoAlias>
<name>Italic</name>
<icon>images/editor/italic.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="italic">italic</tinyMceCommand>
<priority>22</priority>
</command>
<command>
<umbracoAlias>underline</umbracoAlias>
<name>Underline</name>
<icon>images/editor/underline.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="underline">underline</tinyMceCommand>
<priority>23</priority>
</command>
<command>
<umbracoAlias>strikethrough</umbracoAlias>
<name>Strikethrough</name>
<icon>images/editor/strikethrough.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="strikethrough">strikethrough</tinyMceCommand>
<priority>24</priority>
</command>
<command>
<umbracoAlias>justifyleft</umbracoAlias>
<name>Justify left</name>
<icon>images/editor/justifyleft.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="alignleft">justifyleft</tinyMceCommand>
<priority>31</priority>
</command>
<command>
<umbracoAlias>justifycenter</umbracoAlias>
<name>Justify center</name>
<icon>images/editor/justifycenter.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="aligncenter">justifycenter</tinyMceCommand>
<priority>32</priority>
</command>
<command>
<umbracoAlias>justifyright</umbracoAlias>
<name>Justify right</name>
<icon>images/editor/justifyright.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="alignright">justifyright</tinyMceCommand>
<priority>33</priority>
</command>
<command>
<umbracoAlias>justifyfull</umbracoAlias>
<name>Justify full</name>
<icon>images/editor/justifyfull.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="alignjustify">alignjustify</tinyMceCommand>
<priority>34</priority>
</command>
<command>
<umbracoAlias>bullist</umbracoAlias>
<name>Bullet list</name>
<icon>images/editor/bullist.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="bullist">bullist</tinyMceCommand>
<priority>41</priority>
</command>
<command>
<umbracoAlias>numlist</umbracoAlias>
<name>Numbered list</name>
<icon>images/editor/numlist.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="numlist">numlist</tinyMceCommand>
<priority>42</priority>
</command>
<command>
<umbracoAlias>outdent</umbracoAlias>
<name>Decrease indent</name>
<icon>images/editor/outdent.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="outdent">outdent</tinyMceCommand>
<priority>43</priority>
</command>
<command>
<umbracoAlias>indent</umbracoAlias>
<name>Increase indent</name>
<icon>images/editor/indent.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="indent">indent</tinyMceCommand>
<priority>44</priority>
</command>
<command>
<umbracoAlias>mceLink</umbracoAlias>
<name>Insert/edit link</name>
<icon>images/editor/link.gif</icon>
<tinyMceCommand value="" userInterface="true" frontendCommand="link">link</tinyMceCommand>
<priority>51</priority>
</command>
<command>
<umbracoAlias>unlink</umbracoAlias>
<name>Remove link</name>
<icon>images/editor/unLink.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="unlink">unlink</tinyMceCommand>
<priority>52</priority>
</command>
<command>
<umbracoAlias>mceInsertAnchor</umbracoAlias>
<name>Anchor</name>
<icon>images/editor/anchor.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="anchor">anchor</tinyMceCommand>
<priority>53</priority>
</command>
<command>
<umbracoAlias>mceImage</umbracoAlias>
<name>Image</name>
<icon>images/editor/image.gif</icon>
<tinyMceCommand value="" userInterface="true" frontendCommand="umbmediapicker">image</tinyMceCommand>
<priority>61</priority>
</command>
<command>
<umbracoAlias>umbracomacro</umbracoAlias>
<name>Macro</name>
<icon>images/editor/insMacro.gif</icon>
<tinyMceCommand value="" userInterface="true" frontendCommand="umbmacro">umbracomacro</tinyMceCommand>
<priority>62</priority>
</command>
<command>
<umbracoAlias>mceInsertTable</umbracoAlias>
<name>Table</name>
<icon>images/editor/table.gif</icon>
<tinyMceCommand value="" userInterface="true" frontendCommand="table">table</tinyMceCommand>
<priority>63</priority>
</command>
<command>
<umbracoAlias>umbracoembed</umbracoAlias>
<name>Embed</name>
<icon>images/editor/media.gif</icon>
<tinyMceCommand value="" userInterface="true" frontendCommand="umbembeddialog">umbracoembed</tinyMceCommand>
<priority>66</priority>
</command>
<command>
<umbracoAlias>inserthorizontalrule</umbracoAlias>
<name>Horizontal rule</name>
<icon>images/editor/hr.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="hr">hr</tinyMceCommand>
<priority>71</priority>
</command>
<command>
<umbracoAlias>subscript</umbracoAlias>
<name>Subscript</name>
<icon>images/editor/sub.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="subscript">subscript</tinyMceCommand>
<priority>72</priority>
</command>
<command>
<umbracoAlias>superscript</umbracoAlias>
<name>Superscript</name>
<icon>images/editor/sup.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="superscript">superscript</tinyMceCommand>
<priority>73</priority>
</command>
<command>
<umbracoAlias>mceCharMap</umbracoAlias>
<name>Character map</name>
<icon>images/editor/charmap.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="charmap">charmap</tinyMceCommand>
<priority>74</priority>
</command>
</commands>
<plugins>
<plugin loadOnFrontend="true">code</plugin>
<plugin loadOnFrontend="true">codemirror</plugin>
<plugin loadOnFrontend="true">paste</plugin>
<plugin loadOnFrontend="true">anchor</plugin>
<plugin loadOnFrontend="true">charmap</plugin>
<plugin loadOnFrontend="true">table</plugin>
<plugin loadOnFrontend="true">lists</plugin>
<plugin loadOnFrontend="true">hr</plugin>
</plugins>
<validElements>
<![CDATA[+a[id|style|rel|data-id|data-udi|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|
<commands>
<command alias="ace" name="Source code editor" mode="Insert" />
<command alias="removeformat" name="Remove format" mode="Selection"/>
<command alias="undo" name="Undo" mode="Insert" />
<command alias="redo" name="Redo" mode="Insert" />
<command alias="cut" name="Cut" mode="Selection"/>
<command alias="copy" name="Copy" mode="Selection"/>
<command alias="paste" name="Paste" mode="All" />
<command alias="styleselect" name="Style select" mode="Insert" />
<command alias="bold" name="Bold" mode="Selection" />
<command alias="italic" name="Italic" mode="Selection" />
<command alias="underline" name="Underline" mode="Selection" />
<command alias="strikethrough" name="Strikethrough" mode="Selection" />
<command alias="alignleft" name="Justify left" mode="Selection" />
<command alias="aligncenter" name="Justify center" mode="Selection" />
<command alias="alignright" name="Justify right" mode="Selection" />
<command alias="alignjustify" name="Justify full" mode="Selection" />
<command alias="bullist" name="Bullet list" mode="All" />
<command alias="numlist" name="Numbered list" mode="All" />
<command alias="outdent" name="Decrease indent" mode="All" />
<command alias="indent" name="Increase indent" mode="All" />
<command alias="link" name="Insert/edit link" mode="All" />
<command alias="unlink" name="Remove link" mode="Selection" />
<command alias="anchor" name="Anchor" mode="Selection" />
<command alias="umbmediapicker" name="Image" mode="Insert" />
<command alias="umbmacro" name="Macro" mode="All" />
<command alias="table" name="Table" mode="Insert" />
<command alias="umbembeddialog" name="Embed" mode="Insert" />
<command alias="hr" name="Horizontal rule" mode="Insert" />
<command alias="subscript" name="Subscript" mode="Selection" />
<command alias="superscript" name="Superscript" mode="Selection" />
<command alias="charmap" name="Character map" mode="Insert" />
<command alias="rtl" name="Right to left" mode="Selection" />
<command alias="ltr" name="Left to right" mode="Selection" />
</commands>
<plugins>
<plugin>paste</plugin>
<plugin>anchor</plugin>
<plugin>charmap</plugin>
<plugin>table</plugin>
<plugin>lists</plugin>
<plugin>advlist</plugin>
<plugin>hr</plugin>
<plugin>autolink</plugin>
<plugin>directionality</plugin>
<plugin>tabfocus</plugin>
<plugin>searchreplace</plugin>
</plugins>
<validElements>
<![CDATA[+a[id|style|rel|data-id|data-udi|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|
ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],
-strike[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|reversed|start|style|type],-ul[class|style],-li[class|style],br[class],
img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align|umbracoorgwidth|umbracoorgheight|onresize|onresizestart|onresizeend|rel|data-id],
@@ -251,24 +61,12 @@ thead[id|class],tfoot[id|class],#td[id|lang|dir|class|colspan|rowspan|width|heig
-h3[id|dir|class|align|style],-h4[id|dir|class|align|style],-h5[id|dir|class|align|style],-h6[id|style|dir|class|align|style],hr[class|style],small[class|style],
dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang],object[class|id|width|height|codebase|*],
param[name|value|_value|class],embed[type|width|height|src|class|*],map[name|class],area[shape|coords|href|alt|target|class],bdo[class],button[class],iframe[*]]]>
</validElements>
<invalidElements>font</invalidElements>
</validElements>
<invalidElements>font</invalidElements>
<!-- this area is for custom config settings that should be added during TinyMCE initialization -->
<customConfig>
<!-- <config key="myKey">mySetting</config>-->
<config key="entity_encoding">raw</config>
<config key="codemirror">
{
"indentOnInit": false,
"path": "../../../../lib/codemirror",
"config": {
},
"jsFiles": [
],
"cssFiles": [
]
}
</config>
</customConfig>
</tinymceConfig>
<!-- this area is for custom config settings that should be added during TinyMCE initialization -->
<customConfig>
<!-- <config key="myKey">mySetting</config>-->
<config key="entity_encoding">raw</config>
</customConfig>
</tinymceConfig>
+58 -260
View File
@@ -1,245 +1,55 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Any changes to this file requires the application (umbraco) to restart -->
<!-- This can be done by touching the web.config or recycling the application pool -->
<?xml version="1.0" encoding="utf-8"?>
<tinymceConfig>
<commands>
<command>
<umbracoAlias>code</umbracoAlias>
<name>Code</name>
<icon>images/editor/code.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="code">code</tinyMceCommand>
<priority>1</priority>
</command>
<command>
<umbracoAlias>codemirror</umbracoAlias>
<name>Code mirror</name>
<icon>images/editor/code.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="codemirror">codemirror</tinyMceCommand>
<priority>1</priority>
</command>
<command>
<umbracoAlias>removeformat</umbracoAlias>
<name>Remove format</name>
<icon>images/editor/removeformat.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="removeformat">removeformat</tinyMceCommand>
<priority>2</priority>
</command>
<command>
<umbracoAlias>undo</umbracoAlias>
<name>Undo</name>
<icon>images/editor/undo.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="undo">undo</tinyMceCommand>
<priority>11</priority>
</command>
<command>
<umbracoAlias>redo</umbracoAlias>
<name>Redo</name>
<icon>images/editor/redo.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="redo">redo</tinyMceCommand>
<priority>12</priority>
</command>
<command>
<umbracoAlias>cut</umbracoAlias>
<name>Cut</name>
<icon>images/editor/cut.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="cut">cut</tinyMceCommand>
<priority>13</priority>
</command>
<command>
<umbracoAlias>copy</umbracoAlias>
<name>Copy</name>
<icon>images/editor/copy.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="copy">copy</tinyMceCommand>
<priority>14</priority>
</command>
<command>
<umbracoAlias>paste</umbracoAlias>
<name>Paste</name>
<icon>images/editor/paste.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="paste">paste</tinyMceCommand>
<priority>15</priority>
</command>
<command>
<umbracoAlias>styleselect</umbracoAlias>
<name>Style select</name>
<icon>images/editor/showStyles.png</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="styleselect">styleselect</tinyMceCommand>
<priority>20</priority>
</command>
<command>
<umbracoAlias>bold</umbracoAlias>
<name>Bold</name>
<icon>images/editor/bold.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="bold">bold</tinyMceCommand>
<priority>21</priority>
</command>
<command>
<umbracoAlias>italic</umbracoAlias>
<name>Italic</name>
<icon>images/editor/italic.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="italic">italic</tinyMceCommand>
<priority>22</priority>
</command>
<command>
<umbracoAlias>underline</umbracoAlias>
<name>Underline</name>
<icon>images/editor/underline.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="underline">underline</tinyMceCommand>
<priority>23</priority>
</command>
<command>
<umbracoAlias>strikethrough</umbracoAlias>
<name>Strikethrough</name>
<icon>images/editor/strikethrough.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="strikethrough">strikethrough</tinyMceCommand>
<priority>24</priority>
</command>
<command>
<umbracoAlias>justifyleft</umbracoAlias>
<name>Justify left</name>
<icon>images/editor/justifyleft.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="alignleft">justifyleft</tinyMceCommand>
<priority>31</priority>
</command>
<command>
<umbracoAlias>justifycenter</umbracoAlias>
<name>Justify center</name>
<icon>images/editor/justifycenter.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="aligncenter">justifycenter</tinyMceCommand>
<priority>32</priority>
</command>
<command>
<umbracoAlias>justifyright</umbracoAlias>
<name>Justify right</name>
<icon>images/editor/justifyright.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="alignright">justifyright</tinyMceCommand>
<priority>33</priority>
</command>
<command>
<umbracoAlias>justifyfull</umbracoAlias>
<name>Justify full</name>
<icon>images/editor/justifyfull.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="alignjustify">alignjustify</tinyMceCommand>
<priority>34</priority>
</command>
<command>
<umbracoAlias>bullist</umbracoAlias>
<name>Bullet list</name>
<icon>images/editor/bullist.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="bullist">bullist</tinyMceCommand>
<priority>41</priority>
</command>
<command>
<umbracoAlias>numlist</umbracoAlias>
<name>Numbered list</name>
<icon>images/editor/numlist.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="numlist">numlist</tinyMceCommand>
<priority>42</priority>
</command>
<command>
<umbracoAlias>outdent</umbracoAlias>
<name>Decrease indent</name>
<icon>images/editor/outdent.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="outdent">outdent</tinyMceCommand>
<priority>43</priority>
</command>
<command>
<umbracoAlias>indent</umbracoAlias>
<name>Increase indent</name>
<icon>images/editor/indent.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="indent">indent</tinyMceCommand>
<priority>44</priority>
</command>
<command>
<umbracoAlias>mceLink</umbracoAlias>
<name>Insert/edit link</name>
<icon>images/editor/link.gif</icon>
<tinyMceCommand value="" userInterface="true" frontendCommand="link">link</tinyMceCommand>
<priority>51</priority>
</command>
<command>
<umbracoAlias>unlink</umbracoAlias>
<name>Remove link</name>
<icon>images/editor/unLink.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="unlink">unlink</tinyMceCommand>
<priority>52</priority>
</command>
<command>
<umbracoAlias>mceInsertAnchor</umbracoAlias>
<name>Anchor</name>
<icon>images/editor/anchor.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="anchor">anchor</tinyMceCommand>
<priority>53</priority>
</command>
<command>
<umbracoAlias>mceImage</umbracoAlias>
<name>Image</name>
<icon>images/editor/image.gif</icon>
<tinyMceCommand value="" userInterface="true" frontendCommand="umbmediapicker">image</tinyMceCommand>
<priority>61</priority>
</command>
<command>
<umbracoAlias>umbracomacro</umbracoAlias>
<name>Macro</name>
<icon>images/editor/insMacro.gif</icon>
<tinyMceCommand value="" userInterface="true" frontendCommand="umbmacro">umbracomacro</tinyMceCommand>
<priority>62</priority>
</command>
<command>
<umbracoAlias>mceInsertTable</umbracoAlias>
<name>Table</name>
<icon>images/editor/table.gif</icon>
<tinyMceCommand value="" userInterface="true" frontendCommand="table">table</tinyMceCommand>
<priority>63</priority>
</command>
<command>
<umbracoAlias>umbracoembed</umbracoAlias>
<name>Embed</name>
<icon>images/editor/media.gif</icon>
<tinyMceCommand value="" userInterface="true" frontendCommand="umbembeddialog">umbracoembed</tinyMceCommand>
<priority>66</priority>
</command>
<command>
<umbracoAlias>inserthorizontalrule</umbracoAlias>
<name>Horizontal rule</name>
<icon>images/editor/hr.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="hr">hr</tinyMceCommand>
<priority>71</priority>
</command>
<command>
<umbracoAlias>subscript</umbracoAlias>
<name>Subscript</name>
<icon>images/editor/sub.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="subscript">subscript</tinyMceCommand>
<priority>72</priority>
</command>
<command>
<umbracoAlias>superscript</umbracoAlias>
<name>Superscript</name>
<icon>images/editor/sup.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="superscript">superscript</tinyMceCommand>
<priority>73</priority>
</command>
<command>
<umbracoAlias>mceCharMap</umbracoAlias>
<name>Character map</name>
<icon>images/editor/charmap.gif</icon>
<tinyMceCommand value="" userInterface="false" frontendCommand="charmap">charmap</tinyMceCommand>
<priority>74</priority>
</command>
</commands>
<plugins>
<plugin loadOnFrontend="true">code</plugin>
<plugin loadOnFrontend="true">codemirror</plugin>
<plugin loadOnFrontend="true">paste</plugin>
<plugin loadOnFrontend="true">anchor</plugin>
<plugin loadOnFrontend="true">charmap</plugin>
<plugin loadOnFrontend="true">table</plugin>
<plugin loadOnFrontend="true">lists</plugin>
<plugin loadOnFrontend="true">hr</plugin>
</plugins>
<validElements>
<![CDATA[+a[id|style|rel|data-id|data-udi|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|
<commands>
<command alias="ace" name="Source code editor" mode="Insert" />
<command alias="removeformat" name="Remove format" mode="Selection"/>
<command alias="undo" name="Undo" mode="Insert" />
<command alias="redo" name="Redo" mode="Insert" />
<command alias="cut" name="Cut" mode="Selection"/>
<command alias="copy" name="Copy" mode="Selection"/>
<command alias="paste" name="Paste" mode="All" />
<command alias="styleselect" name="Style select" mode="Insert" />
<command alias="bold" name="Bold" mode="Selection" />
<command alias="italic" name="Italic" mode="Selection" />
<command alias="underline" name="Underline" mode="Selection" />
<command alias="strikethrough" name="Strikethrough" mode="Selection" />
<command alias="alignleft" name="Justify left" mode="Selection" />
<command alias="aligncenter" name="Justify center" mode="Selection" />
<command alias="alignright" name="Justify right" mode="Selection" />
<command alias="alignjustify" name="Justify full" mode="Selection" />
<command alias="bullist" name="Bullet list" mode="All" />
<command alias="numlist" name="Numbered list" mode="All" />
<command alias="outdent" name="Decrease indent" mode="All" />
<command alias="indent" name="Increase indent" mode="All" />
<command alias="link" name="Insert/edit link" mode="All" />
<command alias="unlink" name="Remove link" mode="Selection" />
<command alias="anchor" name="Anchor" mode="Selection" />
<command alias="umbmediapicker" name="Image" mode="Insert" />
<command alias="umbmacro" name="Macro" mode="All" />
<command alias="table" name="Table" mode="Insert" />
<command alias="umbembeddialog" name="Embed" mode="Insert" />
<command alias="hr" name="Horizontal rule" mode="Insert" />
<command alias="subscript" name="Subscript" mode="Selection" />
<command alias="superscript" name="Superscript" mode="Selection" />
<command alias="charmap" name="Character map" mode="Insert" />
<command alias="rtl" name="Right to left" mode="Selection" />
<command alias="ltr" name="Left to right" mode="Selection" />
</commands>
<plugins>
<plugin>paste</plugin>
<plugin>anchor</plugin>
<plugin>charmap</plugin>
<plugin>table</plugin>
<plugin>lists</plugin>
<plugin>advlist</plugin>
<plugin>hr</plugin>
<plugin>autolink</plugin>
<plugin>directionality</plugin>
<plugin>tabfocus</plugin>
<plugin>searchreplace</plugin>
</plugins>
<validElements>
<![CDATA[+a[id|style|rel|data-id|data-udi|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|
ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],
-strike[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|reversed|start|style|type],-ul[class|style],-li[class|style],br[class],
img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align|umbracoorgwidth|umbracoorgheight|onresize|onresizestart|onresizeend|rel|data-id],
@@ -251,24 +61,12 @@ thead[id|class],tfoot[id|class],#td[id|lang|dir|class|colspan|rowspan|width|heig
-h3[id|dir|class|align|style],-h4[id|dir|class|align|style],-h5[id|dir|class|align|style],-h6[id|style|dir|class|align|style],hr[class|style],small[class|style],
dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang],object[class|id|width|height|codebase|*],
param[name|value|_value|class],embed[type|width|height|src|class|*],map[name|class],area[shape|coords|href|alt|target|class],bdo[class],button[class],iframe[*]]]>
</validElements>
<invalidElements>font</invalidElements>
</validElements>
<invalidElements>font</invalidElements>
<!-- this area is for custom config settings that should be added during TinyMCE initialization -->
<customConfig>
<!-- <config key="myKey">mySetting</config>-->
<config key="entity_encoding">raw</config>
<config key="codemirror">
{
"indentOnInit": false,
"path": "../../../../lib/codemirror",
"config": {
},
"jsFiles": [
],
"cssFiles": [
]
}
</config>
</customConfig>
<!-- this area is for custom config settings that should be added during TinyMCE initialization -->
<customConfig>
<!-- <config key="myKey">mySetting</config>-->
<config key="entity_encoding">raw</config>
</customConfig>
</tinymceConfig>
@@ -10,19 +10,13 @@ namespace Umbraco.Web.Editors
[PluginController("UmbracoApi")]
public class BackOfficeAssetsController : UmbracoAuthorizedJsonController
{
private readonly FileSystems _fileSystems;
public BackOfficeAssetsController(FileSystems fileSystems)
{
_fileSystems = fileSystems;
}
private readonly IFileSystem _jsLibFileSystem = new PhysicalFileSystem(SystemDirectories.Umbraco + IOHelper.DirSepChar + "lib");
[HttpGet]
public IEnumerable<string> GetSupportedMomentLocales()
{
const string momentLocaleFolder = "moment";
var fileSystem = _fileSystems.JavaScriptLibraryFileSystem;
var cultures = fileSystem.GetFiles(momentLocaleFolder, "*.js").ToList();
var cultures = _jsLibFileSystem.GetFiles(momentLocaleFolder, "*.js").ToList();
for (var i = 0; i < cultures.Count; i++)
{
cultures[i] = cultures[i]
@@ -252,7 +252,7 @@ namespace Umbraco.Web.Editors
break;
case Core.Constants.Trees.Stylesheets:
codeFileDisplay = Mapper.Map<Stylesheet, CodeFileDisplay>(new Stylesheet(string.Empty));
codeFileDisplay.VirtualPath = SystemDirectories.StyleSheets;
codeFileDisplay.VirtualPath = SystemDirectories.Css;
break;
default:
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Unsupported editortype"));
@@ -4,6 +4,8 @@ using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Umbraco.Web.Models.ContentEditing
{
@@ -12,29 +14,19 @@ namespace Umbraco.Web.Models.ContentEditing
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "icon")]
public string Icon { get; set; }
[DataMember(Name = "command")]
public string Command { get; set; }
[DataMember(Name = "alias")]
public string Alias { get; set; }
[DataMember(Name = "userInterface")]
public string UserInterface { get; set; }
[JsonConverter(typeof(StringEnumConverter))]
[DataMember(Name = "mode")]
public RichTextEditorCommandMode Mode { get; set; }
}
[DataMember(Name = "frontEndCommand")]
public string FrontEndCommand { get; set; }
[DataMember(Name = "value")]
public string Value { get; set; }
[DataMember(Name = "priority")]
public int Priority { get; set; }
[DataMember(Name = "isStylePicker")]
public bool IsStylePicker { get; set; }
public enum RichTextEditorCommandMode
{
Insert,
Selection,
All
}
}
@@ -12,8 +12,5 @@ namespace Umbraco.Web.Models.ContentEditing
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "useOnFrontend")]
public bool UseOnFrontend { get; set; }
}
}
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Xml;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Web.Editors;
using Umbraco.Web.Models.ContentEditing;
@@ -15,7 +16,7 @@ namespace Umbraco.Web.PropertyEditors
{
private static volatile bool _init;
private static readonly object Locker = new object();
private static readonly Dictionary<string, RichTextEditorCommand> Commands = new Dictionary<string,RichTextEditorCommand>();
private static readonly Dictionary<string, RichTextEditorCommand> Commands = new Dictionary<string, RichTextEditorCommand>();
private static readonly Dictionary<string, RichTextEditorPlugin> Plugins = new Dictionary<string, RichTextEditorPlugin>();
private static readonly Dictionary<string, string> ConfigOptions = new Dictionary<string, string>();
@@ -26,12 +27,14 @@ namespace Umbraco.Web.PropertyEditors
{
EnsureInit();
RichTextEditorConfiguration config = new RichTextEditorConfiguration();
config.Plugins = Plugins.Values;
config.Commands = Commands.Values;
config.ValidElements = _validElements;
config.InvalidElements = _invalidElements;
config.CustomConfig = ConfigOptions;
var config = new RichTextEditorConfiguration
{
Plugins = Plugins.Values,
Commands = Commands.Values,
ValidElements = _validElements,
InvalidElements = _invalidElements,
CustomConfig = ConfigOptions
};
return config;
}
@@ -51,28 +54,18 @@ namespace Umbraco.Web.PropertyEditors
foreach (XmlNode n in xd.DocumentElement.SelectNodes("//command"))
{
var alias = n.SelectSingleNode("./umbracoAlias").FirstChild.Value.ToLower();
bool isStyle = false;
if (n.Attributes.GetNamedItem("isStyle") != null)
isStyle = bool.Parse(n.Attributes.GetNamedItem("isStyle").Value);
var alias = n.AttributeValue<string>("alias").ToLower();
if (!Commands.ContainsKey(alias))
Commands.Add(
alias,
new RichTextEditorCommand()
{
IsStylePicker = isStyle,
Name = n.SelectSingleNode("./name") != null ? n.SelectSingleNode("./name").FirstChild.Value : alias,
Icon = n.SelectSingleNode("./icon").FirstChild.Value,
Command = n.SelectSingleNode("./tinyMceCommand").FirstChild.Value,
Alias = alias,
UserInterface = n.SelectSingleNode("./tinyMceCommand").Attributes.GetNamedItem("userInterface").Value,
FrontEndCommand = n.SelectSingleNode("./tinyMceCommand").Attributes.GetNamedItem("frontendCommand").Value,
Value = n.SelectSingleNode("./tinyMceCommand").Attributes.GetNamedItem("value").Value,
Priority = int.Parse(n.SelectSingleNode("./priority").FirstChild.Value)
}
);
alias,
new RichTextEditorCommand()
{
Name = n.AttributeValue<string>("name") ?? alias,
Alias = alias,
Mode = Enum<RichTextEditorCommandMode>.Parse(n.AttributeValue<string>("mode"), true)
}
);
}
@@ -80,16 +73,12 @@ namespace Umbraco.Web.PropertyEditors
{
if (!Plugins.ContainsKey(n.FirstChild.Value))
{
bool useOnFrontend = false;
if (n.Attributes.GetNamedItem("loadOnFrontend") != null)
useOnFrontend = bool.Parse(n.Attributes.GetNamedItem("loadOnFrontend").Value);
Plugins.Add(
n.FirstChild.Value.ToLower(),
new RichTextEditorPlugin()
{
Name = n.FirstChild.Value,
UseOnFrontend = useOnFrontend
});
}
}