Przeglądaj źródła

Merge branch 'master' of http://192.168.0.115:3000/4dkankan/laser_v1

xzw 4 lat temu
rodzic
commit
719bd1532c

Plik diff jest za duży
+ 1 - 0
21.6e35bf5486d7bec96c04.js


Plik diff jest za duży
+ 19 - 0
23.8641b8fc3d6165bb187f.js


+ 208 - 0
contents.css

@@ -0,0 +1,208 @@
+/*
+Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+*/
+
+body
+{
+	/* Font */
+	/* Emoji fonts are added to visualise them nicely in Internet Explorer. */
+	font-family: sans-serif, Arial, Verdana, "Trebuchet MS", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+	font-size: 12px;
+
+	/* Text color */
+	color: #333;
+
+	/* Remove the background color to make it transparent. */
+	background-color: #fff;
+
+	margin: 20px;
+}
+
+.cke_editable
+{
+	font-size: 13px;
+	line-height: 1.6;
+
+	/* Fix for missing scrollbars with RTL texts. (#10488) */
+	word-wrap: break-word;
+}
+
+blockquote
+{
+	font-style: italic;
+	font-family: Georgia, Times, "Times New Roman", serif;
+	padding: 2px 0;
+	border-style: solid;
+	border-color: #ccc;
+	border-width: 0;
+}
+
+.cke_contents_ltr blockquote
+{
+	padding-left: 20px;
+	padding-right: 8px;
+	border-left-width: 5px;
+}
+
+.cke_contents_rtl blockquote
+{
+	padding-left: 8px;
+	padding-right: 20px;
+	border-right-width: 5px;
+}
+
+a
+{
+	color: #0782C1;
+}
+
+ol,ul,dl
+{
+	/* IE7: reset rtl list margin. (#7334) */
+	*margin-right: 0px;
+	/* Preserved spaces for list items with text direction different than the list. (#6249,#8049)*/
+	padding: 0 40px;
+}
+
+h1,h2,h3,h4,h5,h6
+{
+	font-weight: normal;
+	line-height: 1.2;
+}
+
+hr
+{
+	border: 0px;
+	border-top: 1px solid #ccc;
+}
+
+img.right
+{
+	border: 1px solid #ccc;
+	float: right;
+	margin-left: 15px;
+	padding: 5px;
+}
+
+img.left
+{
+	border: 1px solid #ccc;
+	float: left;
+	margin-right: 15px;
+	padding: 5px;
+}
+
+pre
+{
+	white-space: pre-wrap; /* CSS 2.1 */
+	word-wrap: break-word; /* IE7 */
+	-moz-tab-size: 4;
+	tab-size: 4;
+}
+
+.marker
+{
+	background-color: Yellow;
+}
+
+span[lang]
+{
+	font-style: italic;
+}
+
+figure
+{
+	text-align: center;
+	outline: solid 1px #ccc;
+	background: rgba(0,0,0,0.05);
+	padding: 10px;
+	margin: 10px 20px;
+	display: inline-block;
+}
+
+figure > figcaption
+{
+	text-align: center;
+	display: block; /* For IE8 */
+}
+
+a > img {
+	padding: 1px;
+	margin: 1px;
+	border: none;
+	outline: 1px solid #0782C1;
+}
+
+/* Widget Styles */
+.code-featured
+{
+	border: 5px solid red;
+}
+
+.math-featured
+{
+	padding: 20px;
+	box-shadow: 0 0 2px rgba(200, 0, 0, 1);
+	background-color: rgba(255, 0, 0, 0.05);
+	margin: 10px;
+}
+
+.image-clean
+{
+	border: 0;
+	background: none;
+	padding: 0;
+}
+
+.image-clean > figcaption
+{
+	font-size: .9em;
+	text-align: right;
+}
+
+.image-grayscale
+{
+	background-color: white;
+	color: #666;
+}
+
+.image-grayscale img, img.image-grayscale
+{
+	filter: grayscale(100%);
+}
+
+.embed-240p
+{
+	max-width: 426px;
+	max-height: 240px;
+	margin:0 auto;
+}
+
+.embed-360p
+{
+	max-width: 640px;
+	max-height: 360px;
+	margin:0 auto;
+}
+
+.embed-480p
+{
+	max-width: 854px;
+	max-height: 480px;
+	margin:0 auto;
+}
+
+.embed-720p
+{
+	max-width: 1280px;
+	max-height: 720px;
+	margin:0 auto;
+}
+
+.embed-1080p
+{
+	max-width: 1920px;
+	max-height: 1080px;
+	margin:0 auto;
+}

+ 21 - 1
css/style.css

@@ -1142,4 +1142,24 @@ button[title="放大镜"].active:hover svg {
 
 /* left-panel .poi-extensions-box {
     overflow-x: hidden;
-} */
+} */
+
+.dropdown-menu {
+    border-top: 1px solid transparent !important;
+}
+
+.dropdown-menu .divider {
+    background-color: rgba(255, 255, 255, .4) !important;
+}
+
+.open>.dropdown-toggle.btn-default {
+    border-color: rgba(255, 255, 255, .4) !important;
+}
+
+.dropdown-toggle {
+    border-color: rgba(255, 255, 255, .4) !important;
+}
+
+.btn-file:hover {
+    background-color: #15BEC8 !important;
+}

BIN
dependencies/ckeditor_plugins/base64image/icons/base64image.png


+ 12 - 0
dependencies/ckeditor_plugins/base64image/lang/zh.js

@@ -0,0 +1,12 @@
+/*
+Translation from original CKEDITOR language files:
+Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("base64image","zh",{
+	"alt":"替代文字",
+	"lockRatio":"固定比例",
+	"vSpace":"VSpace",
+	"hSpace":"HSpace",
+	"border":"框線"
+});

+ 57 - 0
dependencies/ckeditor_plugins/base64image/plugin.js

@@ -0,0 +1,57 @@
+/*
+ * Base64Image Plugin for CKEditor (http://github.com/nmmf/base64image)
+ * Created by ALL-INKL.COM - Neue Medien M�nnich - 04. Feb 2014
+ * Licensed under the terms of GPL, LGPL and MPL licenses.
+ */
+CKEDITOR.plugins.add("base64image", {
+	lang 	: 	["af","ar","bg","bn","bs","ca","cs","cy","da","de","el","en","en-au","en-ca","en-gb","eo","es","et","eu","fa","fi","fo","fr","fr-ca","gl","gu","he","hi","hr","hu","id","is","it","ja","ka","km","ko","ku","lt","lv","mk","mn","ms","nb","nl","no","pl","pt","pt-br","ro","ru","si","sk","sl","sq","sr","sr-latn","sv","th","tr","ug","uk","vi","zh","zh-cn"],
+	requires: 	"dialog",
+	icons	:	"base64image",
+	hidpi	:	true,
+    init	: 	function(editor){
+					var pluginName = 'base64imageDialog';
+					
+					editor.ui.addButton("base64image", {
+						label: editor.lang.common.image,
+						command: pluginName,
+						toolbar: "insert"
+					});
+					CKEDITOR.dialog.add(pluginName, this.path+"dialogs/base64image.js");
+					
+					var allowed = 'img[alt,!src]{border-style,border-width,float,height,margin,margin-bottom,margin-left,margin-right,margin-top,width}',
+						required = 'img[alt,src]';
+					
+					editor.addCommand( pluginName, new CKEDITOR.dialogCommand( pluginName, {
+						allowedContent: allowed,
+						requiredContent: required,
+						contentTransformations: [
+							[ 'img{width}: sizeToStyle', 'img[width]: sizeToAttribute' ],
+							[ 'img{float}: alignmentToStyle', 'img[align]: alignmentToAttribute' ]
+						]
+					} ) );
+					editor.on("doubleclick", function(evt){
+						if(evt.data.element && !evt.data.element.isReadOnly() && evt.data.element.getName() === "img") {
+							evt.data.dialog = pluginName;
+							editor.getSelection().selectElement(evt.data.element);
+						}
+					});
+					if(editor.addMenuItem) {
+						editor.addMenuGroup("base64imageGroup");
+						editor.addMenuItem("base64imageItem", {
+							label: editor.lang.common.image,
+							icon: this.path+"icons/base64image.png",
+							command: pluginName,
+							group: "base64imageGroup"
+						});
+					}
+					if(editor.contextMenu) {
+						editor.contextMenu.addListener(function(element, selection) {
+							if(element && element.getName() === "img") {
+								editor.getSelection().selectElement(element);
+								return { base64imageItem: CKEDITOR.TRISTATE_ON };
+							}
+							return null;
+						});
+					}
+				}
+});

