1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/movim_ynh.git synced 2024-09-03 19:46:19 +02:00

update to movim upstream

This commit is contained in:
src386 2016-03-14 23:16:11 +01:00
parent 75c18d4c3d
commit 429fa1709f
4475 changed files with 207203 additions and 14150 deletions

View file

@ -56,7 +56,7 @@ sudo yunohost app setting movim port -v $port
sudo yunohost app setting movim path -v $path
# Generate random password
db_pwd=$(dd if=/dev/urandom bs=1 count=200 2> /dev/null | tr -c -d '[[:alnum:]]')
db_pwd=$(dd if=/dev/urandom bs=1 count=30 2> /dev/null | tr -c -d '[[:alnum:]]')
# Use 'movim' as database name and user
db_user=movim

View file

@ -1,14 +0,0 @@
*~
*#*
cache.tmp
log/*
locales/files.list
*.pdf
*.swp
./cache
./config/*
./lib/Modl
./lib/Moxl
./users/*
./log

View file

@ -1,4 +0,0 @@
((nil . ((indent-tabs-mode . nil)
(tab-width . 4)
(fill-column . 80)))
(c-mode . ((c-file-style . "stroustrup"))))

8
sources/.gitignore vendored
View file

@ -1,8 +0,0 @@
/vendor
/log
/users
/cache
*~
/config/db.inc.php
/composer.lock
/composer.phar

View file

@ -1,22 +0,0 @@
Options -Indexes
AddType application/x-web-app-manifest+json .webapp
<IfModule mod_rewrite.c>
# Tell PHP that the mod_rewrite module is ENABLED.
SetEnv HTTP_MOD_REWRITE 1
# If you have troubles or use VirtualDocumentRoot
# uncomment this and set it to the path where your Movim installation is
# i.e.:
# Movim url: http://example.com
# RewriteBase /
# Movim url: http://some.example.com/movim
# RewriteBase /movim/
RewriteBase /0.9/
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?query=$1 [L]
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>

View file

@ -1,462 +0,0 @@
/* required styles */
.leaflet-map-pane,
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow,
.leaflet-tile-pane,
.leaflet-overlay-pane,
.leaflet-shadow-pane,
.leaflet-marker-pane,
.leaflet-popup-pane,
.leaflet-overlay-pane svg,
.leaflet-zoom-box,
.leaflet-image-layer,
.leaflet-layer {
position: absolute;
left: 0;
top: 0;
}
.leaflet-container {
overflow: hidden;
-ms-touch-action: none;
}
.leaflet-tile,
.leaflet-marker-icon,
.leaflet-marker-shadow {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.leaflet-marker-icon,
.leaflet-marker-shadow {
display: block;
}
/* map is broken in FF if you have max-width: 100% on tiles */
.leaflet-container img {
max-width: none !important;
}
.leaflet-popup-content img {
max-width: 4em !important;
}
/* stupid Android 2 doesn't understand "max-width: none" properly */
.leaflet-container img.leaflet-image-layer {
max-width: 15000px !important;
}
.leaflet-tile {
filter: inherit;
visibility: hidden;
}
.leaflet-tile-loaded {
visibility: inherit;
}
.leaflet-zoom-box {
width: 0;
height: 0;
}
.leaflet-tile-pane { z-index: 2; }
.leaflet-objects-pane { z-index: 3; }
.leaflet-overlay-pane { z-index: 4; }
.leaflet-shadow-pane { z-index: 5; }
.leaflet-marker-pane { z-index: 6; }
.leaflet-popup-pane { z-index: 7; }
/* control positioning */
.leaflet-control {
position: relative;
z-index: 7;
pointer-events: auto;
}
.leaflet-top,
.leaflet-bottom {
position: absolute;
z-index: 1000;
pointer-events: none;
}
.leaflet-top {
top: 0;
}
.leaflet-right {
right: 0;
}
.leaflet-bottom {
bottom: 0;
}
.leaflet-left {
left: 0;
}
.leaflet-control {
float: left;
clear: both;
}
.leaflet-right .leaflet-control {
float: right;
}
.leaflet-top .leaflet-control {
margin-top: 10px;
}
.leaflet-bottom .leaflet-control {
margin-bottom: 10px;
}
.leaflet-left .leaflet-control {
margin-left: 10px;
}
.leaflet-right .leaflet-control {
margin-right: 10px;
}
/* zoom and fade animations */
.leaflet-fade-anim .leaflet-tile,
.leaflet-fade-anim .leaflet-popup {
opacity: 0;
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.leaflet-fade-anim .leaflet-tile-loaded,
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
opacity: 1;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
-o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1);
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
}
.leaflet-zoom-anim .leaflet-tile,
.leaflet-pan-anim .leaflet-tile,
.leaflet-touching .leaflet-zoom-animated {
-webkit-transition: none;
-moz-transition: none;
-o-transition: none;
transition: none;
}
.leaflet-zoom-anim .leaflet-zoom-hide {
visibility: hidden;
}
/* cursors */
.leaflet-clickable {
cursor: pointer;
}
.leaflet-container {
cursor: -webkit-grab;
cursor: -moz-grab;
}
.leaflet-popup-pane,
.leaflet-control {
cursor: auto;
}
.leaflet-dragging,
.leaflet-dragging .leaflet-clickable,
.leaflet-dragging .leaflet-container {
cursor: move;
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
}
/* visual tweaks */
.leaflet-container {
background: #ddd;
outline: 0;
}
.leaflet-container a {
color: #0078A8;
}
.leaflet-container a.leaflet-active {
outline: 2px solid orange;
}
.leaflet-zoom-box {
border: 2px dotted #05f;
background: white;
opacity: 0.5;
}
/* general typography */
.leaflet-container {
font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
}
/* general toolbar styles */
.leaflet-bar {
box-shadow: 0 0 8px rgba(0,0,0,0.4);
border: 1px solid #888;
-webkit-border-radius: 5px;
border-radius: 5px;
}
.leaflet-bar-part {
background-color: rgba(255, 255, 255, 0.8);
border-bottom: 1px solid #aaa;
}
.leaflet-bar-part-top {
-webkit-border-radius: 4px 4px 0 0;
border-radius: 4px 4px 0 0;
}
.leaflet-bar-part-bottom {
-webkit-border-radius: 0 0 4px 4px;
border-radius: 0 0 4px 4px;
border-bottom: none;
}
.leaflet-touch .leaflet-bar {
-webkit-border-radius: 10px;
border-radius: 10px;
}
.leaflet-touch .leaflet-bar-part {
border-bottom: 4px solid rgba(0,0,0,0.3);
}
.leaflet-touch .leaflet-bar-part-top {
-webkit-border-radius: 7px 7px 0 0;
border-radius: 7px 7px 0 0;
}
.leaflet-touch .leaflet-bar-part-bottom {
-webkit-border-radius: 0 0 7px 7px;
border-radius: 0 0 7px 7px;
border-bottom: none;
}
/* zoom control */
.leaflet-container .leaflet-control-zoom {
margin-left: 13px;
margin-top: 12px;
}
.leaflet-control-zoom a {
width: 22px;
height: 22px;
text-align: center;
text-decoration: none;
color: black;
}
.leaflet-control-zoom a,
.leaflet-control-layers-toggle {
background-position: 50% 50%;
background-repeat: no-repeat;
display: block;
}
.leaflet-control-zoom a:hover {
background-color: #fff;
color: #777;
}
.leaflet-control-zoom-in {
font: bold 18px/24px Arial, Helvetica, sans-serif;
}
.leaflet-control-zoom-out {
font: bold 23px/20px Tahoma, Verdana, sans-serif;
}
.leaflet-control-zoom a.leaflet-control-zoom-disabled {
cursor: default;
background-color: rgba(255, 255, 255, 0.8);
color: #bbb;
}
.leaflet-touch .leaflet-control-zoom a {
width: 30px;
height: 30px;
}
.leaflet-touch .leaflet-control-zoom-in {
font-size: 24px;
line-height: 29px;
}
.leaflet-touch .leaflet-control-zoom-out {
font-size: 28px;
line-height: 24px;
}
/* layers control */
.leaflet-control-layers {
box-shadow: 0 1px 7px rgba(0,0,0,0.4);
background: #f8f8f9;
-webkit-border-radius: 8px;
border-radius: 8px;
}
.leaflet-control-layers-toggle {
background-image: url(images/layers.png);
width: 36px;
height: 36px;
}
.leaflet-touch .leaflet-control-layers-toggle {
width: 44px;
height: 44px;
}
.leaflet-control-layers .leaflet-control-layers-list,
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
display: none;
}
.leaflet-control-layers-expanded .leaflet-control-layers-list {
display: block;
position: relative;
}
.leaflet-control-layers-expanded {
padding: 6px 10px 6px 6px;
color: #333;
background: #fff;
}
.leaflet-control-layers-selector {
margin-top: 2px;
position: relative;
top: 1px;
}
.leaflet-control-layers label {
display: block;
}
.leaflet-control-layers-separator {
height: 0;
border-top: 1px solid #ddd;
margin: 5px -10px 5px -6px;
}
/* attribution and scale controls */
.leaflet-container .leaflet-control-attribution {
background-color: rgba(255, 255, 255, 0.7);
box-shadow: 0 0 5px #bbb;
margin: 0;
}
.leaflet-control-attribution,
.leaflet-control-scale-line {
padding: 0 5px;
color: #333;
}
.leaflet-container .leaflet-control-attribution,
.leaflet-container .leaflet-control-scale {
font-size: 11px;
}
.leaflet-left .leaflet-control-scale {
margin-left: 5px;
}
.leaflet-bottom .leaflet-control-scale {
margin-bottom: 5px;
}
.leaflet-control-scale-line {
border: 2px solid #777;
border-top: none;
color: black;
line-height: 1.1;
padding: 2px 5px 1px;
font-size: 11px;
text-shadow: 1px 1px 1px #fff;
background-color: rgba(255, 255, 255, 0.5);
box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.2);
white-space: nowrap;
overflow: hidden;
}
.leaflet-control-scale-line:not(:first-child) {
border-top: 2px solid #777;
border-bottom: none;
margin-top: -2px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
border-bottom: 2px solid #777;
}
.leaflet-touch .leaflet-control-attribution,
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-control-zoom {
box-shadow: none;
}
.leaflet-touch .leaflet-control-layers,
.leaflet-touch .leaflet-control-zoom {
border: 4px solid rgba(0,0,0,0.3);
}
/* popup */
.leaflet-popup {
position: absolute;
text-align: center;
}
.leaflet-popup-content-wrapper {
padding: 1px;
text-align: left;
}
.leaflet-popup-content {
/*margin: 14px 20px;
line-height: 1.4;*/
line-height: 1em;
}
.leaflet-popup-content p {
margin: 18px 0;
}
.leaflet-popup-tip-container {
margin: 0 auto;
width: 40px;
height: 20px;
position: relative;
overflow: hidden;
}
.leaflet-popup-tip {
width: 15px;
height: 15px;
padding: 1px;
margin: -8px auto 0;
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
transform: rotate(45deg);
}
.leaflet-popup-content-wrapper, .leaflet-popup-tip {
background: white;
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
}
.leaflet-container a.leaflet-popup-close-button {
display: none;
position: absolute;
top: 0;
right: 0;
padding: 4px 5px 0 0;
text-align: center;
width: 18px;
height: 14px;
font: 16px/14px Tahoma, Verdana, sans-serif;
color: #c3c3c3;
text-decoration: none;
font-weight: bold;
background: transparent;
}
.leaflet-container a.leaflet-popup-close-button:hover {
color: #999;
}
.leaflet-popup-scrolled {
overflow: auto;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
}
/* div icon */
.leaflet-div-icon {
background: #fff;
border: 1px solid #666;
}
.leaflet-editing-icon {
-webkit-border-radius: 2px;
border-radius: 2px;
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,455 +0,0 @@
/*!
* EventEmitter v4.2.3 - git.io/ee
* Oliver Caldwell
* MIT license
* @preserve
*/
(function () {
'use strict';
/**
* Class for managing events.
* Can be extended to provide event functionality in other classes.
*
* @class EventEmitter Manages event registering and emitting.
*/
function EventEmitter() {}
// Shortcuts to improve speed and size
// Easy access to the prototype
var proto = EventEmitter.prototype;
/**
* Finds the index of the listener for the event in it's storage array.
*
* @param {Function[]} listeners Array of listeners to search through.
* @param {Function} listener Method to look for.
* @return {Number} Index of the specified listener, -1 if not found
* @api private
*/
function indexOfListener(listeners, listener) {
var i = listeners.length;
while (i--) {
if (listeners[i].listener === listener) {
return i;
}
}
return -1;
}
/**
* Alias a method while keeping the context correct, to allow for overwriting of target method.
*
* @param {String} name The name of the target method.
* @return {Function} The aliased method
* @api private
*/
function alias(name) {
return function aliasClosure() {
return this[name].apply(this, arguments);
};
}
/**
* Returns the listener array for the specified event.
* Will initialise the event object and listener arrays if required.
* Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
* Each property in the object response is an array of listener functions.
*
* @param {String|RegExp} evt Name of the event to return the listeners from.
* @return {Function[]|Object} All listener functions for the event.
*/
proto.getListeners = function getListeners(evt) {
var events = this._getEvents();
var response;
var key;
// Return a concatenated array of all matching events if
// the selector is a regular expression.
if (typeof evt === 'object') {
response = {};
for (key in events) {
if (events.hasOwnProperty(key) && evt.test(key)) {
response[key] = events[key];
}
}
}
else {
response = events[evt] || (events[evt] = []);
}
return response;
};
/**
* Takes a list of listener objects and flattens it into a list of listener functions.
*
* @param {Object[]} listeners Raw listener objects.
* @return {Function[]} Just the listener functions.
*/
proto.flattenListeners = function flattenListeners(listeners) {
var flatListeners = [];
var i;
for (i = 0; i < listeners.length; i += 1) {
flatListeners.push(listeners[i].listener);
}
return flatListeners;
};
/**
* Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
*
* @param {String|RegExp} evt Name of the event to return the listeners from.
* @return {Object} All listener functions for an event in an object.
*/
proto.getListenersAsObject = function getListenersAsObject(evt) {
var listeners = this.getListeners(evt);
var response;
if (listeners instanceof Array) {
response = {};
response[evt] = listeners;
}
return response || listeners;
};
/**
* Adds a listener function to the specified event.
* The listener will not be added if it is a duplicate.
* If the listener returns true then it will be removed after it is called.
* If you pass a regular expression as the event name then the listener will be added to all events that match it.
*
* @param {String|RegExp} evt Name of the event to attach the listener to.
* @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.addListener = function addListener(evt, listener) {
var listeners = this.getListenersAsObject(evt);
var listenerIsWrapped = typeof listener === 'object';
var key;
for (key in listeners) {
if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
listeners[key].push(listenerIsWrapped ? listener : {
listener: listener,
once: false
});
}
}
return this;
};
/**
* Alias of addListener
*/
proto.on = alias('addListener');
/**
* Semi-alias of addListener. It will add a listener that will be
* automatically removed after it's first execution.
*
* @param {String|RegExp} evt Name of the event to attach the listener to.
* @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.addOnceListener = function addOnceListener(evt, listener) {
return this.addListener(evt, {
listener: listener,
once: true
});
};
/**
* Alias of addOnceListener.
*/
proto.once = alias('addOnceListener');
/**
* Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
* You need to tell it what event names should be matched by a regex.
*
* @param {String} evt Name of the event to create.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.defineEvent = function defineEvent(evt) {
this.getListeners(evt);
return this;
};
/**
* Uses defineEvent to define multiple events.
*
* @param {String[]} evts An array of event names to define.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.defineEvents = function defineEvents(evts) {
for (var i = 0; i < evts.length; i += 1) {
this.defineEvent(evts[i]);
}
return this;
};
/**
* Removes a listener function from the specified event.
* When passed a regular expression as the event name, it will remove the listener from all events that match it.
*
* @param {String|RegExp} evt Name of the event to remove the listener from.
* @param {Function} listener Method to remove from the event.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.removeListener = function removeListener(evt, listener) {
var listeners = this.getListenersAsObject(evt);
var index;
var key;
for (key in listeners) {
if (listeners.hasOwnProperty(key)) {
index = indexOfListener(listeners[key], listener);
if (index !== -1) {
listeners[key].splice(index, 1);
}
}
}
return this;
};
/**
* Alias of removeListener
*/
proto.off = alias('removeListener');
/**
* Adds listeners in bulk using the manipulateListeners method.
* If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
* You can also pass it a regular expression to add the array of listeners to all events that match it.
* Yeah, this function does quite a bit. That's probably a bad thing.
*
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
* @param {Function[]} [listeners] An optional array of listener functions to add.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.addListeners = function addListeners(evt, listeners) {
// Pass through to manipulateListeners
return this.manipulateListeners(false, evt, listeners);
};
/**
* Removes listeners in bulk using the manipulateListeners method.
* If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
* You can also pass it an event name and an array of listeners to be removed.
* You can also pass it a regular expression to remove the listeners from all events that match it.
*
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
* @param {Function[]} [listeners] An optional array of listener functions to remove.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.removeListeners = function removeListeners(evt, listeners) {
// Pass through to manipulateListeners
return this.manipulateListeners(true, evt, listeners);
};
/**
* Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
* The first argument will determine if the listeners are removed (true) or added (false).
* If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
* You can also pass it an event name and an array of listeners to be added/removed.
* You can also pass it a regular expression to manipulate the listeners of all events that match it.
*
* @param {Boolean} remove True if you want to remove listeners, false if you want to add.
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
* @param {Function[]} [listeners] An optional array of listener functions to add/remove.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
var i;
var value;
var single = remove ? this.removeListener : this.addListener;
var multiple = remove ? this.removeListeners : this.addListeners;
// If evt is an object then pass each of it's properties to this method
if (typeof evt === 'object' && !(evt instanceof RegExp)) {
for (i in evt) {
if (evt.hasOwnProperty(i) && (value = evt[i])) {
// Pass the single listener straight through to the singular method
if (typeof value === 'function') {
single.call(this, i, value);
}
else {
// Otherwise pass back to the multiple function
multiple.call(this, i, value);
}
}
}
}
else {
// So evt must be a string
// And listeners must be an array of listeners
// Loop over it and pass each one to the multiple method
i = listeners.length;
while (i--) {
single.call(this, evt, listeners[i]);
}
}
return this;
};
/**
* Removes all listeners from a specified event.
* If you do not specify an event then all listeners will be removed.
* That means every event will be emptied.
* You can also pass a regex to remove all events that match it.
*
* @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.removeEvent = function removeEvent(evt) {
var type = typeof evt;
var events = this._getEvents();
var key;
// Remove different things depending on the state of evt
if (type === 'string') {
// Remove all listeners for the specified event
delete events[evt];
}
else if (type === 'object') {
// Remove all events matching the regex.
for (key in events) {
if (events.hasOwnProperty(key) && evt.test(key)) {
delete events[key];
}
}
}
else {
// Remove all listeners in all events
delete this._events;
}
return this;
};
/**
* Emits an event of your choice.
* When emitted, every listener attached to that event will be executed.
* If you pass the optional argument array then those arguments will be passed to every listener upon execution.
* Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
* So they will not arrive within the array on the other side, they will be separate.
* You can also pass a regular expression to emit to all events that match it.
*
* @param {String|RegExp} evt Name of the event to emit and execute listeners for.
* @param {Array} [args] Optional array of arguments to be passed to each listener.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.emitEvent = function emitEvent(evt, args) {
var listeners = this.getListenersAsObject(evt);
var listener;
var i;
var key;
var response;
for (key in listeners) {
if (listeners.hasOwnProperty(key)) {
i = listeners[key].length;
while (i--) {
// If the listener returns true then it shall be removed from the event
// The function is executed either with a basic call or an apply if there is an args array
listener = listeners[key][i];
if (listener.once === true) {
this.removeListener(evt, listener.listener);
}
response = listener.listener.apply(this, args || []);
if (response === this._getOnceReturnValue()) {
this.removeListener(evt, listener.listener);
}
}
}
}
return this;
};
/**
* Alias of emitEvent
*/
proto.trigger = alias('emitEvent');
/**
* Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
* As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
*
* @param {String|RegExp} evt Name of the event to emit and execute listeners for.
* @param {...*} Optional additional arguments to be passed to each listener.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.emit = function emit(evt) {
var args = Array.prototype.slice.call(arguments, 1);
return this.emitEvent(evt, args);
};
/**
* Sets the current value to check against when executing listeners. If a
* listeners return value matches the one set here then it will be removed
* after execution. This value defaults to true.
*
* @param {*} value The new value to check for when executing listeners.
* @return {Object} Current instance of EventEmitter for chaining.
*/
proto.setOnceReturnValue = function setOnceReturnValue(value) {
this._onceReturnValue = value;
return this;
};
/**
* Fetches the current value to check against when executing listeners. If
* the listeners return value matches this one then it should be removed
* automatically. It will return true by default.
*
* @return {*|Boolean} The current value to check for or the default, true.
* @api private
*/
proto._getOnceReturnValue = function _getOnceReturnValue() {
if (this.hasOwnProperty('_onceReturnValue')) {
return this._onceReturnValue;
}
else {
return true;
}
};
/**
* Fetches the events object and creates one if required.
*
* @return {Object} The events storage object.
* @api private
*/
proto._getEvents = function _getEvents() {
return this._events || (this._events = {});
};
// Expose the class either via AMD, CommonJS or the global object
if (typeof define === 'function' && define.amd) {
define(function () {
return EventEmitter;
});
}
else if (typeof module === 'object' && module.exports){
module.exports = EventEmitter;
}
else {
this.EventEmitter = EventEmitter;
}
}.call(this));

View file

@ -1,254 +0,0 @@
// Salsa20 implementation
// Contributed to Cryptocat by Dmitry Chestnykh
// 21-01-2013
;(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(factory)
} else if (typeof module !== 'undefined' && module.exports) {
module.exports = factory()
} else {
root.Salsa20 = factory()
}
}(this, function () {
function Salsa20(key, nonce) {
// Constants.
this.rounds = 20; // number of Salsa rounds
this.sigmaWords = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574];
// State.
this.keyWords = []; // key words
this.nonceWords = [0, 0]; // nonce words
this.counterWords = [0, 0]; // block counter words
// Output buffer.
this.block = []; // output block of 64 bytes
this.blockUsed = 64; // number of block bytes used
this.setKey(key);
this.setNonce(nonce);
}
// setKey sets the key to the given 32-byte array.
Salsa20.prototype.setKey = function(key) {
for (var i = 0, j = 0; i < 8; i++, j += 4) {
this.keyWords[i] = (key[j] & 0xff) |
((key[j+1] & 0xff)<<8) |
((key[j+2] & 0xff)<<16) |
((key[j+3] & 0xff)<<24);
}
this._reset();
};
// setNonce sets the nonce to the given 8-byte array.
Salsa20.prototype.setNonce = function(nonce) {
this.nonceWords[0] = (nonce[0] & 0xff) |
((nonce[1] & 0xff)<<8) |
((nonce[2] & 0xff)<<16) |
((nonce[3] & 0xff)<<24);
this.nonceWords[1] = (nonce[4] & 0xff) |
((nonce[5] & 0xff)<<8) |
((nonce[6] & 0xff)<<16) |
((nonce[7] & 0xff)<<24);
this._reset();
};
// getBytes returns the next numberOfBytes bytes of stream.
Salsa20.prototype.getBytes = function(numberOfBytes) {
var out = new Array(numberOfBytes);
for (var i = 0; i < numberOfBytes; i++) {
if (this.blockUsed == 64) {
this._generateBlock();
this._incrementCounter();
this.blockUsed = 0;
}
out[i] = this.block[this.blockUsed];
this.blockUsed++;
}
return out;
};
Salsa20.prototype.getHexString = function(numberOfBytes) {
var hex=['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
var out = [];
var bytes = this.getBytes(numberOfBytes);
for(var i = 0; i < bytes.length; i++) {
out.push(hex[(bytes[i] >> 4) & 15]);
out.push(hex[bytes[i] & 15]);
}
return out.join('');
};
// Private methods.
Salsa20.prototype._reset = function() {
this.counterWords[0] = 0;
this.counterWords[1] = 0;
this.blockUsed = 64;
};
// _incrementCounter increments block counter.
Salsa20.prototype._incrementCounter = function() {
// Note: maximum 2^64 blocks.
this.counterWords[0] = (this.counterWords[0] + 1) & 0xffffffff;
if (this.counterWords[0] == 0) {
this.counterWords[1] = (this.counterWords[1] + 1) & 0xffffffff;
}
};
// _generateBlock generates 64 bytes from key, nonce, and counter,
// and puts the result into this.block.
Salsa20.prototype._generateBlock = function() {
var j0 = this.sigmaWords[0],
j1 = this.keyWords[0],
j2 = this.keyWords[1],
j3 = this.keyWords[2],
j4 = this.keyWords[3],
j5 = this.sigmaWords[1],
j6 = this.nonceWords[0],
j7 = this.nonceWords[1],
j8 = this.counterWords[0],
j9 = this.counterWords[1],
j10 = this.sigmaWords[2],
j11 = this.keyWords[4],
j12 = this.keyWords[5],
j13 = this.keyWords[6],
j14 = this.keyWords[7],
j15 = this.sigmaWords[3];
var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7,
x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15;
var u;
for (var i = 0; i < this.rounds; i += 2) {
u = x0 + x12;
x4 ^= (u<<7) | (u>>>(32-7));
u = x4 + x0;
x8 ^= (u<<9) | (u>>>(32-9));
u = x8 + x4;
x12 ^= (u<<13) | (u>>>(32-13));
u = x12 + x8;
x0 ^= (u<<18) | (u>>>(32-18));
u = x5 + x1;
x9 ^= (u<<7) | (u>>>(32-7));
u = x9 + x5;
x13 ^= (u<<9) | (u>>>(32-9));
u = x13 + x9;
x1 ^= (u<<13) | (u>>>(32-13));
u = x1 + x13;
x5 ^= (u<<18) | (u>>>(32-18));
u = x10 + x6;
x14 ^= (u<<7) | (u>>>(32-7));
u = x14 + x10;
x2 ^= (u<<9) | (u>>>(32-9));
u = x2 + x14;
x6 ^= (u<<13) | (u>>>(32-13));
u = x6 + x2;
x10 ^= (u<<18) | (u>>>(32-18));
u = x15 + x11;
x3 ^= (u<<7) | (u>>>(32-7));
u = x3 + x15;
x7 ^= (u<<9) | (u>>>(32-9));
u = x7 + x3;
x11 ^= (u<<13) | (u>>>(32-13));
u = x11 + x7;
x15 ^= (u<<18) | (u>>>(32-18));
u = x0 + x3;
x1 ^= (u<<7) | (u>>>(32-7));
u = x1 + x0;
x2 ^= (u<<9) | (u>>>(32-9));
u = x2 + x1;
x3 ^= (u<<13) | (u>>>(32-13));
u = x3 + x2;
x0 ^= (u<<18) | (u>>>(32-18));
u = x5 + x4;
x6 ^= (u<<7) | (u>>>(32-7));
u = x6 + x5;
x7 ^= (u<<9) | (u>>>(32-9));
u = x7 + x6;
x4 ^= (u<<13) | (u>>>(32-13));
u = x4 + x7;
x5 ^= (u<<18) | (u>>>(32-18));
u = x10 + x9;
x11 ^= (u<<7) | (u>>>(32-7));
u = x11 + x10;
x8 ^= (u<<9) | (u>>>(32-9));
u = x8 + x11;
x9 ^= (u<<13) | (u>>>(32-13));
u = x9 + x8;
x10 ^= (u<<18) | (u>>>(32-18));
u = x15 + x14;
x12 ^= (u<<7) | (u>>>(32-7));
u = x12 + x15;
x13 ^= (u<<9) | (u>>>(32-9));
u = x13 + x12;
x14 ^= (u<<13) | (u>>>(32-13));
u = x14 + x13;
x15 ^= (u<<18) | (u>>>(32-18));
}
x0 += j0;
x1 += j1;
x2 += j2;
x3 += j3;
x4 += j4;
x5 += j5;
x6 += j6;
x7 += j7;
x8 += j8;
x9 += j9;
x10 += j10;
x11 += j11;
x12 += j12;
x13 += j13;
x14 += j14;
x15 += j15;
this.block[ 0] = ( x0 >>> 0) & 0xff; this.block[ 1] = ( x0 >>> 8) & 0xff;
this.block[ 2] = ( x0 >>> 16) & 0xff; this.block[ 3] = ( x0 >>> 24) & 0xff;
this.block[ 4] = ( x1 >>> 0) & 0xff; this.block[ 5] = ( x1 >>> 8) & 0xff;
this.block[ 6] = ( x1 >>> 16) & 0xff; this.block[ 7] = ( x1 >>> 24) & 0xff;
this.block[ 8] = ( x2 >>> 0) & 0xff; this.block[ 9] = ( x2 >>> 8) & 0xff;
this.block[10] = ( x2 >>> 16) & 0xff; this.block[11] = ( x2 >>> 24) & 0xff;
this.block[12] = ( x3 >>> 0) & 0xff; this.block[13] = ( x3 >>> 8) & 0xff;
this.block[14] = ( x3 >>> 16) & 0xff; this.block[15] = ( x3 >>> 24) & 0xff;
this.block[16] = ( x4 >>> 0) & 0xff; this.block[17] = ( x4 >>> 8) & 0xff;
this.block[18] = ( x4 >>> 16) & 0xff; this.block[19] = ( x4 >>> 24) & 0xff;
this.block[20] = ( x5 >>> 0) & 0xff; this.block[21] = ( x5 >>> 8) & 0xff;
this.block[22] = ( x5 >>> 16) & 0xff; this.block[23] = ( x5 >>> 24) & 0xff;
this.block[24] = ( x6 >>> 0) & 0xff; this.block[25] = ( x6 >>> 8) & 0xff;
this.block[26] = ( x6 >>> 16) & 0xff; this.block[27] = ( x6 >>> 24) & 0xff;
this.block[28] = ( x7 >>> 0) & 0xff; this.block[29] = ( x7 >>> 8) & 0xff;
this.block[30] = ( x7 >>> 16) & 0xff; this.block[31] = ( x7 >>> 24) & 0xff;
this.block[32] = ( x8 >>> 0) & 0xff; this.block[33] = ( x8 >>> 8) & 0xff;
this.block[34] = ( x8 >>> 16) & 0xff; this.block[35] = ( x8 >>> 24) & 0xff;
this.block[36] = ( x9 >>> 0) & 0xff; this.block[37] = ( x9 >>> 8) & 0xff;
this.block[38] = ( x9 >>> 16) & 0xff; this.block[39] = ( x9 >>> 24) & 0xff;
this.block[40] = (x10 >>> 0) & 0xff; this.block[41] = (x10 >>> 8) & 0xff;
this.block[42] = (x10 >>> 16) & 0xff; this.block[43] = (x10 >>> 24) & 0xff;
this.block[44] = (x11 >>> 0) & 0xff; this.block[45] = (x11 >>> 8) & 0xff;
this.block[46] = (x11 >>> 16) & 0xff; this.block[47] = (x11 >>> 24) & 0xff;
this.block[48] = (x12 >>> 0) & 0xff; this.block[49] = (x12 >>> 8) & 0xff;
this.block[50] = (x12 >>> 16) & 0xff; this.block[51] = (x12 >>> 24) & 0xff;
this.block[52] = (x13 >>> 0) & 0xff; this.block[53] = (x13 >>> 8) & 0xff;
this.block[54] = (x13 >>> 16) & 0xff; this.block[55] = (x13 >>> 24) & 0xff;
this.block[56] = (x14 >>> 0) & 0xff; this.block[57] = (x14 >>> 8) & 0xff;
this.block[58] = (x14 >>> 16) & 0xff; this.block[59] = (x14 >>> 24) & 0xff;
this.block[60] = (x15 >>> 0) & 0xff; this.block[61] = (x15 >>> 8) & 0xff;
this.block[62] = (x15 >>> 16) & 0xff; this.block[63] = (x15 >>> 24) & 0xff;
};
return Salsa20
}))

