59 Commits

Author SHA1 Message Date
c89edd3cd6 Display conversation messages. 2019-01-15 08:25:59 +01:00
4d775494c0 Added all conversation messages 2019-01-15 07:32:07 +01:00
f9c1f37ac6 Display user movies. 2019-01-15 07:17:06 +01:00
0e3aee13bd Display survey responses 2019-01-14 21:19:06 +01:00
4a24d5249c Display user likes 2019-01-14 21:12:06 +01:00
64ead89601 Improved appearance of processed categories 2019-01-14 21:04:10 +01:00
b48b6db028 Display all comments 2019-01-14 21:01:44 +01:00
59e6eb3c30 Improved project structure 2019-01-14 20:51:24 +01:00
8072d1eb3e Display surveys 2019-01-14 20:48:03 +01:00
e1dea40167 Display posts with countdown timer. 2019-01-14 19:26:18 +01:00
f3efb3d390 Show posts with PDFs 2019-01-14 19:22:15 +01:00
2035b85a06 Added post weblink 2019-01-14 19:11:03 +01:00
100032fa86 Can show movies 2019-01-14 18:48:43 +01:00
3da2455945 Display YouTube post 2019-01-14 18:40:28 +01:00
30a96d56ec Begin to display posts 2019-01-14 15:30:42 +01:00
a7a36d8665 Display friends information 2019-01-14 14:36:20 +01:00
a0ef614252 Improved navigation 2019-01-14 14:19:56 +01:00
229b02534e Display user information 2019-01-14 14:13:18 +01:00
f2ab71cf3f Work progress on project UI 2019-01-14 13:17:05 +01:00
497b8f1274 Added export categories 2019-01-14 09:56:46 +01:00
98765057dd Added account export assets 2019-01-14 09:39:09 +01:00
824de4bcdb Added gitignore 2019-01-14 08:27:29 +01:00
72fe0843c4 Fix dark theme issue 2019-01-11 18:27:02 +01:00
584bb42c93 Can update conversation message content. 2019-01-11 18:17:37 +01:00
f8e8454b86 Can delete conversation messages 2019-01-11 17:57:55 +01:00
41354be949 Added easter egg (a pacman game) 2019-01-11 16:34:43 +01:00
457712cd35 Fix HTTPS issue 2019-01-11 15:23:18 +01:00
a0d644469d Added incognito mode 2019-01-11 14:50:06 +01:00
f76d9ba9cd Display bottom links on main menu. 2019-01-11 11:54:22 +01:00
dc7fd44b67 Splited main menu links list and rendering. 2019-01-11 11:38:55 +01:00
fba7937d02 Splited bottom links list and rendering 2019-01-11 11:11:25 +01:00
f418ee25b0 Fix dark theme issue on friends list on mobiles 2019-01-10 17:10:49 +01:00
c05506a2a5 Dark theme persistant on page reload. 2019-01-10 17:07:42 +01:00
5bb4e2ae1f Improved dark theme 2019-01-10 17:01:00 +01:00
fc70840c41 Sceditor auto-expanding on post create form. 2019-01-10 16:47:20 +01:00
dff9831228 Improved Sceditor integration 2019-01-10 16:28:59 +01:00
6d61c0d621 Improve dark theme 2019-01-10 15:53:16 +01:00
b16ca0defd Basic integration of dark theme. 2019-01-10 15:44:39 +01:00
93df9d235d Fixed build issues. 2019-01-10 14:59:12 +01:00
069922b7da Merge remote-tracking branch 'origin/dark-theme-design' 2019-01-10 14:28:40 +01:00
fdabb3e3fc Improved input appearance. 2018-12-27 19:07:39 +01:00
2890b03283 Switched to BBCode language for posts. 2018-12-27 14:02:01 +01:00
f6e2c83dbd Added the possibility to create a detached picker. 2018-12-27 11:18:52 +01:00
c2eba7b3be Fix security breach. 2018-12-08 19:03:53 +01:00
089739e141 Added (w) smiley 2018-12-01 10:46:33 +01:00
5c19d9c04c Play a song when new notifications arrives. 2018-11-24 18:54:02 +01:00
46bb22b17b Display the number of notifications on page title. 2018-11-24 16:01:45 +01:00
d49b04e6fb Do not display JS errors in production mode. 2018-11-24 11:24:31 +01:00
672cbc1409 Form keep focus after sending a message onconversation page. 2018-09-07 10:00:05 +02:00
34f652d3bf Fix issue when responding to a group invitation. 2018-09-02 17:39:00 +02:00
8f65890f29 Added the form to invite a user. 2018-09-02 17:34:30 +02:00
413cc6ddf8 Reorganized groups member page. 2018-09-02 15:05:52 +02:00
ccd0fd03a9 Improve groups appearance 2018-09-02 14:26:20 +02:00
6588b3d13a Add a notice when the user does not belong to any group. 2018-09-02 14:20:32 +02:00
4860ee6623 Upgraded request. 2018-09-02 14:14:21 +02:00
e8df43351f Can force the request to get multiple groups. 2018-09-02 14:14:10 +02:00
1c1dbe8454 Can delete groups. 2018-08-31 10:33:51 +02:00
7e09e0f2f9 Created a method to prompt user password. 2018-08-31 10:25:02 +02:00
c495337aa6 Click on search link collapse toggle menu 2018-08-31 09:06:29 +02:00
141 changed files with 30648 additions and 241 deletions

View File