BIN
dependencies/ckeditor_plugins/insertsound/icons/insertsound.png


+ 23 - 0
dependencies/ckeditor_plugins/insertsound/plugin.js

@@ -0,0 +1,23 @@
+CKEDITOR.plugins.add( 'insertsound', {
+	icons: 'insertsound',
+	init: function( editor ) {
+		editor.addCommand( 'insertsound', new CKEDITOR.dialogCommand( 'insertsoundDialog', {
+			allowedContent: {
+				audio: {
+					attributes: 'controls'
+				},
+				source: {
+					attributes: '!src'
+				}
+			},
+			requiredContent: 'audio'
+		}));
+		editor.ui.addButton( 'insertsound', {
+			label: 'Insert audio',
+			command: 'insertsound',
+			toolbar: 'insert'
+		});
+		CKEDITOR.dialog.add( 'insertsoundDialog', this.path + 'dialogs/insertsound.js' );
+	}
+});
+

BIN
dependencies/ckeditor_plugins/youtube/images/icon.png


+ 24 - 0
dependencies/ckeditor_plugins/youtube/lang/zh.js

@@ -0,0 +1,24 @@
+CKEDITOR.plugins.setLang('youtube', 'zh', {
+    button: '嵌入 Youtube 影片',
+    title: '嵌入 Youtube 影片',
+    txtEmbed: '貼上嵌入碼',
+    txtUrl: '貼上 Youtube 影片 URL',
+    txtWidth: '寬',
+    txtHeight: '高',
+    txtResponsive: '使用自適應縮放模式 (忽略設定的長寬, 以寬為基準縮放)',
+    chkRelated: '影片結束時顯示建議影片',
+    txtStartAt: '開始時間 (ss or mm:ss or hh:mm:ss)',
+    chkPrivacy: '啟用加強隱私模式',
+    chkOlderCode: '使用舊的嵌入碼',
+    chkAutoplay: '自動播放',
+    chkControls: '显示播放器控件',
+    noCode: '必須輸入嵌入碼',
+    invalidEmbed: '錯誤的嵌入碼',
+    invalidUrl: '錯誤的URL',
+    or: '或',
+    noWidth: '必須設定寬',
+    invalidWidth: '寬設定錯誤',
+    noHeight: '必須設定高',
+    invalidHeight: '高設定錯誤',
+    invalidTime: '開始時間設定錯誤'
+});

+ 449 - 0
dependencies/ckeditor_plugins/youtube/plugin.js