View file

@ -1,52 +0,0 @@
;(function (root) {
"use strict";
root.OTR = {}
root.DSA = {}
root.crypto = {
randomBytes: function () {
throw new Error("Haven't seeded yet.")
}
}
// default imports
var imports = [
'vendor/salsa20.js'
, 'vendor/bigint.js'
, 'vendor/crypto.js'
, 'vendor/eventemitter.js'
, 'lib/const.js'
, 'lib/helpers.js'
, 'lib/dsa.js'
]
function sendMsg(type, val) {
postMessage({ type: type, val: val })
}
onmessage = function (e) {
var data = e.data;
if (data.imports) imports = data.imports
importScripts.apply(root, imports);
// use salsa20 since there's no prng in webworkers
var state = new root.Salsa20(data.seed.slice(0, 32), data.seed.slice(32))
root.crypto.randomBytes = function (n) {
return state.getBytes(n)
}
if (data.debug) sendMsg('debug', 'DSA key creation started')
var dsa
try {
dsa = new root.DSA()
} catch (e) {
if (data.debug) sendMsg('debug', e.toString())
return
}
if (data.debug) sendMsg('debug', 'DSA key creation finished')
sendMsg('data', dsa.packPrivate())
}
}(this))

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -1,60 +0,0 @@
;(function (root) {
"use strict";
root.OTR = {}
root.crypto = {
randomBytes: function () {
throw new Error("Haven't seeded yet.")
}
}
// default imports
var imports = [
'vendor/salsa20.js'
, 'vendor/bigint.js'
, 'vendor/crypto.js'
, 'vendor/eventemitter.js'
, 'lib/const.js'
, 'lib/helpers.js'
, 'lib/sm.js'
]
function wrapPostMessage(method) {
return function () {
postMessage({
method: method
, args: Array.prototype.slice.call(arguments, 0)
})
}
}
var sm
onmessage = function (e) {
var data = e.data
switch (data.type) {
case 'seed':
if (data.imports) imports = data.imports
importScripts.apply(root, imports)
// use salsa20 since there's no prng in webworkers
var state = new root.Salsa20(
data.seed.slice(0, 32),
data.seed.slice(32)
)
root.crypto.randomBytes = function (n) {
return state.getBytes(n)
}
break
case 'init':
sm = new root.OTR.SM(data.reqs)
;['trust','question', 'send', 'abort'].forEach(function (m) {
sm.on(m, wrapPostMessage(m));
})
break
case 'method':
sm[data.method].apply(sm, data.args)
break
}
}
}(this))