@ -21,8 +21,11 @@ ComunicWeb would not exists without the following technologies developped by the
- jquery.hotkeys
- bootstrap-wysiwyg (https://github.com/steveathon/bootstrap-wysiwyg/)
- wdt-emoji-bundle (http://ned.im/wdt-emoji-bundle)
- PNGLib (http://www.xarg.org/2010/03/generate-client-side-png-files-using-javascript/) (BSD Licence)
- Identicon (http://github.com/stewartlord/identicon.js) (BSD Licence)
- FileSaver.js (http://eligrey.com) (by Eli Grey) (MIT Licence)
- JSZip (https://github.com/Stuk/jszip.git) (MIT Licence)
- JSZip Utils (https://github.com/Stuk/jszip-utils.git) (MIT Licence)
- PNGLib (http://www.xarg.org/2010/03/generate-client-side-png-files-using-javascript/) (BSD License)
- Identicon (http://github.com/stewartlord/identicon.js) (BSD License)
- FileSaver.js (http://eligrey.com) (by Eli Grey) (MIT License)
- JSZip (https://github.com/Stuk/jszip.git) (MIT License)
- JSZip Utils (https://github.com/Stuk/jszip-utils.git) (MIT License)
- SCEditor (BBC WYIWYG editor) (https://github.com/samclarke/SCEditor) (MIT License)
- JavaScript BBCode Parser (https://github.com/Frug/js-bbcode-parser) (MIT License)
- Pacman (https://github.com/daleharvey/pacman) (WTFPL License)

View File

@ -0,0 +1,301 @@
/*
* Javascript BBCode Parser Config Options
* @author Philip Nicolcev
* @license MIT License
*/
var parserColors = [ 'gray', 'silver', 'white', 'yellow', 'orange', 'red', 'fuchsia', 'blue', 'green', 'black', '#cd38d9' ];
var parserTags = {
'b': {
openTag: function(params,content) {
return '<b>';
},
closeTag: function(params,content) {
return '</b>';
}
},
'code': {
openTag: function(params,content) {
return '<code>';
},
closeTag: function(params,content) {
return '</code>';
},
noParse: true
},
'color': {
openTag: function(params,content) {
var colorCode = params.substr(1) || "inherit";
BBCodeParser.regExpAllowedColors.lastIndex = 0;
BBCodeParser.regExpValidHexColors.lastIndex = 0;
if ( !BBCodeParser.regExpAllowedColors.test( colorCode ) ) {
if ( !BBCodeParser.regExpValidHexColors.test( colorCode ) ) {
colorCode = "inherit";
} else {
if (colorCode.substr(0,1) !== "#") {
colorCode = "#" + colorCode;
}
}
}
return '<span style="color:' + colorCode + '">';
},
closeTag: function(params,content) {
return '</span>';
}
},
'i': {
openTag: function(params,content) {
return '<i>';
},
closeTag: function(params,content) {
return '</i>';
}
},
'img': {
openTag: function(params,content) {
var myUrl = content;
BBCodeParser.urlPattern.lastIndex = 0;
if ( !BBCodeParser.urlPattern.test( myUrl ) ) {
myUrl = "";
}
return '<img class="bbCodeImage" src="' + myUrl + '">';
},
closeTag: function(params,content) {
return '';
},
content: function(params,content) {
return '';
}
},
'list': {
openTag: function(params,content) {
return '<ul>';
},
closeTag: function(params,content) {
return '</ul>';
},
restrictChildrenTo: ["*", "li"]
},
'noparse': {
openTag: function(params,content) {
return '';
},
closeTag: function(params,content) {
return '';
},
noParse: true
},
'quote': {
openTag: function(params,content) {
return '<blockquote>';
},
closeTag: function(params,content) {
return '</blockquote>';
}
},
's': {
openTag: function(params,content) {
return '<s>';
},
closeTag: function(params,content) {
return '</s>';
}
},
'size': {
openTag: function(params,content) {
var mySize = parseInt(params.substr(1),10) || 0;
if (mySize < 10 || mySize > 20) {
mySize = 'inherit';
} else {
mySize = mySize + 'px';
}
return '<span style="font-size:' + mySize + '">';
},
closeTag: function(params,content) {
return '</span>';
}
},
'u': {
openTag: function(params,content) {
return '<span style="text-decoration:underline">';
},
closeTag: function(params,content) {
return '</span>';
}
},
'url': {
openTag: function(params,content) {
var myUrl;
if (!params) {
myUrl = content.replace(/<.*?>/g,"");
} else {
myUrl = params.substr(1);
}
BBCodeParser.urlPattern.lastIndex = 0;
if ( !BBCodeParser.urlPattern.test( myUrl ) ) {
myUrl = "#";
}
BBCodeParser.urlPattern.lastIndex = 0;
if ( !BBCodeParser.urlPattern.test( myUrl ) ) {
myUrl = "";
}
return '<a href="' + myUrl + '">';
},
closeTag: function(params,content) {
return '</a>';
}
},
//COMUNIC ADD BEGIN
'left': {
openTag: function(params,content) {
return '<p style="text-align: left;">';
},
closeTag: function(params,content) {
return '</p>';
}
},
'center': {
openTag: function(params,content) {
return '<p style="text-align: center;">';
},
closeTag: function(params,content) {
return '</p>';
}
},
'right': {
openTag: function(params,content) {
return '<p style="text-align: right;">';
},
closeTag: function(params,content) {
return '</p>';
}
},
'justify': {
openTag: function(params,content) {
return '<p style="text-align: justify;">';
},
closeTag: function(params,content) {
return '</p>';
}
},
'ul': {
openTag: function(params,content) {
return '<ul>';
},
closeTag: function(params,content) {
return '</ul>';
}
},
'ol': {
openTag: function(params,content) {
return '<ol>';
},
closeTag: function(params,content) {
return '</ol>';
}
},
'li': {
openTag: function(params,content) {
return '<li>';
},
closeTag: function(params,content) {
return '</li>';
}
},
'sup': {
openTag: function(params,content) {
return '<sup>';
},
closeTag: function(params,content) {
return '</sup>';
}
},
'sub': {
openTag: function(params,content) {
return '<sub>';
},
closeTag: function(params,content) {
return '</sub>';
}
},
'ltr': {
openTag: function(params,content) {
return '<div style="text-align: left;">';
},
closeTag: function(params,content) {
return '</div>';
}
},
'rtl': {
openTag: function(params,content) {
return '<div style="text-align: right;">';
},
closeTag: function(params,content) {
return '</div>';
}
},
'table': {
openTag: function(params,content) {
return '<table border="1" style="margin: auto;">';
},
closeTag: function(params,content) {
return '</table>';
}
},
'tr': {
openTag: function(params,content) {
return '<tr>';
},
closeTag: function(params,content) {
return '</tr>';
}
},
'td': {
openTag: function(params,content) {
return '<td>';
},
closeTag: function(params,content) {
return '</td>';
}
},
'hr': {
openTag: function(params,content) {
return '<hr />';
},
closeTag: function(params,content) {
return '';
},
content: function(params, content){
return '';
}
},
//COMUNIC ADD END
};

View File

@ -0,0 +1,152 @@
/*
* Javascript BBCode Parser
* @author Philip Nicolcev
* @license MIT License
*/
var BBCodeParser = (function(parserTags, parserColors) {
'use strict';
var me = {},
urlPattern = /^(?:https?|file|c):(?:\/{1,3}|\\{1})[-a-zA-Z0-9:;@#%&()~_?\+=\/\\\.]*$/,
emailPattern = /[^\s@]+@[^\s@]+\.[^\s@]+/,
fontFacePattern = /^([a-z][a-z0-9_]+|"[a-z][a-z0-9_\s]+")$/i,
tagNames = [],
tagNamesNoParse = [],
regExpAllowedColors,
regExpValidHexColors = /^#?[a-fA-F0-9]{6}$/,
ii, tagName, len;
// create tag list and lookup fields
for (tagName in parserTags) {
if (!parserTags.hasOwnProperty(tagName))
continue;
if (tagName === '*') {
tagNames.push('\\' + tagName);
} else {
tagNames.push(tagName);
if ( parserTags[tagName].noParse ) {
tagNamesNoParse.push(tagName);
}
}
parserTags[tagName].validChildLookup = {};
parserTags[tagName].validParentLookup = {};
parserTags[tagName].restrictParentsTo = parserTags[tagName].restrictParentsTo || [];
parserTags[tagName].restrictChildrenTo = parserTags[tagName].restrictChildrenTo || [];
len = parserTags[tagName].restrictChildrenTo.length;
for (ii = 0; ii < len; ii++) {
parserTags[tagName].validChildLookup[ parserTags[tagName].restrictChildrenTo[ii] ] = true;
}
len = parserTags[tagName].restrictParentsTo.length;
for (ii = 0; ii < len; ii++) {
parserTags[tagName].validParentLookup[ parserTags[tagName].restrictParentsTo[ii] ] = true;
}
}
regExpAllowedColors = new RegExp('^(?:' + parserColors.join('|') + ')$');
/*
* Create a regular expression that captures the innermost instance of a tag in an array of tags
* The returned RegExp captures the following in order:
* 1) the tag from the array that was matched
* 2) all (optional) parameters included in the opening tag
* 3) the contents surrounded by the tag
*
* @param {type} tagsArray - the array of tags to capture
* @returns {RegExp}
*/
function createInnermostTagRegExp(tagsArray) {
var openingTag = '\\[(' + tagsArray.join('|') + ')\\b(?:[ =]([\\w"#\\-\\:\\/= ]*?))?\\]',
notContainingOpeningTag = '((?:(?=([^\\[]+))\\4|\\[(?!\\1\\b(?:[ =](?:[\\w"#\\-\\:\\/= ]*?))?\\]))*?)',
closingTag = '\\[\\/\\1\\]';
return new RegExp( openingTag + notContainingOpeningTag + closingTag, 'i');
}
/*
* Escape the contents of a tag and mark the tag with a null unicode character.
* To be used in a loop with a regular expression that captures tags.
* Marking the tag prevents it from being matched again.
*
* @param {type} matchStr - the full match, including the opening and closing tags
* @param {type} tagName - the tag that was matched
* @param {type} tagParams - parameters passed to the tag
* @param {type} tagContents - everything between the opening and closing tags
* @returns {String} - the full match with the tag contents escaped and the tag marked with \u0000
*/
function escapeInnerTags(matchStr, tagName, tagParams, tagContents) {
tagParams = tagParams || "";
tagContents = tagContents || "";
tagContents = tagContents.replace(/\[/g, "&#91;").replace(/\]/g, "&#93;");
return "[\u0000" + tagName + tagParams + "]" + tagContents + "[/\u0000" + tagName + "]";
}
/*
* Escape all BBCodes that are inside the given tags.
*
* @param {string} text - the text to search through
* @param {string[]} tags - the tags to search for
* @returns {string} - the full text with the required code escaped
*/
function escapeBBCodesInsideTags(text, tags) {
var innerMostRegExp;
if (tags.length === 0 || text.length < 7)
return text;
innerMostRegExp = createInnermostTagRegExp(tags);
while (
text !== (text = text.replace(innerMostRegExp, escapeInnerTags))
);
return text.replace(/\u0000/g,'');
}
/*
* Process a tag and its contents according to the rules provided in parserTags.
*
* @param {type} matchStr - the full match, including the opening and closing tags
* @param {type} tagName - the tag that was matched
* @param {type} tagParams - parameters passed to the tag
* @param {type} tagContents - everything between the opening and closing tags
* @returns {string} - the fully processed tag and its contents
*/
function replaceTagsAndContent(matchStr, tagName, tagParams, tagContents) {
tagName = tagName.toLowerCase();
tagParams = tagParams || "";
tagContents = tagContents || "";
return parserTags[tagName].openTag(tagParams, tagContents) + (parserTags[tagName].content ? parserTags[tagName].content(tagParams, tagContents) : tagContents) + parserTags[tagName].closeTag(tagParams, tagContents);
}
function processTags(text, tagNames) {
var innerMostRegExp;
if (tagNames.length === 0 || text.length < 7)
return text;
innerMostRegExp = createInnermostTagRegExp(tagNames);
while (
text !== (text = text.replace(innerMostRegExp, replaceTagsAndContent))
);
return text;
}
/*
* Public Methods and Properties
*/
me.process = function(text, config) {
text = escapeBBCodesInsideTags(text, tagNamesNoParse);
return processTags(text, tagNames);
};
me.allowedTags = tagNames;
me.urlPattern = urlPattern;
me.emailPattern = emailPattern;
me.regExpAllowedColors = regExpAllowedColors;
me.regExpValidHexColors = regExpValidHexColors;
return me;
})(parserTags, parserColors);

Binary file not shown.

13
assets/3rdparty/pacman/LICENSE vendored Normal file
View File

@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.

BIN
assets/3rdparty/pacman/audio/die.mp3 vendored Normal file

Binary file not shown.

BIN
assets/3rdparty/pacman/audio/die.ogg vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/3rdparty/pacman/audio/eating.mp3 vendored Normal file

Binary file not shown.

BIN
assets/3rdparty/pacman/audio/eating.ogg vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/3rdparty/pacman/audio/eatpill.mp3 vendored Normal file

Binary file not shown.

BIN
assets/3rdparty/pacman/audio/eatpill.ogg vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
assets/3rdparty/pacman/audio/siren.mp3 vendored Normal file

Binary file not shown.

BIN
assets/3rdparty/pacman/audio/siren.ogg vendored Normal file

Binary file not shown.

BIN
assets/3rdparty/pacman/audio/vcs_90.mp3 vendored Normal file

Binary file not shown.

BIN
assets/3rdparty/pacman/audio/vcs_90.ogg vendored Normal file

Binary file not shown.

59
assets/3rdparty/pacman/index.html vendored Normal file
View File

@ -0,0 +1,59 @@
<!--
WTFPL License
Origin: https://github.com/daleharvey/pacman
--><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>HTML5 Pacman</title>
<style type="text/css">
@font-face {
font-family: 'BDCartoonShoutRegular';
src: url('BD_Cartoon_Shout-webfont.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
#pacman {
height:450px;
width:342px;
margin:0px auto;
}
#shim {
font-family: BDCartoonShoutRegular;
position:absolute;
visibility:hidden
}
body {
width:342px;
margin:0px;
font-family:sans-serif;
overflow: hidden;
}
</style>
</head>
<body>
<div id="pacman"></div>
<script src="pacman.js"></script>
<script src="modernizr-1.5.min.js"></script>
<script>
var el = document.getElementById("pacman");
if (Modernizr.canvas && Modernizr.localstorage &&
Modernizr.audio && (Modernizr.audio.ogg || Modernizr.audio.mp3)) {
window.setTimeout(function () { PACMAN.init(el, "./"); }, 0);
} else {
el.innerHTML = "Sorry, needs a decent browser<br /><small>" +
"(firefox 3.6+, Chrome 4+, Opera 10+ and Safari 4+)</small>";
}
</script>
</body>
</html>

View File

@ -0,0 +1,28 @@
/*!
* Modernizr JavaScript library 1.5
* http://www.modernizr.com/
*
* Copyright (c) 2009-2010 Faruk Ates - http://farukat.es/
* Dual-licensed under the BSD and MIT licenses.
* http://www.modernizr.com/license/
*
* Featuring major contributions by
* Paul Irish - http://paulirish.com
*/
window.Modernizr=function(i,e,I){function C(a,b){for(var c in a)if(m[a[c]]!==I&&(!b||b(a[c],D)))return true}function r(a,b){var c=a.charAt(0).toUpperCase()+a.substr(1);return!!C([a,"Webkit"+c,"Moz"+c,"O"+c,"ms"+c,"Khtml"+c],b)}function P(){j[E]=function(a){for(var b=0,c=a.length;b<c;b++)J[a[b]]=!!(a[b]in n);return J}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" "));j[Q]=function(a){for(var b=0,c,h=a.length;b<h;b++){n.setAttribute("type",a[b]);if(c=n.type!==
"text"){n.value=K;/tel|search/.test(n.type)||(c=/url|email/.test(n.type)?n.checkValidity&&n.checkValidity()===false:n.value!=K)}L[a[b]]=!!c}return L}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var j={},s=e.documentElement,D=e.createElement("modernizr"),m=D.style,n=e.createElement("input"),E="input",Q=E+"types",K=":)",M=Object.prototype.toString,y=" -o- -moz- -ms- -webkit- -khtml- ".split(" "),d={},L={},J={},N=[],u=function(){var a={select:"input",
change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"},b={};return function(c,h){var t=arguments.length==1;if(t&&b[c])return b[c];h=h||document.createElement(a[c]||"div");c="on"+c;var g=c in h;if(!g&&h.setAttribute){h.setAttribute(c,"return;");g=typeof h[c]=="function"}h=null;return t?(b[c]=g):g}}(),F={}.hasOwnProperty,O;O=typeof F!=="undefined"&&typeof F.call!=="undefined"?function(a,b){return F.call(a,b)}:function(a,b){return b in a&&typeof a.constructor.prototype[b]==="undefined"};
d.canvas=function(){return!!e.createElement("canvas").getContext};d.canvastext=function(){return!!(d.canvas()&&typeof e.createElement("canvas").getContext("2d").fillText=="function")};d.geolocation=function(){return!!navigator.geolocation};d.crosswindowmessaging=function(){return!!i.postMessage};d.websqldatabase=function(){var a=!!i.openDatabase;if(a)try{a=!!openDatabase("testdb","1.0","html5 test db",2E5)}catch(b){a=false}return a};d.indexedDB=function(){return!!i.indexedDB};d.hashchange=function(){return u("hashchange",
i)&&(document.documentMode===I||document.documentMode>7)};d.historymanagement=function(){return!!(i.history&&history.pushState)};d.draganddrop=function(){return u("drag")&&u("dragstart")&&u("dragenter")&&u("dragover")&&u("dragleave")&&u("dragend")&&u("drop")};d.websockets=function(){return"WebSocket"in i};d.rgba=function(){m.cssText="background-color:rgba(150,255,150,.5)";return(""+m.backgroundColor).indexOf("rgba")!==-1};d.hsla=function(){m.cssText="background-color:hsla(120,40%,100%,.5)";return(""+
m.backgroundColor).indexOf("rgba")!==-1};d.multiplebgs=function(){m.cssText="background:url(//:),url(//:),red url(//:)";return/(url\s*\(.*?){3}/.test(m.background)};d.backgroundsize=function(){return r("backgroundSize")};d.borderimage=function(){return r("borderImage")};d.borderradius=function(){return r("borderRadius","",function(a){return(""+a).indexOf("orderRadius")!==-1})};d.boxshadow=function(){return r("boxShadow")};d.opacity=function(){var a=y.join("opacity:.5;")+"";m.cssText=a;return(""+m.opacity).indexOf("0.5")!==
-1};d.cssanimations=function(){return r("animationName")};d.csscolumns=function(){return r("columnCount")};d.cssgradients=function(){var a=("background-image:"+y.join("gradient(linear,left top,right bottom,from(#9f9),to(white));background-image:")+y.join("linear-gradient(left top,#9f9, white);background-image:")).slice(0,-17);m.cssText=a;return(""+m.backgroundImage).indexOf("gradient")!==-1};d.cssreflections=function(){return r("boxReflect")};d.csstransforms=function(){return!!C(["transformProperty",
"WebkitTransform","MozTransform","OTransform","msTransform"])};d.csstransforms3d=function(){var a=!!C(["perspectiveProperty","WebkitPerspective","MozPerspective","OPerspective","msPerspective"]);if(a){var b=document.createElement("style"),c=e.createElement("div");b.textContent="@media ("+y.join("transform-3d),(")+"modernizr){#modernizr{height:3px}}";e.getElementsByTagName("head")[0].appendChild(b);c.id="modernizr";s.appendChild(c);a=c.offsetHeight===3;b.parentNode.removeChild(b);c.parentNode.removeChild(c)}return a};
d.csstransitions=function(){return r("transitionProperty")};d.fontface=function(){var a;if(/*@cc_on@if(@_jscript_version>=5)!@end@*/0)a=true;else{var b=e.createElement("style"),c=e.createElement("span"),h,t=false,g=e.body,o,w;b.textContent="@font-face{font-family:testfont;src:url('data:font/ttf;base64,AAEAAAAMAIAAAwBAT1MvMliohmwAAADMAAAAVmNtYXCp5qrBAAABJAAAANhjdnQgACICiAAAAfwAAAAEZ2FzcP//AAMAAAIAAAAACGdseWYv5OZoAAACCAAAANxoZWFk69bnvwAAAuQAAAA2aGhlYQUJAt8AAAMcAAAAJGhtdHgGDgC4AAADQAAAABRsb2NhAIQAwgAAA1QAAAAMbWF4cABVANgAAANgAAAAIG5hbWUgXduAAAADgAAABPVwb3N03NkzmgAACHgAAAA4AAECBAEsAAUAAAKZAswAAACPApkCzAAAAesAMwEJAAACAAMDAAAAAAAAgAACbwAAAAoAAAAAAAAAAFBmRWQAAAAgqS8DM/8zAFwDMwDNAAAABQAAAAAAAAAAAAMAAAADAAAAHAABAAAAAABGAAMAAQAAAK4ABAAqAAAABgAEAAEAAgAuqQD//wAAAC6pAP///9ZXAwAAAAAAAAACAAAABgBoAAAAAAAvAAEAAAAAAAAAAAAAAAAAAAABAAIAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAEACoAAAAGAAQAAQACAC6pAP//AAAALqkA////1lcDAAAAAAAAAAIAAAAiAogAAAAB//8AAgACACIAAAEyAqoAAwAHAC6xAQAvPLIHBADtMrEGBdw8sgMCAO0yALEDAC88sgUEAO0ysgcGAfw8sgECAO0yMxEhESczESMiARDuzMwCqv1WIgJmAAACAFUAAAIRAc0ADwAfAAATFRQWOwEyNj0BNCYrASIGARQGKwEiJj0BNDY7ATIWFX8aIvAiGhoi8CIaAZIoN/43KCg3/jcoAWD0JB4eJPQkHh7++EY2NkbVRjY2RgAAAAABAEH/+QCdAEEACQAANjQ2MzIWFAYjIkEeEA8fHw8QDxwWFhwWAAAAAQAAAAIAAIuYbWpfDzz1AAsEAAAAAADFn9IuAAAAAMWf0i797/8zA4gDMwAAAAgAAgAAAAAAAAABAAADM/8zAFwDx/3v/98DiAABAAAAAAAAAAAAAAAAAAAABQF2ACIAAAAAAVUAAAJmAFUA3QBBAAAAKgAqACoAWgBuAAEAAAAFAFAABwBUAAQAAgAAAAEAAQAAAEAALgADAAMAAAAQAMYAAQAAAAAAAACLAAAAAQAAAAAAAQAhAIsAAQAAAAAAAgAFAKwAAQAAAAAAAwBDALEAAQAAAAAABAAnAPQAAQAAAAAABQAKARsAAQAAAAAABgAmASUAAQAAAAAADgAaAUsAAwABBAkAAAEWAWUAAwABBAkAAQBCAnsAAwABBAkAAgAKAr0AAwABBAkAAwCGAscAAwABBAkABABOA00AAwABBAkABQAUA5sAAwABBAkABgBMA68AAwABBAkADgA0A/tDb3B5cmlnaHQgMjAwOSBieSBEYW5pZWwgSm9obnNvbi4gIFJlbGVhc2VkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgT3BlbiBGb250IExpY2Vuc2UuIEtheWFoIExpIGdseXBocyBhcmUgcmVsZWFzZWQgdW5kZXIgdGhlIEdQTCB2ZXJzaW9uIDMuYmFlYzJhOTJiZmZlNTAzMiAtIHN1YnNldCBvZiBKdXJhTGlnaHRiYWVjMmE5MmJmZmU1MDMyIC0gc3Vic2V0IG9mIEZvbnRGb3JnZSAyLjAgOiBKdXJhIExpZ2h0IDogMjMtMS0yMDA5YmFlYzJhOTJiZmZlNTAzMiAtIHN1YnNldCBvZiBKdXJhIExpZ2h0VmVyc2lvbiAyIGJhZWMyYTkyYmZmZTUwMzIgLSBzdWJzZXQgb2YgSnVyYUxpZ2h0aHR0cDovL3NjcmlwdHMuc2lsLm9yZy9PRkwAQwBvAHAAeQByAGkAZwBoAHQAIAAyADAAMAA5ACAAYgB5ACAARABhAG4AaQBlAGwAIABKAG8AaABuAHMAbwBuAC4AIAAgAFIAZQBsAGUAYQBzAGUAZAAgAHUAbgBkAGUAcgAgAHQAaABlACAAdABlAHIAbQBzACAAbwBmACAAdABoAGUAIABPAHAAZQBuACAARgBvAG4AdAAgAEwAaQBjAGUAbgBzAGUALgAgAEsAYQB5AGEAaAAgAEwAaQAgAGcAbAB5AHAAaABzACAAYQByAGUAIAByAGUAbABlAGEAcwBlAGQAIAB1AG4AZABlAHIAIAB0AGgAZQAgAEcAUABMACAAdgBlAHIAcwBpAG8AbgAgADMALgBiAGEAZQBjADIAYQA5ADIAYgBmAGYAZQA1ADAAMwAyACAALQAgAHMAdQBiAHMAZQB0ACAAbwBmACAASgB1AHIAYQBMAGkAZwBoAHQAYgBhAGUAYwAyAGEAOQAyAGIAZgBmAGUANQAwADMAMgAgAC0AIABzAHUAYgBzAGUAdAAgAG8AZgAgAEYAbwBuAHQARgBvAHIAZwBlACAAMgAuADAAIAA6ACAASgB1AHIAYQAgAEwAaQBnAGgAdAAgADoAIAAyADMALQAxAC0AMgAwADAAOQBiAGEAZQBjADIAYQA5ADIAYgBmAGYAZQA1ADAAMwAyACAALQAgAHMAdQBiAHMAZQB0ACAAbwBmACAASgB1AHIAYQAgAEwAaQBnAGgAdABWAGUAcgBzAGkAbwBuACAAMgAgAGIAYQBlAGMAMgBhADkAMgBiAGYAZgBlADUAMAAzADIAIAAtACAAcwB1AGIAcwBlAHQAIABvAGYAIABKAHUAcgBhAEwAaQBnAGgAdABoAHQAdABwADoALwAvAHMAYwByAGkAcAB0AHMALgBzAGkAbAAuAG8AcgBnAC8ATwBGAEwAAAAAAgAAAAAAAP+BADMAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAQACAQIAEQt6ZXJva2F5YWhsaQ==')}";
e.getElementsByTagName("head")[0].appendChild(b);c.setAttribute("style","font:99px _,arial,helvetica;position:absolute;visibility:hidden");if(!g){g=s.appendChild(e.createElement("fontface"));t=true}c.innerHTML="........";c.id="fonttest";g.appendChild(c);h=c.offsetWidth*c.offsetHeight;c.style.font="99px testfont,_,arial,helvetica";a=h!==c.offsetWidth*c.offsetHeight;var v=function(){if(g.parentNode){a=j.fontface=h!==c.offsetWidth*c.offsetHeight;s.className=s.className.replace(/(no-)?fontface\b/,"")+
(a?" ":" no-")+"fontface"}};setTimeout(v,75);setTimeout(v,150);addEventListener("load",function(){v();(w=true)&&o&&o(a);setTimeout(function(){t||(g=c);g.parentNode.removeChild(g);b.parentNode.removeChild(b)},50)},false)}j._fontfaceready=function(p){w||a?p(a):(o=p)};return a||h!==c.offsetWidth};d.video=function(){var a=e.createElement("video"),b=!!a.canPlayType;if(b){b=new Boolean(b);b.ogg=a.canPlayType('video/ogg; codecs="theora"');b.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"');b.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"')}return b};
d.audio=function(){var a=e.createElement("audio"),b=!!a.canPlayType;if(b){b=new Boolean(b);b.ogg=a.canPlayType('audio/ogg; codecs="vorbis"');b.mp3=a.canPlayType("audio/mpeg;");b.wav=a.canPlayType('audio/wav; codecs="1"');b.m4a=a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")}return b};d.localStorage=function(){return"localStorage"in i&&i.localStorage!==null};d.sessionStorage=function(){try{return"sessionStorage"in i&&i.sessionStorage!==null}catch(a){return false}};d.webworkers=function(){return!!i.Worker};
d.applicationCache=function(){var a=i.applicationCache;return!!(a&&typeof a.status!="undefined"&&typeof a.update=="function"&&typeof a.swapCache=="function")};d.svg=function(){return!!e.createElementNS&&!!e.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect};d.smil=function(){return!!e.createElementNS&&/SVG/.test(M.call(e.createElementNS("http://www.w3.org/2000/svg","animate")))};d.svgclippaths=function(){return!!e.createElementNS&&/SVG/.test(M.call(e.createElementNS("http://www.w3.org/2000/svg",
"clipPath")))};for(var z in d)if(O(d,z))N.push(((j[z.toLowerCase()]=d[z]())?"":"no-")+z.toLowerCase());j[E]||P();j.addTest=function(a,b){a=a.toLowerCase();if(!j[a]){b=!!b();s.className+=" "+(b?"":"no-")+a;j[a]=b;return j}};m.cssText="";D=n=null;(function(){var a=e.createElement("div");a.innerHTML="<elem></elem>";return a.childNodes.length!==1})()&&function(a,b){function c(f,k){if(o[f])o[f].styleSheet.cssText+=k;else{var l=t[G],q=b[A]("style");q.media=f;l.insertBefore(q,l[G]);o[f]=q;c(f,k)}}function h(f,
k){for(var l=new RegExp("\\b("+w+")\\b(?!.*[;}])","gi"),q=function(B){return".iepp_"+B},x=-1;++x<f.length;){k=f[x].media||k;h(f[x].imports,k);c(k,f[x].cssText.replace(l,q))}}for(var t=b.documentElement,g=b.createDocumentFragment(),o={},w="abbr|article|aside|audio|canvas|command|datalist|details|figure|figcaption|footer|header|hgroup|keygen|mark|meter|nav|output|progress|section|source|summary|time|video",v=w.split("|"),p=[],H=-1,G="firstChild",A="createElement";++H<v.length;){b[A](v[H]);g[A](v[H])}g=
g.appendChild(b[A]("div"));a.attachEvent("onbeforeprint",function(){for(var f,k=b.getElementsByTagName("*"),l,q,x=new RegExp("^"+w+"$","i"),B=-1;++B<k.length;)if((f=k[B])&&(q=f.nodeName.match(x))){l=new RegExp("^\\s*<"+q+"(.*)\\/"+q+">\\s*$","i");g.innerHTML=f.outerHTML.replace(/\r|\n/g," ").replace(l,f.currentStyle.display=="block"?"<div$1/div>":"<span$1/span>");l=g.childNodes[0];l.className+=" iepp_"+q;l=p[p.length]=[f,l];f.parentNode.replaceChild(l[1],l[0])}h(b.styleSheets,"all")});a.attachEvent("onafterprint",
function(){for(var f=-1,k;++f<p.length;)p[f][1].parentNode.replaceChild(p[f][0],p[f][1]);for(k in o)t[G].removeChild(o[k]);o={};p=[]})}(this,e);j._enableHTML5=true;j._version="1.5";s.className=s.className.replace(/\bno-js\b/,"")+" js";s.className+=" "+N.join(" ");return j}(this,this.document);

1270
assets/3rdparty/pacman/pacman.js vendored Normal file

File diff suppressed because it is too large Load Diff

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

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

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,3 @@
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
!function(e){"use strict";var t="sce-autodraft-"+location.pathname+location.search;function i(e){localStorage.removeItem(e||t)}e.plugins.autosave=function(){var a,e=this,o=t,r=864e5,n=function(e){localStorage.setItem(o,JSON.stringify(e))},s=function(){return JSON.parse(localStorage.getItem(o))};e.init=function(){var e=(a=this).opts&&a.opts.autosave||{};n=e.save||n,s=e.load||s,o=e.storageKey||o,r=e.expires||r,function(){for(var e=0;e<localStorage.length;e++){var t=localStorage.key(e);if(/^sce\-autodraft\-/.test(t)){var a=JSON.parse(localStorage.getItem(o));a&&a.time<Date.now()-r&&i(t)}}}()},e.signalReady=function(){for(var e=a.getContentAreaContainer();e;){if(/form/i.test(e.nodeName)){e.addEventListener("submit",i.bind(null,o),!0);break}e=e.parentNode}var t=s();t&&(a.sourceMode(t.sourceMode),a.val(t.value,!1),a.focus(),t.sourceMode?a.sourceEditorCaret(t.caret):a.getRangeHelper().restoreRange()),n({caret:this.sourceEditorCaret(),sourceMode:this.sourceMode(),value:a.val(null,!1),time:Date.now()})},e.signalValuechangedEvent=function(e){n({caret:this.sourceEditorCaret(),sourceMode:this.sourceMode(),value:e.detail.rawValue,time:Date.now()})}},e.plugins.autosave.clear=i}(sceditor);

View File

@ -0,0 +1,3 @@
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
!function(u,e){"use strict";var a=e.dom,c=/(^|\s)(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/watch\?v=)([^"&?\/ ]{11})(?:\&[\&_\?0-9a-z\#]+)?(\s|$)/i;e.plugins.autoyoutube=function(){this.signalPasteRaw=function(e){if(!a.closest(this.currentNode(),"code")&&(e.html||e.text)){var t=u.createElement("div");e.html?t.innerHTML=e.html:t.textContent=e.text,function e(t){for(var o,n=t.firstChild;n;){if(3===n.nodeType){var i=n.nodeValue,r=n.parentNode,s=i.match(c);s&&(r.insertBefore(u.createTextNode(i.substr(0,s.index)+s[1]),n),r.insertBefore(a.parseHTML('<iframe width="560" height="315" frameborder="0" src="https://www.youtube-nocookie.com/embed/'+(o=s[2])+'" data-youtube-id="'+o+'" allowfullscreen></iframe>'),n),n.nodeValue=s[3]+i.substr(s.index+s[0].length))}else a.is(n,"code")||e(n);n=n.nextSibling}}(t),e.html=t.innerHTML}}}}(document,sceditor);

View File

@ -0,0 +1,3 @@
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
!function(n){"use strict";var v="data:image/gif;base64,R0lGODlhlgBkAPABAH19ffb29iH5BAAKAAAAIf4aQ3JlYXRlZCB3aXRoIGFqYXhsb2FkLmluZm8AIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAlgBkAAAC1YyPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5LL5jE6r1+y2+w2Py+f0uv2OvwD2fP6iD/gH6Pc2GIhg2JeQSNjGuLf4GMlYKIloefAIUEl52ZmJyaY5mUhqyFnqmQr6KRoaMKp66hbLumpQ69oK+5qrOyg4a6qYV2x8jJysvMzc7PwMHS09TV1tfY2drb3N3e39DR4uPk5ebn6Onq6+zt7u/g4fL99UAAAh+QQACgAAACwAAAAAlgBkAIEAAAB9fX329vYAAAAC3JSPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5LL5jE6r1+y2+w2Py+f0uv2OvwD2fP4iABgY+CcoCNeHuJdQyLjIaOiWiOj4CEhZ+SbZd/nI2RipqYhQOThKGpAZCuBZyArZprpqSupaCqtaazmLCRqai7rb2av5W5wqSShcm8fc7PwMHS09TV1tfY2drb3N3e39DR4uPk5ebn6Onq6+zt7u/g4fLz9PX29/j5/vVAAAIfkEAAoAAAAsAAAAAJYAZACBAAAAfX199vb2AAAAAuCUj6nL7Q+jnLTai7PevPsPhuJIluaJpurKtu4Lx/JM1/aN5/rO9/4PDAqHxKLxiEwql8ym8wmNSqfUqvWKzWq33K73Cw6Lx+Sy+YxOq9fstvsNj8vn9Lr9jr8E9nz+AgAYGLjQVwhXiJgguAiYgGjo9tinyCjoKLn3hpmJUGmJsBmguUnpCXCJOZraaXoKShoJe9DqehCqKlnqiZobuzrbyvuIO8xqKpxIPKlwrPCbBx0tPU1dbX2Nna29zd3t/Q0eLj5OXm5+jp6uvs7e7v4OHy8/T19vf4+fr7/P379UAAAh+QQACgAAACwAAAAAlgBkAIEAAAB9fX329vYAAAAC4JSPqcvtD6OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofEovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5LL5jE6r1+y2+w2Py+f0uv2OvwT2fP6iD7gAMEhICAeImIAYiFDoOPi22KcouZfw6BhZGUBZeYlp6LbJiTD6CQqg6Vm6eQqqKtkZ24iaKtrKunpQa9tmmju7Wwu7KFtMi3oYDMzompkHHS09TV1tfY2drb3N3e39DR4uPk5ebn6Onq6+zt7u/g4fLz9PX29/j5+vv8/f31QAADs=",c=void 0!==window.FileReader,u=/data:[^;]+;base64,/i;function g(e){for(var t=e.substr(5,e.indexOf(";")-5),n=atob(e.substr(e.indexOf(",")+1)),r=new Uint8Array(n.length),i=0;i<n.length;i++)r[i]=n[i].charCodeAt(0);try{return new Blob([r],{type:t})}catch(e){return null}}n.plugins.dragdrop=function(){if(c){var A,r,o,i,a,s=0;this.signalReady=function(){A=(r=this).opts.dragdrop||{},o=A.handleFile,i=r.getContentAreaContainer().parentNode,a=i.appendChild(n.dom.parseHTML('<div class="sceditor-dnd-cover" style="display: none"><p>'+r._("Drop files here")+"</p></div>").firstChild),i.addEventListener("dragover",e),i.addEventListener("dragleave",d),i.addEventListener("dragend",d),i.addEventListener("drop",t),r.getBody().addEventListener("dragover",e),r.getBody().addEventListener("drop",d)},this.signalPasteHtml=function(e){if(!("handlePaste"in A)||A.handlePaste){var t=document.createElement("div");t.innerHTML=e.val;for(var n=t.querySelectorAll("img"),r=0;r<n.length;r++){var i=n[r];if(u.test(i.src)){var a=g(i.src);a&&l(a)?o(a,f(i)):i.parentNode.removeChild(i)}}e.val=t.innerHTML}}}function d(){a.style.display="none",i.className=i.className.replace(/(^| )dnd( |$)/g,"")}function l(e){return!("application/x-moz-file"!==e.type&&A.allowedTypes&&A.allowedTypes.indexOf(e.type)<0)&&(!A.isAllowed||A.isAllowed(e))}function f(e){var n=document.createElement("img");function t(e){var t=r.getBody().ownerDocument.getElementById(n.id);t&&("string"==typeof e&&t.insertAdjacentHTML("afterend",e),t.parentNode.removeChild(t))}return n.src=v,n.className="sceditor-ignore",n.id="sce-dragdrop-"+s++,function(){return e?e.parentNode.replaceChild(n,e):r.wysiwygEditorInsertHtml(n.outerHTML),{insert:function(e){t(e)},cancel:t}}}function e(e){for(var t=e.dataTransfer,n=t.files.length||!t.items?t.files:t.items,r=0;r<n.length;r++)if("string"===n[r].kind)return;"none"===a.style.display&&(a.style.display="block",i.className+=" dnd"),e.preventDefault()}function t(e){var t=e.dataTransfer,n=t.files.length||!t.items?t.files:t.items;d();for(var r=0;r<n.length;r++){if("string"===n[r].kind)return;l(n[r])&&o(n[r],f())}e.preventDefault()}}}(sceditor);

View File

@ -0,0 +1,3 @@
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
!function(i){"use strict";i.plugins.format=function(){var n,a,c={p:"Paragraph",h1:"Heading 1",h2:"Heading 2",h3:"Heading 3",h4:"Heading 4",h5:"Heading 5",h6:"Heading 6",address:"Address",pre:"Preformatted Text"};this.init=function(){var e=this.opts,t=e.paragraphformat;e.format&&"bbcode"===e.format||(t&&(t.tags&&(c=t.tags),t.excludeTags&&t.excludeTags.forEach(function(e){delete c[e]})),this.commands.format||(this.commands.format={exec:a,txtExec:a,tooltip:"Format Paragraph"}),e.toolbar===i.defaultOptions.toolbar&&(e.toolbar=e.toolbar.replace(",color,",",color,format,")))},n=function(e,t){e.sourceMode()?e.insert("<"+t+">","</"+t+">"):e.execCommand("formatblock","<"+t+">")},a=function(e){var o=this,r=document.createElement("div");i.utils.each(c,function(t,a){var e=document.createElement("a");e.className="sceditor-option",e.textContent=a.name||a,e.addEventListener("click",function(e){o.closeDropDown(!0),a.exec?a.exec(o):n(o,t),e.preventDefault()}),r.appendChild(e)}),o.createDropDown(e,"format",r)}}}(sceditor);

View File

@ -0,0 +1,3 @@
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
!function(t){"use strict";var i=t.utils.extend;t.plugins.plaintext=function(){var e=!0;this.init=function(){var t=this.commands,n=this.opts;n&&n.plaintext&&n.plaintext.addButton&&(e=n.plaintext.enabled,t.pastetext=i(t.pastetext||{},{state:function(){return e?1:0},exec:function(){e=!e}}))},this.signalPasteRaw=function(t){if(e){if(t.html&&!t.text){var n=document.createElement("div");n.innerHTML=t.html,t.text=n.innerText}t.html=null}}}}(sceditor);

View File

@ -0,0 +1,2 @@
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */

View File

@ -0,0 +1,3 @@
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
!function(e){"use strict";sceditor.plugins.undo=function(){var r,o,e=this,u=0,a=50,n=[],c=[],s=!1,l=function(e){s=!0,o=e.value,r.sourceMode(e.sourceMode),r.val(e.value,!1),r.focus(),e.sourceMode?r.sourceEditorCaret(e.caret):r.getRangeHelper().restoreRange(),s=!1};e.init=function(){a=(r=this).undoLimit||a,r.addShortcut("ctrl+z",e.undo),r.addShortcut("ctrl+shift+z",e.redo),r.addShortcut("ctrl+y",e.redo)},e.undo=function(){var e=c.pop(),t=r.val(null,!1);return e&&!n.length&&t===e.value&&(e=c.pop()),e&&(n.length||n.push({caret:r.sourceEditorCaret(),sourceMode:r.sourceMode(),value:t}),n.push(e),l(e)),!1},e.redo=function(){var e=n.pop();return c.length||(c.push(e),e=n.pop()),e&&(c.push(e),l(e)),!1},e.signalReady=function(){var e=r.val(null,!1);o=e,c.push({caret:this.sourceEditorCaret(),sourceMode:this.sourceMode(),value:e})},e.signalValuechangedEvent=function(e){var t=e.detail.rawValue;0<a&&c.length>a&&c.shift(),!s&&o&&o!==t&&(n.length=0,(u+=function(e,t){var r,o,u,a,n=e.length,c=t.length,s=Math.max(n,c);for(r=0;r<s&&e.charAt(r)===t.charAt(r);r++);for(u=n<c?c-n:0,a=c<n?n-c:0,o=s-1;0<=o&&e.charAt(o-u)===t.charAt(o-a);o--);return o-r+1}(o,t))<20||u<50&&!/\s$/g.test(e.rawValue)||(c.push({caret:r.sourceEditorCaret(),sourceMode:r.sourceMode(),value:t}),u=0,o=t))}}}();

View File

@ -0,0 +1,3 @@
/* SCEditor v2.1.3 | (C) 2017, Sam Clarke | sceditor.com/license */
!function(t,r){"use strict";var e=t.plugins;function n(c){if(c._scePatched)return c;var t=function(){for(var t=[],e=0;e<arguments.length;e++){var n=arguments[e];n&&n.nodeType?t.push(r(n)):t.push(n)}return c.apply(this,t)};return t._scePatched=!0,t}function c(t){if(t._scePatched)return t;var e=function(){return r(t.apply(this,arguments))};return e._scePatched=!0,e}var o=t.command.set;if(t.command.set=function(t,e){return e&&"function"==typeof e.exec&&(e.exec=n(e.exec)),e&&"function"==typeof e.txtExec&&(e.txtExec=n(e.txtExec)),o.call(this,t,e)},e.bbcode){var a=e.bbcode.bbcode.set;e.bbcode.bbcode.set=function(t,e){return e&&"function"==typeof e.format&&(e.format=n(e.format)),a.call(this,t,e)}}var i=t.create;t.create=function(t,e){if(i.call(this,t,e),t&&t._sceditor){var n=t._sceditor;n.getBody=c(n.getBody),n.getContentAreaContainer=c(n.getContentAreaContainer)}}}(sceditor,jQuery);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
/*! SCEditor | (C) 2011-2013, Sam Clarke | sceditor.com/license */body,code:before,html,p,table{margin:0;padding:0;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px;color:#111;line-height:1.25;overflow:visible}html{height:100%}.ios{overflow:auto;-webkit-overflow-scrolling:touch}.ios body{position:relative;overflow:auto}body{min-height:100%;word-wrap:break-word}body.placeholder::before{content:attr(placeholder);color:#555;font-style:italic}ol,ul{margin-top:0;margin-bottom:0;padding-top:0;padding-bottom:0}table,td{border:1px dotted #000;empty-cells:show}table td{min-width:5px}code{display:block;background:#f1f1f1;white-space:pre;padding:1em;text-align:left;margin:.25em 0;direction:ltr}blockquote{background:#fff7d9;margin:.25em 0;border-left:.3em solid #f4e59f;padding:.5em .5em .5em .75em}blockquote cite{font-weight:700;display:block;font-size:1em;margin:0 -.5em .25em -.75em;padding:0 .5em .15em .75em;border-bottom:1px solid #f4e59f}h1,h2,h3,h4,h5,h6{padding:0;margin:0}div,p{min-height:1.25em}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

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

File diff suppressed because one or more lines are too long

BIN
assets/audio/notif_song.mp3 Normal file

Binary file not shown.

BIN
assets/audio/notif_song.ogg Normal file

Binary file not shown.

View File

@ -0,0 +1,551 @@
/*! SCEditor | (C) 2011-2016, Sam Clarke | sceditor.com/license */
/**
* Default SCEditor
* http://www.sceditor.com/
*
* Copyright (C) 2011-16, Sam Clarke
*
* SCEditor is licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* This version of the theme has been adapated by Pierre HUBERT for Comunic
* Modifications: Copyright (c) 2018-2019 Pierre HUBERT (MIT License)
*/
div.sceditor-grip,
.sceditor-button div {
background-image: url("famfamfam.png");
background-repeat: no-repeat;
width: 16px;
height: 16px;
}
.sceditor-button-youtube div {
background-position: 0px 0px;
}
.sceditor-button-link div {
background-position: 0px -16px;
}
.sceditor-button-unlink div {
background-position: 0px -32px;
}
.sceditor-button-underline div {
background-position: 0px -48px;
}
.sceditor-button-time div {
background-position: 0px -64px;
}
.sceditor-button-table div {
background-position: 0px -80px;
}
.sceditor-button-superscript div {
background-position: 0px -96px;
}
.sceditor-button-subscript div {
background-position: 0px -112px;
}
.sceditor-button-strike div {
background-position: 0px -128px;
}
.sceditor-button-source div {
background-position: 0px -144px;
}
.sceditor-button-size div {
background-position: 0px -160px;
}
.sceditor-button-rtl div {
background-position: 0px -176px;
}
.sceditor-button-right div {
background-position: 0px -192px;
}
.sceditor-button-removeformat div {
background-position: 0px -208px;
}
.sceditor-button-quote div {
background-position: 0px -224px;
}
.sceditor-button-print div {
background-position: 0px -240px;
}
.sceditor-button-pastetext div {
background-position: 0px -256px;
}
.sceditor-button-paste div {
background-position: 0px -272px;
}
.sceditor-button-outdent div {
background-position: 0px -288px;
}
.sceditor-button-orderedlist div {
background-position: 0px -304px;
}
.sceditor-button-maximize div {
background-position: 0px -320px;
}
.sceditor-button-ltr div {
background-position: 0px -336px;
}
.sceditor-button-left div {
background-position: 0px -352px;
}
.sceditor-button-justify div {
background-position: 0px -368px;
}
.sceditor-button-italic div {
background-position: 0px -384px;
}
.sceditor-button-indent div {
background-position: 0px -400px;
}
.sceditor-button-image div {
background-position: 0px -416px;
}
.sceditor-button-horizontalrule div {
background-position: 0px -432px;
}
.sceditor-button-format div {
background-position: 0px -448px;
}
.sceditor-button-font div {
background-position: 0px -464px;
}
.sceditor-button-emoticon div {
background-position: 0px -480px;
}
.sceditor-button-email div {
background-position: 0px -496px;
}
.sceditor-button-date div {
background-position: 0px -512px;
}
.sceditor-button-cut div {
background-position: 0px -528px;
}
.sceditor-button-copy div {
background-position: 0px -544px;
}
.sceditor-button-color div {
background-position: 0px -560px;
}
.sceditor-button-code div {
background-position: 0px -576px;
}
.sceditor-button-center div {
background-position: 0px -592px;
}
.sceditor-button-bulletlist div {
background-position: 0px -608px;
}
.sceditor-button-bold div {
background-position: 0px -624px;
}
div.sceditor-grip {
background-position: 0px -640px;
width: 10px;
height: 10px;
}
.rtl div.sceditor-grip {
background-position: 0px -650px;
}
/**
* SCEditor
* http://www.sceditor.com/
*
* Copyright (C) 2017, Sam Clarke (samclarke.com)
*
* SCEditor is licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*/
/*---------------------------------------------------
LESS Elements 0.7
---------------------------------------------------
A set of useful LESS mixins
More info at: http://lesselements.com
---------------------------------------------------*/
.sceditor-container {
display: -ms-flexbox;
display: flex;
-ms-flex-direction: column;
flex-direction: column;
position: relative;
/*background: #fff;
border: 1px solid #d9d9d9;
font-size: 13px;
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
color: #333;
line-height: 1;
font-weight: bold;
height: 250px;
border-radius: 4px;
background-clip: padding-box;*/
width: 100%;
min-height: 100px;
font-size: 14px;
line-height: 18px;
border: 1px solid #dddddd;
margin-bottom: 10px;
}
.sceditor-container *,
.sceditor-container *:before,
.sceditor-container *:after {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.sceditor-container,
.sceditor-container div,
div.sceditor-dropdown,
div.sceditor-dropdown div {
padding: 0;
margin: 0;
z-index: 3;
}
.sceditor-container iframe,
.sceditor-container textarea {
display: block;
-ms-flex: 1 1 0%;
flex: 1 1 0%;
line-height: 1.25;
border: 0;
outline: none;
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 14px;
color: #111;
padding: 0;
margin: 0px;
resize: none;
background: #fff;
height: auto !important;
width: auto !important;
width: calc(100% - 10px) !important;
min-height: 1px;
}
.sceditor-container textarea {
margin: 7px 5px;
}
div.sceditor-dnd-cover {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: rgba(255, 255, 255, 0.2);
border: 5px dashed #aaa;
z-index: 200;
font-size: 2em;
text-align: center;
color: #aaa;
}
div.sceditor-dnd-cover p {
position: relative;
top: 45%;
pointer-events: none;
}
div.sceditor-resize-cover {
position: absolute;
top: 0;
left: 0;
background: #000;
width: 100%;
height: 100%;
z-index: 10;
opacity: 0.3;
}
div.sceditor-grip {
overflow: hidden;
width: 10px;
height: 10px;
cursor: pointer;
position: absolute;
bottom: 0;
right: 0;
z-index: 3;
line-height: 0;
}
div.sceditor-grip.has-icon {
background-image: none;
}
.sceditor-maximize {
position: fixed;
top: 0;
left: 0;
height: 100% !important;
width: 100% !important;
border-radius: 0;
background-clip: padding-box;
z-index: 2000;
}
html.sceditor-maximize,
body.sceditor-maximize {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
overflow: hidden;
}
.sceditor-maximize div.sceditor-grip {
display: none;
}
.sceditor-maximize div.sceditor-toolbar {
border-radius: 0;
background-clip: padding-box;
}
/**
* Dropdown styleing
*/
div.sceditor-dropdown {
position: absolute;
border: 1px solid #ccc;
background: #fff;
z-index: 4000;
padding: 10px;
font-weight: normal;
font-size: 15px;
border-radius: 2px;
background-clip: padding-box;
box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.2);
}
div.sceditor-dropdown *,
div.sceditor-dropdown *:before,
div.sceditor-dropdown *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
div.sceditor-dropdown a,
div.sceditor-dropdown a:link {
color: #333;
}
div.sceditor-dropdown form {
margin: 0;
}
div.sceditor-dropdown label {
display: block;
font-weight: bold;
color: #3c3c3c;
padding: 4px 0;
}
div.sceditor-dropdown input,
div.sceditor-dropdown textarea {
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
outline: 0;
padding: 4px;
border: 1px solid #ccc;
border-top-color: #888;
margin: 0 0 .75em;
border-radius: 1px;
background-clip: padding-box;
}
div.sceditor-dropdown textarea {
padding: 6px;
}
div.sceditor-dropdown input:focus,
div.sceditor-dropdown textarea:focus {
border-color: #aaa;
border-top-color: #666;
box-shadow: inset 0 1px 5px rgba(0, 0, 0, 0.1);
}
div.sceditor-dropdown .button {
font-weight: bold;
color: #444;
padding: 6px 12px;
background: #ececec;
border: solid 1px #ccc;
border-radius: 2px;
background-clip: padding-box;
cursor: pointer;
margin: .3em 0 0;
}
div.sceditor-dropdown .button:hover {
background: #f3f3f3;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
}
div.sceditor-font-picker,
div.sceditor-fontsize-picker,
div.sceditor-format {
padding: 6px 0;
}
div.sceditor-color-picker {
padding: 4px;
}
div.sceditor-emoticons,
div.sceditor-more-emoticons {
padding: 0;
}
.sceditor-pastetext textarea {
border: 1px solid #bbb;
width: 20em;
}
.sceditor-emoticons img,
.sceditor-more-emoticons img {
padding: 0;
cursor: pointer;
margin: 2px;
}
.sceditor-more {
border-top: 1px solid #bbb;
display: block;
text-align: center;
cursor: pointer;
font-weight: bold;
padding: 6px 0;
}
.sceditor-dropdown a:hover {
background: #eee;
}
.sceditor-fontsize-option,
.sceditor-font-option,
.sceditor-format a {
display: block;
padding: 7px 10px;
cursor: pointer;
text-decoration: none;
color: #222;
}
.sceditor-fontsize-option {
padding: 7px 13px;
}
.sceditor-color-column {
float: left;
}
.sceditor-color-option {
display: block;
border: 2px solid #fff;
height: 18px;
width: 18px;
overflow: hidden;
}
.sceditor-color-option:hover {
border: 1px solid #aaa;
}
/**
* Toolbar styleing
*/
div.sceditor-toolbar {
flex-shrink: 0;
overflow: hidden;
padding: 3px 5px 2px;
/*background: #f7f7f7;
border-bottom: 1px solid #c0c0c0;*/
line-height: 0;
text-align: left;
user-select: none;
border-radius: 3px 3px 0 0;
background-clip: padding-box;
}
div.sceditor-group {
display: inline-block;
/*background: #ddd;*/
margin: 1px 5px 1px 0;
padding: 1px;
/*border-bottom: 1px solid #aaa;*/
border-radius: 3px;
background-clip: padding-box;
}
.sceditor-button {
float: left;
cursor: pointer;
padding: 3px 5px;
width: 22px;
height: 20px;
background-clip: padding-box;
background: #ddd;
display: flex !important;
align-items: center;
justify-content: center;
}
.sceditor-button:first-child {
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
}
.sceditor-button:last-child {
border-top-right-radius: 3px;
border-bottom-right-radius: 3px;
}
.sceditor-button:hover,
.sceditor-button:active,
.sceditor-button.active {
background: #fff;
box-shadow: inset 1px 1px 0 rgba(0,0,0,0.3), inset -1px 0 rgba(0,0,0,0.3), inset 0 -1px 0 rgba(0,0,0,0.2);
}
.sceditor-button:active {
background: #fff;
box-shadow: inset 1px 1px 0 rgba(0,0,0,0.3), inset -1px 0 rgba(0,0,0,0.3), inset 0 -1px 0 rgba(0,0,0,0.2), inset 0 0 8px rgba(0,0,0,0.3);
}
.sceditor-button.disabled:hover {
background: inherit;
cursor: default;
box-shadow: none;
}
.sceditor-button,
.sceditor-button div {
display: block;
}
.sceditor-button svg {
display: inline-block;
height: 12px;
width: 12px;
margin: 2px 0;
fill: #111;
text-decoration: none;
pointer-events: none;
line-height: 1;
}
.sceditor-button.disabled svg {
fill: #888;
}
.sceditor-button div {
display: inline-block;
margin: 2px 0;
padding: 0;
overflow: hidden;
line-height: 0;
font-size: 0;
color: transparent;
}
.sceditor-button.has-icon div {
display: none;
}
.sceditor-button.disabled div {
opacity: 0.3;
}
.text .sceditor-button,
.text .sceditor-button div,
.sceditor-button.text,
.sceditor-button.text div,
.text-icon .sceditor-button,
.text-icon .sceditor-button div,
.sceditor-button.text-icon,
.sceditor-button.text-icon div {
display: inline-block;
width: auto;
line-height: 16px;
font-size: 1em;
color: inherit;
text-indent: 0;
}
.text-icon .sceditor-button.has-icon div,
.sceditor-button.has-icon div,
.text .sceditor-button div,
.sceditor-button.text div {
padding: 0 2px;
background: none;
}
.text .sceditor-button svg,
.sceditor-button.text svg {
display: none;
}
.text-icon .sceditor-button div,
.sceditor-button.text-icon div {
padding: 0 2px 0 20px;
}
.rtl div.sceditor-toolbar {
text-align: right;
}
.rtl .sceditor-button {
float: right;
}
.rtl div.sceditor-grip {
right: auto;
left: 0;
}

View File

@ -23,4 +23,12 @@ a {
.a:focus, .a:hover {
color: #72afd2;
}
/**
* Sceditor iframe
*/
.sceditor-iframe-body {
padding: 5px;
padding-bottom: 0px;
}

View File

@ -115,4 +115,8 @@
#conversationsElem .direct-chat-msg.not-last-message-from-user .direct-chat-img {
margin-bottom: -5px;
}
#conversationsElem .direct-chat-msg.open .dropdown-menu {
margin-top: -20px;
}

View File

@ -0,0 +1,23 @@
/**
* Incognito mode stylesheet
*
* @author Pierre HUBERT
*/
#incognito-block {
position: fixed;
left: 10px;
bottom: 54px;
text-align: center;
background-color: #001F3F;
padding: 10px;
color: white;
}
#incognito-block i {
font-size: 200%;
}
#incognito-block span {
display: block;
}

View File

@ -0,0 +1,16 @@
/**
* Pacman stylesheet
*
* @author Pierre HUBERT
*/
.pacman-iframe {
width: 342px;
height: 426px;
margin: auto;
display: block;
}
.pacman-iframe + p {
text-align: center;
}

View File

@ -17,6 +17,9 @@
margin-bottom: 10px;
}
.post-form .new-message-content-container {
margin-bottom: 15px;
}
/**
* Message type chooser

View File

@ -1,8 +1,8 @@
/**
* ComunicWeb dark theme
*
* @author Pierre HUBERT
*/
* ComunicWeb dark theme
*
* @author Pierre HUBERT
*/
/**
* General definitions
@ -17,6 +17,10 @@
--white: silver;
}
body {
background-color: var(--black6);
}
p, h1, h2, h3, h4, h5, h6 {
color: var(--white);
}
@ -227,6 +231,12 @@ fieldset[disabled] .form-control {
}
}
@media screen and (max-width: 513px) {
#friendsList {
background-color: var(--black5);
}
}
#friendsList h4 {
color: var(--white);
}
@ -236,8 +246,8 @@ fieldset[disabled] .form-control {
}
/**
* Emoji picker
*/
* Emoji picker
*/
.wdt-emoji-popup {
background-color: var(--black6);
border: 1px var(--black6) solid;
@ -271,6 +281,50 @@ fieldset[disabled] .form-control {
background-color: var(--black4) !important;;
}
/**
* Sceditor
*/
.sceditor-iframe-body {
background-color: var(--black5);
color: var(--white);
}
.sceditor-container textarea {
background-color: var(--black5);
color: var(--white);
}
.sceditor-button {
background-color: var(--black6);
}
.sceditor-button svg {
fill: var(--black4);
}
.sceditor-button:hover,
.sceditor-button:active,
.sceditor-button.active {
background-color: var(--black4);
color: white;
}
.sceditor-button:hover svg,
.sceditor-button:active svg,
.sceditor-button.active svg {
fill: var(--black6);
}
div.sceditor-dropdown {
background-color: var(--black5);
}
div.sceditor-dropdown input {
background-color: var(--black4);
}
/**
* Conversations
*/
@ -307,6 +361,10 @@ fieldset[disabled] .form-control {
color: var(--white);
}
.conversation-settings-pane {
background-color: var(--black5) !important;
}
/**
* Home page
*/
@ -399,6 +457,10 @@ fieldset[disabled] .form-control {
color: var(--black4);
}
.post-form-choice span span {
color: inherit;
}
.post-form .post-form-choice input:checked ~ span {
color: var(--white);
}
@ -431,8 +493,8 @@ fieldset[disabled] .form-control {
/**
* Search page
*/
* Search page
*/
.nav > li > a:hover,
.nav > li > a:active,
.nav > li > a:focus {
@ -440,8 +502,8 @@ fieldset[disabled] .form-control {
}
/**
* Conversation page
*/
* Conversation page
*/
.conversations-page-container a {
background-color: var(--black6) !important;;
}
@ -480,4 +542,18 @@ fieldset[disabled] .form-control {
.big-box-conversation .direct-chat-text a {
background-color: transparent !important;
color: inherit !important;
}
/**
* Groups logo
*/
img[src$="groups_logo/default.png"] {
filter: invert(1) brightness(50%);
}
/**
* Read only friends list
*/
.friends-list-ro .friend a:hover .friends-name {
color: var(--black4);
}

View File

@ -11,6 +11,11 @@
padding-top: 50px;
}
.groups-main-page .no-group-notice {
margin-top: 10px;
text-align: center;
}
.groups-main-page .group-item {
text-align: justify;
margin-top: 10px;

View File

@ -18,6 +18,11 @@
text-align: center;
}
.group-members-page .invite-user-form {
margin-top: 30px;
margin-bottom: 30px;
}
.group-members-page .member {
margin-bottom: 10px;
}

View File

@ -35,4 +35,13 @@
margin: auto;
margin-bottom: 10px;
display: block;
}
.group-settings-container .delete-group-link-container {
text-align: center;
padding: 20px;
}
.group-settings-container .delete-group-link-container a {
color: black;
}

View File

@ -33,6 +33,10 @@ ComunicWeb.common.api = {
}
//Enable incognito mode if required
if(ComunicWeb.components.incognito.management.isEnabled())
params.incognito = true;
//Prepare data to send in request
var count = 0;
var datas = "";
@ -90,7 +94,11 @@ ComunicWeb.common.api = {
data.append('userToken2', tokens.token2);
}
}
}
//Enable incognito mode if required
if(ComunicWeb.components.incognito.management.isEnabled())
data.append("incognito", true);
//Create request
var apiXHR = new XMLHttpRequest();

View File

@ -109,6 +109,10 @@ ComunicWeb.common.error.pageNotFound = function(additionnalData, targetElement){
*/
ComunicWeb.common.error.syntaxtError = function(error, additional){
//Do not do anything in production mode
if(ComunicWeb.__config.productionMode == true)
return;
//Create a modal dialog to report error
var dialog = ComunicWeb.common.messages.createDialogSkeleton({
type: "danger",

View File

@ -118,6 +118,12 @@ var ComunicWeb = {
* Prompt the user to input a string
*/
inputString: function(title, message, defaultValue, callback){},
/**
* Prompt the user to enter his password
*/
promptPassword: function(info){},
},
/**
@ -222,6 +228,22 @@ var ComunicWeb = {
getAndShowJSONtemplate: function(targetElem, templateURI, additionalData, afterParsingJSONtemplate, cleanContainer){},
},
/**
* Page title management
*/
pageTitle: {
/**
* Set a new title to the page
*/
setTitle: function(title){},
/**
* Set new number of notifications
*/
setNotificationsNumber: function(number){}
},
/**
* Functions to check data input in forms
*/
@ -570,6 +592,13 @@ var ComunicWeb = {
*/
bottom: {
/**
* Bottom links
*/
links: [
//TODO : implement
],
/**
* Main bottom script file
*/
@ -781,7 +810,14 @@ var ComunicWeb = {
*/
unreadDropdown: {
//TODO : implementd
}
},
/**
* Conversation message editor
*/
messageEditor: {
//TODO : implement
},
},
/**
@ -1016,6 +1052,13 @@ var ComunicWeb = {
//TODO : implement
},
/**
* Notification song system
*/
song: {
//TODO : implement
},
/**
* Notifications utilities
*/
@ -1065,6 +1108,48 @@ var ComunicWeb = {
},
},
/**
* Dark Theme component
*/
darkTheme: {
//TODO : implement
},
/**
* Incognito mode component
*/
incognito: {
/**
* Keyboard catcher
*/
keyboard: {
//TODO : implement
},
/**
* Incognito management
*/
management: {
//TODO : implement
},
/**
* UI management
*/
ui: {
//TODO : implement
},
},
/**
* Easter egg : pacman
*/
pacman: {
//TODO : implement
},
},
/**

View File

@ -382,4 +382,85 @@ ComunicWeb.common.messages.inputString = function(title, message, defaultValue,
//Show the modal
$(modal).modal('show');
}
/**
* Prompt the user to input his password
*
* @param {Object} info Additionnal information
*/
ComunicWeb.common.messages.promptPassword = function(info){
var dialog = ComunicWeb.common.messages.createDialogSkeleton({
type: "danger",
title: "Password required"
});
$(dialog.modal).modal("show");
//Create modal close function
var closeModal = function(e, password){
$(dialog.modal).modal("hide");
emptyElem(dialog.modal);
dialog.modal.remove();
//Callback
if(info.callback)
info.callback(password);
};
dialog.cancelButton.addEventListener("click", closeModal);
dialog.closeModal.addEventListener("click", closeModal);
//Set dialog body
var passwordForm = createElem2({
appendTo: dialog.modalBody,
type: "div"
});
createElem2({
appendTo: passwordForm,
type: "p",
innerHTML: "We need your password to continue."
});
//Create pasword input group
var inputGroup = createElem2({
appendTo: passwordForm,
type: "div",
class: "input-group input-group-sm"
});
//Create password input
var passwordInput = createElem2({
appendTo: inputGroup,
type: "input",
class: "form-control",
elemType: "password"
});
//Create input group
var inputGroupContainer = createElem2({
appendTo: inputGroup,
type: "span",
class: "input-group-btn"
});
//Add submit button
var submitButton = createElem2({
appendTo: inputGroupContainer,
type: "button",
class: "btn btn-danger",
innerHTML: "Confirm deletion"
});
submitButton.addEventListener("click", function(e){
//Check given password
var password = passwordInput.value;
if(password.length < 4)
return notify("Please check given password !", "danger");
//Close modal
closeModal(null, password);
});
}

View File

@ -196,7 +196,7 @@ ComunicWeb.common.page = {
}
//Change page title
document.title = pageInfos.pageTitle;
ComunicWeb.common.pageTitle.setTitle(pageInfos.pageTitle);
//Change page URL, if required
if(additionnalData.no_url_update ? !additionnalData.no_url_update : true)
@ -277,6 +277,11 @@ ComunicWeb.common.page = {
//Call the method related to the page
eval(pageInfos.methodHandler + ("(additionnalData, pageTarget);"));
//Propagate information
SendEvent("openPage", {
page: pageURI
});
//Success
return true;

View File

@ -0,0 +1,53 @@
/**
* Page title management
*
* @author Pierre HUBERT
*/
ComunicWeb.common.pageTitle = {
/**
* Current page title
*/
_curr_title: "Comunic",
/**
* Current number of notifications
*/
_curr_notifications_number: 0,
/**
* Set a new title to the page
*
* @param {string} title The new title for the page
*/
setTitle: function(title){
this._curr_title = title;
this.__refresh();
},
/**
* Set new number of notifications
*
* @param {number} number The new number of notifications
*/
setNotificationsNumber: function(number){
this._curr_notifications_number = number;
this.__refresh();
},
/**
* Refresh document title
*/
__refresh: function(){
var title = "";
if(this._curr_notifications_number > 0)
title += "(" + this._curr_notifications_number + ") ";
title += this._curr_title;
document.title = title;
}
}

View File

@ -167,7 +167,8 @@ function getInfoGroup(id, callback){
*
* @param {Array} IDs The IDs of the groups to get information about
* @param {Function} callback Callback to call once we have information about the group
* @param {Boolean} force TRUE to force the request (ignore cache)
*/
function getInfoMultipleGroups(IDs, callback){
ComunicWeb.components.groups.info.getInfoMultiple(IDs, callback);
function getInfoMultipleGroups(IDs, callback, force){
ComunicWeb.components.groups.info.getInfoMultiple(IDs, callback, force);
}

View File

@ -48,6 +48,16 @@ ComunicWeb.common.system = {
*/
ComunicWeb.common.langs.initLanguages();
/**
* Initialize incognito mode detection
*/
ComunicWeb.components.incognito.management.init();
/**
* Refresh dark theme mode
*/
ComunicWeb.components.darkTheme.refresh();
/**
* What to do after login refresh
*/

View File

@ -40,6 +40,7 @@ function createElem(nodeType, appendTo){
* @info {String} placeholder The placeholder of the new element
* @info {String} innerHTML Specify the html content of the newly created element
* @info {String} innerLang Specify the key of the lang to use to fill the element
* @info {String} innerHTMLprefix Specify prefix to add at the begining of the content of the element
* @info {boolean} disabled Set whether the field should be disabled or not (input only)
* @return {HTMLElement} The newly created element
*/
@ -105,6 +106,9 @@ function createElem2(infos){
if(infos.innerLang)
newElem.innerHTML = lang(infos.innerLang);
if(infos.innerHTMLprefix)
newElem.innerHTML = infos.innerHTMLprefix + newElem.innerHTML;
//Set field state
if(infos.disabled)
@ -416,6 +420,10 @@ function checkString(value){
*/
function removeHtmlTags(input){
//Check if input string is empty
if(input == null)
return "";
//Prepare update
var output = input;
@ -435,6 +443,25 @@ function removeHtmlTags(input){
return output;
}
/**
* Replace all line break with paragraph tags
*
* @param {string} input Input string to convert
* @return {string} Generated string
*/
function lineBreakToPTags(input){
//Check if the string is empty
if(input == null || input == "")
return input;
//Change string
while(input.includes("\n"))
input = input.replace("\n", "</p><p>");
return "<p>"+input+"</p>";
}
/**
* Check a URL validity
*
@ -592,4 +619,85 @@ function dataURItoBlob(dataURI){
return new Blob([ia], {type: mimeString});
}
/**
* Satinize some HTML source code by removing all javascript event detectors
* from it
*
* @param {string} html The source code to update
* @return {string} Secured html
*/
function removeJavascriptEventsFromHTML(html){
//Check if the string to check is null (we will consider
//at safe in this case)
if(html == null)
return html;
//Search for unexceptable references
while(html.match(/on[a-zA-Z ]+=/i) != null){
var match = html.match(/on[a-zA-Z ]+=/i)[0];
html = html.replace(match, match.replace("on", "o<block></block>n"))
}
return html;
}
/**
* Get and return the DOM of a specified iframe
*
* @param {HTMLIFrameElement} iframe The iframe to process
* @return {HTMLDocument} DOM of the iframe
*/
function GetIframeDOM(iframe){
return iframe.contentWindow
? iframe.contentWindow.document
: iframe.contentDocument;
}
/**
* Initialize styles for a sceditor textarea
*
* @param {HTMLTextAreaElement} textarea Target textarea element that
* have sceditor initialized
*/
function ApplySceditorStyle(textarea){
//Get iframe DOM
var iframeDOM = GetIframeDOM(textarea.parentNode.getElementsByTagName("iframe")[0]);
//Apply stylesheets
document.querySelectorAll("link[rel='stylesheet']").forEach(function(entry){
//Skip the entry if it is disabled
if(entry.disabled)
return;
var elem = iframeDOM.createElement("link");
elem.rel = "stylesheet";
elem.href = entry.href;
iframeDOM.head.appendChild(elem);
});
//Apply new styles to body
iframeDOM.body.className += " sceditor-iframe-body";
}
/**
* Send a new javascript event
*
* @param {String} name The name of the event to create
* @param {Object} details Information about the event to create
*/
function SendEvent(name, details){
var event = new CustomEvent(name, {
detail: details,
bubbles: true,
cancelable: false
});
document.dispatchEvent(event);
}

View File

@ -0,0 +1,23 @@
/**
* Comunic bottom links list
*
* @author Pierre HUBERT
*/
ComunicWeb.components.bottom.links = [
//Language selector
{
innerLang: "bottom_bar_action_language",
icon: "fa-globe",
onclick: function(){ComunicWeb.components.langPicker.show();}
},
//About Comunic
{
innerLang: "bottom_bar_action_about",
icon: "fa-question-circle",
href: ComunicWeb.__config.aboutWebsiteURL,
target: "_blank"
}
];

View File

@ -43,27 +43,26 @@ ComunicWeb.components.bottom.main = {
innerHTML: "Comunic &nbsp; &nbsp; "
});
//Put the language selector link on the right
var langLink = createElem2({
appendTo: leftElements,
type: "a",
innerHTML: "<i class='fa fa-globe'></i> Language"
});
langLink.onclick = function(){
ComunicWeb.components.langPicker.show();
};
ComunicWeb.components.bottom.links.forEach(function(link){
add_space(leftElements);
add_space(leftElements);
var linkEl = createElem2({
appendTo: leftElements,
type: "a",
href: link.href,
innerHTML: link.innerHTML,
innerLang: link.innerLang,
innerHTMLprefix: "<i class='fa "+link.icon+"'></i> "
});
//Add about link
var aboutLink = createElem2({
appendTo: leftElements,
type: "a",
innerHTML: "<i class='fa fa-question-circle'></i> About",
href: ComunicWeb.__config.aboutWebsiteURL
if(link.target)
linkEl.setAttribute("target", link.target);
if(link.onclick)
linkEl.onclick = link.onclick;
add_space(leftElements);
add_space(leftElements);
});
aboutLink.setAttribute("target", "_blank");
}
}

View File

@ -910,6 +910,95 @@ ComunicWeb.components.conversations.chatWindows = {
element: textMessage,
});
//Add message dropdown menu
messageContainer.className += " dropdown";
var dropdownToggle = createElem2({
insertBefore: dateElem,
type: "i",
class: "hidden"
});
dropdownToggle.setAttribute("data-toggle", "dropdown");
var dropdownMenu = createElem2({
insertBefore: dateElem,
type: "ul",
class: "dropdown-menu"
});
dropdownMenu.setAttribute("role", "menu");
messageTargetElem.addEventListener("dblclick", function(){
$(dropdownToggle).dropdown("toggle");
});
//Add message options
if(userIsPoster){
//Update message content
var updateLi = createElem2({
type: "li",
appendTo: dropdownMenu
});
var updateLink = createElem2({
type: "a",
appendTo: updateLi,
innerHTML: "Edit"
});
updateLink.addEventListener("click", function(){
ComunicWeb.components.conversations.messageEditor.open(message, function(newContent){
//Apply and parse new message
textMessage.innerHTML = removeHtmlTags(newContent);
ComunicWeb.components.textParser.parse({
element: textMessage,
});
});
});
//Delete the message
var deleteLi = createElem2({
type: "li",
appendTo: dropdownMenu
});
var deleteLink = createElem2({
type: "a",
appendTo: deleteLi,
innerHTML: "Delete"
});
deleteLink.addEventListener("click", function(){
ComunicWeb.common.messages.confirm(
"Do you really want to delete this message? The operation can not be reverted!",
function(confirm){
if(!confirm) return;
//Hide the message
messageTargetElem.style.display = "none";
//Execute the request
ComunicWeb.components.conversations.interface.DeleteSingleMessage(
message.ID,
function(result){
if(!result){
messageTargetElem.style.display = "block";
notify("Could delete conversation message!", "danger");
}
}
);
}
)
});
}
//Return information about the message
return {
userID: message.ID_user,

View File

@ -363,6 +363,50 @@ ComunicWeb.components.conversations.interface = {
},
/**
* Intend to update the content of a single message
*
* @param {Number} messageID The ID of the message to update
* @param {String} content New content for the message
* @param {(success : Boolean) => any} callback Function called when
* the request is terminated
*/
UpdateSingleMessage: function(messageID, content, callback){
ComunicWeb.common.api.makeAPIrequest(
"conversations/updateMessage",
{
"messageID": messageID,
"content": content
},
true,
function(result){
callback(result.error ? false : true);
}
);
},
/**
* Intend to delete a single conversation message
*
* @param {Number} messageID The ID of the message to delete
* @param {(success: Boolean) => any} callback Function to call once the
* conversation message has been deleted
*/
DeleteSingleMessage: function(messageID, callback){
ComunicWeb.common.api.makeAPIrequest(
"conversations/deleteMessage",
{"messageID": messageID},
true,
function(result){
callback(result.error ? false : true);
}
);
},
/**
* Empty conversations cache
*

View File

@ -0,0 +1,46 @@
/**
* Conversation message editor
*
* @author Pierre HUBERT
*/
ComunicWeb.components.conversations.messageEditor = {
/**
* Open conversation message editor
*
* @param {Object} message Information about the message to open
* @param {(newcontent : String) => any} callback Callback function called only
* when the new message content has been applied
*/
open: function(message, callback){
ComunicWeb.common.messages.inputString(
"Update message content",
"Please specify the new content of the message:",
message.message,
function(content){
//Intend to update message content
ComunicWeb.components.conversations.interface.UpdateSingleMessage(
message.ID,
content,
function(result){
if(!result)
return notify("Could not update conversation message content!", "danger");
message.message = content;
callback(content);
}
);
}
);
}
}

View File

@ -0,0 +1,66 @@
/**
* Dark theme component
*
* @author Pierre HUBERT
*/
ComunicWeb.components.darkTheme = {
/**
* Specify whether dark theme has to be enabled or not
*/
_local_storage_name: "dark_theme_mode",
/**
* CSS element that contains dark theme CSS rules
*/
_cssElem: null,
/**
* Check out whether dark theme is enabled or not
*
* @return {boolean} TRUE if enabled / FALSE else
*/
isEnabled: function(){
return localStorage.getItem(this._local_storage_name) == "true";
},
/**
* Specify whether dark theme should be enabled or not
*
* @param {boolean} enable TRUE to enable / FALSE else
*/
setEnabled: function(enable){
localStorage.setItem(this._local_storage_name, enable ? "true" : "false");
this.refresh();
},
/**
* Refresh dark theme state
*/
refresh: function(){
//Check if the theme has to be disabled
if(!this.isEnabled()){
if(this._cssElem != null)
this._cssElem.disabled = true;
return;
}
//Check if CSS element is already loaded
else if(this._cssElem != null)
this._cssElem.disabled = false;
//We need to load dark theme
else {
this._cssElem = createElem2({
type: "link",
href: ComunicWeb.__config.assetsURL + "css/dark_theme.css"
});
this._cssElem.setAttribute("rel", "stylesheet");
document.head.appendChild(this._cssElem);
}
}
}

View File

@ -23,6 +23,7 @@ ComunicWeb.components.emoji.list = {
//Objects
"(movie)": "&#x1F4FD;",
"(w)": " &#x2753;"
}
}

View File

@ -99,6 +99,47 @@ ComunicWeb.components.emoji.picker = {
var parent = elem.parentNode;
parent.className += ' wdt-emoji-picker-parent';
elem.className += ' wdt-emoji-bundle-enabled wdt-emoji-picker-ready';
},
/**
* Add a detached picker to a page
*
* @param {HTMLElement} target Target element that will contains the icon
* @param {(emojie : string) => any} callback Callback function called each time a new
* emojie is selected
*/
addDetachedPicker: function(target, callback){
this.init();
//Create input text that will received new emojies
var input = createElem2({
type: "input",
appendTo: target,
class: "wdt-emoji-bundle-enabled hidden",
elemType: "text",
style: "display: none;"
});
ComunicWeb.components.emoji.picker.addPicker(input);
var interval = setInterval(function(){
//Check if input has been detached
if(!input.isConnected){
clearInterval(interval);
return;
}
//Securely send value to callback
if(input.value.length > 0){
var value = input.value;
input.value = "";
callback(value);
}
}, 500);
}
}

View File

@ -44,14 +44,15 @@ ComunicWeb.components.groups.info = {
*
* @param {Array} list The list of the IDs of the group to get information about
* @param {Function} callback
* @param {Boolean} force TRUE to ignore cache (FALSE by default)
*/
getInfoMultiple: function(list, callback){
getInfoMultiple: function(list, callback, force){
//First, check which group are unknown in the cache
var toFetch = Array();
list.forEach(function(id){
if(!ComunicWeb.components.groups.info._cache[id])
if(!ComunicWeb.components.groups.info._cache[id] || force)
toFetch.push(id);
});

View File

@ -171,6 +171,24 @@ ComunicWeb.components.groups.interface = {
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
},
/**
* Invite a user to join a group
*
* @param {Number} user_id The ID of the user to invite
* @param {Number} group_id Target group
* @param {Function} callback
*/
inviteUser: function(user_id, group_id, callback){
ComunicWeb.common.api.makeAPIrequest(
"groups/invite",
{
userID: user_id,
group_id: group_id
},
true, callback
);
},
/**
* Respond to a group invitation
*
@ -337,5 +355,22 @@ ComunicWeb.components.groups.interface = {
follow: follow
};
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
},
/**
* Delete a group
*
* @param {Number} groupID The ID of the group to delete
* @param {String} password The password of the user, for security
* @param {Function} callback
*/
deleteGroup: function(groupID, password, callback){
//Perform the request over the API
var apiURI = "groups/delete";
var params = {
groupID: groupID,
password: password
};
ComunicWeb.common.api.makeAPIrequest(apiURI, params, true, callback);
}
};

View File

@ -0,0 +1,31 @@
/**
* Incognito mode keyboard catcher
*
* @author Pierre HUBERT
*/
ComunicWeb.components.incognito.keyboard = {
/**
* Initialize incognito mode requests detection
*/
init: function(){
//We need to catch keyboard press to check if F6 key is pressed
window.addEventListener("keydown", function(e){
//Filter key
if(e.keyCode != 117)
return;
//If incognito mode is enabled, disable it
if(ComunicWeb.components.incognito.management.isEnabled())
ComunicWeb.components.incognito.management.setEnabled(false);
//Else we ask user confirmation
else
ComunicWeb.components.incognito.ui.confirmEnable();
});
}
}

View File

@ -0,0 +1,59 @@
/**
* Incognito mode management
*
* @author Pierre HUBERT
*/
ComunicWeb.components.incognito.management = {
/**
* This variable is use to check if incognito mode
* has already be initialized or not
*/
_is_init: false,
/**
* Specify whether incognito mode should be enabled or not
*/
_local_storage_name: "incognito_mode",
/**
* Initialize incognito component
*/
init: function(){
//This code should be run only once
if(this._is_init)
return;
this._is_init = true;
log("Initialize incognito mode");
//Initialize components
ComunicWeb.components.incognito.keyboard.init();
ComunicWeb.components.incognito.ui.init();
},
/**
* Check out whether incognito mode is enabled or not
*
* @return {Boolean} TRUE if incognito mode is enabled / FALSE else
*/
isEnabled: function(){
return localStorage.getItem(this._local_storage_name) === "true";
},
/**
* Update status of incognito mode
*
* @param {Boolean} enable TRUE to enable incognito mode / FALSE else
*/
setEnabled: function(enable){
localStorage.setItem(this._local_storage_name, enable ? "true" : "false");
//Propagate information
SendEvent("incognitoStatusChanged", {
enabled: enable
});
}
}

View File

@ -0,0 +1,97 @@
/**
* Incognito mode management
*
* @author Pierre HUBERT
*/
ComunicWeb.components.incognito.ui = {
/**
* Initialize UI component
*/
init: function(){
//Initialize incognito mode updates detection
document.addEventListener("incognitoStatusChanged", function(e){
ComunicWeb.components.incognito.ui.statusChanged();
})
document.addEventListener("openPage", function(){
ComunicWeb.components.incognito.ui.statusChanged();
});
},
/**
* Show confirmation dialog to enable incognito mode
*/
confirmEnable: function(){
//Ask user confirmation
ComunicWeb.common.messages.confirm(
"Are you sure do you want to enable incognito mode? When this mode is enabled, you can use Comunic while appearing as disconnected for your friends...",
function(confirm){
if(!confirm)
return;
//Enable incognito mode
ComunicWeb.components.incognito.management.setEnabled(true);
});
},
/**
* Function called each time incognito status is updated
*/
statusChanged: function(){
var enabled = ComunicWeb.components.incognito.management.isEnabled();
var incognitoBlock = byId("incognito-block");
//Check if incognito mode is disabled
if(!enabled){
if(incognitoBlock != null)
//Remove incognito block
incognitoBlock.remove();
return;
}
//Nothing has to done if incognito block is already visible
if(incognitoBlock)
return;
//Create incognito block
incognitoBlock = createElem2({
type: "div",
appendTo: document.body,
id: "incognito-block",
});
createElem2({
type: "i",
appendTo: incognitoBlock,
class: "fa fa-user-secret",
});
createElem2({
type: "span",
appendTo: incognitoBlock,
innerHTML: "Incognito mode"
});
var disableLink = createElem2({
type: "span",
appendTo: incognitoBlock,
class: "a",
innerHTML: "Disable"
});
disableLink.addEventListener("click", function(){
ComunicWeb.components.incognito.management.setEnabled(false);
})
}
}

View File

@ -5,6 +5,50 @@
*/
ComunicWeb.components.menuBar.authenticated = {
/**
* Dropdown menu links list
*/
dropdownMenuLinksList: [
//Conversations
{
innerLang: "menu_bar_action_conversations",
targetPage: "conversations",
icon: "fa-comments-o"
},
//Groups list
{
innerLang: "menu_bar_action_groups",
targetPage: "groups",
icon: "fa-group"
},
//Dark theme
{
innerLang: "menu_bar_action_dark_theme",
onclick: function(b){ComunicWeb.components.menuBar.authenticated.darkThemeButtonClicked(true, b)},
oninit: function(b){ComunicWeb.components.menuBar.authenticated.darkThemeButtonClicked(false, b)},
icon: "fa-sun-o"
},
//Settings list
{
innerLang: "menu_bar_action_settings",
targetPage: "settings",
icon: "fa-gear"
},
//Logout link
{
innerLang: "_menu_bar_action_logout",
targetPage: "logout",
icon: "fa-sign-out"
}
],
/**
* Add authenticated user specific elements
*
@ -79,63 +123,87 @@ ComunicWeb.components.menuBar.authenticated = {
dropdownContent.setAttribute("role", "menu");
//Add conversations link
var conversationsButton = createElem2({
appendTo: dropdownContent,
type: "li"
});
var conversationsLink = createElem2({
appendTo: conversationsButton,
type: "a",
innerLang: "menu_bar_action_conversations"
});
conversationsButton.onclick = function(){
openPage("conversations");
//Process links list
var addMenuOption = function(entry){
var linkButton = createElem2({
appendTo: dropdownContent,
type: "li"
});
var link = createElem2({
appendTo: linkButton,
type: "a",
href: entry.href,
innerLang: entry.innerLang,
innerHTML: entry.innerHTML,
innerHTMLprefix: entry.icon ? "<i class='fa " + entry.icon + "'></i> " : undefined,
});
if(entry.targetPage){
linkButton.onclick = function(){
openPage(entry.targetPage);
};
}
if(entry.target)
link.setAttribute("target", entry.target);
if(entry.onclick){
linkButton.addEventListener("click", function(){
entry.onclick(link);
});
}
if(entry.oninit){
entry.oninit(link);
}
};
//Add groups link
var groupsButton = createElem2({
appendTo: dropdownContent,
type: "li"
});
this.dropdownMenuLinksList.forEach(addMenuOption);
//Add divider
createElem2({
appendTo: groupsButton,
type: "a",
innerLang: "menu_bar_action_groups"
});
groupsButton.onclick = function(){
openPage("groups");
}
//Add settings link
var settingsButton = createElem2({
appendTo: dropdownContent,
type: "li"
type: "li",
class: "divider"
});
var settingsLink = createElem2({
appendTo: settingsButton,
type: "a",
innerLang: "menu_bar_action_settings"
});
settingsButton.onclick = function(){
openPage("settings");
};
//Add logout link
var logoutButton = createElem("li", dropdownContent);
var logoutButtonLink = createElem("a", logoutButton);
logoutButtonLink.innerHTML = lang("_menu_bar_action_logout");
logoutButton.onclick = function(){openPage("logout")};
ComunicWeb.components.bottom.links.forEach(addMenuOption);
//Return dropdown content element
return dropdownContent;
},
/**
* Called this method each time the dark theme button
* is clicked
*
* @param {Boolean} invert Specify whether dark theme mode should
* be inverted or not
* @param {HTMLElement} button Button element that has been
* clicked
*/
darkThemeButtonClicked: function(invert, button){
if(invert)
ComunicWeb.components.darkTheme.setEnabled(!ComunicWeb.components.darkTheme.isEnabled());
//Update icon
button.getElementsByTagName("i")[0].className =
"fa " + (ComunicWeb.components.darkTheme.isEnabled() ? "fa-moon-o" : "fa-sun-o");
},
/**
* Add alternate latest posts button
* (if the screen is too small to display "Comunic")
*
* @param {HTMLElement} target The target for the ubutton
* @param {HTMLElement} target The target for the button
*/
addAlternateLatestPostsButton: function(target){
//Create button
@ -258,7 +326,7 @@ ComunicWeb.components.menuBar.authenticated = {
var searchLinkLi = createElem2({
appendTo: navbarElem,
type: "li",
class: "navbar-left messages-menu visible-xs"
class: "navbar-left visible-xs"
});
var searchLink = createElem2({
@ -269,6 +337,7 @@ ComunicWeb.components.menuBar.authenticated = {
searchLink.addEventListener("click", function(){
openPage("search");
$(navbarElem.parentNode).collapse("toggle");
});
}

View File

@ -6,6 +6,11 @@
ComunicWeb.components.notifications.service = {
/**
* Last known number of notifications
*/
last_notifs_number: -1,
/**
* Init the service
*
@ -22,8 +27,12 @@ ComunicWeb.components.notifications.service = {
var interval = setInterval(function(){
//Auto-remove interval if the target has been removed
if(!target.isConnected)
if(!target.isConnected){
ComunicWeb.common.pageTitle.setNotificationsNumber(0);
ComunicWeb.components.notifications.service.last_notifs_number = -1;
return clearInterval(interval);
}
//Get the number of notifications from the API
ComunicWeb.components.notifications.interface.getAllUnread(function(response){
@ -55,6 +64,18 @@ ComunicWeb.components.notifications.service = {
}
//Sum notification number
var total_number_notifs = response.notifications + response.conversations;
//Update page title too
ComunicWeb.common.pageTitle.setNotificationsNumber(total_number_notifs);
//Play song if required
if(ComunicWeb.components.notifications.service.last_notifs_number != -1
&& total_number_notifs > ComunicWeb.components.notifications.service.last_notifs_number)
ComunicWeb.components.notifications.song.play();
ComunicWeb.components.notifications.service.last_notifs_number = total_number_notifs;
});
}, 2000);

View File

@ -0,0 +1,41 @@
/**
* Notification song
*
* @author Pierre HUBERT
*/
ComunicWeb.components.notifications.song = {
/**
* Song element : null by default
*/
songElem: null,
/**
* Play notification song once
*/
play: function(){
//Create song element if required
if(this.songElem == null){
this.songElem = createElem2({
type: "audio"
});
createElem2({
type: "source",
appendTo: this.songElem,
src: ComunicWeb.__config.assetsURL + "audio/notif_song.mp3"
});
createElem2({
type: "source",
appendTo: this.songElem,
src: ComunicWeb.__config.assetsURL + "audio/notif_song.ogg"
});
}
//Play song
this.songElem.play();
}
}

View File

@ -0,0 +1,46 @@
/**
* A little easter egg....
* A pacman !
*
* @author Pierre HUBERT
*/
ComunicWeb.components.pacman = {
/**
* Open pacman game
*/
open: function(){
var dialog = ComunicWeb.common.messages.createDialogSkeleton({
title: "Pacman game",
type: "default"
});
$(dialog.modal).modal("show");
//Create modal close function
var closeModal = function(){
$(dialog.modal).modal("hide");
};
dialog.cancelButton.addEventListener("click", closeModal);
dialog.closeModal.addEventListener("click", closeModal);
//This modal must be completely cleaned
$(dialog.modal).on("hidden.bs.modal", function(){
emptyElem(dialog.modal);
dialog.modal.remove();
});
//Create iframe
createElem2({
appendTo: dialog.modalBody,
type: "iframe",
class: "pacman-iframe",
src: ComunicWeb.__config.assetsURL + "3rdparty/pacman"
});
//Add a notice
add_p(dialog.modalBody, "Please click on the pacman grid and press N to start a new game.");
},
}

View File

@ -106,13 +106,22 @@ ComunicWeb.components.posts.edit = {
});
//Create update editor
var editorDiv = createElem2({
var editorTextarea = createElem2({
appendTo: updateDiv,
type: "div",
type: "textarea",
class: "editor",
innerHTML: infos.content
value: infos.content
});
$(editorDiv).wysiwyg();
sceditor.create(editorTextarea, {
format: 'bbcode',
width: "100%",
icons: "material",
height: "200px",
toolbarExclude: "youtube,image,size,link,print,mail,emoticon,maximize"
});
ApplySceditorStyle(editorTextarea);
//Create function to close modal
var closeModal = function(){
@ -131,7 +140,7 @@ ComunicWeb.components.posts.edit = {
}
//Get the new post content
var new_content = editorDiv.innerHTML;
var new_content = sceditor.instance(editorTextarea).getWysiwygEditorValue();
//Check the new post content
if(!ComunicWeb.components.posts.form._check_message(new_content)){

View File

@ -42,18 +42,42 @@ ComunicWeb.components.posts.form = {
});
//Create post message textarea
var inputMessageDiv = createElem2({
var inputMessageTextarea = createElem2({
appendTo: newPostMessageContener,
type: "div",
class: "new-message wdt-emoji-bundle-enabled",
type: "textarea",
class: "new-message",
innerHTML: ""
});
//Enable bootstrap-wysiwyg
$(inputMessageDiv).wysiwyg();
var inputMessageToolbarTarget = createElem2({
appendTo: newPostMessageContener,
type: "div",
class: "new-message-content-container"
});
sceditor.create(inputMessageTextarea, {
format: 'bbcode',
width: "100%",
toolbar: 'bold,italic,underline,subscript,superscript,' +
'left,center,right,justify,color,' +
'bulletlist,orderedlist,table,code,quote,source',
emoticonsEnabled: false,
icons: "material",
autoExpand: true,
resizeMaxHeight: -1,
toolbarContainer: inputMessageToolbarTarget
});
//Apply all stylesheets to the editor iframe
ApplySceditorStyle(inputMessageTextarea);
//Enable emojies picker
ComunicWeb.components.emoji.picker.addPicker(inputMessageDiv);
ComunicWeb.components.emoji.picker.addDetachedPicker(newPostMessageContener, function(emojie){
//Append new emojie to the instance
sceditor.instance(inputMessageTextarea).insertText(emojie);
});
//Add the different post types
@ -344,7 +368,7 @@ ComunicWeb.components.posts.form = {
var datas = new FormData();
//Get the message content
var message_content = inputMessageDiv.innerHTML;
var message_content = sceditor.instance(inputMessageTextarea).getWysiwygEditorValue();
datas.append("content", message_content);
//Check if the message includes an image

View File

@ -826,7 +826,7 @@ ComunicWeb.components.posts.ui = {
appendTo: postRoot,
type: "div",
class: "post_content",
innerHTML: info.content
innerHTML: lineBreakToPTags(BBCodeParser.process(removeHtmlTags(info.content)))
});
//Parse emojies

View File

@ -53,9 +53,15 @@ ComunicWeb.common.langs.en = {
_menu_bar_search_placeholder: "Search...",
menu_bar_action_conversations: "Conversations",
menu_bar_action_groups: "Groups",
menu_bar_action_dark_theme: "Dark theme",
menu_bar_action_settings: "Settings",
_menu_bar_action_logout: "Logout",
//Bottom bar - links
bottom_bar_action_language: "Language",
bottom_bar_action_about: "About",
//Posts - Actions
posts_actions_err_get_single: "An error occured while getting information about the post !",

View File

@ -54,9 +54,14 @@ ComunicWeb.common.langs.fr = {
_menu_bar_search_placeholder: "Recherche...",
menu_bar_action_conversations: "Conversations",
menu_bar_action_groups: "Groupes",
menu_bar_action_dark_theme: "Th&egrave;me sombre",
menu_bar_action_settings: "Param&egrave;tres",
_menu_bar_action_logout: "Déconnexion",
//Bottom bar - links
bottom_bar_action_language: "Langue",
bottom_bar_action_about: "A propos",
//Posts - Actions
posts_actions_err_get_single: "Une erreur a survenue lors de la r&eacute;cup&eacute;ration d'informations sur le post !",

View File

@ -376,6 +376,7 @@ ComunicWeb.pages.conversations.conversation = {
placeholder: "New message...",
});
inputText.maxLength = 200;
inputText.focus();
//Enable textarea 2.0 on the message

View File

@ -14,7 +14,7 @@ ComunicWeb.pages.groups.pages.create = {
open: function(target){
//Update page title
document.title = "Create a group";
ComunicWeb.common.pageTitle.setTitle("Create a group");
//Create page container
var pageContainer = createElem2({

View File

@ -62,7 +62,7 @@ ComunicWeb.pages.groups.pages.forbidden = {
display: function(id, result, target){
//Update page title
document.title = result.name;
ComunicWeb.common.pageTitle.setTitle(result.name);
//Create a box to contain information about registration
var box = createElem2({

View File

@ -49,7 +49,7 @@ ComunicWeb.pages.groups.pages.group = {
display: function(id, info, target){
//Update page title
document.title = info.name;
ComunicWeb.common.pageTitle.setTitle(info.name);
//Create page row
var pageRow = createElem2({

View File

@ -38,23 +38,43 @@ ComunicWeb.pages.groups.pages.main = {
"info");
pageContainer.appendChild(message);
/**
* This function is used if an error occurs while retrieving the list
* of groups of the user
*/
var getListError = function(){
message.remove();
pageContainer.appendChild(
ComunicWeb.common.messages.createCalloutElem(
"Error",
"An error occurred while retrieving the list of groups of the user!",
"danger"
)
);
}
//Get the list of groups of the user
ComunicWeb.components.groups.interface.getListUser(function(list){
message.remove();
//Check for errors
if(list.error)
return pageContainer.appendChild(
ComunicWeb.common.messages.createCalloutElem(
"Error",
"An error occurred while retrieving the list of groups of the user!",
"danger"
)
);
return getListError();
//Display the list of the groups of the user
ComunicWeb.pages.groups.pages.main._display_list(pageContainer, list);
//Get information about the groups
getInfoMultipleGroups(list, function(info){
if(info.error)
return getListError();
message.remove();
//Display the list of the groups of the user
ComunicWeb.pages.groups.pages.main._display_list(pageContainer, info);
}, true);
});
},
@ -65,70 +85,95 @@ ComunicWeb.pages.groups.pages.main = {
* @param {Object} list The list to apply
*/
_display_list: function(target, list){
var has_group = false;
//Process the list of groups
list.forEach(function(group){
for (var i in list) {
if (list.hasOwnProperty(i)) {
var group = list[i];
has_group = true;
ComunicWeb.pages.groups.pages.main._display_group(group, target);
}
}
//Create group item
var groupItem = createElem2({
appendTo: target,
type: "div",
class: "group-item"
});
//Display group information
//Check if the user does not belong to any groups
if(!has_group){
createElem2({
appendTo: groupItem,
type: "img",
class: "group-icon",
src: group.icon_url
});
var groupName = createElem2({
appendTo: groupItem,
appendTo: target,
type: "div",
class: "group-name a",
innerHTML: group.name
class: "no-group-notice",
innerHTML:"You do not belong to any group yet."
});
}
},
groupName.addEventListener("click", function(e){
openGroupPage(group);
});
/**
* Display single group entry
*
* @param {Object} group Information about the group
* @param {HTMLElement} target The target to display
* information about the group
*/
_display_group: function(group, target){
//Offer the user to delete its membership
var deleteButton = createElem2({
appendTo: groupItem,
type: "div",
class: "buttons-area a",
innerHTML: "<i class='fa fa-trash'></i>"
});
deleteButton.addEventListener("click", function(e){
//Ask user confirmation
ComunicWeb.common.messages.confirm("Do you really want to delete your membership of this group ?", function(r){
if(!r) return;
groupItem.style.visibility = "hidden";
ComunicWeb.components.groups.interface.removeMembership(group.id, function(result){
groupItem.style.visibility = "visible";
if(result.error)
return notify("Could not delete your membership to this group!", "error");
groupItem.remove();
});
});
});
//Display membership status
ComunicWeb.pages.groups.sections.membershipBlock.display(group, groupItem);
//Create group item
var groupItem = createElem2({
appendTo: target,
type: "div",
class: "group-item"
});
//Display group information
createElem2({
appendTo: groupItem,
type: "img",
class: "group-icon",
src: group.icon_url
});
var groupName = createElem2({
appendTo: groupItem,
type: "div",
class: "group-name a",
innerHTML: group.name
});
groupName.addEventListener("click", function(e){
openGroupPage(group);
});
//Offer the user to delete its membership
var deleteButton = createElem2({
appendTo: groupItem,
type: "div",
class: "buttons-area a",
innerHTML: "<i class='fa fa-trash'></i>"
});
deleteButton.addEventListener("click", function(e){
//Ask user confirmation
ComunicWeb.common.messages.confirm("Do you really want to delete your membership of this group ?", function(r){
if(!r) return;
groupItem.style.visibility = "hidden";
ComunicWeb.components.groups.interface.removeMembership(group.id, function(result){
groupItem.style.visibility = "visible";
if(result.error)
return notify("Could not delete your membership to this group!", "error");
groupItem.remove();
});
});
});
//Display membership status
ComunicWeb.pages.groups.sections.membershipBlock.display(group, groupItem);
}
}

Some files were not shown because too many files have changed in this diff Show More