@@ -0,0 +1,449 @@
+/*
+* Youtube Embed Plugin
+*
+* @author Jonnas Fonini <jonnasfonini@gmail.com>
+* @version 2.1.14
+*/
+(function () {
+	CKEDITOR.plugins.add('youtube', {
+		lang: [ 'en', 'bg', 'pt', 'pt-br', 'ja', 'hu', 'it', 'fr', 'tr', 'ru', 'de', 'ar', 'nl', 'pl', 'vi', 'zh', 'el', 'he', 'es', 'nb', 'nn', 'fi', 'et', 'sk', 'cs', 'ko', 'eu', 'uk'],
+		init: function (editor) {
+			editor.addCommand('youtube', new CKEDITOR.dialogCommand('youtube', {
+				allowedContent: 'div{*}(*); iframe{*}[!width,!height,!src,!frameborder,!allowfullscreen,!allow]; object param[*]; a[*]; img[*]'
+			}));
+
+			editor.ui.addButton('Youtube', {
+				label : editor.lang.youtube.button,
+				toolbar : 'insert',
+				command : 'youtube',
+				icon : this.path + 'images/icon.png'
+			});
+
+			CKEDITOR.dialog.add('youtube', function (instance) {
+				var video,
+					disabled = editor.config.youtube_disabled_fields || [];
+
+				return {
+					title : editor.lang.youtube.title,
+					minWidth : 510,
+					minHeight : 200,
+					onShow: function () {
+						for (var i = 0; i < disabled.length; i++) {
+							this.getContentElement('youtubePlugin', disabled[i]).disable();
+						}
+					},
+					contents :
+						[{
+							id : 'youtubePlugin',
+							expand : true,
+							elements :
+								[{
+									id : 'txtEmbed',
+									type : 'textarea',
+									label : editor.lang.youtube.txtEmbed,
+									onChange : function (api) {
+										handleEmbedChange(this, api);
+									},
+									onKeyUp : function (api) {
+										handleEmbedChange(this, api);
+									},
+									validate : function () {
+										if (this.isEnabled()) {
+											if (!this.getValue()) {
+												alert(editor.lang.youtube.noCode);
+												return false;
+											}
+											else
+											if (this.getValue().length === 0 || this.getValue().indexOf('//') === -1) {
+												alert(editor.lang.youtube.invalidEmbed);
+												return false;
+											}
+										}
+									}
+								},
+								{
+									type : 'html',
+									html : editor.lang.youtube.or + '<hr>'
+								},
+								{
+									type : 'hbox',
+									widths : [ '70%', '15%', '15%' ],
+									children :
+									[
+										{
+											id : 'txtUrl',
+											type : 'text',
+											label : editor.lang.youtube.txtUrl,
+											onChange : function (api) {
+												handleLinkChange(this, api);
+											},
+											onKeyUp : function (api) {
+												handleLinkChange(this, api);
+											},
+											validate : function () {
+												if (this.isEnabled()) {
+													if (!this.getValue()) {
+														alert(editor.lang.youtube.noCode);
+														return false;
+													}
+													else{
+														video = ytVidId(this.getValue());
+
+														if (this.getValue().length === 0 ||  video === false)
+														{
+															alert(editor.lang.youtube.invalidUrl);
+															return false;
+														}
+													}
+												}
+											}
+										},
+										{
+											type : 'text',
+											id : 'txtWidth',
+											width : '60px',
+											label : editor.lang.youtube.txtWidth,
+											'default' : editor.config.youtube_width != null ? editor.config.youtube_width : '640',
+											validate : function () {
+												if (this.getValue()) {
+													var width = parseInt (this.getValue()) || 0;
+
+													if (width === 0) {
+														alert(editor.lang.youtube.invalidWidth);
+														return false;
+													}
+												}
+												else {
+													alert(editor.lang.youtube.noWidth);
+													return false;
+												}
+											}
+										},
+										{
+											type : 'text',
+											id : 'txtHeight',
+											width : '60px',
+											label : editor.lang.youtube.txtHeight,
+											'default' : editor.config.youtube_height != null ? editor.config.youtube_height : '360',
+											validate : function () {
+												if (this.getValue()) {
+													var height = parseInt(this.getValue()) || 0;
+
+													if (height === 0) {
+														alert(editor.lang.youtube.invalidHeight);
+														return false;
+													}
+												}
+												else {
+													alert(editor.lang.youtube.noHeight);
+													return false;
+												}
+											}
+										}
+									]
+								},
+								{
+									type : 'hbox',
+									widths : [ '55%', '45%' ],
+									children :
+										[
+											{
+												id : 'chkResponsive',
+												type : 'checkbox',
+												label : editor.lang.youtube.txtResponsive,
+												'default' : editor.config.youtube_responsive != null ? editor.config.youtube_responsive : false
+											},
+											{
+												id : 'chkNoEmbed',
+												type : 'checkbox',
+												label : editor.lang.youtube.txtNoEmbed,
+												'default' : editor.config.youtube_noembed != null ? editor.config.youtube_noembed : false
+											}
+										]
+								},
+								{
+									type : 'hbox',
+									widths : [ '55%', '45%' ],
+									children :
+									[
+										{
+											id : 'chkRelated',
+											type : 'checkbox',
+											'default' : editor.config.youtube_related != null ? editor.config.youtube_related : true,
+											label : editor.lang.youtube.chkRelated
+										},
+										{
+											id : 'chkOlderCode',
+											type : 'checkbox',
+											'default' : editor.config.youtube_older != null ? editor.config.youtube_older : false,
+											label : editor.lang.youtube.chkOlderCode
+										}
+									]
+								},
+								{
+									type : 'hbox',
+									widths : [ '55%', '45%' ],
+									children :
+									[
+										{
+											id : 'chkPrivacy',
+											type : 'checkbox',
+											label : editor.lang.youtube.chkPrivacy,
+											'default' : editor.config.youtube_privacy != null ? editor.config.youtube_privacy : false
+										},
+										{
+											id : 'chkAutoplay',
+											type : 'checkbox',
+											'default' : editor.config.youtube_autoplay != null ? editor.config.youtube_autoplay : false,
+											label : editor.lang.youtube.chkAutoplay
+										}
+									]
+								},
+								{
+									type : 'hbox',
+									widths : [ '55%', '45%'],
+									children :
+									[
+										{
+											id : 'txtStartAt',
+											type : 'text',
+											label : editor.lang.youtube.txtStartAt,
+											validate : function () {
+												if (this.getValue()) {
+													var str = this.getValue();
+
+													if (!/^(?:(?:([01]?\d|2[0-3]):)?([0-5]?\d):)?([0-5]?\d)$/i.test(str)) {
+														alert(editor.lang.youtube.invalidTime);
+														return false;
+													}
+												}
+											}
+										},
+										{
+											id : 'chkControls',
+											type : 'checkbox',
+											'default' : editor.config.youtube_controls != null ? editor.config.youtube_controls : true,
+											label : editor.lang.youtube.chkControls
+										}
+									]
+								}
+							]
+						}
+					],
+					onOk: function()
+					{
+						var content = '';
+						var responsiveStyle = '';
+
+						if (this.getContentElement('youtubePlugin', 'txtEmbed').isEnabled()) {
+							content = this.getValueOf('youtubePlugin', 'txtEmbed');
+						}
+						else {
+							var url = 'https://', params = [], startSecs, paramAutoplay='';
+							var width = this.getValueOf('youtubePlugin', 'txtWidth');
+							var height = this.getValueOf('youtubePlugin', 'txtHeight');
+
+							if (this.getContentElement('youtubePlugin', 'chkPrivacy').getValue() === true) {
+								url += 'www.youtube-nocookie.com/';
+							}
+							else {
+								url += 'www.youtube.com/';
+							}
+
+							url += 'embed/' + video;
+
+							if (this.getContentElement('youtubePlugin', 'chkRelated').getValue() === false) {
+								params.push('rel=0');
+							}
+
+							if (this.getContentElement('youtubePlugin', 'chkAutoplay').getValue() === true) {
+								params.push('autoplay=1');
+								paramAutoplay='autoplay';
+							}
+
+							if (this.getContentElement('youtubePlugin', 'chkControls').getValue() === false) {
+								params.push('controls=0');
+							}
+
+							startSecs = this.getValueOf('youtubePlugin', 'txtStartAt');
+
+							if (startSecs) {
+								var seconds = hmsToSeconds(startSecs);
+
+								params.push('start=' + seconds);
+							}
+
+							if (params.length > 0) {
+								url = url + '?' + params.join('&');
+							}
+
+							if (this.getContentElement('youtubePlugin', 'chkResponsive').getValue() === true) {
+								content += '<div class="youtube-embed-wrapper" style="position:relative;padding-bottom:56.25%;padding-top:30px;height:0;overflow:hidden">';
+								responsiveStyle = 'style="position:absolute;top:0;left:0;width:100%;height:100%"';
+							}
+
+							if (this.getContentElement('youtubePlugin', 'chkOlderCode').getValue() === true) {
+								url = url.replace('embed/', 'v/');
+								url = url.replace(/&/g, '&amp;');
+
+								if (url.indexOf('?') === -1) {
+									url += '?';
+								}
+								else {
+									url += '&amp;';
+								}
+								url += 'hl=' + (this.getParentEditor().config.language ? this.getParentEditor().config.language : 'en') + '&amp;version=3';
+
+								content += '<object width="' + width + '" height="' + height + '" ' + responsiveStyle + '>';
+								content += '<param name="movie" value="' + url + '"></param>';
+								content += '<param name="allowFullScreen" value="true"></param>';
+								content += '<param name="allowscriptaccess" value="always"></param>';
+								content += '<embed src="' + url + '" type="application/x-shockwave-flash" ';
+								content += 'width="' + width + '" height="' + height + '" '+ responsiveStyle + ' allowscriptaccess="always" ';
+								content += 'allowfullscreen="true"></embed>';
+								content += '</object>';
+							}
+							else
+							if (this.getContentElement('youtubePlugin', 'chkNoEmbed').getValue() === true) {
+								var imgSrc = 'https://img.youtube.com/vi/' + video + '/sddefault.jpg';
+								content += '<a href="' + url + '" ><img width="' + width + '" height="' + height + '" src="' + imgSrc + '" '  + responsiveStyle + '/></a>';
+							}
+							else {
+								content += '<iframe ' + (paramAutoplay ? 'allow="' + paramAutoplay + ';" ' : '') + 'width="' + width + '" height="' + height + '" src="' + url + '" ' + responsiveStyle;
+								content += 'frameborder="0" allowfullscreen></iframe>';
+							}
+
+							if (this.getContentElement('youtubePlugin', 'chkResponsive').getValue() === true) {
+								content += '</div>';
+							}
+						}
+
+						var element = CKEDITOR.dom.element.createFromHtml(content);
+						var instance = this.getParentEditor();
+						instance.insertElement(element);
+					}
+				};
+			});
+		}
+	});
+})();
+
+function handleLinkChange(el, api) {
+	var video = ytVidId(el.getValue());
+	var time = ytVidTime(el.getValue());
+
+	if (el.getValue().length > 0) {
+		el.getDialog().getContentElement('youtubePlugin', 'txtEmbed').disable();
+	}
+	else if (!disabled.length || !disabled.includes('txtEmbed')) {
+		el.getDialog().getContentElement('youtubePlugin', 'txtEmbed').enable();
+	}
+
+	if (video && time) {
+		var seconds = timeParamToSeconds(time);
+		var hms = secondsToHms(seconds);
+		el.getDialog().getContentElement('youtubePlugin', 'txtStartAt').setValue(hms);
+	}
+}
+
+function handleEmbedChange(el, api) {
+	if (el.getValue().length > 0) {
+		el.getDialog().getContentElement('youtubePlugin', 'txtUrl').disable();
+	}
+	else {
+		el.getDialog().getContentElement('youtubePlugin', 'txtUrl').enable();
+	}
+}
+
+
+/**
+ * JavaScript function to match (and return) the video Id
+ * of any valid Youtube Url, given as input string.
+ * @author: Stephan Schmitz <eyecatchup@gmail.com>
+ * @url: http://stackoverflow.com/a/10315969/624466
+ */
+function ytVidId(url) {
+	var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
+	return (url.match(p)) ? RegExp.$1 : false;
+}
+
+/**
+ * Matches and returns time param in YouTube Urls.
+ */
+function ytVidTime(url) {
+	var p = /t=([0-9hms]+)/;
+	return (url.match(p)) ? RegExp.$1 : false;
+}
+
+/**
+ * Converts time in hms format to seconds only
+ */
+function hmsToSeconds(time) {
+	var arr = time.split(':'), s = 0, m = 1;
+
+	while (arr.length > 0) {
+		s += m * parseInt(arr.pop(), 10);
+		m *= 60;
+	}
+
+	return s;
+}
+
+/**
+ * Converts seconds to hms format
+ */
+function secondsToHms(seconds) {
+	var h = Math.floor(seconds / 3600);
+	var m = Math.floor((seconds / 60) % 60);
+	var s = seconds % 60;
+
+	var pad = function (n) {
+		n = String(n);
+		return n.length >= 2 ? n : "0" + n;
+	};
+
+	if (h > 0) {
+		return pad(h) + ':' + pad(m) + ':' + pad(s);
+	}
+	else {
+		return pad(m) + ':' + pad(s);
+	}
+}
+
+/**
+ * Converts time in youtube t-param format to seconds
+ */
+function timeParamToSeconds(param) {
+	var componentValue = function (si) {
+		var regex = new RegExp('(\\d+)' + si);
+		return param.match(regex) ? parseInt(RegExp.$1, 10) : 0;
+	};
+
+	return componentValue('h') * 3600
+		+ componentValue('m') * 60
+		+ componentValue('s');
+}
+
+/**
+ * Converts seconds into youtube t-param value, e.g. 1h4m30s
+ */
+function secondsToTimeParam(seconds) {
+	var h = Math.floor(seconds / 3600);
+	var m = Math.floor((seconds / 60) % 60);
+	var s = seconds % 60;
+	var param = '';
+
+	if (h > 0) {
+		param += h + 'h';
+	}
+
+	if (m > 0) {
+		param += m + 'm';
+	}
+
+	if (s > 0) {
+		param += s + 's';
+	}
+
+	return param;
+}