View file

@ -1,11 +0,0 @@
<?php
class GrouppublicController extends BaseController {
function load() {
$this->session_only = false;
}
function dispatch() {
$this->page->setTitle(__('page.groups'));
}
}

View file

@ -1,26 +0,0 @@
<?php /* -*- mode: html -*- */
?>
<?php $this->widget('Presence');?>
<?php $this->widget('Chat');?>
<?php $this->widget('VisioExt');?>
<div id="main">
<div id="left">
<?php $this->widget('ContactSummary');?>
<?php $this->widget('ContactInfo');?>
<?php $this->widget('ContactAction');?>
<div class="clear"></div>
<?php $this->widget('ContactManage');?>
</div>
<?php $this->widget('Tabs');?>
<div id="center">
<?php $this->widget('Wall');?>
<?php $this->widget('ContactCard');?>
<?php $this->widget('ContactPubsubSubscription');?>
</div>
</div>
<div id="right">
<?php $this->widget('Roster');?>
</div>

View file

@ -1,7 +0,0 @@
<main>
<section>
<div style="background-color: #EEE;">
<?php $this->widget('Blog');?>
</div>
</section>
</main>

View file

@ -1,40 +0,0 @@
<div>
<ul class="list middle">
<li>
<span class="primary on_desktop icon"><i class="zmdi zmdi-comments"></i></span>
<p>
{$c->__('page.chats')}
</p>
</li>
</ul>
</div>
<div>
<ul class="list middle">
<li id="chat_header">
<span onclick="
MovimTpl.hidePanel();
Notification.current('chat');
Header_ajaxReset('chat');
Chat_ajaxGet();"
id="back" class="primary icon active">
<i class="zmdi zmdi-arrow-back"></i>
</span>
<span class="control icon active" onclick="Chats_ajaxClose('{$jid|echapJS}'); MovimTpl.hidePanel();">
<i class="zmdi zmdi-close"></i>
</span>
{if="$c->supported('upload')"}
<span class="control icon active" onclick="Upload_ajaxRequest()">
<i class="zmdi zmdi-attachment-alt"></i>
</span>
{/if}
<p class="line">
{if="$contact != null"}
{$contact->getTrueName()}
{else}
{$jid|echapJS}
{/if}
</p>
<p class="line" id="{$jid}_state">{$contact->jid}</p>
</li>
</ul>
</div>

View file