+ 797 - 0
js/OBJLoader.js

@@ -0,0 +1,797 @@
+/**
+ * @author mrdoob / http://mrdoob.com/
+ */
+function OBJLoader_plugin() {
+    IV.THREE.OBJLoader = (function () {
+
+        // o object_name | g group_name
+        var object_pattern = /^[og]\s*(.+)?/;
+        // mtllib file_reference
+        var material_library_pattern = /^mtllib /;
+        // usemtl material_name
+        var material_use_pattern = /^usemtl /;
+
+        function ParserState() {
+
+            var state = {
+                objects: [],
+                object: {},
+
+                vertices: [],
+                normals: [],
+                colors: [],
+                uvs: [],
+
+                materialLibraries: [],
+
+                startObject: function (name, fromDeclaration) {
+
+                    // If the current object (initial from reset) is not from a g/o declaration in the parsed
+                    // file. We need to use it for the first parsed g/o to keep things in sync.
+                    if (this.object && this.object.fromDeclaration === false) {
+
+                        this.object.name = name;
+                        this.object.fromDeclaration = (fromDeclaration !== false);
+                        return;
+
+                    }
+
+                    var previousMaterial = (this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined);
+
+                    if (this.object && typeof this.object._finalize === 'function') {
+
+                        this.object._finalize(true);
+
+                    }
+
+                    this.object = {
+                        name: name || '',
+                        fromDeclaration: (fromDeclaration !== false),
+
+                        geometry: {
+                            vertices: [],
+                            normals: [],
+                            colors: [],
+                            uvs: []
+                        },
+                        materials: [],
+                        smooth: true,
+
+                        startMaterial: function (name, libraries) {
+
+                            var previous = this._finalize(false);
+
+                            // New usemtl declaration overwrites an inherited material, except if faces were declared
+                            // after the material, then it must be preserved for proper MultiMaterial continuation.
+                            if (previous && (previous.inherited || previous.groupCount <= 0)) {
+
+                                this.materials.splice(previous.index, 1);
+
+                            }
+
+                            var material = {
+                                index: this.materials.length,
+                                name: name || '',
+                                mtllib: (Array.isArray(libraries) && libraries.length > 0 ? libraries[libraries.length - 1] : ''),
+                                smooth: (previous !== undefined ? previous.smooth : this.smooth),
+                                groupStart: (previous !== undefined ? previous.groupEnd : 0),
+                                groupEnd: -1,
+                                groupCount: -1,
+                                inherited: false,
+
+                                clone: function (index) {
+
+                                    var cloned = {
+                                        index: (typeof index === 'number' ? index : this.index),
+                                        name: this.name,
+                                        mtllib: this.mtllib,
+                                        smooth: this.smooth,
+                                        groupStart: 0,
+                                        groupEnd: -1,
+                                        groupCount: -1,
+                                        inherited: false
+                                    };
+                                    cloned.clone = this.clone.bind(cloned);
+                                    return cloned;
+
+                                }
+                            };
+
+                            this.materials.push(material);
+
+                            return material;
+
+                        },
+
+                        currentMaterial: function () {
+
+                            if (this.materials.length > 0) {
+
+                                return this.materials[this.materials.length - 1];
+
+                            }
+
+                            return undefined;
+
+                        },
+
+                        _finalize: function (end) {
+
+                            var lastMultiMaterial = this.currentMaterial();
+                            if (lastMultiMaterial && lastMultiMaterial.groupEnd === -1) {
+
+                                lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
+                                lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
+                                lastMultiMaterial.inherited = false;
+
+                            }
+
+                            // Ignore objects tail materials if no face declarations followed them before a new o/g started.
+                            if (end && this.materials.length > 1) {
+
+                                for (var mi = this.materials.length - 1; mi >= 0; mi--) {
+
+                                    if (this.materials[mi].groupCount <= 0) {
+
+                                        this.materials.splice(mi, 1);
+
+                                    }
+
+                                }
+
+                            }
+
+                            // Guarantee at least one empty material, this makes the creation later more straight forward.
+                            if (end && this.materials.length === 0) {
+
+                                this.materials.push({
+                                    name: '',
+                                    smooth: this.smooth
+                                });
+
+                            }
+
+                            return lastMultiMaterial;
+
+                        }
+                    };
+
+                    // Inherit previous objects material.
+                    // Spec tells us that a declared material must be set to all objects until a new material is declared.
+                    // If a usemtl declaration is encountered while this new object is being parsed, it will
+                    // overwrite the inherited material. Exception being that there was already face declarations
+                    // to the inherited material, then it will be preserved for proper MultiMaterial continuation.
+
+                    if (previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function') {
+
+                        var declared = previousMaterial.clone(0);
+                        declared.inherited = true;
+                        this.object.materials.push(declared);
+
+                    }
+
+                    this.objects.push(this.object);
+
+                },
+
+                finalize: function () {
+
+                    if (this.object && typeof this.object._finalize === 'function') {
+
+                        this.object._finalize(true);
+
+                    }
+
+                },
+
+                parseVertexIndex: function (value, len) {
+
+                    var index = parseInt(value, 10);
+                    return (index >= 0 ? index - 1 : index + len / 3) * 3;
+
+                },
+
+                parseNormalIndex: function (value, len) {
+
+                    var index = parseInt(value, 10);
+                    return (index >= 0 ? index - 1 : index + len / 3) * 3;
+
+                },
+
+                parseUVIndex: function (value, len) {
+
+                    var index = parseInt(value, 10);
+                    return (index >= 0 ? index - 1 : index + len / 2) * 2;
+
+                },
+
+                addVertex: function (a, b, c) {
+
+                    var src = this.vertices;
+                    var dst = this.object.geometry.vertices;
+
+                    dst.push(src[a + 0], src[a + 1], src[a + 2]);
+                    dst.push(src[b + 0], src[b + 1], src[b + 2]);
+                    dst.push(src[c + 0], src[c + 1], src[c + 2]);
+
+                },
+
+                addVertexPoint: function (a) {
+
+                    var src = this.vertices;
+                    var dst = this.object.geometry.vertices;
+
+                    dst.push(src[a + 0], src[a + 1], src[a + 2]);
+
+                },
+
+                addVertexLine: function (a) {
+
+                    var src = this.vertices;
+                    var dst = this.object.geometry.vertices;
+
+                    dst.push(src[a + 0], src[a + 1], src[a + 2]);
+
+                },
+
+                addNormal: function (a, b, c) {
+
+                    var src = this.normals;
+                    var dst = this.object.geometry.normals;
+
+                    dst.push(src[a + 0], src[a + 1], src[a + 2]);
+                    dst.push(src[b + 0], src[b + 1], src[b + 2]);
+                    dst.push(src[c + 0], src[c + 1], src[c + 2]);
+
+                },
+
+                addColor: function (a, b, c) {
+
+                    var src = this.colors;
+                    var dst = this.object.geometry.colors;
+
+                    dst.push(src[a + 0], src[a + 1], src[a + 2]);
+                    dst.push(src[b + 0], src[b + 1], src[b + 2]);
+                    dst.push(src[c + 0], src[c + 1], src[c + 2]);
+
+                },
+
+                addUV: function (a, b, c) {
+
+                    var src = this.uvs;
+                    var dst = this.object.geometry.uvs;
+
+                    dst.push(src[a + 0], src[a + 1]);
+                    dst.push(src[b + 0], src[b + 1]);
+                    dst.push(src[c + 0], src[c + 1]);
+
+                },
+
+                addUVLine: function (a) {
+
+                    var src = this.uvs;
+                    var dst = this.object.geometry.uvs;
+
+                    dst.push(src[a + 0], src[a + 1]);
+
+                },
+
+                addFace: function (a, b, c, ua, ub, uc, na, nb, nc) {
+
+                    var vLen = this.vertices.length;
+
+                    var ia = this.parseVertexIndex(a, vLen);
+                    var ib = this.parseVertexIndex(b, vLen);
+                    var ic = this.parseVertexIndex(c, vLen);
+
+                    this.addVertex(ia, ib, ic);
+
+                    if (ua !== undefined && ua !== '') {
+
+                        var uvLen = this.uvs.length;
+                        ia = this.parseUVIndex(ua, uvLen);
+                        ib = this.parseUVIndex(ub, uvLen);
+                        ic = this.parseUVIndex(uc, uvLen);
+                        this.addUV(ia, ib, ic);
+
+                    }
+
+                    if (na !== undefined && na !== '') {
+
+                        // Normals are many times the same. If so, skip function call and parseInt.
+                        var nLen = this.normals.length;
+                        ia = this.parseNormalIndex(na, nLen);
+
+                        ib = na === nb ? ia : this.parseNormalIndex(nb, nLen);
+                        ic = na === nc ? ia : this.parseNormalIndex(nc, nLen);
+
+                        this.addNormal(ia, ib, ic);
+
+                    }
+
+                    if (this.colors.length > 0) {
+
+                        this.addColor(ia, ib, ic);
+
+                    }
+
+                },
+
+                addPointGeometry: function (vertices) {
+
+                    this.object.geometry.type = 'Points';
+
+                    var vLen = this.vertices.length;
+
+                    for (var vi = 0, l = vertices.length; vi < l; vi++) {
+
+                        this.addVertexPoint(this.parseVertexIndex(vertices[vi], vLen));
+
+                    }
+
+                },
+
+                addLineGeometry: function (vertices, uvs) {
+
+                    this.object.geometry.type = 'Line';
+
+                    var vLen = this.vertices.length;
+                    var uvLen = this.uvs.length;
+
+                    for (var vi = 0, l = vertices.length; vi < l; vi++) {
+
+                        this.addVertexLine(this.parseVertexIndex(vertices[vi], vLen));
+
+                    }
+
+                    for (var uvi = 0, l = uvs.length; uvi < l; uvi++) {
+
+                        this.addUVLine(this.parseUVIndex(uvs[uvi], uvLen));
+
+                    }
+
+                }
+
+            };
+
+            state.startObject('', false);
+
+            return state;
+
+        }
+
+        //
+
+        function OBJLoader(manager) {
+
+            this.manager = (manager !== undefined) ? manager : IV.THREE.DefaultLoadingManager;
+
+            this.materials = null;
+
+        }
+
+        OBJLoader.prototype = {
+
+            constructor: OBJLoader,
+
+            load: function (url, onLoad, onProgress, onError) {
+
+                var scope = this;
+
+                var loader = new IV.THREE.FileLoader(scope.manager);
+                loader.setPath(this.path);
+                loader.load(url, function (text) {
+
+                    onLoad(scope.parse(text));
+
+                }, onProgress, onError);
+
+            },
+
+            setPath: function (value) {
+
+                this.path = value;
+
+                return this;
+
+            },
+
+            setMaterials: function (materials) {
+
+                this.materials = materials;
+
+                return this;
+
+            },
+
+            parse: function (text) {
+
+                console.time('OBJLoader');
+
+                var state = new ParserState();
+
+                if (text.indexOf('\r\n') !== -1) {
+
+                    // This is faster than String.split with regex that splits on both
+                    text = text.replace(/\r\n/g, '\n');
+
+                }
+
+                if (text.indexOf('\\\n') !== -1) {
+
+                    // join lines separated by a line continuation character (\)
+                    text = text.replace(/\\\n/g, '');
+
+                }
+
+                var lines = text.split('\n');
+                var line = '', lineFirstChar = '';
+                var lineLength = 0;
+                var result = [];
+
+                // Faster to just trim left side of the line. Use if available.
+                var trimLeft = (typeof ''.trimLeft === 'function');
+
+                for (var i = 0, l = lines.length; i < l; i++) {
+
+                    line = lines[i];
+
+                    line = trimLeft ? line.trimLeft() : line.trim();
+
+                    lineLength = line.length;
+
+                    if (lineLength === 0) continue;
+
+                    lineFirstChar = line.charAt(0);
+
+                    // @todo invoke passed in handler if any
+                    if (lineFirstChar === '#') continue;
+
+                    if (lineFirstChar === 'v') {
+
+                        var data = line.split(/\s+/);
+
+                        switch (data[0]) {
+
+                            case 'v':
+                                state.vertices.push(
+                                    parseFloat(data[1]),
+                                    parseFloat(data[2]),
+                                    parseFloat(data[3])
+                                );
+                                if (data.length === 8) {
+
+                                    state.colors.push(
+                                        parseFloat(data[4]),
+                                        parseFloat(data[5]),
+                                        parseFloat(data[6])
+                                    );
+
+                                }
+                                break;
+                            case 'vn':
+                                state.normals.push(
+                                    parseFloat(data[1]),
+                                    parseFloat(data[2]),
+                                    parseFloat(data[3])
+                                );
+                                break;
+                            case 'vt':
+                                state.uvs.push(
+                                    parseFloat(data[1]),
+                                    parseFloat(data[2])
+                                );
+                                break;
+
+                        }
+
+                    } else if (lineFirstChar === 'f') {
+
+                        var lineData = line.substr(1).trim();
+                        var vertexData = lineData.split(/\s+/);
+                        var faceVertices = [];
+
+                        // Parse the face vertex data into an easy to work with format
+
+                        for (var j = 0, jl = vertexData.length; j < jl; j++) {
+
+                            var vertex = vertexData[j];
+
+                            if (vertex.length > 0) {
+
+                                var vertexParts = vertex.split('/');
+                                faceVertices.push(vertexParts);
+
+                            }
+
+                        }
+
+                        // Draw an edge between the first vertex and all subsequent vertices to form an n-gon
+
+                        var v1 = faceVertices[0];
+
+                        for (var j = 1, jl = faceVertices.length - 1; j < jl; j++) {
+
+                            var v2 = faceVertices[j];
+                            var v3 = faceVertices[j + 1];
+
+                            state.addFace(
+                                v1[0], v2[0], v3[0],
+                                v1[1], v2[1], v3[1],
+                                v1[2], v2[2], v3[2]
+                            );
+
+                        }
+
+                    } else if (lineFirstChar === 'l') {
+
+                        var lineParts = line.substring(1).trim().split(" ");
+                        var lineVertices = [], lineUVs = [];
+
+                        if (line.indexOf("/") === -1) {
+
+                            lineVertices = lineParts;
+
+                        } else {
+
+                            for (var li = 0, llen = lineParts.length; li < llen; li++) {
+
+                                var parts = lineParts[li].split("/");
+
+                                if (parts[0] !== "") lineVertices.push(parts[0]);
+                                if (parts[1] !== "") lineUVs.push(parts[1]);
+
+                            }
+
+                        }
+                        state.addLineGeometry(lineVertices, lineUVs);
+
+                    } else if (lineFirstChar === 'p') {
+
+                        var lineData = line.substr(1).trim();
+                        var pointData = lineData.split(" ");
+
+                        state.addPointGeometry(pointData);
+
+                    } else if ((result = object_pattern.exec(line)) !== null) {
+
+                        // o object_name
+                        // or
+                        // g group_name
+
+                        // WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
+                        // var name = result[ 0 ].substr( 1 ).trim();
+                        var name = (" " + result[0].substr(1).trim()).substr(1);
+
+                        state.startObject(name);
+
+                    } else if (material_use_pattern.test(line)) {
+
+                        // material
+
+                        state.object.startMaterial(line.substring(7).trim(), state.materialLibraries);
+
+                    } else if (material_library_pattern.test(line)) {
+
+                        // mtl file
+
+                        state.materialLibraries.push(line.substring(7).trim());
+
+                    } else if (lineFirstChar === 's') {
+
+                        result = line.split(' ');
+
+                        // smooth shading
+
+                        // @todo Handle files that have varying smooth values for a set of faces inside one geometry,
+                        // but does not define a usemtl for each face set.
+                        // This should be detected and a dummy material created (later MultiMaterial and geometry groups).
+                        // This requires some care to not create extra material on each smooth value for "normal" obj files.
+                        // where explicit usemtl defines geometry groups.
+                        // Example asset: examples/models/obj/cerberus/Cerberus.obj
+
+                        /*
+                         * http://paulbourke.net/dataformats/obj/
+                         * or
+                         * http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf
+                         *
+                         * From chapter "Grouping" Syntax explanation "s group_number":
+                         * "group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off.
+                         * Polygonal elements use group numbers to put elements in different smoothing groups. For free-form
+                         * surfaces, smoothing groups are either turned on or off; there is no difference between values greater
+                         * than 0."
+                         */
+                        if (result.length > 1) {
+
+                            var value = result[1].trim().toLowerCase();
+                            state.object.smooth = (value !== '0' && value !== 'off');
+
+                        } else {
+
+                            // ZBrush can produce "s" lines #11707
+                            state.object.smooth = true;
+
+                        }
+                        var material = state.object.currentMaterial();
+                        if (material) material.smooth = state.object.smooth;
+
+                    } else {
+
+                        // Handle null terminated files without exception
+                        if (line === '\0') continue;
+
+                        throw new Error('IV.THREE.OBJLoader: Unexpected line: "' + line + '"');
+
+                    }
+
+                }
+
+                state.finalize();
+
+                var container = new IV.THREE.Group();
+                container.materialLibraries = [].concat(state.materialLibraries);
+
+                for (var i = 0, l = state.objects.length; i < l; i++) {
+
+                    var object = state.objects[i];
+                    var geometry = object.geometry;
+                    var materials = object.materials;
+                    var isLine = (geometry.type === 'Line');
+                    var isPoints = (geometry.type === 'Points');
+                    var hasVertexColors = false;
+
+                    // Skip o/g line declarations that did not follow with any faces
+                    if (geometry.vertices.length === 0) continue;
+
+                    var buffergeometry = new IV.THREE.BufferGeometry();
+
+                    buffergeometry.addAttribute('position', new IV.THREE.Float32BufferAttribute(geometry.vertices, 3));
+
+                    if (geometry.normals.length > 0) {
+
+                        buffergeometry.addAttribute('normal', new IV.THREE.Float32BufferAttribute(geometry.normals, 3));
+
+                    } else {
+
+                        buffergeometry.computeVertexNormals();
+
+                    }
+
+                    if (geometry.colors.length > 0) {
+
+                        hasVertexColors = true;
+                        buffergeometry.addAttribute('color', new IV.THREE.Float32BufferAttribute(geometry.colors, 3));
+
+                    }
+
+                    if (geometry.uvs.length > 0) {
+
+                        buffergeometry.addAttribute('uv', new IV.THREE.Float32BufferAttribute(geometry.uvs, 2));
+
+                    }
+
+                    // Create materials
+
+                    var createdMaterials = [];
+
+                    for (var mi = 0, miLen = materials.length; mi < miLen; mi++) {
+
+                        var sourceMaterial = materials[mi];
+                        var material = undefined;
+
+                        if (this.materials !== null) {
+
+                            material = this.materials.create(sourceMaterial.name);
+
+                            // mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.
+                            if (isLine && material && !(material instanceof IV.THREE.LineBasicMaterial)) {
+
+                                var materialLine = new IV.THREE.LineBasicMaterial();
+                                IV.THREE.Material.prototype.copy.call(materialLine, material);
+                                materialLine.color.copy(material.color);
+                                materialLine.lights = false;
+                                material = materialLine;
+
+                            } else if (isPoints && material && !(material instanceof IV.THREE.PointsMaterial)) {
+
+                                var materialPoints = new IV.THREE.PointsMaterial({size: 10, sizeAttenuation: false});
+                                IV.THREE.Material.prototype.copy.call(materialPoints, material);
+                                materialPoints.color.copy(material.color);
+                                materialPoints.map = material.map;
+                                materialPoints.lights = false;
+                                material = materialPoints;
+
+                            }
+
+                        }
+
+                        if (!material) {
+
+                            if (isLine) {
+
+                                material = new IV.THREE.LineBasicMaterial();
+
+                            } else if (isPoints) {
+
+                                material = new IV.THREE.PointsMaterial({size: 1, sizeAttenuation: false});
+
+                            } else {
+
+                                material = new IV.THREE.MeshPhongMaterial();
+
+                            }
+
+                            material.name = sourceMaterial.name;
+
+                        }
+
+                        material.flatShading = sourceMaterial.smooth ? false : true;
+                        material.vertexColors = hasVertexColors ? IV.THREE.VertexColors : IV.THREE.NoColors;
+
+                        createdMaterials.push(material);
+
+                    }
+
+                    // Create mesh
+
+                    var mesh;
+
+                    if (createdMaterials.length > 1) {
+
+                        for (var mi = 0, miLen = materials.length; mi < miLen; mi++) {
+
+                            var sourceMaterial = materials[mi];
+                            buffergeometry.addGroup(sourceMaterial.groupStart, sourceMaterial.groupCount, mi);
+
+                        }
+
+                        if (isLine) {
+
+                            mesh = new IV.THREE.LineSegments(buffergeometry, createdMaterials);
+
+                        } else if (isPoints) {
+
+                            mesh = new IV.THREE.Points(buffergeometry, createdMaterials);
+
+                        } else {
+
+                            mesh = new IV.THREE.Mesh(buffergeometry, createdMaterials);
+
+                        }
+
+                    } else {
+
+                        if (isLine) {
+
+                            mesh = new IV.THREE.LineSegments(buffergeometry, createdMaterials[0]);
+
+                        } else if (isPoints) {
+
+                            mesh = new IV.THREE.Points(buffergeometry, createdMaterials[0]);
+
+                        } else {
+
+                            mesh = new IV.THREE.Mesh(buffergeometry, createdMaterials[0]);
+
+                        }
+
+                    }
+
+                    mesh.name = object.name;
+
+                    container.add(mesh);
+
+                }
+
+                console.timeEnd('OBJLoader');
+
+                return container;
+
+            }
+
+        };
+
+        return OBJLoader;
+
+    })();
+}