@ -1,88 +0,0 @@
<section>
<table class="emojis">
<tbody>
<tr class="active">
<td onclick="Chat.addSmiley(this);" data-emoji="😂"><img alt=":joy:" class="emoji large" src="{$c->getSmileyPath('1f602')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😃"><img alt=":smiley:" class="emoji large" src="{$c->getSmileyPath('1f603')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😄"><img alt=":smile:" class="emoji large" src="{$c->getSmileyPath('1f604')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😆"><img alt=":laughing:" class="emoji large" src="{$c->getSmileyPath('1f606')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😍"><img alt=":heart_eyes:" class="emoji large" src="{$c->getSmileyPath('1f60d')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😉"><img alt=":wink:" class="emoji large" src="{$c->getSmileyPath('1f609')}"></td>
</tr>
<tr class="active">
<td onclick="Chat.addSmiley(this);" data-emoji="😠"><img alt=":angry:" class="emoji large" src="{$c->getSmileyPath('1f620')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😜"><img alt=":stuck_out_tongue_winking_eye:" class="emoji large" src="{$c->getSmileyPath('1f61c')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😝"><img alt=":stuck_out_tongue_closed_eyes:" class="emoji large" src="{$c->getSmileyPath('1f61d')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😒"><img alt=":unamused:" class="emoji large" src="{$c->getSmileyPath('1f612')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😓"><img alt=":sweat:" class="emoji large" src="{$c->getSmileyPath('1f613')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😖"><img alt=":confounded:" class="emoji large" src="{$c->getSmileyPath('1f616')}"></td>
</tr>
<tr class="active">
<td onclick="Chat.addSmiley(this);" data-emoji="😢"><img alt=":cry:" class="emoji large" src="{$c->getSmileyPath('1f622')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😤"><img alt=":triumph:" class="emoji large" src="{$c->getSmileyPath('1f624')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😥"><img alt=":disappointed_relieved:" class="emoji large" src="{$c->getSmileyPath('1f625')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😪"><img alt=":sleepy:" class="emoji large" src="{$c->getSmileyPath('1f62a')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😭"><img alt=":sob:" class="emoji large" src="{$c->getSmileyPath('1f62d')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="😱"><img alt=":scream:" class="emoji large" src="{$c->getSmileyPath('1f631')}"></td>
</tr>
<tr class="active">
<td onclick="Chat.addSmiley(this);" data-emoji="🍌"><img alt=":banana:" class="emoji large" src="{$c->getSmileyPath('1f34c')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🍎"><img alt=":apple:" class="emoji large" src="{$c->getSmileyPath('1f34e')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🌼"><img alt=":blossom:" class="emoji large" src="{$c->getSmileyPath('1f33c')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🌵"><img alt=":cactus:" class="emoji large" src="{$c->getSmileyPath('1f335')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🌹"><img alt=":rose:" class="emoji large" src="{$c->getSmileyPath('1f339')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🍄"><img alt=":mushroom:" class="emoji large" src="{$c->getSmileyPath('1f344')}"></td>
</tr>
<tr class="active">
<td onclick="Chat.addSmiley(this);" data-emoji="🍔"><img alt=":hamburger:" class="emoji large" src="{$c->getSmileyPath('1f354')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🍕"><img alt=":pizza:" class="emoji large" src="{$c->getSmileyPath('1f355')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🍗"><img alt=":poultry_leg:" class="emoji large" src="{$c->getSmileyPath('1f357')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🍚"><img alt=":rice:" class="emoji large" src="{$c->getSmileyPath('1f35a')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🍜"><img alt=":ramen:" class="emoji large" src="{$c->getSmileyPath('1f35c')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🍣"><img alt=":sushi:" class="emoji large" src="{$c->getSmileyPath('1f363')}"></td>
</tr>
<tr class="active">
<td onclick="Chat.addSmiley(this);" data-emoji="🛀"><img alt=":bath:" class="emoji large" src="{$c->getSmileyPath('1f6c0')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🎧"><img alt=":headphones:" class="emoji large" src="{$c->getSmileyPath('1f3a7')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🎮"><img alt=":video_game:" class="emoji large" src="{$c->getSmileyPath('1f3ae')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🎫"><img alt=":ticket:" class="emoji large" src="{$c->getSmileyPath('1f3ab')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="💼"><img alt=":briefcase:" class="emoji large" src="{$c->getSmileyPath('1f4bc')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🎒"><img alt=":school_satchel:" class="emoji large" src="{$c->getSmileyPath('1f392')}"></td>
</tr>
<tr class="active">
<td onclick="Chat.addSmiley(this);" data-emoji="💡"><img alt=":bulb:" class="emoji large" src="{$c->getSmileyPath('1f4a1')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="📞"><img alt=":telephone_receiver:" class="emoji large" src="{$c->getSmileyPath('1f4de')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🔥"><img alt=":fire:" class="emoji large" src="{$c->getSmileyPath('1f525')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🕐"><img alt=":clock1:" class="emoji large" src="{$c->getSmileyPath('1f550')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="✉"><img alt=":email:" class="emoji large" src="{$c->getSmileyPath('2709')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="✏"><img alt=":pencil2:" class="emoji large" src="{$c->getSmileyPath('270f')}"></td>
</tr>
<tr class="active">
<td onclick="Chat.addSmiley(this);" data-emoji="💋"><img alt=":kiss:" class="emoji large" src="{$c->getSmileyPath('1f48b')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="♥"><img alt=":hearts:" class="emoji large" src="{$c->getSmileyPath('2665')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="💊"><img alt=":pill:" class="emoji large" src="{$c->getSmileyPath('1f48a')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="💩"><img alt=":hankey:" class="emoji large" src="{$c->getSmileyPath('1f4a9')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="☕"><img alt=":coffee:" class="emoji large" src="{$c->getSmileyPath('2615')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="⏰"><img alt=":alarm_clock:" class="emoji large" src="{$c->getSmileyPath('23f0')}"></td>
</tr>
<tr class="active">
<td onclick="Chat.addSmiley(this);" data-emoji="🐷"><img alt=":pig:" class="emoji large" src="{$c->getSmileyPath('1f437')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🐵"><img alt=":monkey_face:" class="emoji large" src="{$c->getSmileyPath('1f435')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🐶"><img alt=":dog:" class="emoji large" src="{$c->getSmileyPath('1f436')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🐸"><img alt=":frog:" class="emoji large" src="{$c->getSmileyPath('1f438')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🐹"><img alt=":hamster:" class="emoji large" src="{$c->getSmileyPath('1f439')}"></td>
<td onclick="Chat.addSmiley(this);" data-emoji="🐻"><img alt=":bear:" class="emoji large" src="{$c->getSmileyPath('1f43b')}"></td>
</tr>
</tbody>
</table>
</section>
<div>
<!--
<a onclick="Stickers_ajaxShow()" class="button flat">
Stickers
</a>
-->
<a onclick="Dialog.clear()" class="button flat">
{$c->__('button.close')}
</a>
</div>

View file

@ -1,79 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Wall.php
* This file is part of MOVIM.
*
* @brief The configuration form
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 28 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
class ConfigData extends WidgetBase
{
function load()
{
$this->addcss('configdata.css');
}
function formatDate($month, $year) {
return date('M', mktime(0, 0, 0, $month, 1, $year));
}
function formatHeight($height) {
return log10($height)*20;
}
function ajaxClearRosterLink() {
$rd = new \modl\RosterLinkDAO();
$rd->clearRosterLink();
$this->refresh();
}
function ajaxClearMessage() {
$md = new \modl\MessageDAO();
$md->clearMessage();
$this->refresh();
}
function ajaxClearPost() {
$pd = new \modl\PostnDAO();
$pd->clearPost();
$this->refresh();
}
function refresh() {
RPC::call('movim_reload_this');
RPC::commit();
}
function display() {
$cd = new \modl\ContactDAO();
$stats = $cd->getStatistics();
$pd = new \modl\PostnDAO();
$pstats = array_slice($pd->getStatistics(), 0, 7);
$md = new \modl\MessageDAO();
$mstats = array_slice($md->getStatistics(), 0, 7);
$this->view->assign('stats', $stats[0]);
$this->view->assign('pstats', $pstats);
$this->view->assign('mstats', $mstats);
$this->view->assign('clearrosterlink', $this->call('ajaxClearRosterLink'));
$this->view->assign('clearmessage', $this->call('ajaxClearMessage'));
$this->view->assign('clearpost', $this->call('ajaxClearPost'));
}
}

View file

@ -1,26 +0,0 @@
ul.stats {
list-style-type: none;
position: relative;
height: 200px;
}
ul.stats li {
background-color: #383735;
width: 9%;
display: inline-block;
margin-top: 2em;
}
ul.stats li span {
text-align: center;
display: block;
}
ul.stats li span.date {
margin-top: -2em;
margin-bottom: 1.5em;
}
ul.stats li span.num {
color: white;
}

View file

@ -1,73 +0,0 @@
<div class="tabelem" title="{$c->__('title')}" id="configdata" >
<form enctype="multipart/form-data" method="post" action="index.php" name="general">
<ul class="thick">
<li>
<div class="control">
<a
class="button"
onclick="{$clearrosterlink}">
{$c->__('button.clear')}
</a>
</div>
<span class="icon bubble color orange"><i class="zmdi zmdi-contacts"></i></span>
<span>{$c->__('title.contacts')} - {$stats.rosterlink}</span>
</li>
<li>
<div class="control">
<a
type="button"
name="email"
class="button"
onclick="{$clearpost}">
{$c->__('button.clear')}
</a>
</div>
<span class="icon bubble color blue"><i class="zmdi zmdi-contacts"></i></span>
<span>{$c->__('title.posts')} - {$stats.post}</span>
</li>
<li>
<ul class="stats">
{loop="$pstats"}
<li style="height: {$c->formatHeight($value.count)}%;">
<span class="date">
{$c->formatDate($value.month, $value.year)}
</span>
<span class="num">
{$value.count}
</span>
</li>
{/loop}
</ul>
</li>
<li>
<div class="control">
<a
type="button"
name="email"
class="button"
onclick="{$clearmessage}">
{$c->__('button.clear')}
</a>
</div>
<span class="icon bubble color brown"><i class="zmdi zmdi-comments"></i></span>
<span>{$c->__('title.messages')} - {$stats.message}</span>
</li>
<li>
<ul class="stats">
{loop="$mstats"}
<li style="height: {$c->formatHeight($value.count)}%">
<span class="date">
{$c->formatDate($value.month, $value.year)}
</span>
<span class="num">
{$value.count}
</span>
</li>
{/loop}
</ul>
</li>
</ul>
</form>
</div>

View file

@ -1,6 +0,0 @@
[title]
data = Data
cache = Cache
contacts = Contacts
posts = Posts
messages = Messages

View file

@ -1,50 +0,0 @@
<div>
<span class="icon"><i class="zmdi zmdi-accounts"></i></span>
<h2>{$c->__('page.contacts')}</h2>
</div>
<div>
{if="$contactr != null"}
<ul class="active">
<li onclick="{$edit}">
<span class="icon">
<i class="zmdi zmdi-edit"></i>
</span>
</li>
<li onclick="{$delete}">
<span class="icon">
<i class="zmdi zmdi-delete"></i>
</span>
</li>
</ul>
<div class="return active r2" onclick="MovimTpl.hidePanel(); Contact_ajaxClear({$page});">
<span id="back" class="icon" ><i class="zmdi zmdi-arrow-back"></i></span>
<h2>{$contactr->getTrueName()}</h2>
</div>
{else}
{if="$contact != null"}
<ul class="active">
<li onclick="Roster_ajaxDisplaySearch('{$jid}')">
<span class="icon">
<i class="zmdi zmdi-account-add"></i>
</span>
</li>
</ul>
<div class="return active r2" onclick="MovimTpl.hidePanel(); Contact_ajaxClear({$page});">
<span id="back" class="icon" ><i class="zmdi zmdi-arrow-back"></i></span>
<h2>{$contact->getTrueName()}</h2>
</div>
{else}
<ul class="active">
<li onclick="Roster_ajaxDisplaySearch('{$jid}')">
<span class="icon">
<i class="zmdi zmdi-account-add"></i>
</span>
</li>
</ul>
<div class="return active r2" onclick="MovimTpl.hidePanel(); Contact_ajaxClear({$page});">
<span id="back" class="icon" ><i class="zmdi zmdi-arrow-back"></i></span>
<h2>{$jid}</h2>
</div>
{/if}
{/if}
</div>

View file

@ -1,9 +0,0 @@
<div>
<ul class="list middle">
<li>
<span id="menu" class="primary on_mobile icon active" onclick="MovimTpl.toggleMenu()"><i class="zmdi zmdi-menu"></i></span>
<span class="primary icon on_desktop icon"><i class="zmdi zmdi-comments"></i></span>
<p>{$c->__('page.chats')}</p>
</li>
</ul>
</div>

View file

@ -1,10 +0,0 @@
<div>
<span id="menu" class="on_mobile icon active" onclick="MovimTpl.toggleMenu()"><i class="zmdi zmdi-menu"></i></span>
<span class="on_desktop icon"><i class="zmdi zmdi-search"></i></span>
<form>
<div onclick="Roster.init();">
<input type="text" name="search" id="rostersearch" autocomplete="off" placeholder="{$c->__('roster.search');}"/>
</div>
</form>
</div>

View file

@ -1,5 +0,0 @@
<div>
<span id="menu" class="on_mobile icon active" onclick="MovimTpl.toggleMenu()"><i class="zmdi zmdi-menu"></i></span>
<span class="on_desktop icon"><i class="zmdi zmdi-home"></i></span>
<h2 class="r1">{$c->__('page.home')}</h2>
</div>

View file

@ -1,16 +0,0 @@
<div>
<span id="menu" class="on_mobile icon active" onclick="MovimTpl.toggleMenu()"><i class="zmdi zmdi-menu"></i></span>
<span class="on_desktop icon"><i class="zmdi zmdi-filter-list"></i></span>
<form>
<div>
<div class="select">
<select onchange="window[this.value].apply()" name="language" id="language">
<option value="Menu_ajaxGetAll" selected="selected">{$c->__('menu.all')}</option>
<option value="Menu_ajaxGetNews">{$c->__('menu.groups')}</option>
<option value="Menu_ajaxGetFeed">{$c->__('menu.contacts')}</option>
<option value="Menu_ajaxGetMe">{$c->__('menu.me')}</option>
</select>
</div>
</div>
</form>
</div>

View file

@ -1,2 +0,0 @@
[roster]
search = Search in your contacts

View file

@ -1,12 +0,0 @@
var Help = {
joinChatroom : function() {
var hash = new H();
hash.set('jid', 'movim@conference.movim.eu');
hash.set('name', 'Movim Chatroom');
hash.set('nick', false);
hash.set('autojoin', 0);
Bookmark_ajaxBookmarkMucAdd(hash);
Bookmark_ajaxBookmarkMucJoin('movim@conference.movim.eu', '');
}
}

View file

@ -1,115 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Profile.php
* This file is part of MOVIM.
*
* @brief The Profile widget
*
* @author Timothée Jaussoin <edhelas_at_gmail_dot_com>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
use Moxl\Xec\Action\Location\Publish;
class Location extends WidgetBase
{
function load()
{
$this->addjs('location.js');
$this->registerEvent('locationpublished', 'onLocationPublished');
$this->registerEvent('locationpublisherror', 'onLocationPublishError');
}
function ajaxLocationPublish($pos)
{
$pos = json_decode($pos);
if($pos->place_id) {
$geo = array(
'latitude' => (string)$pos->lat,
'longitude' => (string)$pos->lon,
'altitude' => (string)$pos->alt,
'country' => (string)$pos->address->country,
'countrycode' => (string)$pos->address->country_code,
'region' => (string)$pos->address->county,
'postalcode' => (string)$pos->address->postcode,
'locality' => (string)$pos->address->city,
'street' => (string)$pos->address->path,
'building' => (string)$pos->address->building,
'text' => (string)$pos->display_name,
'uri' => ''//'http://www.openstreetmap.org/'.urlencode('?lat='.(string)$pos->lat.'&lon='.(string)$pos->lon.'&zoom=10')
);
$p = new Publish;
$p->setTo($this->user->getLogin())
->setGeo($geo)
->request();
} else {
Notification::append(null, $this->__('location.wrong_postition'));
}
}
function onLocationPublished($me)
{
$html = $me->getPlace();
RPC::call('movim_fill', 'mapdata', $html);
Notification::append(null, $this->__('location.updated'));
RPC::commit();
}
function onLocationPublishError($error)
{
Notification::append(null, $error);
RPC::call('movim_delete', 'mapdiv');
RPC::call('movim_delete', 'mapdata');
RPC::commit();
}
function prepareProfileData()
{
$submit = $this->call('ajaxLocationPublish', "getMyPositionData()");
$cd = new \Modl\ContactDAO();
$c = $cd->get($this->user->getLogin());
if($c->loctimestamp) {
$data = prepareDate(strtotime($c->loctimestamp)).'<br /><br />';
$data .= $c->getPlace();
} else {
$data = '';
}
$html = '';
$html .= '
<div id="location">
<div id="mapdata" style="margin: 1em 0;">'.$data.'</div>
<div id="mapdiv" style="width: auto; height: 250px; display: none;"></div>
<div class="clear"></div>
<a
class="button color green"
style="margin-top: 1em;"
onclick="getMyPosition(); this.style.display = \'none\';">
<i class="fa fa-compass"></i> '.$this->__('location.update').'
</a>
<a
id="mypossubmit"
style="display: none; margin-top: 1em; float: right;"
class="button color green merged left"
onclick="'.$submit.' hidePositionChoice();">
<i class="fa fa-check"></i> '.$this->__('button.accept').'</a>
</div>';
return $html;
}
}

View file

@ -1,5 +0,0 @@
[location]
title = Location
wrong_postition = Wrong position
updated = Location updated
update = Update my position

View file

@ -1,61 +0,0 @@
var myposition = 0;
function getMyPositionData() { return myposition; }
window.cb = function cb(json) {
document.getElementById('mapdata').innerHTML = json.display_name + ',' + json.address.city;
myposition = JSON.stringify(json);
}
function hidePositionChoice()
{
document.querySelector("#mypossubmit").style.display = 'none';
document.querySelector("#myposrefuse").style.display = 'none';
}
function getMyPosition() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function (position) {
document.querySelector("#mapdiv").style.display = 'block';
var map = L.map("mapdiv").setView([position.coords.latitude ,position.coords.longitude], 11);
L.tileLayer("http://tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: "",
maxZoom: 18
}).addTo(map);
var marker = L.marker([position.coords.latitude ,position.coords.longitude]).addTo(map)
var s = document.createElement('script');
s.src = 'http://nominatim.openstreetmap.org/reverse?json_callback=cb&format=json&lat='+position.coords.latitude+'&lon='+position.coords.longitude+'&zoom=27&addressdetails=1';
document.getElementsByTagName('head')[0].appendChild(s);
document.querySelector("#mypossubmit").style.display = 'inline-block';
},
// next function is the error callback
function (error)
{
switch(error.code)
{
case error.TIMEOUT:
alert ('Timeout');
break;
case error.POSITION_UNAVAILABLE:
alert ('Position unavailable');
break;
case error.PERMISSION_DENIED:
alert ('Permission denied');
break;
case error.UNKNOWN_ERROR:
alert ('Unknown error');
break;
}
}
);
}
else {
}
}

View file

@ -1,10 +0,0 @@
<div class="tabelem padded" title="{$c->__('location.title')}" id="location" >
<div class="protect orange" title="{function="getFlagTitle("orange")"}"></div>
<form>
<fieldset>
<legend{$c->__('location.title')}</legend>
<div class="clear"></div>
{$c->prepareProfileData()}
</fieldset>
</form>
</div>

View file

@ -1,99 +0,0 @@
<?php
/**
* @package Widgets
*
* @file NodeAffiliations.php
* This file is part of MOVIM.
*
* @brief A widget for retrieving your group's members
*
* @author Ho Christine <nodpounod@gmail.com>
*
* @version 1.0
* @date 17 April 2013
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
use Moxl\Xec\Action\Pubsub\GetAffiliations;
use Moxl\Xec\Action\Pubsub\SetAffiliations;
class NodeAffiliations extends WidgetBase
{
function load()
{
$this->registerEvent('pubsubaffiliations', 'onGroupMemberList');
$this->registerEvent('pubsubaffiliationssubmited', 'onSubmit');
}
function display() {
$this->view->assign('pepfilter', !filter_var($_GET['s'], FILTER_VALIDATE_EMAIL));
$this->view->assign('getaffiliations',
$this->call('ajaxGetGroupMemberList',
"'".$_GET['s']."'",
"'".$_GET['n']."'"));
}
function prepareList($list) { //0:data 1:server 2:node
$affiliation = array("owner", "member", "none");
$html = '<form id="affiliationsManaging">';
foreach($list[0] as $item){ //0:jid 1:affiliation 2:subid
$html .= '
<div class="element">
<label for="'.$item[0].'_'.$item[2].'">
<a href="'.Route::urlize('friend', $item[0]).'">'.$item[0].'</a>
</label>
<div class="select">
<select name="'.$item[0].'_'.$item[2].'">';
foreach($affiliation as $status){
$status == $item[1] ? $selected = "selected" : $selected = "";
$html .= '<option '.$selected.'>'.t($status).'</option>';
}
$html .= ' </select>
</div>
</div>';
}
$ok = $this->call(
'ajaxChangeAffiliation',
"'".$list[1]."'",
"'".$list[2]."'",
"movim_parse_form('affiliationsManaging')");
$html .= '
<hr />
<br />
<a
class="button color green oppose"
onclick="'.$ok.'">
<i class="fa fa-check"></i> '.__('button.validate').'
</a></form><div class="clear"></div>';
return $html;
}
function onSubmit($stanza) {
Notification::append(null, $this->__('affiliations.saved'));
RPC::commit();
}
function onGroupMemberList($list) {
$html = $this->prepareList($list);
RPC::call('movim_fill', 'memberlist', $html);
RPC::commit();
}
function ajaxChangeAffiliation($server, $node, $data){
$r = new SetAffiliations;
$r->setNode($node)->setTo($server)->setData($data)
->request();
}
function ajaxGetGroupMemberList($server, $node){
$r = new GetAffiliations;
$r->setTo($server)->setNode($node)
->request();
}
}

View file

@ -1,4 +0,0 @@
[affiliations]
title = Manage your members
get = Get the members
saved = Affiliations saved

View file

@ -1,14 +0,0 @@
{if="$pepfilter"}
<div class="tabelem" title="{$c->__('affiliations.title')}" id="groupmemberlist">
<h1 class="paddedtopbottom"><i class="fa fa-key"></i> {$c->__('affiliations.title')}</h1>
<div class="posthead paddedtopbottom">
<a
class="button color green"
onclick="{$getaffiliations} this.parentNode.style.display = 'none'">
<i class="fa fa-key"></i> {$c->__('affiliations.get')}
</a>
</div>
<div id="memberlist" class="paddedtop"></div>
</div>
{/if}

View file

@ -1,99 +0,0 @@
<?php
/**
* @package Widgets
*
* @file NodeAffiliations.php
* This file is part of MOVIM.
*
* @brief A widget for retrieving your group's members
*
* @author Ho Christine <nodpounod@gmail.com>
*
* @version 1.0
* @date 17 April 2013
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
use Moxl\Xec\Action\Pubsub\GetSubscriptions;
use Moxl\Xec\Action\Pubsub\SetSubscriptions;
class NodeSubscriptions extends WidgetBase
{
function load() {
$this->registerEvent('pubsubsubscriptions', 'onSubscriptionsList');
$this->registerEvent('pubsubsubscriptionsssubmited', 'onSubmit');
}
function display() {
$this->view->assign('pepfilter', !filter_var($_GET['s'], FILTER_VALIDATE_EMAIL));
$this->view->assign('getsubscriptions',
$this->call('ajaxGetSubscriptions',
"'".$_GET['s']."'",
"'".$_GET['n']."'"));
}
function prepareList($list) { //0:data 1:server 2:node
$subscription = array("none", "pending", "unconfigured", "subscribed");
$html = '<form id="subscriptionsManaging">';
foreach($list['subscriptions'] as $item){ //0:jid 1:affiliation 2:subid
$html .= '
<div class="element">
<label for="'.$item['jid'].'_'.$item['subid'].'">
<a href="'.Route::urlize('friend', $item['jid']).'">'.$item['jid'].'</a>
</label>
<div class="select">
<select name="'.$item['jid'].'_'.$item['subid'].'">';
foreach($subscription as $status){
$status == $item['subscription'] ? $selected = "selected" : $selected = "";
$html .= '<option '.$selected.'>'.t($status).'</option>';
}
$html .= ' </select>
</div>
</div>';
}
$ok = $this->call('ajaxChangeSubscriptions', "'".$list['to']."'", "'".$list['node']."'", "movim_parse_form('subscriptionsManaging')");
$html .= '
<hr />
<br />
<a
class="button color green oppose"
onclick="'.$ok.'">
<i class="fa fa-check"></i> '.__('button.validate').'
</a></form><div class="clear"></div>';
return $html;
}
function onSubmit($stanza) {
Notification::append(null, $this->__('subscriptions.saved'));
RPC::commit();
}
function onSubscriptionsList($list) {
$html = $this->prepareList($list);
RPC::call('movim_fill', 'subscriptionslist', $html);
RPC::commit();
}
function ajaxChangeSubscriptions($server, $node, $data){
$r = new SetSubscriptions;
$r->setNode($node)
->setTo($server)
->setData($data)
->request();
}
function ajaxGetSubscriptions($server, $node){
$r = new GetSubscriptions;
$r->setTo($server)
->setNode($node)
->request();
}
}
?>

View file

@ -1,5 +0,0 @@
[subscriptions]
title = Manage your subscriptions
info = Manage the subscriptions
get = Get the subscriptions
saved = Subscriptions saved

View file

@ -1,14 +0,0 @@
{if="$pepfilter"}
<div id="subscriptions" class="tabelem" title="{$c->__('subscriptions.title')}">
<h1 class="paddedtopbottom"><i class="fa fa-users"></i> {$c->__('subscriptions.info')}</h1>
<div class="posthead paddedtopbottom">
<a
class="button color green"
onclick="{$getsubscriptions} this.parentNode.style.display = 'none'">
<i class="fa fa-users"></i> {$c->__('subscriptions.get')}
</a>
</div>
<div id="subscriptionslist" class="padded"></div>
</div>
{/if}

View file

@ -1,41 +0,0 @@
<div>
{if="$post->isMicroblog()"}
<span class="on_desktop icon"><i class="zmdi zmdi-account"></i></span>
<h2>{$c->__('page.blog')}</h2>
{else}
<span class="on_desktop icon"><i class="zmdi zmdi-pages"></i></span>
<h2>{$post->node}</h2>
{/if}
</div>
<div>
{if="$post->isMine()"}
<ul class="active">
{if="$post->isEditable()"}
<li onclick="Publish_ajaxCreate('{$post->origin}', '{$post->node}', '{$post->nodeid}')" title="{$c->__('button.edit')}">
<span class="icon">
<i class="zmdi zmdi-edit"></i>
</span>
</li>
{/if}
<li onclick="Post_ajaxDelete('{$post->origin}', '{$post->node}', '{$post->nodeid}')" title="{$c->__('button.delete')}">
<span class="icon">
<i class="zmdi zmdi-delete"></i>
</span>
</li>
</ul>
{/if}
<div class="return active {if="$post->isMine()"}{if="$post->isEditable()"}r2{else}r1{/if}{/if}" onclick="MovimTpl.hidePanel(); Post_ajaxClear();">
<span id="back" class="icon"><i class="zmdi zmdi-arrow-back"></i></span>
<h2>
{if="$post != null"}
{if="$post->title != null"}
{$post->title}
{else}
{$c->__('post.default_title')}
{/if}
{else}
Empty
{/if}
</h2>
</h2>
</div>

View file

@ -1,8 +0,0 @@
form[name=post] article section {
padding: 0;
}
#comments li.action div.action:hover {
cursor: pointer;
color: #333;
}

View file

@ -1,135 +0,0 @@
<?php
/**
* @package Widgets
*
* @file PubsubSubscriptionConfig.php
* This file is part of MOVIM.
*
* @brief The Group configuration widget
*
* @author Ho Christine <nodpounod@gmail.com>
*
* @version 1.0
* @date 24 March 2013
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
use Moxl\Xec\Action\PubsubSubscription\ListGet;
use Moxl\Xec\Action\PubsubSubscription\ListAdd;
use Moxl\Xec\Action\PubsubSubscription\ListRemove;
class PubsubSubscriptionConfig extends WidgetBase
{
function load()
{
$this->registerEvent('groupsubscribedlist', 'onGroupSubscribedList');
$this->registerEvent('groupadded', 'onGroupAdded');
$this->registerEvent('groupremoved', 'onGroupRemoved');
}
function display()
{
$this->view->assign(
'getsubscribedlist',
$this->call('ajaxGetGroupSubscribedList')
);
}
function onGroupSubscribedList($list) {
$html = $this->prepareList($list);
RPC::call('movim_fill', 'groupsubscribedlistconfig', $html);
}
function prepareList($list) {
$configlist = $this->tpl();
$sd = new \Modl\SubscriptionDAO();
$listhtml = '';
//if($sd != null && $sd->getSubscribed() != null) {
foreach($sd->getSubscribed() as $s) {
if($s->name != null)
$name = $s->name;
else
$name = $s->node;
if(isset($list[$s->server.$s->node]))
$checked = 'checked';
else
$checked = '';
$switch = $this->call(
'ajaxChangeSubscribed',
"'".$s->server."'",
"'".$s->node."'",
"this.checked",
"'".$name."'");
$listhtml .= '
<li class="action">
<span class="icon bubble color '.stringToColor($s->node).'">
'.firstLetterCapitalize($s->node).'
</span>
<form>
<div class="action">
<div class="checkbox">
<input
type="checkbox"
id="privacy'.$s->node.'"
name="privacy'.$s->node.'"
'.$checked.'
onchange="'.$switch.'"/>
<label for="privacy'.$s->node.'"></label>
</div>
</div>
</form>
<a href="'.Route::urlize('node', array($s->server, $s->node)).'">'.
$name.'
</a>
</li>';
}
$configlist->assign('list', $listhtml);
return $configlist->draw('_pubsubsubscriptionconfig_list', true);
//} else return t('No public groups found');
}
function onGroupAdded($node) {
Notification::append(null, $this->__('public_groups.added', $node));
}
function onGroupRemoved($node) {
Notification::append(null, $this->__('public_groups.removed', $node));
}
function ajaxChangeSubscribed($server, $node, $state, $name) {
$data = array('title' => $name);
if($state) {
$r = new ListAdd;
$r->setNode($node)
->setTo($server)
->setFrom($this->user->getLogin())
->setData($data)
->request();
} else {
$r = new ListRemove;
$r->setNode($node)
->setTo($server)
->setFrom($this->user->getLogin())
->request();
}
}
function ajaxGetGroupSubscribedList(){
$r = new ListGet;
$r->request();
}
}

View file

@ -1,6 +0,0 @@
<ul>
<li class="subheader">
{$c->__('public_groups.shared')}
</li>
{$list}
</ul>

View file

@ -1,5 +0,0 @@
[public_groups]
shared = Shared
name = Name
added = %s has been added to your public groups
removed = %s has been removed from your public groups

View file

@ -1,7 +0,0 @@
<div class="tabelem" title="{$c->__('page.public_groups')}" id="groupsubscribedlistconfig">
<script type="text/javascript">
MovimWebsocket.attach(function() {
{$getsubscribedlist}
});
</script>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

View file

@ -1,231 +0,0 @@
<?php
/**
* @package Widgets
*
* @file Visio.php
* This file is part of Movim.
*
* @brief A jabber chat widget.
*
* @author Timothée Jaussoin
*
* See COPYING for licensing information.
*/
//require_once(APP_PATH . "widgets/ChatExt/ChatExt.php");
use Moxl\Xec\Action\Jingle\SessionInitiate;
use Moxl\Xec\Action\Jingle\SessionTerminate;
class Visio extends WidgetBase
{
function load()
{
$this->addcss('visio.css');
$this->addjs('visio.js');
$this->addjs('adapter.js');
$this->addjs('webrtc.js');
$this->addjs('turn.js');
$this->registerEvent('jinglesessioninitiate', 'onSessionInitiate');
$this->registerEvent('jingle_sessioninitiate_erroritemnotfound', 'onInitiationError');
$this->registerEvent('jingle_sessioninitiate_errorunexpectedrequest', 'onInitiationError');
$this->registerEvent('jinglesessionterminate', 'onSessionTerminate');
$this->registerEvent('jinglesessionaccept', 'onSessionAccept');
$this->registerEvent('jingletransportinfo', 'onTransportInfo');
$this->registerEvent('jinglecreationsuccess', 'onCreationSuccess');
}
function onInitiationError() {
RPC::call('sendTerminate');
RPC::call('terminate');
}
function onSessionInitiate($jingle) {
$jts = new \JingletoSDP($jingle);
$sdp = $jts->generate();
$cd = new \Modl\ContactDAO();
$contact = $cd->get(cleanJid((string)$jingle->attributes()->initiator));
if(!isset($contact))
$contact = new Modl\Contact;
if($sdp) {
RPC::call(
'movim_desktop_notification',
$contact->getTrueName(),
$this->__('visio.calling'),
$contact->getPhoto('m'));
//RPC::call('Popup.setJid', (string)$jingle->attributes()->initiator);
RPC::call('onOffer', $sdp);
}
}
function onSessionAccept($jingle) {
$jts = new \JingletoSDP($jingle);
$sdp = $jts->generate();
$sid = $jts->getSessionId();
RPC::call('onAccept', $sdp);
$s = Session::start('movim');
$s->set('jingleSid', $sid);
}
function onTransportInfo($jingle) {
$jts = new \JingletoSDP($jingle);
RPC::call('onCandidate', $jts->generate(), $jts->media);
}
function onSessionTerminate($jingle) {
$message = '';
switch($jingle->reason->children()->getName()) {
case 'success':
$message = $this->__('visio.hung_up');
break;
case 'busy':
$message = $this->__('visio.busy');
break;
case 'decline':
$message = $this->__('visio.declined');
break;
case 'unsupported-transports':
break;
case 'failed-transport':
break;
case 'unsupported-applications':
break;
case 'failed-application':
$message = $this->__('visio.remote_incompatible');
break;
case 'incompatible-parameters':
break;
default:
$message = $this->__('visio.unknown_error');
break;
}
RPC::call('terminate');
RPC::call('movim_fill', 'status', $message);
}
function ajaxSendProposal($proposal) {
$p = json_decode($proposal);
$sd = Sessionx::start();
$stj = new SDPtoJingle(
$p->sdp,
$this->user->getLogin().'/'.$sd->resource,
$p->jid.'/'.$p->resource,
'session-initiate');
$r = new SessionInitiate;
$r->setTo($p->jid.'/'.$p->resource)
->setOffer($stj->generate())
->request();
$sid = $stj->getSessionId();
$s = Session::start('movim');
$s->set('jingleSid', $sid);
}
function ajaxSendAcceptance($proposal) {
$p = json_decode($proposal);
$sd = Sessionx::start();
$stj = new SDPtoJingle(
$p->sdp,
$this->user->getLogin().'/'.$sd->resource,
$p->jid.'/'.$p->resource,
'session-accept');
$r = new SessionInitiate;
$r->setTo($p->jid.'/'.$p->resource)
->setOffer($stj->generate())
->request();
}
function ajaxSendSessionTerminate($jid, $resource, $reason = null) {
$s = Session::start();
$jingleSid = $s->get("jingleSid");
$r = new SessionTerminate;
$r->setTo($jid.'/'.$resource);
$r->setJingleSid($jingleSid);
if(isset($reason))
$r->setReason($reason);
$r->request();
}
function ajaxSendCandidate($candidate) {
$p = json_decode($candidate);
$sd = Sessionx::start();
$sdp =
'm='.$p->mid."\n".
$p->sdp;
$stj = new SDPtoJingle(
$sdp,
$this->user->getLogin().'/'.$sd->resource,
$p->jid.'/'.$p->resource,
'transport-info');
$r = new SessionInitiate;
$r->setTo($p->jid.'/'.$p->resource)
->setOffer($stj->generate())
->request();
}
function ajaxGetContact($jid)
{
$cd = new \Modl\ContactDAO();
$contact = $cd->get($jid);
$contactview = $this->tpl();
$contactview->assign('contact', $contact);
RPC::call('movim_fill', 'avatar', $contactview->draw('_visio_contact', true));
}
function display()
{
//if(isset($_GET['f'])) {
// list($jid, $resource) = explode('/', htmlentities($_GET['f']));
$json = requestURL('https://computeengineondemand.appspot.com/turn?username=93773443&key=4080218913', 1);
$this->view->assign('turn_list' , $json);
/* $cd = new \Modl\ContactDAO();
$contact = $cd->get($jid);
if(!$contact)
$contact = new modl\Contact();
$this->view->assign('avatar',$contact->getPhoto('l'));
$this->view->assign('name' ,$contact->getTrueName());
$this->view->assign('jid' ,$jid);
$this->view->assign('resource' ,$resource);
}*/
}
}

View file

@ -1,3 +0,0 @@
<img src="{$contact->getPhoto('l')}"/>
<span class="name">{$contact->getTrueName()}</span>
<div id="status"></div>

View file

@ -1,142 +0,0 @@
var RTCPeerConnection = null;
var getUserMedia = null;
var attachMediaStream = null;
var reattachMediaStream = null;
var webrtcDetectedBrowser = null;
var webrtcDetectedVersion = null;
function trace(text) {
// This function is used for logging.
if (text[text.length - 1] == '\n') {
text = text.substring(0, text.length - 1);
}
console.log((performance.now() / 1000).toFixed(3) + ": " + text);
}
if (navigator.mozGetUserMedia) {
console.log("This appears to be Firefox");
webrtcDetectedBrowser = "firefox";
webrtcDetectedVersion =
parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);
// The RTCPeerConnection object.
RTCPeerConnection = mozRTCPeerConnection;
// The RTCSessionDescription object.
RTCSessionDescription = mozRTCSessionDescription;
// The RTCIceCandidate object.
RTCIceCandidate = mozRTCIceCandidate;
// Get UserMedia (only difference is the prefix).
// Code from Adam Barth.
getUserMedia = navigator.mozGetUserMedia.bind(navigator);
navigator.getUserMedia = getUserMedia;
// Creates iceServer from the url for FF.
createIceServer = function(url, username, password) {
var iceServer = null;
var url_parts = url.split(':');
if (url_parts[0].indexOf('stun') === 0) {
// Create iceServer with stun url.
iceServer = { 'url': url };
} else if (url_parts[0].indexOf('turn') === 0) {
if (webrtcDetectedVersion < 27) {
// Create iceServer with turn url.
// Ignore the transport parameter from TURN url for FF version <=27.
var turn_url_parts = url.split("?");
// Return null for createIceServer if transport=tcp.
if (turn_url_parts.length === 1 ||
turn_url_parts[1].indexOf('transport=udp') === 0) {
iceServer = { 'url': turn_url_parts[0],
'credential': password,
'username': username };
}
} else {
// FF 27 and above supports transport parameters in TURN url,
// So passing in the full url to create iceServer.
iceServer = { 'url': url,
'credential': password,
'username': username };
}
}
return iceServer;
};
// Attach a media stream to an element.
attachMediaStream = function(element, stream) {
console.log("Attaching media stream");
element.mozSrcObject = stream;
element.play();
};
reattachMediaStream = function(to, from) {
console.log("Reattaching media stream");
to.mozSrcObject = from.mozSrcObject;
to.play();
};
// Fake get{Video,Audio}Tracks
if (!MediaStream.prototype.getVideoTracks) {
MediaStream.prototype.getVideoTracks = function() {
return [];
};
}
if (!MediaStream.prototype.getAudioTracks) {
MediaStream.prototype.getAudioTracks = function() {
return [];
};
}
} else if (navigator.webkitGetUserMedia) {
console.log("This appears to be Chrome");
webrtcDetectedBrowser = "chrome";
webrtcDetectedVersion =
parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2], 10);
// Creates iceServer from the url for Chrome.
createIceServer = function(url, username, password) {
var iceServer = null;
var url_parts = url.split(':');
if (url_parts[0].indexOf('stun') === 0) {
// Create iceServer with stun url.
iceServer = { 'url': url };
} else if (url_parts[0].indexOf('turn') === 0) {
// Chrome M28 & above uses below TURN format.
iceServer = { 'url': url,
'credential': password,
'username': username };
}
return iceServer;
};
// The RTCPeerConnection object.
RTCPeerConnection = webkitRTCPeerConnection;
// Get UserMedia (only difference is the prefix).
// Code from Adam Barth.
getUserMedia = navigator.webkitGetUserMedia.bind(navigator);
navigator.getUserMedia = getUserMedia;
// Attach a media stream to an element.
attachMediaStream = function(element, stream) {
if (typeof element.srcObject !== 'undefined') {
element.srcObject = stream;
} else if (typeof element.mozSrcObject !== 'undefined') {
element.mozSrcObject = stream;
} else if (typeof element.src !== 'undefined') {
element.src = URL.createObjectURL(stream);
} else {
console.log('Error attaching stream to element.');
}
};
reattachMediaStream = function(to, from) {
to.src = from.src;
};
} else {
console.log("Browser does not appear to be WebRTC-capable");
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 376 B

View file

@ -1,10 +0,0 @@
[visio]
call = Call
hang_up = Hang up
connection= Connection
hung_up = Hung up
busy = Your contact is busy
declined = Declined
remote_incompatible = Remote application incompatible
unknown_error = Unknown error
calling = Is calling you

View file

@ -1,59 +0,0 @@
var turnUrl = 'https://computeengineondemand.appspot.com/turn?username=93773443&key=4080218913';
var turnDone = false;
function maybeRequestTurn() {
if (turnUrl == '') {
turnDone = true;
}
for (var i = 0, len = configuration.iceServers.length; i < len; i++) {
if (configuration.iceServers[i].url.substr(0, 5) === 'turn:') {
turnDone = true;
}
}
var currentDomain = document.domain;
if (currentDomain.search('localhost') === -1 &&
currentDomain.search('apprtc') === -1) {
// Not authorized domain. Try with default STUN instead.
turnDone = true;
}
// No TURN server. Get one from computeengineondemand.appspot.com.
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = onTurnResult;
xmlhttp.open('GET', turnUrl, true);
xmlhttp.send();
/*for (i = 0; i < VISIO_TURN_LIST.uris.length; i++) {
var iceServer = createIceServer(VISIO_TURN_LIST.uris[i],
VISIO_TURN_LIST.username,
VISIO_TURN_LIST.password);
if (iceServer !== null) {
configuration.iceServers.push(iceServer);
}
}*/
}
function onTurnResult() {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
var turnServer = JSON.parse(xmlhttp.responseText);
for (i = 0; i < turnServer.uris.length; i++) {
// Create a turnUri using the polyfill (adapter.js).
var iceServer = createIceServer(turnServer.uris[i],
turnServer.username,
turnServer.password);
if (iceServer !== null) {
configuration.iceServers.push(iceServer);
}
}
} /*else {
console.log(
'Error: Status '
+ xmlhttp.status
+ ', State '
+ xmlhttp.readyState);
}*/
// If TURN request failed, continue the call with default STUN.
turnDone = true;
}

View file

@ -1,141 +0,0 @@
html {
height: 100%;
}
body {
background-color: #040404 !important;
height: 100%;
overflow: hidden;
margin: 0 auto;
padding: 0;
max-width: auto !important;
background-image: url('img/background.png');
}
#visio {
width: 100%;
height: 100%;
position: relative;
}
#visio .menu {
position: absolute;
bottom: 0;
text-align: center;
background-color: rgba(0, 0, 0, 0.3);
padding: 0.5em 0;
width: 100%;
}
#visio .menu #toggle-microphone,
#visio .menu #toggle-camera,
#visio .menu #hang-up {
display: none;
}
#visio .menu #toggle-screen {
float: left;
margin-left: 0.5em;
}
#visio .menu .oppose:first-child {
margin-right: 0.5em;
}
#visio #avatar {
position: absolute;
left: 50%;
top: 50%;
max-width: 200px;
margin-left: -100px;
margin-top: -160px;
}
#visio #avatar img {
width: 100%;
display: block;
}
#visio #avatar.tiny {
display: none;
}
#visio #avatar .name {
color: white;
display: block;
text-align: center;
line-height: 1.3em;
margin-top: 1em;
font-size: 1.6em;
}
#visio #avatar #status {
color: white;
text-align: center;
margin-top: 1em;
line-height: 1.5em;
}
#visio #remote-video,
#visio #local-video {
position: absolute;
max-width: 100%;
max-height: 100%;
width: 100%;
height: 100%;
display: none;
}
#visio #log {
color: white;
position: absolute;
top: 0;
left: 0;
/*display: none;*/
}
#visio #log div {
margin-bottom: 1em;
}
/* Status calling */
#visio.calling #remote-video,
#visio.calling #local-video {
display: block;
}
#visio.calling #local-video {
width: 20%;
height: auto;
bottom: 3.5em;
transition: width 0.5s ease;
right: 0;
}
#visio.calling #local-video:hover {
width: 40%;
}
#visio.calling .menu #call {
display: none;
}
#visio.calling .menu #toggle-microphone,
#visio.calling .menu #toggle-camera,
#visio.calling .menu #hang-up {
display: inline-block;
}
#visio.calling #avatar {
display: none;
}
#connection {
position: absolute;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, 0.8);
padding: 2em;
color: white;
width: 100%;
height: 100%;
}

View file

@ -1,157 +0,0 @@
function notifyOpener() {
document.querySelector('#connection').style.display = 'none';
if(self.opener || !self.opener.Popup.win)
self.opener.Popup.win = self;
}
setInterval( notifyOpener, 200 );
self.focus();
VISIO_JID = '';
VISIO_RESOURCE = '';
/**
* When an error occured
*/
window.onerror = function() {
document.querySelector('#connection').style.display = 'block';
};
/**
* When the popup is closed
*/
window.onunload = function() {
//self.opener.Roster_ajaxToggleChat();
};
var Visio = {
isVideoMuted: false,
fullScreen: function() {
var toggle = document.querySelector("#toggle-screen i");
if(document.fullscreenElement == null
&& document.mozFullScreenElement == null
&& document.webkitFullscreenElement == null) { // current working methods
toggle.className = toggle.className.replace('fa-expand', 'fa-compress');
if (document.documentElement.requestFullscreen) {
document.documentElement.requestFullscreen();
} else if (document.documentElement.mozRequestFullScreen) {
document.documentElement.mozRequestFullScreen();
} else if (document.documentElement.webkitRequestFullscreen) {
document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
}
} else {
toggle.className = toggle.className.replace('fa-compress', 'fa-expand');
if (document.cancelFullScreen) {
document.cancelFullScreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
}
}
},
log: function(content) {
var date = new Date();
movim_prepend(
"log",
"<div>["
+ date.getHours() + ":"+date.getMinutes() + ":"+date.getSeconds() + "] "
+ content +
"</div>");
},
toggleVideoMute: function() {
videoTracks = localStream.getVideoTracks();
var camera = document.getElementById("toggle-camera");
if (videoTracks.length === 0) {
console.log('No local video available.');
return;
}
if (this.isVideoMuted) {
for (i = 0; i < videoTracks.length; i++) {
videoTracks[i].enabled = true;
}
camera.className = camera.className.replace('camera-off', 'camera');
console.log('Video unmuted.');
} else {
for (i = 0; i < videoTracks.length; i++) {
videoTracks[i].enabled = false;
}
camera.className = camera.className.replace('camera', 'camera-off');
console.log('Video muted.');
}
this.isVideoMuted = !this.isVideoMuted;
},
toggleAudioMute: function() {
audioTracks = localStream.getAudioTracks();
var micro = document.getElementById("toggle-microphone");
if (audioTracks.length === 0) {
console.log('No local audio available.');
return;
}
if (this.isAudioMuted) {
for (i = 0; i < audioTracks.length; i++) {
audioTracks[i].enabled = true;
}
micro.className = micro.className.replace('microphone-off', 'microphone');
console.log('Video unmuted.');
} else {
for (i = 0; i < audioTracks.length; i++) {
audioTracks[i].enabled = false;
}
micro.className = micro.className.replace('microphone', 'microphone-off');
console.log('Video muted.');
}
this.isAudioMuted = !this.isAudioMuted;
},
readStack: function() {
if(self.opener.popup.stack != null) {
var stack = self.opener.popup.stack;
if(stack.jid != null) {
jid = stack.jid.split('/');
VISIO_JID = jid[0];
VISIO_RESOURCE = jid[1];
delete stack.jid;
}
for(var call in stack) {
console.log('Call function ' + call);
window[call].call(null, stack[call]);
delete stack[call];
}
}
}
}
movim_add_onload(function()
{
maybeRequestTurn();
document.getElementById("call").addEventListener('click', function() { init(true); answer(true); }, false);
document.getElementById("hang-up").addEventListener('click', function() { sendTerminate('success'); terminate(); }, false);
document.getElementById("toggle-screen").addEventListener('click', function() { Visio.fullScreen(); }, false);
document.getElementById("toggle-camera").addEventListener('click', function() { Visio.toggleVideoMute(); }, false);
document.getElementById("toggle-microphone").addEventListener('click', function() { Visio.toggleAudioMute(); }, false);
Visio.readStack();
Visio_ajaxGetContact(VISIO_JID);
});