Plik diff jest za duży
+ 5 - 0
lang/zh.js


Plik diff jest za duży
+ 2 - 0
plugins/colorbutton/lang/zh.js


Plik diff jest za duży
+ 18 - 0
plugins/colorbutton/plugin.js


+ 18 - 0
plugins/dialog/styles/dialog.css

@@ -0,0 +1,18 @@
+.cke_dialog_open {
+	overflow: hidden;
+}
+
+.cke_dialog_container {
+	position: fixed;
+	overflow-y: auto;
+	overflow-x: auto;
+	width: 100%;
+	height: 100%;
+	top: 0;
+	left: 0;
+	z-index: 10010;
+}
+
+.cke_dialog_body {
+	position: relative;
+}

+ 1 - 0
plugins/font/lang/zh.js

@@ -0,0 +1 @@
+CKEDITOR.plugins.setLang("font","zh",{fontSize:{label:"大小",voiceLabel:"字型大小",panelTitle:"字型大小"},label:"字型",panelTitle:"字型名稱",voiceLabel:"字型"});

Plik diff jest za duży
+ 14 - 0
plugins/font/plugin.js


Plik diff jest za duży
+ 8 - 0
plugins/panelbutton/plugin.js


+ 23 - 0
plugins/scayt/dialogs/dialog.css

@@ -0,0 +1,23 @@
+div.cke_dialog_ui_scaytItemList {
+	border: 1px solid #c9cccf;
+}
+
+.cke_scaytItemList-child {
+	position: relative;
+	padding: 6px 30px 6px 5px;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+
+.cke_scaytItemList-child:hover {
+	background: #ebebeb;
+}
+
+.cke_scaytItemList-child .cke_scaytItemList_remove {
+	position: absolute;
+	top: 0;
+	right: 5px;
+	width: 26px;
+	height: 26px;
+}

+ 25 - 0
plugins/scayt/skins/moono-lisa/scayt.css

@@ -0,0 +1,25 @@
+.scayt-lang-list > div
+{
+    padding-bottom: 6px !important;
+}
+
+.scayt-lang-list > div input
+{
+    margin-right: 4px;
+}
+
+#scayt_about_
+{
+    margin: 30px auto 0 auto;
+}
+
+#scayt_about_ p
+{
+	text-align: center;
+	margin-bottom: 10px;
+}
+
+.cke_dialog_contents_body div[name=dictionaries] .cke_dialog_ui_hbox_last > a.cke_dialog_ui_button
+{
+    margin-top: 0;
+}

+ 36 - 0
plugins/tableselection/styles/tableselection.css

@@ -0,0 +1,36 @@
+.cke_table-faked-selection-editor *::selection, table[data-cke-table-faked-selection-table] *::selection {
+	background: transparent;
+}
+
+.cke_table-faked-selection {
+	background: darkgray !important;
+	color: black;
+}
+.cke_table-faked-selection a {
+	color: black;
+}
+.cke_editable:focus .cke_table-faked-selection {
+	/* We have to use !important here, as td might specify it's own background, thus table selection
+	would not be visible. */
+	background: #0076cb !important;
+	color: white;
+}
+.cke_editable:focus .cke_table-faked-selection a {
+	color: white;
+}
+.cke_table-faked-selection::-moz-selection, .cke_table-faked-selection ::-moz-selection {
+	background: transparent;
+}
+.cke_table-faked-selection::selection, .cke_table-faked-selection ::selection {
+	background: transparent;
+}
+
+/* Change the cursor when selecting cells (#706).
+ *
+ * This solution does not work in IE, Edge and Safari due to upstream isues:
+ * https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/3419602/
+ * https://bugs.webkit.org/show_bug.cgi?id=53341
+ */
+table[data-cke-table-faked-selection-table] {
+	cursor: cell;
+}

+ 43 - 0
plugins/wsc/skins/moono-lisa/wsc.css

@@ -0,0 +1,43 @@
+.cke_dialog_body #overlayBlock,
+.cke_dialog_body #no_check_over
+{
+    top: 39px !important;
+}
+
+div[name=SpellTab] .wsc-spelltab-bottom .cke_dialog_ui_vbox td > .cke_dialog_ui_button:first-child
+{
+    margin-top: 4px;
+}
+
+div[name=SpellTab] .wsc-spelltab-bottom .cke_dialog_ui_hbox_first .cke_dialog_ui_select > label
+{
+    margin-left: 0;
+}
+
+div[name=SpellTab] .wsc-spelltab-bottom .cke_dialog_ui_hbox_first .cke_dialog_ui_select div.cke_dialog_ui_input_select
+{
+    width: 140px !important;
+}
+
+div[name=SpellTab] .wsc-spelltab-bottom .cke_dialog_ui_hbox_first .cke_dialog_ui_select select.cke_dialog_ui_input_select,
+div[name=Thesaurus] div.cke_dialog_ui_input_select select.cke_dialog_ui_input_select
+{
+    margin-top: 1px;
+}
+
+div[name=SpellTab] .wsc-spelltab-bottom .cke_dialog_ui_hbox_first .cke_dialog_ui_select select.cke_dialog_ui_input_select:focus,
+div[name=Thesaurus] div.cke_dialog_ui_input_select select.cke_dialog_ui_input_select:focus
+{
+    margin-top: 0;
+}
+
+div[name=GrammTab] .cke_dialog_ui_vbox tbody > tr:first-child .cke_dialog_ui_button,
+div[name=Thesaurus] .cke_dialog_ui_vbox tbody > tr:first-child .cke_dialog_ui_button
+{
+    margin-top: 4px !important;
+}
+
+div[name=Thesaurus] div.cke_dialog_ui_input_select
+{
+    width: 180px !important;
+}

Plik diff jest za duży
+ 5 - 0
skins/moono-lisa/editor.css


BIN
skins/moono-lisa/icons.png


+ 137 - 0
styles.js

@@ -0,0 +1,137 @@
+/**
+ * Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
+ */
+
+// This file contains style definitions that can be used by CKEditor plugins.
+//
+// The most common use for it is the "stylescombo" plugin which shows the Styles drop-down
+// list containing all styles in the editor toolbar. Other plugins, like
+// the "div" plugin, use a subset of the styles for their features.
+//
+// If you do not have plugins that depend on this file in your editor build, you can simply
+// ignore it. Otherwise it is strongly recommended to customize this file to match your
+// website requirements and design properly.
+//
+// For more information refer to: https://ckeditor.com/docs/ckeditor4/latest/guide/dev_styles.html#style-rules
+
+CKEDITOR.stylesSet.add( 'default', [
+	/* Block styles */
+
+	// These styles are already available in the "Format" drop-down list ("format" plugin),
+	// so they are not needed here by default. You may enable them to avoid
+	// placing the "Format" combo in the toolbar, maintaining the same features.
+	/*
+	{ name: 'Paragraph',		element: 'p' },
+	{ name: 'Heading 1',		element: 'h1' },
+	{ name: 'Heading 2',		element: 'h2' },
+	{ name: 'Heading 3',		element: 'h3' },
+	{ name: 'Heading 4',		element: 'h4' },
+	{ name: 'Heading 5',		element: 'h5' },
+	{ name: 'Heading 6',		element: 'h6' },
+	{ name: 'Preformatted Text',element: 'pre' },
+	{ name: 'Address',			element: 'address' },
+	*/
+
+	{ name: 'Italic Title',		element: 'h2', styles: { 'font-style': 'italic' } },
+	{ name: 'Subtitle',			element: 'h3', styles: { 'color': '#aaa', 'font-style': 'italic' } },
+	{
+		name: 'Special Container',
+		element: 'div',
+		styles: {
+			padding: '5px 10px',
+			background: '#eee',
+			border: '1px solid #ccc'
+		}
+	},
+
+	/* Inline styles */
+
+	// These are core styles available as toolbar buttons. You may opt enabling
+	// some of them in the Styles drop-down list, removing them from the toolbar.
+	// (This requires the "stylescombo" plugin.)
+	/*
+	{ name: 'Strong',			element: 'strong', overrides: 'b' },
+	{ name: 'Emphasis',			element: 'em'	, overrides: 'i' },
+	{ name: 'Underline',		element: 'u' },
+	{ name: 'Strikethrough',	element: 'strike' },
+	{ name: 'Subscript',		element: 'sub' },
+	{ name: 'Superscript',		element: 'sup' },
+	*/
+
+	{ name: 'Marker',			element: 'span', attributes: { 'class': 'marker' } },
+
+	{ name: 'Big',				element: 'big' },
+	{ name: 'Small',			element: 'small' },
+	{ name: 'Typewriter',		element: 'tt' },
+
+	{ name: 'Computer Code',	element: 'code' },
+	{ name: 'Keyboard Phrase',	element: 'kbd' },
+	{ name: 'Sample Text',		element: 'samp' },
+	{ name: 'Variable',			element: 'var' },
+
+	{ name: 'Deleted Text',		element: 'del' },
+	{ name: 'Inserted Text',	element: 'ins' },
+
+	{ name: 'Cited Work',		element: 'cite' },
+	{ name: 'Inline Quotation',	element: 'q' },
+
+	{ name: 'Language: RTL',	element: 'span', attributes: { 'dir': 'rtl' } },
+	{ name: 'Language: LTR',	element: 'span', attributes: { 'dir': 'ltr' } },
+
+	/* Object styles */
+
+	{
+		name: 'Styled Image (left)',
+		element: 'img',
+		attributes: { 'class': 'left' }
+	},
+
+	{
+		name: 'Styled Image (right)',
+		element: 'img',
+		attributes: { 'class': 'right' }
+	},
+
+	{
+		name: 'Compact Table',
+		element: 'table',
+		attributes: {
+			cellpadding: '5',
+			cellspacing: '0',
+			border: '1',
+			bordercolor: '#ccc'
+		},
+		styles: {
+			'border-collapse': 'collapse'
+		}
+	},
+
+	{ name: 'Borderless Table',		element: 'table',	styles: { 'border-style': 'hidden', 'background-color': '#E6E6FA' } },
+	{ name: 'Square Bulleted List',	element: 'ul',		styles: { 'list-style-type': 'square' } },
+
+	/* Widget styles */
+
+	{ name: 'Clean Image', type: 'widget', widget: 'image', attributes: { 'class': 'image-clean' } },
+	{ name: 'Grayscale Image', type: 'widget', widget: 'image', attributes: { 'class': 'image-grayscale' } },
+
+	{ name: 'Featured Snippet', type: 'widget', widget: 'codeSnippet', attributes: { 'class': 'code-featured' } },
+
+	{ name: 'Featured Formula', type: 'widget', widget: 'mathjax', attributes: { 'class': 'math-featured' } },
+
+	{ name: '240p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-240p' }, group: 'size' },
+	{ name: '360p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-360p' }, group: 'size' },
+	{ name: '480p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-480p' }, group: 'size' },
+	{ name: '720p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-720p' }, group: 'size' },
+	{ name: '1080p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-1080p' }, group: 'size' },
+
+	// Adding space after the style name is an intended workaround. For now, there
+	// is no option to create two styles with the same name for different widget types. See https://dev.ckeditor.com/ticket/16664.
+	{ name: '240p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-240p' }, group: 'size' },
+	{ name: '360p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-360p' }, group: 'size' },
+	{ name: '480p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-480p' }, group: 'size' },
+	{ name: '720p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-720p' }, group: 'size' },
+	{ name: '1080p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-1080p' }, group: 'size' }
+
+] );
+