View file

@ -1,37 +0,0 @@
<div id="visio">
<div id="log">
</div>
<video autoplay="true" id="remote-video">
</video>
<video autoplay="true" id="local-video" muted="true">
</video>
<div id="avatar">
</div>
<div class="menu">
<a id="toggle-microphone" class="button color alone merged right oppose">
<i class="fa fa-microphone"></i>
</a><a id="toggle-camera" class="button color alone merged left oppose">
<i class="fa fa-video-camera"></i>
</a>
<a id="call" class="button color green">
<i class="fa fa-phone"></i> {$c->__('visio.call')}
</a>
<a id="hang-up" class="button color red icon hang-up">
<i class="fa fa-stop"></i> {$c->__('visio.hang_up')}
</a>
<a id="toggle-screen" class="button color blue alone oppose"><i class="fa fa-expand"></i></a>
</div>
</div>
<script type="text/javascript">
VISIO_TURN_LIST = {$turn_list};
</script>
<div id="connection">
{$c->__('visio.connection')}...
</div>

View file

@ -1,309 +0,0 @@
var DtlsSrtpKeyAgreement = {
DtlsSrtpKeyAgreement: true
};
var optional = {
optional: [DtlsSrtpKeyAgreement]
};
var pc;
var remoteStream;
var localStream;
// The RTCPeerConnection configuration
var configuration = {"iceServers":[{"url": "stun:stun.services.mozilla.com"}]};
// Set up audio and video regardless of what devices are present.
var sdpConstraints = {'mandatory': {
'OfferToReceiveAudio': true,
'OfferToReceiveVideo': true }};
function onIceConnectionStateChanged(event) {
Visio.log('onIceConnectionStateChanged');
Visio.log(event);
}
function onSignalingStateChanged(event) {
Visio.log('onSignalingStateChanged');
Visio.log(event);
}
function onIceCandidateAdded(event) {
Visio.log('onIceCandidateAdded');
Visio.log(event);
}
function onRemoteIceCandidateAdded(event) {
Visio.log('onRemoteIceCandidateAdded');
Visio.log(event);
}
function onRemoteIceCandidateError(event) {
Visio.log('onRemoteIceCandidateError');
Visio.log(event);
}
function onSignalingStateChanged(event) {
Visio.log('onSignalingStateChanged');
Visio.log(event);
}
function onRemoteStreamAdded(event) {
var vid = document.getElementById('remote-video');
vid.src = window.URL.createObjectURL(event.stream);
remoteStream = event.stream;
//console.log(remoteStream);
//console.log(vid);
/*
audioTracks = remoteStream.getAudioTracks();
for (i = 0; i < audioTracks.length; i++) {
audioTracks[i].enabled = true;
}*/
}
function onError(err) {
console.log(err);
}
function onOfferCreated(offer) {
pc.setLocalDescription(offer,onSetSessionDescriptionSuccess, onSetSessionDescriptionError);
sendMessage(offer);
}
function onAnswerCreated(offer) {
pc.setLocalDescription(offer,onSetSessionDescriptionSuccess, onSetSessionDescriptionError);
sendMessage(offer, true);
}
function onIceCandidate(event) {
Visio.log('onIceCandidate');
console.log('CANDIDATE');
console.log(event);
candidate = {};
if(event.candidate != null) {
candidate.sdp = event.candidate.candidate;
candidate.mid = event.candidate.sdpMid;
candidate.line = event.candidate.sdpMLineIndex;
candidate.jid = VISIO_JID;
candidate.resource = VISIO_RESOURCE;
var msgString = JSON.stringify(candidate);
Visio_ajaxSendCandidate(msgString);
}
}
function sendTerminate(reason) {
Visio_ajaxSendSessionTerminate(VISIO_JID, VISIO_RESOURCE, reason);
}
function sendMessage(msg, accept) {
offer = {};
offer.sdp = msg.sdp;
offer.jid = VISIO_JID;
offer.resource = VISIO_RESOURCE;
document.getElementById('visio').className = 'calling';
if(webrtcDetectedBrowser == 'chrome') {
setTimeout(function() {
if(!accept)
offer.sdp = pc.localDescription.sdp;
var msgString = JSON.stringify(offer);
if(accept) {
Visio.log('Send the acceptance.');
Visio.log('ACCEPTANCE ' + msg.sdp);
Visio_ajaxSendAcceptance(msgString);
} else {
Visio.log('Send the proposal.');
Visio.log('PROPOSAL ' + msg.sdp);
console.log(msg.sdp);
Visio_ajaxSendProposal(msgString);
}
}, 1000);
} else {
var msgString = JSON.stringify(offer);
if(accept) {
Visio.log('Send the acceptance.');
Visio.log('ACCEPTANCE ' + msg.sdp);
Visio_ajaxSendAcceptance(msgString);
} else {
Visio.log('Send the proposal.');
Visio.log('PROPOSAL ' + msg.sdp);
Visio_ajaxSendProposal(msgString);
}
}
}
function onSetSessionDescriptionSuccess() {
Visio.log('Set local session description success.');
}
function onSetSessionDescriptionError(error) {
Visio.log('Failed to set local session description: ' + error.toString());
sendTerminate('failed-application');
}
function onSetRemoteSessionDescriptionSuccess() {
Visio.log('Set remote session description success.');
}
function onSetRemoteSessionDescriptionError(error) {
Visio.log('Failed to set remote session description: ' + error.message);
sendTerminate('failed-application');
}
function onOffer(offer) {
console.log(offer);
Visio.log('Offer received.');
Visio.log('OFFER ' + offer);
init(false);
if(offer != null) {
var message = {};
message.sdp = offer+"\n";
message.type = 'offer';
var desc = new RTCSessionDescription(message);
pc.setRemoteDescription(desc,
onSetRemoteSessionDescriptionSuccess, onSetRemoteSessionDescriptionError);
answer(false);
}
}
function onAccept(offer) {
Visio.log('Accept received.');
Visio.log('ACCEPT ' + offer);
if(offer != null) {
var desc = new RTCSessionDescription();
desc.sdp = offer;
desc.type = 'answer';
pc.setRemoteDescription(desc,
onSetRemoteSessionDescriptionSuccess, onSetRemoteSessionDescriptionError);
}
}
function onCandidate(sdp, media) {
var label = {
'audio' : 0,
'video' : 1
};
var candidate = new RTCIceCandidate({sdpMLineIndex: label[media],
candidate: sdp});
pc.addIceCandidate(candidate, onRemoteIceCandidateAdded, onRemoteIceCandidateError);
}
function preInit(isCaller) {
// We try to grab TURN servers, init() is called here
maybeRequestTurn(isCaller);
}
function init(isCaller) {
try {
console.log(configuration);
pc = new RTCPeerConnection(configuration, optional);
console.log('Created RTCPeerConnnection with:\n' +
' config: \'' + JSON.stringify(configuration) + '\';\n' +
' constraints: \'' + JSON.stringify(optional) + '\'.');
pc.onicecandidate = onIceCandidate;
pc.onsignalingstatechange = onSignalingStateChanged;
pc.oniceconnectionstatechange = onIceConnectionStateChanged;
pc.onaddstream = onRemoteStreamAdded;
} catch (e) {
Visio.log('Failed to create PeerConnection, exception: ' + e.message);
alert('Cannot create RTCPeerConnection object; \
WebRTC is not supported by this browser.');
return;
}
}
function answer(isCaller) {
if(getUserMedia) {
if (getUserMedia) {
getUserMedia = getUserMedia.bind(navigator);
}
// Request the camera.
getUserMedia(
// Constraints
{
video: true, audio: true
},
// Success Callback
function(localMediaStream) {
// Get a reference to the video element on the page.
var vid = document.getElementById('local-video');
var avatar = document.getElementById('avatar');
// Create an object URL for the video stream and use this
// to set the video source.
vid.src = window.URL.createObjectURL(localMediaStream);
localStream = localMediaStream;
pc.addStream(localStream);
channel = pc.createDataChannel("visio");
if(isCaller)
pc.createOffer(onOfferCreated, onError);
else
pc.createAnswer(onAnswerCreated, onError);
},
// Error Callback
function(err) {
// Log the error to the console.
Visio.log('The following error occurred when trying to use getUserMedia: ' + err);
sendTerminate('decline');
}
);
} else {
alert('Sorry, your browser does not support getUserMedia');
}
}
function terminate() {
// We close the RTCPeerConnection
if(pc != null && pc.signalingState != 'closed')
pc.close();
// We close the local webcam and microphone
if(localStream != null)
localStream.stop();
remoteStream = null;
// Get a reference to the video elements on the page.
var vid = document.getElementById('local-video');
var rvid = document.getElementById('remote-video');
document.getElementById('visio').className = '';
}

View file

@ -1,195 +0,0 @@
<?php
/**
* @package Widgets
*
* @file ChatExt.php
* This file is part of MOVIM.
*
* @brief A jabber chat widget.
*
* @author Guillaume Pasquet <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 20 October 2010
*
* Copyright (C)2010 MOVIM project
*
* See COPYING for licensing information.
*/
use Moxl\Xec\Action\Jingle\SessionInitiate;
use Moxl\Xec\Action\Jingle\SessionTerminate;
class VisioExt extends WidgetBase
{
function load() {
$this->addjs('visioext.js');
$this->registerEvent('jinglesessioninitiate', 'onSessionInitiate');
/*$this->registerEvent('jinglesessionterminate', 'onSessionTerminate');
$this->registerEvent('jinglesessionaccept', 'onSessionAccept');
$this->registerEvent('jingletransportinfo', 'onTransportInfo');
$this->registerEvent('jinglecreationsuccess', 'onCreationSuccess');*/
}
function onSessionInitiate($jingle) {
$jts = new \JingletoSDP($jingle);
$sdp = $jts->generate();
$cd = new \Modl\ContactDAO();
$contact = $cd->get(cleanJid((string)$jingle->attributes()->initiator));
if(!isset($contact))
$contact = new Modl\Contact;
if($sdp) {
RPC::call(
'movim_desktop_notification',
$contact->getTrueName(),
$this->__('visio.calling'),
$contact->getPhoto('m'));
RPC::call('remoteSetJid', (string)$jingle->attributes()->initiator);
RPC::call('remoteCall', 'onOffer', $sdp);
RPC::commit();
}
}
/*
function onSessionAccept($jingle) {
$jts = new \JingletoSDP($jingle);
$sdp = $jts->generate();
$sid = $jts->getSessionId();
RPC::call('Popup.call', 'onAccept', $sdp);
$s = Session::start('movim');
$s->set('jingleSid', $sid);
}
function onTransportInfo($jingle) {
$jts = new \JingletoSDP($jingle);
RPC::call('Popup.call', 'onCandidate', $jts->generate(), $jts->media);
}
function onSessionTerminate($jingle) {
$message = '';
switch($jingle->reason->children()->getName()) {
case 'success':
$message = $this->__('visio.hung_up');
break;
case 'busy':
$message = $this->__('visio.busy');
break;
case 'decline':
$message = $this->__('visio.declined');
break;
case 'unsupported-transports':
break;
case 'failed-transport':
break;
case 'unsupported-applications':
break;
case 'failed-application':
$message = $this->__('visio.remote_incompatible');
break;
case 'incompatible-parameters':
break;
default:
$message = $this->__('visio.unknown_error');
break;
}
RPC::call('Popup.call', 'terminate');
RPC::call('Popup.call', 'movim_fill', 'status', $message);
}
function ajaxSendProposal($proposal) {
$p = json_decode($proposal);
$sd = Sessionx::start();
$stj = new SDPtoJingle(
$p->sdp,
$this->user->getLogin().'/'.$sd->refsource,
$p->jid.'/'.$p->resource,
'session-initiate');
$r = new SessionInitiate;
$r->setTo($p->jid.'/'.$p->resource)
->setOffer($stj->generate())
->request();
$sid = $stj->getSessionId();
$s = Session::start('movim');
$s->set('jingleSid', $sid);
}
function ajaxSendAcceptance($proposal) {
$p = json_decode($proposal);
$sd = Sessionx::start();
$stj = new SDPtoJingle(
$p->sdp,
$this->user->getLogin().'/'.$sd->resource,
$p->jid.'/'.$p->resource,
'session-accept');
$r = new SessionInitiate;
$r->setTo($p->jid.'/'.$p->resource)
->setOffer($stj->generate())
->request();
}
function ajaxSendSessionTerminate($jid, $resource, $reason = null) {
$s = Session::start('movim');
$jingleSid = $s->get("jingleSid");
$r = new SessionTerminate;
$r->setTo($jid.'/'.$resource);
$r->setJingleSid($jingleSid);
if(isset($reason))
$r->setReason($reason);
$r->request();
}
function ajaxSendCandidate($candidate) {
$p = json_decode($candidate);
$sd = Sessionx::start();
$sdp =
'm='.$p->mid."\n".
$p->sdp;
$stj = new SDPtoJingle(
$sdp,
$this->user->getLogin().'/'.$sd->resource,
$p->jid.'/'.$p->resource,
'transport-info');
$r = new SessionInitiate;
$r->setTo($p->jid.'/'.$p->resource)
->setOffer($stj->generate())
->request();
}*/
function build() {
}
}

View file

@ -1,7 +0,0 @@
[visio]
hung_up = Hung up
busy = Your contact is busy
declined = Declined
remote_incompatible = Remote application incompatible
unknown_error = Unknown error
calling = Is calling you

View file

@ -1,59 +0,0 @@
/**
* @brief Definition of the MovimWebsocket object
* @param string error
*/
function Popup() {
var stack;
var win;
}
Popup.prototype.init = function() {
this.stack = {};
}
Popup.prototype.open = function() {
console.log('Popup already opened');
var url = BASE_URI + PAGE_KEY_URI + 'visio';
//this.setJid(jid);
console.log(url);
if( !this.win || this.win.closed ) {
console.log('Opening the Popup');
this.win = window.open( url, "win", "height=480,width=640,directories=0,titlebar=0,toolbar=0,location=0,status=0, personalbar=0,menubar=0,resizable=0" );
} else this.win.focus();
}
Popup.prototype.close = function() {
if(this.win) { this.win.close(); }
}
Popup.prototype.focus = function() {
if(this.win) { this.win.focus(); }
}
Popup.prototype.setJid = function(jid) {
this.stack.jid = jid;
}
Popup.prototype.call = function(func, param) {
if(!this.win || this.win.closed ) {
/*if(this.stack == null) {
this.stack = {};
}*/
this.stack[func] = param;
this.open();
}
}
function remoteCall(func, param) {
console.log('HOP');
console.log(popup);
popup.call(func, param);
}
function remoteSetJid(jid) {
popup.setJid(jid);
}
var popup = new Popup;
popup.init();

View file

@ -1,78 +0,0 @@
<?php
/**
* @file WidgetCommon.php
* This file is part of MOVIM.
*
* @brief The widgets commons methods.
*
* @author Timothée Jaussoin <edhelas@gmail.com>
*
* @date 08 march 2012
*
* Copyright (C)2010 MOVIM Project
*
* See COPYING for licensing information.
*
*/
class WidgetCommon extends WidgetBase {
function ajaxShowPosition($pos)
{
list($lat,$lon) = explode(',', $pos);
$pos = json_decode(
file_get_contents('http://nominatim.openstreetmap.org/reverse?format=json&lat='.$lat.'&lon='.$lon.'&zoom=27&addressdetails=1')
);
RPC::call('movim_fill', 'postpublishlocation' , (string)$pos->display_name);
RPC::commit();
}
function ajaxPublishItem($server, $node, $form)
{
$content = $form['content'];
$title = $form['title'];
$geo = false;
if(isset($form['latlonpos']) && $form['latlonpos'] != '') {
list($lat,$lon) = explode(',', $form['latlonpos']);
$pos = json_decode(
file_get_contents('http://nominatim.openstreetmap.org/reverse?format=json&lat='.$lat.'&lon='.$lon.'&zoom=27&addressdetails=1')
);
$geo = array(
'latitude' => (string)$pos->lat,
'longitude' => (string)$pos->lon,
'altitude' => (string)$pos->alt,
'country' => (string)$pos->address->country,
'countrycode' => (string)$pos->address->country_code,
'region' => (string)$pos->address->county,
'postalcode' => (string)$pos->address->postcode,
'locality' => (string)$pos->address->city,
'street' => (string)$pos->address->path,
'building' => (string)$pos->address->building,
'text' => (string)$pos->display_name,
'uri' => ''//'http://www.openstreetmap.org/'.urlencode('?lat='.(string)$pos->lat.'&lon='.(string)$pos->lon.'&zoom=10')
);
}
if($content != '') {
$content = Markdown::defaultTransform($content);
$p = new PostPublish;
$p->setFrom($this->user->getLogin())
->setTo($server)
->setNode($node)
->setLocation($geo)
->setTitle($title)
->setContentXhtml(rawurldecode($content))
->enableComments()
->request();
}
}
}

View file

@ -1,41 +0,0 @@
<div class="comments" id="{$post->nodeid}comments">
{$comments}
<a
class="getcomments"
onclick="{$getcomments} this.innerHTML = '<i class=\'fa fa-clock-o\'></i> {$c->__('post.comments_loading')}'"
>
<i class="fa fa-comments-o"></i> {$c->__('post.comments_get')}
</a>
</div>
<div class="comments">
<a class="addcomment"
onclick="
this.parentNode.querySelector('#commentsubmit').style.display = 'table';
this.style.display ='none'">
<i class="fa fa-comment-o"></i> {$c->__('post.comment_add')}
</a>
<table id="commentsubmit">
<tr>
<td>
<textarea
id="{$post->nodeid}commentcontent"
onkeyup="movim_textarea_autoheight(this);"></textarea>
</td>
</tr>
<tr class="commentsubmitrow">
<td style="width: 100%;"></td>
<td>
<a
onclick="
if(document.getElementById('{$post->nodeid}commentcontent').value != '') {
{$publishcomment}
document.getElementById('{$post->nodeid}commentcontent').value = '';
}"
class="button color green"
>
<i class="fa fa-check"></i> {$c->__('button.submit')}
</a>
</td>
</tr>
</table>
</div>

View file

@ -1,27 +0,0 @@
<span id="{$idhash}"></span>
<article class="block" id="{$id}" {if="$post->getPlace()"}data-lat="{$post->lat}" data-lon="{$post->lon}"{/if}>
{if="$access"}
<div class="{$access}" title="{$flagtitle}"></div>
{/if}
<header>
<a href="{$friend}">
{$avatar}
</a>
<span class="title" title="{$title}">{$title}</span>
<span class="contact">{$contact}</span>
<span class="date">{$date}</span>
</header>
<section class="content {if="$spoiler != false"}spoiler{/if}" onclick="{$spoiler}">
{$content}
</section>
<footer>
{$tags}
{$enc}
{$comments}
{$place}
{$recycle}
{$group}
{$toolbox}
</footer>
</article>

View file

@ -1,33 +0,0 @@
<div class="tools">
{$c->__("post.share")} :
<a
onclick="{$privacy_post_black}" >
{$c->__('post.share_everyone')}</a>,
<a
onclick="{$privacy_post_orange}" >
{$c->__('post.share_your_contacts')}</a><br />
<a
style="padding-right: 1em;";
onclick="
this.parentNode.querySelector('#deleteyes').style.display = 'inline';
this.parentNode.querySelector('#deleteno').style.display = 'inline';
"
title="{$c->__('post.delete')}">
{$c->__('post.delete')}
</a>
<a
style="padding-right: 1em; display: none;";
id="deleteyes"
onclick="{$delete_post}" >
{$c->__('button.bool_yes')}
</a>
<a
style="display: none;";
id="deleteno"
onclick="
this.parentNode.querySelector('#deleteyes').style.display = 'none';
this.style.display = 'none';
">
{$c->__('button.bool_no')}
</a>
</div>

View file

@ -1,116 +0,0 @@
<script type="text/javascript">
function showPosition(poss) {
{$toggle_position}
}
function insertImg(url) {
var cont = document.querySelector('#postpublishcontent');
cont.value = cont.value + '![](' + url + ')';
movim_textarea_autoheight(cont);
}
</script>
<div class="popup post" id="postpreview">
<div class="content" id="postpreviewcontent">
</div>
<div class="menu">
<a
class="button color icon no"
onclick="movim_toggle_display('#postpreview');"
>{$c->__('button.close')}</a>
</div>
</div>
<div class="popup post" id="galleryselect" style="padding: 0;">
<ul class="thumb">
{loop="$gallery"}
<li style="background-image: url({$value.thumb});">
<a
href="#"
onclick="
insertImg('{$value.uri}');
movim_toggle_display('#galleryselect');">
</a>
</li>
{/loop}
</ul>
{if="$gallery == null"}
<div class="placeholder paddedtop icon media">
<h1>{$c->__('error.whoops')}</h1>
<p class="paddedtop">
{$c->__('error.media_not_found')}<br />
{$c->__('error.media_ask_upload')}
</p>
<a class="button color green" href="{$c->route('media')}"><i class="fa fa-folder-open"></i> {$c->__('page.media')}</a>
<br /><br /><br />
</div>
{/if}
<div class="menu">
<a
class="button color icon no"
onclick="movim_toggle_display('#galleryselect');"
>{$c->__('button.close')}</a>
</div>
</div>
<table id="feedsubmitform">
<tbody>
<form name="postpublish" id="postpublish">
<tr>
<td>
<input name="title" placeholder="{$c->__('post.title')}"/>
</td>
<td>
<textarea
name="content"
id="postpublishcontent"
onkeyup="movim_textarea_autoheight(this);"
placeholder="{$c->__('post.whats_new')}" ></textarea>
</td>
</tr>
<tr id="feedsubmitrow">
<td>
<input type="hidden" id="latlonpos" name="latlonpos"/>
<a
title="{$c->__('button.submit')}"
href="#"
id="feedmessagesubmit"
onclick="{$publish_item}
document.querySelector('#postpublish').reset();
movim_textarea_autoheight(document.querySelector('#postpublishcontent'));"
class="button color green">
<i class="fa fa-envelope"></i> {$c->__('button.submit')}
</a>
<a
class="button color alone merged left images"
style="float: left;"
title="{$c->__('page.gallery')}"
onclick="
movim_toggle_display('#galleryselect');
"
><i class="fa fa-picture-o"></i></a>
<a
class="button color alone merged left"
style="float: left;"
title="{$c->__('page.preview')}"
onclick="
movim_toggle_display('#postpreview');
{$post_preview}"
><i class="fa fa-eye"></i></a><a
class="button color alone merged"
style="float: left;"
href="http://daringfireball.net/projects/markdown/basics"
title="{$c->__('page.help')}"
target="_blank"
><i class="fa fa-life-ring"></i></a><a title="{$c->__('post.geolocalisation')}"
onclick="setPosition(document.querySelector('#latlonpos')); showPosition(document.querySelector('#latlonpos').value);"
style="float: left;"
class="button color alone merged right"><i class="fa fa-location-arrow"></i></a>
<span id="postpublishlocation"></span>
</td>
</tr>
</form>
</tbody>
</table>

0
sources/cache/test.tmp vendored Normal file
View file

1596
sources/composer.lock generated Normal file

File diff suppressed because it is too large Load diff

BIN
sources/composer.phar Executable file

Binary file not shown.

17
sources/config/db.inc.php Normal file
View file

@ -0,0 +1,17 @@
<?php
# This is the database configuration of Movim
# You need to copy an rename this file to 'db.inc.php' and complete the values
$conf = array(
# The type can be 'pgsql' or 'mysql'
'type' => 'mysql',
# The database username
'username' => 'movim',
# The password
'password' => 'yCHeH]UB1YpSjMEihTQZJQyGSoEjZUu8SO]BonYmTTpvi',
# Where can we find the database ?
'host' => 'localhost',
# The port number, 3306 for MySQL and 5432 for PostGreSQL
'port' => 3306,
# The database name
'database' => 'movim'
);

0
sources/log/logger.log Normal file
View file

6
sources/log/php.log Normal file
View file

@ -0,0 +1,6 @@
[07-Mar-2016 22:03:46 Europe/Berlin] PHP Fatal error: Uncaught exception 'Exception' with message 'Cannot find config/db.inc.php file' in /root/movim/bootstrap.php:324
Stack trace:
#0 /root/movim/bootstrap.php(64): Bootstrap->loadModl()
#1 /root/movim/mud.php(7): Bootstrap->boot()
#2 {main}
thrown in /root/movim/bootstrap.php on line 324

View file

@ -1,222 +0,0 @@
<?php
class Locale {
private static $_instance;
public $translations;
public $language;
public $hash = array();
private function __construct()
{
$this->loadIni(
LOCALES_PATH . 'locales.ini',
true,
INI_SCANNER_RAW);
$dir = scandir(WIDGETS_PATH);
foreach($dir as $widget) {
$path = WIDGETS_PATH . $widget . '/locales.ini';
if(file_exists($path)) {
$this->loadIni($path);
}
}
}
/**
* @desc Load a locales ini file and merge it with hash attribute
* @param $file The path of the fie
*/
private function loadIni($file)
{
$this->hash = array_merge_recursive(
$this->hash,
parse_ini_file(
$file,
true,
INI_SCANNER_RAW
)
);
}
public static function start()
{
if(!isset(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* @desc Return an array containing all the presents languages in i18n
*/
public function getList() {
require_once('languages.php');
$lang_list = get_lang_list();
$dir = scandir(LOCALES_PATH);
$po = array();
foreach($dir as $files) {
$explode = explode('.', $files);
if(end($explode) == 'po') {
$po[$explode[0]] = $lang_list[$explode[0]];
}
}
return $po;
}
/**
* @desc Translate a key
* @param $key The key to translate
* @param $args Arguments to pass to sprintf
*/
public function translate($key, $args = false)
{
$arr = explode('.', $key);
if(is_array($this->hash)
&& array_key_exists($arr[0], $this->hash)
&& array_key_exists($arr[1], $this->hash[$arr[0]])) {
$skey = $this->hash[$arr[0]][$arr[1]];
if(is_array($this->translations)
&& array_key_exists($skey, $this->translations)
&& isset($this->translations[$skey])) {
$string = $this->translations[$skey];
} else {
if($this->language != 'en') {
Utils::log('Locale: Translation not found in ['.$this->language.'] for "'.$key.'" : "'.$skey.'"');
}
if(is_string($skey)) {
$string = $skey;
} else {
Utils::log('Locale: Double definition for "'.$key.'" got '.serialize($skey));
$string = $skey[0];
}
}
if($args != false) {
array_unshift($args, $string);
$string = call_user_func_array("sprintf", $args);
}
return $string;
} else {
Utils::log('Locale: Translation key "'.$key.'" not found');
}
}
/**
* @desc Auto-detects the language from the user browser
*/
public function detect()
{
$langs = array();
preg_match_all(
'/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
$_SERVER['HTTP_ACCEPT_LANGUAGE'],
$lang_parse);
if (count($lang_parse[1])) {
$langs = array_combine($lang_parse[1], $lang_parse[4]);
foreach ($langs as $lang => $val) {
if ($val === '') $langs[$lang] = 1;
}
arsort($langs, SORT_NUMERIC);
}
while((list($key, $value) = each($langs))) {
if(file_exists(LOCALES_PATH . $key . '.po')) {
$this->language = $key;
return;
}
$exploded = explode('-', $key);
$key = reset($exploded);
if(file_exists(LOCALES_PATH . $key . '.po')) {
$this->language = $key;
return;
}
$this->language = 'en';
}
}
/**
* @desc Load a specific language
* @param $language The language key to load
*/
public function load($language)
{
$this->language = $language;
$this->loadPo();
}
/**
* @desc Parses a .po file based on the current language
*/
public function loadPo()
{
$pofile = LOCALES_PATH.$this->language.'.po';
if(!file_exists($pofile)) {
return false;
}
// Parsing the file.
$handle = fopen($pofile, 'r');
$this->translations = array();
$msgid = "";
$msgstr = "";
$last_token = "";
while($line = fgets($handle)) {
if($line[0] == "#" || trim(rtrim($line)) == "") {
continue;
}
if(preg_match('#^msgid#', $line)) {
if($last_token == "msgstr") {
$this->translations[$msgid] = $msgstr;
}
$last_token = "msgid";
$msgid = $this->getQuotedString($line);
}
else if(preg_match('#^msgstr#', $line)) {
$last_token = "msgstr";
$msgstr = $this->getQuotedString($line);
}
else {
$last_token .= $this->getQuotedString($line);
}
}
if($last_token == "msgstr") {
$this->translations[$msgid] = $msgstr;
}
fclose($handle);
}
private function getQuotedString($string)
{
$matches = array();
preg_match('#"(.+)"#', $string, $matches);
if(isset($matches[1]))
return $matches[1];
}
}
function __() {
$args = func_get_args();
$l = Locale::start();
$string = array_shift($args);
return $l->translate($string, $args);
}

View file

@ -1,259 +0,0 @@
<?php
/**
* @file i18n.php
* This file is part of MOVIM.
*
* @brief A collection of functions to translate strings.
*
* @author Etenil <etenil@etenilsrealm.nl>
*
* @version 1.0
* @date 22 December 2010
*
* Copyright (C)2010 MOVIM team.
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
require_once('languages.php');
$language = "";
$hash = array();
$translationshash = array();
/**
* Translates strings into the given langage.
*
* This has a sprintf() like behaviour so as to ease translation. Use as:
* echo t("my %s string of %d chars", "beautiful", 20);
*
* Prototype:
* t(string $string, ...)
*/
function t($string)
{
global $language;
global $translations;
$lstring = $string;
if(isset($translations[$string])) {
$lstring = $translations[$string];
}
// For compiled lang files, set en english default if no translation
if($lstring == '')
$lstring = $string;
if(func_num_args() > 1) {
$args = func_get_args();
$args[0] = $lstring; // Replacing with the translated string.
$lstring = call_user_func_array("sprintf", $args);
}
return $lstring;
}
function __() {
$args = func_get_args();
global $translationshash;
$arr = explode('.', $args[0]);
if(is_array($translationshash) && array_key_exists($arr[0], $translationshash)) {
$args[0] = $translationshash[$arr[0]][$arr[1]];
return call_user_func_array('t', $args);
} else {
return $args[0];
}
}
function getQuotedString($string)
{
$matches = array();
preg_match('#"(.+)"#', $string, $matches);
if(isset($matches[1]))
return $matches[1];
}
/**
* Parses a .po file.
*/
function parseLangFile($pofile)
{
if(!file_exists($pofile)) {
return false;
}
// Parsing the file.
$handle = fopen($pofile, 'r');
$trans_string = array();
$msgid = "";
$msgstr = "";
$last_token = "";
while($line = fgets($handle)) {
if($line[0] == "#" || trim(rtrim($line)) == "") {
continue;
}
if(preg_match('#^msgid#', $line)) {
if($last_token == "msgstr") {
$trans_string[$msgid] = $msgstr;
}
$last_token = "msgid";
$msgid = getQuotedString($line);
}
else if(preg_match('#^msgstr#', $line)) {
$last_token = "msgstr";
$msgstr = getQuotedString($line);
}
else {
$last_token .= getQuotedString($line);
}
}
if($last_token == "msgstr") {
$trans_string[$msgid] = $msgstr;
}
fclose($handle);
return $trans_string;
}
/**
* Auto-detects and loads the language.
*/
function loadLanguageAuto()
{
$langs = array();
$langNotFound = true;
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);
if (count($lang_parse[1])) {
$langs = array_combine($lang_parse[1], $lang_parse[4]);
foreach ($langs as $lang => $val) {
if ($val === '') $langs[$lang] = 1;
}
arsort($langs, SORT_NUMERIC);
}
while((list($key, $value) = each($langs)) && $langNotFound == true) {
$exploded = explode('-', $key);
$key = reset($exploded);
$cd = new \Modl\ConfigDAO();
$config = $cd->get();
if($key == 'en') {
loadLanguage($config->locale);
$langNotFound = false;
} elseif(file_exists(LOCALES_PATH . $key . '.po')) {
loadLanguage($key);
$langNotFound = false;
}
}
}
/**
* Loads the given language.
*/
function loadLanguage($lang)
{
global $translations;
global $language;
global $translationshash;
if($lang == $language) {
return true;
}
// Here we load the compiled language file
if(file_exists(CACHE_PATH . '/locales/' . $lang . '.php')) {
// And we set our global $translations
require_once(CACHE_PATH . '/locales/' . $lang . '.php');
} else
$translations = parseLangFile(LOCALES_PATH . $lang . '.po');
if(file_exists(LOCALES_PATH . 'locales.ini')) {
$translationshash = parse_ini_file(LOCALES_PATH . 'locales.ini', true, INI_SCANNER_RAW);
}
$language = $lang;
return true;
}
/**
* Loads a .po file and adds the translations to the existing ones.
* Conflicting translation strings will be rejected.
*/
function loadExtraLang($directory)
{
global $translations;
global $language;
// Converting to unix path (simpler and portable.)
$directory = str_replace('\\', '/', $directory);
if($directory[-1] != '/') {
$directory .= '/';
}
$trans = parseLangFile($directory . $language . '.po');
if(!$trans) {
return false;
}
// Merging the arrays. The existing translations have priority.
foreach($trans as $msgid => $msgstr) {
if(array_key_exists($msgid, $translations)) {
continue;
}
$translations[$msgid] = $msgstr;
}
return true;
}
/**
* Return an array containing all the presents languages in i18n/
*
*/
function loadLangArray() {
$lang_list = get_lang_list();
$dir = scandir(LOCALES_PATH);
$po = array();
foreach($dir as $files) {
$explode = explode('.', $files);
if(end($explode) == 'po') {
$po[$explode[0]] = $lang_list[$explode[0]];
}
}
return $po;
}
?>

View file

@ -1,206 +0,0 @@
<?php
/**
* Return an array containing all the presents languages in i18n/
*
*/
function get_lang_list() {
$lang_list = array(
'aa' => "Afar",
'ab' => "Abkhazian",
'af' => "Afrikaans",
'am' => "Amharic",
'an' => "Aragon&#233;s",
'ar' => "&#1593;&#1585;&#1576;&#1610;",
'as' => "Assamese",
'ast' => "Asturianu",
'ay' => "Aymara",
'az' => "&#1040;&#1079;&#1241;&#1088;&#1073;&#1072;&#1112;&#1209;&#1072;&#1085;",
'ba' => "Bashkir",
'be' => "&#1041;&#1077;&#1083;&#1072;&#1088;&#1091;&#1089;&#1082;&#1110;",
'ber_tam' => "Tamazigh",
'ber_tam_tfng' => "Tamazigh tifinagh",
'bg' => "&#1073;&#1098;&#1083;&#1075;&#1072;&#1088;&#1089;&#1082;&#1080;",
'bh' => "Bihari",
'bi' => "Bislama",
'bm' => "Bambara",
'bn' => "Bengali; Bangla",
'bo' => "Tibetan",
'br' => "brezhoneg",
'bs' => "bosanski",
'ca' => "Catal&#224;",
'co' => "Corsu",
'cpf' => "Kr&eacute;ol r&eacute;yon&eacute;",
'cpf_dom' => "Krey&ograve;l",
'cpf_hat' => "Kr&eacute;y&ograve;l (P&eacute;yi Dayiti)",
'cs' => "&#269;e&#353;tina",
'cy' => "Cymraeg", # welsh, gallois
'da' => "Dansk",
'de' => "Deutsch",
'dz' => "Bhutani",
'el' => "&#949;&#955;&#955;&#951;&#957;&#953;&#954;&#940;",
'en' => "English",
'en_hx' => "H4ck3R",
'en_sm' => "Smurf",
'eo' => "Esperanto",
'es' => "Espa&#241;ol",
'es_co' => "Colombiano",
'et' => "Eesti",
'eu' => "Euskara",
'fa' => "&#1601;&#1575;&#1585;&#1587;&#1609;",
'ff' => "Fulah", // peul
'fi' => "Suomi",
'fj' => "Fiji",
'fo' => "F&#248;royskt",
'fon' => "Fongb&egrave;",
'fr' => "Fran&#231;ais",
'fr_sc' => "Schtroumpf",
'fr_lpc' => "Langue parl&#233;e compl&#233;t&#233;e",
'fr_lsf' => "Langue des signes fran&#231;aise",
'fr_spl' => "Fran&#231;ais simplifi&#233;",
'fr_tu' => "Fran&#231;ais copain",
'fy' => "Frisian",
'ga' => "Irish",
'gd' => "Scots Gaelic",
'gl' => "Galego",
'gn' => "Guarani",
'grc' => "&#7944;&#961;&#967;&#945;&#943;&#945; &#7961;&#955;&#955;&#951;&#957;&#953;&#954;&#942;", // grec ancien
'gu' => "Gujarati",
'ha' => "Hausa",
'hbo' => "&#1506;&#1489;&#1512;&#1497;&#1514;&#1470;&#1492;&#1514;&#1504;&#1498;", // hebreu classique ou biblique
'he' => "&#1506;&#1489;&#1512;&#1497;&#1514;",
'hi' => "&#2361;&#2367;&#2306;&#2342;&#2368;",
'hr' => "Hrvatski",
'hu' => "Magyar",
'hy' => "Armenian",
'ia' => "Interlingua",
'id' => "Indonesia",
'ie' => "Interlingue",
'io' => "Ido",
'ik' => "Inupiak",
'is' => "&#237;slenska",
'it' => "Italiano",
'it_fem' => "Italiana",
'iu' => "Inuktitut",
'ja' => "&#26085;&#26412;&#35486;",
'jv' => "Javanese",
'ka' => "&#4325;&#4304;&#4320;&#4311;&#4323;&#4314;&#4312;",
'kk' => "&#2325;&#2379;&#2306;&#2325;&#2339;&#2368;",
'kl' => "Kalaallisut",
'km' => "Cambodian",
'kn' => "Kannada",
'ko' => "&#54620;&#44397;&#50612;",
'ks' => "Kashmiri",
'ku' => "Kurdish",
'ky' => "Kirghiz",
'la' => "lingua latina",
'lb' => "L&euml;tzebuergesch",
'ln' => "Lingala",
'lo' => "&#3742;&#3762;&#3754;&#3762;&#3749;&#3762;&#3751;", # lao
'lt' => "Lietuvi&#371;",
'lu' => "Luba-katanga",
'lv' => "Latvie&#353;u",
'man' => "Mandingue", # a traduire en mandingue
'mfv' => "Manjak", # ISO-639-3
'mg' => "Malagasy",
'mi' => "Maori",
'mk' => "&#1084;&#1072;&#1082;&#1077;&#1076;&#1086;&#1085;&#1089;&#1082;&#1080; &#1112;&#1072;&#1079;&#1080;&#1082;",
'ml' => "Malayalam",
'mn' => "Mongolian",
'mo' => "Moldavian",
'mos' => "Mor&eacute;",
'mr' => "&#2350;&#2352;&#2366;&#2336;&#2368;",
'ms' => "Bahasa Malaysia",
'mt' => "Maltese",
'my' => "Burmese",
'na' => "Nauru",
'nap' => "Napulitano",
'ne' => "Nepali",
'nqo' => "N'ko", // www.manden.org
'nl' => "Nederlands",
'no' => "Norsk",
'nb' => "Norsk bokm&aring;l",
'nn' => "Norsk nynorsk",
'oc' => "&Ograve;c",
'oc_lnc' => "&Ograve;c lengadocian",
'oc_ni' => "&Ograve;c ni&ccedil;ard",
'oc_ni_la' => "&Ograve;c ni&ccedil;ard (larg)",
'oc_prv' => "&Ograve;c proven&ccedil;au",
'oc_gsc' => "&Ograve;c gascon",
'oc_lms' => "&Ograve;c lemosin",
'oc_auv' => "&Ograve;c auvernhat",
'oc_va' => "&Ograve;c vivaroaupenc",
'om' => "(Afan) Oromo",
'or' => "Oriya",
'pa' => "Punjabi",
'pbb' => 'Nasa Yuwe',
'pl' => "Polski",
'ps' => "Pashto, Pushto",
'pt' => "Portugu&#234;s",
'pt_br' => "Portugu&#234;s do Brasil",
'qu' => "Quechua",
'rm' => "Rhaeto-Romance",
'rn' => "Kirundi",
'ro' => "Rom&#226;n&#259;",
'roa' => "Ch'ti",
'ru' => "&#1088;&#1091;&#1089;&#1089;&#1082;&#1080;&#1081;",
'rw' => "Kinyarwanda",
'sa' => "&#2360;&#2306;&#2360;&#2381;&#2325;&#2371;&#2340;",
'sc' => "Sardu",
'scn' => "Sicilianu",
'sd' => "Sindhi",
'sg' => "Sangho",
'sh' => "Srpskohrvastski",
'sh_latn' => 'Srpskohrvastski',
'sh_cyrl' => '&#1057;&#1088;&#1087;&#1089;&#1082;&#1086;&#1093;&#1088;&#1074;&#1072;&#1090;&#1089;&#1082;&#1080;',
'si' => "Sinhalese",
'sk' => "Sloven&#269;ina", // (Slovakia)
'sl' => "Sloven&#353;&#269;ina", // (Slovenia)
'sm' => "Samoan",
'sn' => "Shona",
'so' => "Somali",
'sq' => "Shqip",
'sr' => "&#1089;&#1088;&#1087;&#1089;&#1082;&#1080;",
'src' => 'Sardu logudor&#233;su', // sarde cf 'sc'
'sro' => 'Sardu campidan&#233;su',
'ss' => "Siswati",
'st' => "Sesotho",
'su' => "Sundanese",
'sv' => "Svenska",
'sw' => "Kiswahili",
'ta' => "&#2980;&#2990;&#3007;&#2996;&#3021;", // Tamil
'te' => "Telugu",
'tg' => "Tajik",
'th' => "&#3652;&#3607;&#3618;",
'ti' => "Tigrinya",
'tk' => "Turkmen",
'tl' => "Tagalog",
'tn' => "Setswana",
'to' => "Tonga",
'tr' => "T&#252;rk&#231;e",
'ts' => "Tsonga",
'tt' => "&#1058;&#1072;&#1090;&#1072;&#1088;",
'tw' => "Twi",
'ty' => "Reo m&#257;`ohi", // tahitien
'ug' => "Uighur",
'uk' => "&#1091;&#1082;&#1088;&#1072;&#1111;&#1085;&#1089;&#1100;&#1082;&#1072;",
'ur' => "&#1649;&#1585;&#1583;&#1608;",
'uz' => "U'zbek",
'vi' => "Ti&#7871;ng Vi&#7879;t",
'vo' => "Volapuk",
'wa' => "Walon",
'wo' => "Wolof",
'xh' => "Xhosa",
'yi' => "Yiddish",
'yo' => "Yoruba",
'za' => "Zhuang",
'zh' => "&#20013;&#25991;", // chinois (ecriture simplifiee)
'zh_tw' => "&#21488;&#28771;&#20013;&#25991;", // chinois taiwan (ecr. traditionnelle)
'zu' => "Zulu"
);
return $lang_list;
}
?>

View file

@ -1,324 +0,0 @@
/* List */
ul li {
padding: 0 2rem;
padding-left: 9rem;
font-size: 2rem;
min-height: 6rem;
line-height: 6rem;
position: relative;
box-sizing: border-box;
text-overflow: ellipsis;
overflow: hidden;
/*min-width: 12rem;*/
}
ul > a {
max-width: 100%;
display: block;
}
ul li.oppose {
padding-left: 0;
padding-right: 9rem;
}
ul li.inactive {
opacity: 0.6;
}
ul.simple > li {
padding-left: 2rem;
line-height: 6rem;
}
ul.simple > li span.icon {
display: none;
}
ul.middle > li {
min-height: 7rem;
line-height: 5rem;
padding-top: 1rem;
padding-bottom: 1rem;
}
ul.thin > li {
min-height: 5rem;
line-height: 5rem;
}
ul.thick > li {
min-height: 7rem;
line-height: 5rem;
padding-top: 2rem;
padding-bottom: 2rem;
}
ul li.subheader {
min-height: 0;
height: 5rem;
line-height: 5rem;
font-size: 1.75rem;
padding-left: 2rem;
padding-top: 0;
font-weight: 600;
/*
position: sticky;
top: 0;
background-color: white;
z-index: 1;
*/
}
ul.active li:hover:not(.subheader),
ul.active.all li:hover,
ul.active li.active:not(.subheader) {
background-color: rgba(0, 0, 0, 0.03);
cursor: pointer;
}
ul.active li:hover:not(.subheader) > p.more:after,
ul.active.all li:hover > p.more:after,
ul.active li.active:not(.subheader) > p.more:after {
background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(247, 247, 247, 1));
}
ul.active li:focus:not(.subheader),
ul.active.all li:focus,
ul.active li.active:not(.subheader) {
background-color: rgba(0, 0, 0, 0.07);
}
ul.active li:focus:not(.subheader) > p.more:after,
ul.active.all li:focus > p.more:after,
ul.active li.active:not(.subheader) > p.more:after {
background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), rgba(237, 237, 237, 1));
}
.dark ul.active li:hover:not(.subheader),
.dark ul.active.all li:hover,
.dark ul.active li.active:not(.subheader) {
background-color: rgba(255, 255, 255, 0.035);
}
ul li.condensed,
ul.thin li.condensed,
ul.thick li.condensed {
line-height: 3rem;
}
ul li.condensed p,
ul.thin li.condensed p,
ul.thick li.condensed p {
line-height: 2.5rem;
margin-bottom: 0;
}
ul li > p,
ul li > a > p {
display: block;
font-size: 1.75rem;
color: rgba(0, 0, 0, 0.60);
overflow: hidden;
text-overflow: ellipsis;
max-height: 8rem;
line-height: 2.5rem;
position: relative;
}
ul li > p.more:after {
display: block;
width: 100%;
height: 3rem;
background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0), white);
content: "";
position: absolute;
bottom: 0;
}
ul li > p.all {
max-height: 100%;
}
ul li p.wrap {
white-space: nowrap;
}
ul li span {
white-space: nowrap;
}
ul li div.bubble span {
white-space: initial;
}
ul li span.second {
opacity: 0.6;
padding-left: 0.5rem;
}
ul li img {
max-width: 100%;
height: auto;
}
ul li > p.more img:not(.emoji) {
margin: 1rem auto;
display: block;
}
ul li.action {
padding-right: 7rem;
}
ul li.action > div.action,
ul li.action > form > div.action {
position: absolute;
top: 50%;
right: 2rem;
margin-top: -2.5rem;
font-size: 3rem;
height: 5rem;
line-height: 5rem;
}
ul li span.info {
float: right;
margin-left: 1rem;
}
/* Counter */
ul li span.counter:empty {
display: none;
}
ul li span.counter {
position: absolute;
right: 1rem;
top: calc(50% - 1.5rem);
line-height: 2rem;
border-radius: 3rem;
padding: 0.5rem;
text-align: center;
min-width: 2rem;
}
ul li span.counter.bottom {
top: calc(50%);
}
/* Bubble */
ul li div.bubble {
padding: 1rem 2rem;
border-radius: 0.25rem;
line-height: 2.75rem;
position: relative;
box-sizing: border-box;
display: block;
font-size: 1.75rem;
background-color: white;
border-color: white;
max-width: 100%;
float: left;
}
ul li div.bubble div {
/*white-space: pre-wrap;*/
display: inline;
}
ul li div.quote {
font-style: italic;
}
ul li.oppose div.bubble {
margin-left: 2rem;
float: right;
}
ul li div.bubble:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
ul li:not(.same) div.bubble:before {
content: "";
position: absolute;
top: 0;
left: -1.5rem;
border-top: 1.5rem solid black;
border-top-color: inherit;
border-left: 1.5rem solid transparent;
border-right: 1.5rem solid transparent;
}
ul li.oppose:not(.same) div.bubble:before {
left: calc(100% - 1.5rem);
}
ul li.same span.icon {
display: none;
}
/* Tabs */
ul.tabs {
text-align: center;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
overflow: hidden;
white-space: nowrap;
height: 6rem;
}
ul.tabs:hover {
overflow-x: auto;
}
ul.tabs li {
display: inline-block;
white-space: nowrap;
text-transform: uppercase;
font-size: 1.75rem;
font-weight: 600;
opacity: 0.6;
padding: 0 2rem;
height: 2rem;
box-sizing: border-box;
}
ul.tabs li:hover {
cursor: pointer;
}
ul.tabs li.active {
opacity: 1;
border-bottom-width: 2px;
border-bottom-style: solid;
}
/* Menu */
ul.context_menu {
border-radius: 0.25rem;
overflow: hidden;
background-color: white;
color: #333;
position: absolute;
top: 0;
right: 0;
margin: 0.5rem;
z-index: 3;
box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.26), 0px 2px 10px 0px rgba(0, 0, 0, 0.16);
display: none;
}
ul.context_menu.shown {
display: block;
}

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 170 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 B

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