-- « La route est longue, mais la voie est libre... »
31 | Framasoft ne vit que par vos dons (déductibles des impôts).
32 | Merci d’avance pour votre soutien https://soutenir.framasoft.org.
33 |
34 |
35 |
36 |
37 |
Important : Ne répondez pas à ce mail. Si vous avez besoin d’aide ou pensez avoir reçu ce mail par erreur, contactez-nous.
38 |
11 | Si vous avez reçu ce mail par erreur, vous n'avez rien à faire pour supprimer votre compte.
12 | Votre compte ne sera tout simplement pas activé et vous ne recevrez pas d’autre email de notre part.
13 |
14 |
15 |
16 | Si vous ne parvenez pas à cliquer sur le lien ci-dessus,
17 | copiez et coller l’URL dans la barre d’adresse de votre navigateur web.
18 |
19 |
20 |
21 | Si vous avez des questions relatives à l’utilisation de votre compte, contactez-nous.
22 |
23 |
24 |
25 | Cordialement,
26 | L’équipe Framasoft.
27 |
28 |
-- « La route est longue, mais la voie est libre... »
29 | Framasoft ne vit que par vos dons (déductibles des impôts).
30 | Merci d’avance pour votre soutien https://soutenir.framasoft.org.
Cliquez sur le lien suivant pour ouvrir la carte mentale : ${mindmap.title}
28 |
29 |
Si vous n’avez pas de compte sur Framindmap, vous pouvez créer un compte gratuitement et librement.
30 |
31 |
Cordialement,
32 | L’équipe Framasoft
33 |
34 |
-- « La route est longue, mais la voie est libre... »
35 | Framasoft ne vit que par vos dons (déductibles des impôts).
36 | Merci d’avance pour votre soutien https://soutenir.framasoft.org.
37 |
38 |
39 |
40 |
41 |
Important : Ne répondez pas à ce mail. Si vous avez besoin d’aide ou pensez avoir reçu ce mail par erreur, contactez-nous.
42 |
Attention : Sur la version actuellement installée de Wisemapping, l’export en pdf ou jpg/png ne fonctionne pas. Nous avons donc désactivé cette fonctionnalité. Lorsqu’une version plus récente du logiciel corrigera ce bug, nous la proposerons à nouveau.
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
Le logiciel
59 |
60 |
Framindmap repose sur le logiciel libre Wisemapping.
61 |
Ce logiciel est compatible avec les navigateurs web suivants :
Auparavant, Framindmap reposait sur le logiciel Mindmaps de David Richard.
88 | Ce logiciel dispose d'une interface plus simple et ne nécessite ni de créer un compte ni de faire transiter vos données sur notre serveur.
89 | Si vous le souhaitez vous pouvez toujours l'utiliser ici :
10 | Contrairement à ce qui est indiqué dans le tutoriel vidéo, les exports en pdf ou en jpg/png ne fonctionnent pas sur cette version de Wisemapping. Nous les avons donc désactivés.
11 |
140 | Tous les champs de ce formulaire sont requis pour le bon fonctionnement du logiciel.
141 | Cependant, il n'est pas nécessaire que vous nous donniez votre véritable identité.
142 |
13 | Thanks so much for your interest in WiseMapping.
14 |
15 |
16 |
17 |
18 | If you have any questions or have any feedback, please don't hesitate to use the on line form.
19 | We'd love to hear from you.
20 |
21 |
22 |
23 |
24 | Votre compte a été créé, vous pouvez vous connecter dès à presént et commencer à apprécier Framindmap.
25 |
26 |
27 |
28 |
29 |
Se connecter
30 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/README.md:
--------------------------------------------------------------------------------
1 | Framindmap
2 | ==========
3 |
4 | Framindmap permet de créer des cartes mentales (aussi appelées « cartes heuristiques »).
5 |
6 | C'est la version traduite en français et précompilée du logiciel mindmaps de David Richard :
7 | https://github.com/drichard/mindmaps
8 | Le logiciel est sous licence AGPLv3
9 |
10 | Cette version est nettoyée des éléments spécifiques à Framasoft (page d'accueil, barre de navigation et script de tracking).
11 | La traduction s'est faite directement dans le code html du fichier framindmap.html (= index.html de la version drichard).
12 |
13 | L'installation se fait par simple copier/coller des fichiers sur un serveur web (c'est juste du html/css/javascript).
14 |
15 | Ce logiciel est proposé comme service en ligne par l'association Framasoft depuis 2012 sur le site :
16 | http://framindmap.org/
17 |
18 |
19 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | mindmaps
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
3 | * Creates a new MindMapModel.
4 | *
5 | * This object represents the underlying mind map model and provides access
6 | * to the document, the mind map and the currently selected node.
7 | *
8 | * All changes to the mind map pass through this object, either through calling
9 | * methods directly or using the executeAction() method to perform NodeActions.
10 | *
11 | *
12 | * @constructor
13 | * @param {mindmaps.EventBus} eventBus
14 | * @param {mindmaps.CommandRegistry} commandRegistry
15 | */
16 | mindmaps.MindMapModel = function(eventBus, commandRegistry, undoController) {
17 | var self = this;
18 | this.document = null;
19 | this.selectedNode = null;
20 |
21 | /**
22 | * Gets the current document.
23 | *
24 | * @returns {mindmaps.Document} the current document.
25 | */
26 | this.getDocument = function() {
27 | return this.document;
28 | };
29 |
30 | /**
31 | * Sets the current document and will publish a DOCUMENT_OPENED or
32 | * DOCUMENT_CLOSED event.
33 | *
34 | * @param {mindmaps.Document} doc or pass null to close the document
35 | */
36 | this.setDocument = function(doc) {
37 | this.document = doc;
38 | if (doc) {
39 | eventBus.publish(mindmaps.Event.DOCUMENT_OPENED, doc);
40 | } else {
41 | eventBus.publish(mindmaps.Event.DOCUMENT_CLOSED);
42 | }
43 | };
44 |
45 | /**
46 | * Gets the current mind map associated with the document.
47 | *
48 | * @returns {mindmaps.MindMap} the mind map or null
49 | */
50 | this.getMindMap = function() {
51 | if (this.document) {
52 | return this.document.mindmap;
53 | }
54 | return null;
55 | };
56 |
57 | /**
58 | * Initialise.
59 | *
60 | * @private
61 | */
62 | this.init = function() {
63 | var createNodeCommand = commandRegistry.get(mindmaps.CreateNodeCommand);
64 | createNodeCommand.setHandler(this.createNode.bind(this));
65 |
66 | var createSiblingNodeCommand = commandRegistry
67 | .get(mindmaps.CreateSiblingNodeCommand);
68 | createSiblingNodeCommand.setHandler(this.createSiblingNode.bind(this));
69 |
70 | var deleteNodeCommand = commandRegistry.get(mindmaps.DeleteNodeCommand);
71 | deleteNodeCommand.setHandler(this.deleteNode.bind(this));
72 |
73 | eventBus.subscribe(mindmaps.Event.DOCUMENT_CLOSED, function() {
74 | createNodeCommand.setEnabled(false);
75 | createSiblingNodeCommand.setEnabled(false);
76 | deleteNodeCommand.setEnabled(false);
77 | });
78 |
79 | eventBus.subscribe(mindmaps.Event.DOCUMENT_OPENED, function() {
80 | createNodeCommand.setEnabled(true);
81 | createSiblingNodeCommand.setEnabled(true);
82 | deleteNodeCommand.setEnabled(true);
83 | });
84 | };
85 |
86 | /**
87 | * Deletes a node or the currently selected one if no argument is passed.
88 | *
89 | * @param {mindmaps.Node} [node] defaults to currently selected.
90 | */
91 | this.deleteNode = function(node) {
92 | if (!node) {
93 | node = this.selectedNode;
94 | }
95 | var map = this.getMindMap();
96 | var action = new mindmaps.action.DeleteNodeAction(node, map);
97 | this.executeAction(action);
98 | };
99 |
100 | /**
101 | * Attaches a new node the mind map. If invoked without arguments, it will
102 | * add a new child to the selected node with an automatically generated
103 | * position.
104 | *
105 | * @param {mindmaps.Node} node the new node
106 | * @param {mindmaps.Node} parent
107 | */
108 | this.createNode = function(node, parent) {
109 | var map = this.getMindMap();
110 | if (!(node && parent)) {
111 | parent = this.selectedNode;
112 | var action = new mindmaps.action.CreateAutoPositionedNodeAction(
113 | parent, map);
114 | } else {
115 | var action = new mindmaps.action.CreateNodeAction(node, parent, map);
116 | }
117 |
118 | this.executeAction(action);
119 | };
120 |
121 | /**
122 | * Creates a new auto positioned node as a sibling to the current selected
123 | * node.
124 | */
125 | this.createSiblingNode = function() {
126 | var map = this.getMindMap();
127 | var selected = this.selectedNode;
128 | var parent = selected.getParent();
129 |
130 | // root nodes dont have a parent
131 | if (parent === null) {
132 | return;
133 | }
134 |
135 | var action = new mindmaps.action.CreateAutoPositionedNodeAction(parent,
136 | map);
137 | this.executeAction(action);
138 | };
139 |
140 | /**
141 | * Sets the node as the currently selected.
142 | *
143 | * @param {mindmaps.Node} node
144 | */
145 | this.selectNode = function(node) {
146 | if (node === this.selectedNode) {
147 | return;
148 | }
149 |
150 | var oldSelected = this.selectedNode;
151 | this.selectedNode = node;
152 | eventBus.publish(mindmaps.Event.NODE_SELECTED, node, oldSelected);
153 | };
154 |
155 | /**
156 | * Changes the caption for the passed node or for the selected one if node
157 | * is null.
158 | *
159 | * @param {mindmaps.Node} node
160 | * @param {String} caption
161 | */
162 | this.changeNodeCaption = function(node, caption) {
163 | if (!node) {
164 | node = this.selectedNode;
165 | }
166 |
167 | var action = new mindmaps.action.ChangeNodeCaptionAction(node, caption);
168 | this.executeAction(action);
169 | };
170 |
171 | /**
172 | * Executes a node action. An executed action might raise an event over the
173 | * event bus and cause an undo event to be emitted via
174 | * MindMapModel#undoAction.
175 | *
176 | * @param {mindmaps.Action} action
177 | */
178 | this.executeAction = function(action) {
179 | // a composite action consists of multiple actions which are
180 | // processed individually.
181 | if (action instanceof mindmaps.action.CompositeAction) {
182 | var execute = this.executeAction.bind(this);
183 | action.forEachAction(execute);
184 | return;
185 | }
186 |
187 | var executed = action.execute();
188 |
189 | // cancel action if false was returned
190 | if (executed !== undefined && !executed) {
191 | return false;
192 | }
193 |
194 | // publish event
195 | if (action.event) {
196 | if (!Array.isArray(action.event)) {
197 | action.event = [ action.event ];
198 | }
199 | eventBus.publish.apply(eventBus, action.event);
200 | }
201 |
202 | // register undo function if available
203 | if (action.undo) {
204 | var undoFunc = function() {
205 | self.executeAction(action.undo());
206 | };
207 |
208 | // register redo function
209 | if (action.redo) {
210 | var redoFunc = function() {
211 | self.executeAction(action.redo());
212 | };
213 | }
214 |
215 | undoController.addUndo(undoFunc, redoFunc);
216 | }
217 | };
218 |
219 | /**
220 | * Saves a document to the localstorage and publishes DOCUMENT_SAVED event on success.
221 | *
222 | * @returns {Boolean} whether the save was successful.
223 | */
224 | this.saveToLocalStorage = function() {
225 | var doc = this.document;
226 | doc.dates.modified = new Date();
227 | doc.title = this.getMindMap().getRoot().getCaption();
228 | var success = mindmaps.LocalDocumentStorage.saveDocument(doc);
229 | if (success) {
230 | eventBus.publish(mindmaps.Event.DOCUMENT_SAVED, doc);
231 | }
232 |
233 | return success;
234 | }
235 |
236 | this.init();
237 | };
238 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/NewDocument.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Unused for now.
3 | *
4 | * @constructor
5 | */
6 | mindmaps.NewDocumentView = function() {
7 |
8 | };
9 |
10 | /**
11 | * Creates a new NewDocumentPresenter. This presenter has no view associated
12 | * with it for now. It simply creates a new document. It could in the future
13 | * display a dialog where the user could chose options like document title and
14 | * such.
15 | *
16 | * @constructor
17 | */
18 | mindmaps.NewDocumentPresenter = function(eventBus, mindmapModel, view) {
19 |
20 | this.go = function() {
21 | var doc = new mindmaps.Document();
22 | mindmapModel.setDocument(doc);
23 | };
24 | };
25 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/NodeMap.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates a new NodeMap object. Map implementation for nodes. The key is
3 | * automatically set to the node id.
4 | *
5 | * @constructor
6 | */
7 | mindmaps.NodeMap = function() {
8 | this.nodes = {};
9 | this.count = 0;
10 | };
11 |
12 | /**
13 | * Return a node by its ID.
14 | *
15 | * @param {String} nodeId
16 | * @returns {mindmaps.Node}
17 | */
18 | mindmaps.NodeMap.prototype.get = function(nodeId) {
19 | return this.nodes[nodeId];
20 | };
21 |
22 | /**
23 | * Adds a node to the map if it hasn't been added before.
24 | *
25 | * @param {mindmaps.Node} node
26 | * @returns {Boolean} true if added, false otherwise.
27 | */
28 | mindmaps.NodeMap.prototype.add = function(node) {
29 | if (!this.nodes.hasOwnProperty(node.id)) {
30 | this.nodes[node.id] = node;
31 | this.count++;
32 | return true;
33 | }
34 | return false;
35 | };
36 |
37 | /**
38 | * Removes a node from the map.
39 | *
40 | * @param {mindmaps.Node} node
41 | * @returns {Boolean} true if removed, false otherwise.
42 | */
43 | mindmaps.NodeMap.prototype.remove = function(node) {
44 | if (this.nodes.hasOwnProperty(node.id)) {
45 | delete this.nodes[node.id];
46 | this.count--;
47 | return true;
48 | }
49 | return false;
50 | };
51 |
52 | /**
53 | * Returns the number of nodes in the map.
54 | *
55 | * @returns {Number}
56 | */
57 | mindmaps.NodeMap.prototype.size = function() {
58 | return this.count;
59 | };
60 |
61 | /**
62 | * Returns all nodes in the map.
63 | *
64 | * @returns {Array}
65 | */
66 | mindmaps.NodeMap.prototype.values = function() {
67 | return Object.keys(this.nodes).map(function(key) {
68 | return this.nodes[key];
69 | }, this);
70 | };
71 |
72 | /**
73 | * Iterator for nodes.
74 | *
75 | * @param {Function} callback, first argument should be the node.
76 | */
77 | mindmaps.NodeMap.prototype.each = function(callback) {
78 | for ( var id in this.nodes) {
79 | callback(this.nodes[id]);
80 | }
81 | };
82 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/Notification.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates a new notification and attaches it to the target selector. If the
3 | * selector matches more than one element, the first one is taken.
4 | *
5 | * @constructor
6 | * @param {String} targetSelector
7 | * @param [options] the options
8 | * @param {String} [options.title] the title of the notification
9 | * @param {String} [options.content] the content
10 | * @param {String} [options.position] possible values: topLeft, topMiddle,
11 | * topRight, rightTop, rightMiddle, rightBottom, bottomLeft,
12 | * bottomMiddle, bottomRight, leftTop, leftMiddle, leftBottom
13 | * @param {Integer} [options.padding]
14 | * @param {Integer} [options.expires]
15 | * @param {Boolean} [options.closeButton]
16 | * @param {Integer} [options.maxWidth]
17 | * @param {String} [options.type] possible values: info, warn, error
18 | */
19 | mindmaps.Notification = function(targetSelector, options) {
20 | var self = this;
21 | options = $.extend({}, mindmaps.Notification.Defaults, options);
22 |
23 | // render template
24 | var $notification = this.$el = $("#template-notification").tmpl(options)
25 | .css({
26 | "max-width" : options.maxWidth
27 | }).addClass(options.type);
28 |
29 | // notification target
30 | var $target = $(targetSelector);
31 | if ($target.length === 0) {
32 | /**
33 | * Return unfinished, invisible notification if selector didn't match.
34 | * It will simply not show up, and does not have to be handled specially
35 | * by the caller.
36 | */
37 | return this;
38 | }
39 |
40 | var offset = $target.offset();
41 | var targetLeft = offset.left;
42 | var targetTop = offset.top;
43 | var targetWidth = $target.outerWidth();
44 | var targetHeight = $target.outerHeight();
45 |
46 | // add to dom. we need measurings
47 | $notification.appendTo($("body"));
48 | var notiWidth = $notification.outerWidth();
49 | var notiHeight = $notification.outerHeight();
50 | var notiLeft, notiTop;
51 | var padding = options.padding;
52 |
53 | // position
54 | switch (options.position) {
55 |
56 | case "topLeft":
57 | notiTop = targetTop - padding - notiHeight;
58 | notiLeft = targetLeft;
59 | break;
60 | case "topMiddle":
61 | notiTop = targetTop - padding - notiHeight;
62 | if (notiWidth < targetWidth) {
63 | notiLeft = targetLeft + (targetWidth - notiWidth) / 2;
64 | } else {
65 | notiLeft = targetLeft - (notiWidth - targetWidth) / 2;
66 | }
67 | break;
68 | case "topRight":
69 | notiTop = targetTop - padding - notiHeight;
70 | notiLeft = targetLeft + targetWidth - notiWidth;
71 | break;
72 | case "rightTop":
73 | notiTop = targetTop;
74 |
75 | break;
76 | case "rightMiddle":
77 | if (notiHeight < targetHeight) {
78 | notiTop = targetTop + (targetHeight - notiHeight) / 2;
79 | } else {
80 | notiTop = targetTop - (notiHeight - targetHeight) / 2;
81 | }
82 | notiLeft = targetLeft + padding + targetWidth;
83 | break;
84 | case "rightBottom":
85 | notiTop = targetTop + targetHeight - notiHeight;
86 | notiLeft = targetLeft + padding + targetWidth;
87 | break;
88 | case "bottomLeft":
89 | notiTop = targetTop + padding + targetHeight;
90 | notiLeft = targetLeft;
91 | break;
92 | case "bottomMiddle":
93 | notiTop = targetTop + padding + targetHeight;
94 | if (notiWidth < targetWidth) {
95 | notiLeft = targetLeft + (targetWidth - notiWidth) / 2;
96 | } else {
97 | notiLeft = targetLeft - (notiWidth - targetWidth) / 2;
98 | }
99 | break;
100 | case "bottomRight":
101 | notiTop = targetTop + padding + targetHeight;
102 | notiLeft = targetLeft + targetWidth - notiWidth;
103 | break;
104 | case "leftTop":
105 | notiTop = targetTop;
106 | notiLeft = targetLeft - padding - notiWidth;
107 | break;
108 | case "leftMiddle":
109 | if (notiHeight < targetHeight) {
110 | notiTop = targetTop + (targetHeight - notiHeight) / 2;
111 | } else {
112 | notiTop = targetTop - (notiHeight - targetHeight) / 2;
113 | }
114 | notiLeft = targetLeft - padding - notiWidth;
115 | break;
116 | case "leftBottom":
117 | notiTop = targetTop + targetHeight - notiHeight;
118 | notiLeft = targetLeft - padding - notiWidth;
119 | break;
120 | }
121 |
122 | $notification.offset({
123 | left : notiLeft,
124 | top : notiTop
125 | });
126 |
127 | // fadeout?
128 | if (options.expires) {
129 | setTimeout(function() {
130 | self.close();
131 | }, options.expires);
132 | }
133 |
134 | // close button
135 | if (options.closeButton) {
136 | $notification.find(".close-button").click(function() {
137 | self.close();
138 | });
139 | }
140 |
141 | // display
142 | $notification.fadeIn(600);
143 | };
144 |
145 | mindmaps.Notification.prototype = {
146 | /**
147 | * Removes the notification.
148 | */
149 | close : function() {
150 | var n = this.$el;
151 | n.fadeOut(800, function() {
152 | n.remove();
153 | this.removed = true;
154 | });
155 | },
156 | /**
157 | * Returns whether the notification is still on screen.
158 | *
159 | * @returns {Boolean}
160 | */
161 | isVisible : function() {
162 | return !this.removed;
163 | },
164 | /**
165 | * Returns the element as a jQuery object.
166 | *
167 | * @returns {jQuery}
168 | */
169 | $ : function() {
170 | return this.$el;
171 | }
172 | };
173 |
174 | /**
175 | * The default options.
176 | */
177 | mindmaps.Notification.Defaults = {
178 | title : null,
179 | content : "New Notification",
180 | position : "topLeft",
181 | padding : 10,
182 | expires : 0,
183 | closeButton : false,
184 | maxWidth : 500,
185 | type : "info"
186 | };
187 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/OpenDocument.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates a new OpenDocumentView. This view shows a dialog from which the user
3 | * can select a mind map from the local storage or a hard disk.
4 | *
5 | * @constructor
6 | */
7 | mindmaps.OpenDocumentView = function() {
8 | var self = this;
9 |
10 | // create dialog
11 | var $dialog = $("#template-open").tmpl().dialog({
12 | autoOpen : false,
13 | modal : true,
14 | zIndex : 5000,
15 | width : 550,
16 | close : function() {
17 | $(this).dialog("destroy");
18 | $(this).remove();
19 | }
20 | });
21 |
22 | $dialog.find("input").bind("change", function(e) {
23 | if (self.openExernalFileClicked) {
24 | self.openExernalFileClicked(e);
25 | }
26 | });
27 |
28 | var $table = $dialog.find(".localstorage-filelist");
29 | $table.delegate("a.title", "click", function() {
30 | if (self.documentClicked) {
31 | var t = $(this).tmplItem();
32 | self.documentClicked(t.data);
33 | }
34 | }).delegate("a.delete", "click", function() {
35 | if (self.deleteDocumentClicked) {
36 | var t = $(this).tmplItem();
37 | self.deleteDocumentClicked(t.data);
38 | }
39 | });
40 |
41 | /**
42 | * Render list of documents in the local storage
43 | *
44 | * @param {mindmaps.Document[]} docs
45 | */
46 | this.render = function(docs) {
47 | // empty list and insert list of documents
48 | var $list = $(".document-list", $dialog).empty();
49 |
50 | $("#template-open-table-item").tmpl(docs, {
51 | format : function(date) {
52 | if (!date) return "";
53 |
54 | var day = date.getDate();
55 | var month = date.getMonth() + 1;
56 | var year = date.getFullYear();
57 | return day + "/" + month + "/" + year;
58 | }
59 | }).appendTo($list);
60 | };
61 |
62 | /**
63 | * Shows the dialog.
64 | *
65 | * @param {mindmaps.Document[]} docs
66 | */
67 | this.showOpenDialog = function(docs) {
68 | this.render(docs);
69 | $dialog.dialog("open");
70 | };
71 |
72 | /**
73 | * Hides the dialog.
74 | */
75 | this.hideOpenDialog = function() {
76 | $dialog.dialog("close");
77 | };
78 | };
79 |
80 | /**
81 | * Creates a new OpenDocumentPresenter. The presenter can load documents from
82 | * the local storage or hard disk.
83 | *
84 | * @constructor
85 | * @param {mindmaps.EventBus} eventBus
86 | * @param {mindmaps.MindMapModel} mindmapModel
87 | * @param {mindmaps.OpenDocumentView} view
88 | */
89 | mindmaps.OpenDocumentPresenter = function(eventBus, mindmapModel, view) {
90 |
91 | // TODO experimental, catch errrs
92 | // http://www.w3.org/TR/FileAPI/#dfn-filereader
93 | /**
94 | * View callback: external file has been selected. Try to read and parse a
95 | * valid mindmaps Document.
96 | *
97 | * @ignore
98 | */
99 | view.openExernalFileClicked = function(e) {
100 | var files = e.target.files;
101 | var file = files[0];
102 |
103 | var reader = new FileReader();
104 | reader.onload = function() {
105 | var doc = mindmaps.Document.fromJSON(reader.result);
106 | mindmapModel.setDocument(doc);
107 | view.hideOpenDialog();
108 | };
109 |
110 | reader.readAsText(file);
111 | };
112 |
113 | /**
114 | * View callback: A document in the local storage list has been clicked.
115 | * Load the document and close view.
116 | *
117 | * @ignore
118 | * @param {mindmaps.Document} doc
119 | */
120 | view.documentClicked = function(doc) {
121 | mindmapModel.setDocument(doc);
122 | view.hideOpenDialog();
123 | };
124 |
125 | /**
126 | * View callback: The delete link the local storage list has been clicked.
127 | * Delete the document, and render list again.
128 | *
129 | * @ignore
130 | * @param {mindmaps.Document} doc
131 | */
132 | view.deleteDocumentClicked = function(doc) {
133 | // TODO event
134 | mindmaps.LocalDocumentStorage.deleteDocument(doc);
135 |
136 | // re-render view
137 | var docs = mindmaps.LocalDocumentStorage.getDocuments();
138 | view.render(docs);
139 | };
140 |
141 | /**
142 | * Initialize.
143 | */
144 | this.go = function() {
145 | var docs = mindmaps.LocalDocumentStorage.getDocuments();
146 | docs.sort(mindmaps.Document.sortByModifiedDateDescending);
147 | view.showOpenDialog(docs);
148 | };
149 | };
150 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/Point.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Point class.
3 | *
4 | * @constructor
5 | * @param {Number} [x=0]
6 | * @param {Number} [y=0]
7 | */
8 | mindmaps.Point = function(x, y) {
9 | this.x = x || 0;
10 | this.y = y || 0;
11 | };
12 |
13 | /**
14 | * Returns a new point object from generic obj.
15 | *
16 | * @static
17 | * @param obj
18 | * @returns {mindmaps.Point}
19 | */
20 | mindmaps.Point.fromObject = function(obj) {
21 | return new mindmaps.Point(obj.x, obj.y);
22 | };
23 |
24 | /**
25 | * Clones a the point.
26 | *
27 | * @returns {mindmaps.Point}
28 | */
29 | mindmaps.Point.prototype.clone = function() {
30 | return new mindmaps.Point(this.x, this.y);
31 | };
32 |
33 | /**
34 | * Adds a point to the point.
35 | * @param {mindmaps.Point} point
36 | */
37 | mindmaps.Point.prototype.add = function(point) {
38 | this.x += point.x;
39 | this.y += point.y;
40 | };
41 |
42 | /**
43 | * Returns a String representation.
44 | * @returns {String}
45 | */
46 | mindmaps.Point.prototype.toString = function() {
47 | return "{x: " + this.x + " y: " + this.y + "}";
48 | };
49 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/PrintController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @constructor
3 | * @param {mindmaps.EventBus} eventBus
4 | * @param {mindmaps.CommandRegistry} commandRegistry
5 | * @param {mindmaps.MindMapModel} mindmapModel
6 | */
7 | mindmaps.PrintController = function(eventBus, commandRegistry, mindmapModel) {
8 | var printCommand = commandRegistry.get(mindmaps.PrintCommand);
9 | printCommand.setHandler(doPrintDocument);
10 |
11 | var renderer = new mindmaps.StaticCanvasRenderer();
12 |
13 | function doPrintDocument() {
14 | var $img = renderer.renderAsPNG(mindmapModel.getDocument());
15 | $("#print-area").html($img);
16 | window.print();
17 |
18 | // TODO chrome only: after print() opens a new tab, and one switches
19 | // back to the old tab the canvas container has scrolled top-left.
20 | }
21 |
22 | eventBus.subscribe(mindmaps.Event.DOCUMENT_CLOSED, function() {
23 | printCommand.setEnabled(false);
24 | });
25 |
26 | eventBus.subscribe(mindmaps.Event.DOCUMENT_OPENED, function() {
27 | printCommand.setEnabled(true);
28 | });
29 | };
30 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/SaveDocument.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates a new SaveDocumentView. This view renders a dialog where the user can
3 | * save the mind map.
4 | *
5 | * @constructor
6 | */
7 | mindmaps.SaveDocumentView = function() {
8 | var self = this;
9 |
10 | var $dialog = $("#template-save").tmpl().dialog({
11 | autoOpen : false,
12 | modal : true,
13 | zIndex : 5000,
14 | width : 550,
15 | close : function() {
16 | // remove dialog from DOM
17 | $(this).dialog("destroy");
18 | $(this).remove();
19 | }
20 | });
21 |
22 | var $localSorageButton = $("#button-save-localstorage").button().click(
23 | function() {
24 | if (self.localStorageButtonClicked) {
25 | self.localStorageButtonClicked();
26 | }
27 | });
28 |
29 | var $autoSaveCheckbox = $("#checkbox-autosave-localstorage").click(
30 | function() {
31 | if (self.autoSaveCheckboxClicked) {
32 | self.autoSaveCheckboxClicked($(this).prop("checked"));
33 | }
34 | });
35 |
36 | var $hddSaveButton = $("#button-save-hdd").button().downloadify({
37 | filename : function() {
38 | if (self.fileNameRequested) {
39 | return self.fileNameRequested();
40 | }
41 | },
42 | data : function() {
43 | if (self.fileContentsRequested) {
44 | return self.fileContentsRequested();
45 | }
46 | },
47 | onComplete : function() {
48 | if (self.saveToHddComplete) {
49 | self.saveToHddComplete();
50 | }
51 | },
52 | onError : function() {
53 | console.log("error while saving to hdd");
54 | },
55 | swf : 'media/downloadify.swf',
56 | downloadImage : 'img/transparent.png',
57 | width : 65,
58 | height : 29,
59 | append : true
60 | });
61 |
62 | this.setAutoSaveCheckboxState = function(checked) {
63 | $autoSaveCheckbox.prop("checked", checked);
64 | }
65 |
66 | this.showSaveDialog = function() {
67 | $dialog.dialog("open");
68 | };
69 |
70 | this.hideSaveDialog = function() {
71 | $dialog.dialog("close");
72 | };
73 | };
74 |
75 | /**
76 | * Creates a new SaveDocumentPresenter. The presenter can store documents in the
77 | * local storage or to a hard disk.
78 | *
79 | * @constructor
80 | * @param {mindmaps.EventBus} eventBus
81 | * @param {mindmaps.MindMapModel} mindmapModel
82 | * @param {mindmaps.SaveDocumentView} view
83 | * @param {mindmaps.AutoSaveController} autosaveController
84 | */
85 | mindmaps.SaveDocumentPresenter = function(eventBus, mindmapModel, view, autosaveController) {
86 | /**
87 | * View callback when local storage button was clicked. Saves the document
88 | * in the local storage.
89 | *
90 | * @ignore
91 | */
92 | view.localStorageButtonClicked = function() {
93 | var success = mindmapModel.saveToLocalStorage();
94 | if (success) {
95 | view.hideSaveDialog();
96 | } else {
97 | // TODO display error hint
98 | }
99 | };
100 |
101 |
102 | /**
103 | * View callback: Enables or disables the autosave function for localstorage.
104 | *
105 | * @ignore
106 | */
107 | view.autoSaveCheckboxClicked = function(checked) {
108 | if (checked) {
109 | autosaveController.enable();
110 | } else {
111 | autosaveController.disable();
112 | }
113 | }
114 |
115 | /**
116 | * View callback: Returns the filename for the document for saving on hard
117 | * drive.
118 | *
119 | * @ignore
120 | * @returns {String}
121 | */
122 | view.fileNameRequested = function() {
123 | return mindmapModel.getMindMap().getRoot().getCaption() + ".json";
124 | };
125 |
126 | /**
127 | * View callback: Returns the serialized document.
128 | *
129 | * @ignore
130 | * @returns {String}
131 | */
132 | view.fileContentsRequested = function() {
133 | var doc = mindmapModel.getDocument();
134 | doc.dates.modified = new Date();
135 | return doc.serialize();
136 | };
137 |
138 | /**
139 | * View callback: Saving to the hard drive was sucessful.
140 | *
141 | * @ignore
142 | */
143 | view.saveToHddComplete = function() {
144 | var doc = mindmapModel.getDocument();
145 | eventBus.publish(mindmaps.Event.DOCUMENT_SAVED, doc);
146 | view.hideSaveDialog();
147 | };
148 |
149 | this.go = function() {
150 | view.setAutoSaveCheckboxState(autosaveController.isEnabled());
151 | view.showSaveDialog();
152 | };
153 | };
154 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/ShortcutController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates a new ShortcutController. This object takes care of all keyboard
3 | * shortcuts.
4 | *
5 | * @constructor
6 | */
7 | mindmaps.ShortcutController = function() {
8 | // set to save shortcuts in
9 | /**
10 | * @private
11 | */
12 | this.shortcuts = {};
13 |
14 | /**
15 | * Set the event type and add namespace for later removal.
16 | *
17 | * @param {String} shortcut the key combination
18 | * @param {String} [type="keydown"]
19 | * @returns {String}
20 | */
21 | function getType(shortcut, type) {
22 | type = type || "keydown";
23 | return type + "." + shortcut;
24 | }
25 |
26 | /**
27 | * Registers a new application wide shortcut. shortcuts can be
28 | * either a string or an array containing multiple possible
29 | * shortcuts for the same action.
30 | *
31 | * @param {String|Array} shortcuts
32 | * @param {Function} handler
33 | * @param {String} [type="keydown"]
34 | */
35 | this.register = function(shortcuts, handler, type) {
36 | if (!Array.isArray(shortcuts)) {
37 | shortcuts = [shortcuts];
38 | }
39 |
40 | var self = this;
41 | shortcuts.forEach(function(shortcut) {
42 | type = getType(shortcut, type);
43 | $(document).bind(type, shortcut, function(e) {
44 | // try best to cancel default actions on shortcuts like ctrl+n
45 | e.stopImmediatePropagation();
46 | e.stopPropagation();
47 | e.preventDefault();
48 | handler();
49 | return false;
50 | self.shortcut[type] = true
51 | });
52 | });
53 | };
54 |
55 | /**
56 | * Unregisters a application shortcut.
57 | *
58 | * @param {String} shortcut
59 | * @param {String} [type="keydown"]
60 | */
61 | this.unregister = function(shortcut, type) {
62 | type = getType(shortcut, type);
63 | $(document).unbind(type);
64 | delete this.shortcuts[type];
65 | };
66 |
67 | /**
68 | * Removes all shortcuts.
69 | */
70 | this.unregisterAll = function() {
71 | for ( var shortcut in shortcuts) {
72 | $(document).unbind(shortcut);
73 | }
74 | };
75 | };
76 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/StatusBar.js:
--------------------------------------------------------------------------------
1 | // TODO Rename those objects to TaskBar*
2 |
3 | /**
4 | * Creates a new StatusBarView.
5 | *
6 | * @constructor
7 | */
8 | mindmaps.StatusBarView = function() {
9 | var self = this;
10 | var $statusbar = $("#statusbar");
11 |
12 | this.init = function() {
13 | };
14 |
15 | /**
16 | * Creates and adds a new button to the stats baar.
17 | *
18 | * @param {String} id
19 | * @param {String} text
20 | * @returns {jQuery}
21 | */
22 | this.createButton = function(id, text) {
23 | return $("", {
24 | id : "statusbar-button-" + id
25 | }).button({
26 | label : text
27 | }).click(function() {
28 | if (self.buttonClicked) {
29 | self.buttonClicked(id);
30 | }
31 | }).prependTo($statusbar.find(".buttons"));
32 | };
33 |
34 | /**
35 | * Returns the underlying jquery object.
36 | *
37 | * @returns {jQuery}
38 | */
39 | this.getContent = function() {
40 | return $statusbar;
41 | };
42 | };
43 |
44 | /**
45 | * Creates a new StatusBarPresenter. This object provides buttons for the
46 | * floating panels for a taskbar-like behaviour.
47 | *
48 | * @constructor
49 | * @param {mindmaps.EventBus} eventBus
50 | * @param {mindmaps.StatusBarView} view
51 | */
52 | mindmaps.StatusBarPresenter = function(eventBus, view) {
53 | var buttonCounter = 0;
54 | var buttonIdPanelMap = {};
55 | var statusController = new mindmaps.StatusNotificationController(eventBus,
56 | view.getContent());
57 |
58 | view.buttonClicked = function(id) {
59 | buttonIdPanelMap[id].toggle();
60 | };
61 |
62 | this.go = function() {
63 | view.init();
64 |
65 | };
66 |
67 | /**
68 | * Adds a new button for a panel to the statusbar and registers the button
69 | * as a hide target for the panel.
70 | *
71 | * @param {mindmaps.FloatPanel} panel
72 | */
73 | this.addEntry = function(panel) {
74 | var id = buttonCounter++;
75 | var $button = view.createButton(id, panel.caption);
76 | panel.setHideTarget($button);
77 | buttonIdPanelMap[id] = panel;
78 | };
79 | };
80 |
81 | /**
82 | * This object subscribes to some events and displays status messages in the
83 | * bottom right corner.
84 | *
85 | * @constructor
86 | * @param {mindmaps.EventBus} eventBus
87 | * @param {mindmaps.StatusBarView} view
88 | */
89 | mindmaps.StatusNotificationController = function(eventBus, view) {
90 | var $anchor = $("").css({
91 | position : "absolute",
92 | right : 20
93 | }).appendTo(view);
94 |
95 | eventBus.subscribe(mindmaps.Event.DOCUMENT_SAVED, function() {
96 | var n = new mindmaps.Notification($anchor, {
97 | position : "topRight",
98 | expires : 2500,
99 | content : "Carte mentale enregistr\351e"
100 | });
101 | });
102 |
103 | eventBus.subscribe(mindmaps.Event.NOTIFICATION_INFO, function(message) {
104 | var n = new mindmaps.Notification($anchor, {
105 | position : "topRight",
106 | content : message,
107 | expires : 2500,
108 | type: "info"
109 | });
110 | });
111 |
112 | eventBus.subscribe(mindmaps.Event.NOTIFICATION_WARN, function(message) {
113 | var n = new mindmaps.Notification($anchor, {
114 | position : "topRight",
115 | title: "Attention",
116 | content : message,
117 | expires : 3000,
118 | type: "warn"
119 | });
120 | });
121 |
122 |
123 | eventBus.subscribe(mindmaps.Event.NOTIFICATION_ERROR, function(message) {
124 | var n = new mindmaps.Notification($anchor, {
125 | position : "topRight",
126 | title: "Erreur",
127 | content : message,
128 | expires : 3500,
129 | type: "error"
130 | });
131 | });
132 | };
133 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/Storage.js:
--------------------------------------------------------------------------------
1 | // TODO store a wrapper object with doc title, modified date and document as string in localstorage.
2 | // in open document window show wrapper object and only parse document on demand.
3 | // when many large documents are stored in LS, opening of window takes a rather long time
4 | mindmaps.LocalStorage = (function() {
5 | return {
6 | put : function(key, value) {
7 | localStorage.setItem(key, value);
8 | },
9 | get : function(key) {
10 | return localStorage.getItem(key);
11 | },
12 | clear : function() {
13 | localStorage.clear();
14 | }
15 | };
16 | })();
17 |
18 | mindmaps.SessionStorage = (function() {
19 | return {
20 | put : function(key, value) {
21 | sessionStorage.setItem(key, value);
22 | },
23 | get : function(key) {
24 | return sessionStorage.getItem(key);
25 | },
26 | clear : function() {
27 | sessionStorage.clear();
28 | }
29 | };
30 | })();
31 |
32 | /**
33 | * @namespace
34 | */
35 | mindmaps.LocalDocumentStorage = (function() {
36 | var prefix = "mindmaps.document.";
37 |
38 | var getDocumentByKey = function(key) {
39 | var json = localStorage.getItem(key);
40 | if (json === null) {
41 | return null;
42 | }
43 |
44 | /**
45 | * Catch any SytaxErrors when document can't be parsed.
46 | */
47 | try {
48 | return mindmaps.Document.fromJSON(json);
49 | } catch (error) {
50 | console.error("Error while loading document from local storage",
51 | error);
52 | return null;
53 | }
54 | };
55 |
56 | /**
57 | * Public API
58 | * @scope mindmaps.LocalDocumentStorage
59 | */
60 | return {
61 | /**
62 | * Saves a document to the localstorage. Overwrites the old document if
63 | * one with the same id exists.
64 | *
65 | * @param {mindmaps.Document} doc
66 | *
67 | * @returns {Boolean} true if save was successful, false otherwise.
68 | */
69 | saveDocument : function(doc) {
70 | try {
71 | localStorage.setItem(prefix + doc.id, doc.serialize());
72 | return true;
73 | } catch (error) {
74 | // QUOTA_EXCEEDED
75 | console.error("Error while saving document to local storage",
76 | error);
77 | return false;
78 | }
79 | },
80 |
81 | /**
82 | * Loads a document from the local storage.
83 | *
84 | * @param {String} docId
85 | *
86 | * @returns {mindmaps.Document} the document or null if not found.
87 | */
88 | loadDocument : function(docId) {
89 | return getDocumentByKey(prefix + docId);
90 | },
91 |
92 | /**
93 | * Finds all documents in the local storage object.
94 | *
95 | * @returns {Array} an Array of documents
96 | */
97 | getDocuments : function() {
98 | var documents = [];
99 | // search localstorage for saved documents
100 | for ( var i = 0, max = localStorage.length; i < max; i++) {
101 | var key = localStorage.key(i);
102 | // value is a document if key confirms to prefix
103 | if (key.indexOf(prefix) == 0) {
104 | var doc = getDocumentByKey(key);
105 | if (doc) {
106 | documents.push(doc);
107 | }
108 | }
109 | }
110 | return documents;
111 | },
112 |
113 | /**
114 | * Gets all document ids found in the local storage object.
115 | *
116 | * @returns {Array} an Array of document ids
117 | */
118 | getDocumentIds : function() {
119 | var ids = [];
120 | // search localstorage for saved documents
121 | for ( var i = 0, max = localStorage.length; i < max; i++) {
122 | var key = localStorage.key(i);
123 | // value is a document if key confirms to prefix
124 | if (key.indexOf(prefix) == 0) {
125 | ids.push(key.substring(prefix.length));
126 | }
127 | }
128 | return ids;
129 | },
130 |
131 | /**
132 | * Deletes a document from the local storage.
133 | *
134 | * @param {mindmaps.Document} doc
135 | */
136 | deleteDocument : function(doc) {
137 | localStorage.removeItem(prefix + doc.id);
138 | },
139 |
140 | /**
141 | * Deletes all documents from the local storage.
142 | */
143 | deleteAllDocuments : function() {
144 | this.getDocuments().forEach(this.deleteDocument);
145 | }
146 | };
147 | })();
148 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/UndoController.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates a new UndoController. The undo controller manages an instance of
3 | * UndoManager and delegates all undo and redo commands to the undo manager.
4 | *
5 | * @constructor
6 | * @param {mindmaps.EventBus} eventBus
7 | * @param {mindmaps.CommandRegistry} commandRegistry
8 | */
9 | mindmaps.UndoController = function(eventBus, commandRegistry) {
10 |
11 | /**
12 | * Initialise.
13 | *
14 | * @private
15 | */
16 | this.init = function() {
17 | this.undoManager = new UndoManager(128);
18 | this.undoManager.stateChanged = this.undoStateChanged.bind(this);
19 |
20 | this.undoCommand = commandRegistry.get(mindmaps.UndoCommand);
21 | this.undoCommand.setHandler(this.doUndo.bind(this));
22 |
23 | this.redoCommand = commandRegistry.get(mindmaps.RedoCommand);
24 | this.redoCommand.setHandler(this.doRedo.bind(this));
25 |
26 | eventBus.subscribe(mindmaps.Event.DOCUMENT_OPENED, this.documentOpened
27 | .bind(this));
28 |
29 | eventBus.subscribe(mindmaps.Event.DOCUMENT_CLOSED, this.documentClosed
30 | .bind(this));
31 | };
32 |
33 | /**
34 | * Handler for state changed event from undo manager.
35 | */
36 | this.undoStateChanged = function() {
37 | this.undoCommand.setEnabled(this.undoManager.canUndo());
38 | this.redoCommand.setEnabled(this.undoManager.canRedo());
39 | };
40 |
41 | /**
42 | * @see mindmaps.UndoManager#addUndo
43 | */
44 | this.addUndo = function(undoFunc, redoFunc) {
45 | this.undoManager.addUndo(undoFunc, redoFunc);
46 | };
47 |
48 | /**
49 | * Handler for undo command.
50 | */
51 | this.doUndo = function() {
52 | this.undoManager.undo();
53 | };
54 |
55 | /**
56 | * Handler for redo command.
57 | */
58 | this.doRedo = function() {
59 | this.undoManager.redo();
60 | };
61 |
62 | /**
63 | * Handler for document opened event.
64 | */
65 | this.documentOpened = function() {
66 | this.undoManager.reset();
67 | this.undoStateChanged();
68 | };
69 |
70 | /**
71 | * Handler for document closed event.
72 | */
73 | this.documentClosed = function() {
74 | this.undoManager.reset();
75 | this.undoStateChanged();
76 | };
77 |
78 | this.init();
79 | };
80 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/UndoManager.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Creates a new UndoManager
3 | *
4 | * @constructor
5 | * @param {Integer} [maxStackSize=64]
6 | */
7 | function UndoManager(maxStackSize) {
8 | this.maxStackSize = maxStackSize || 64;
9 |
10 | var State = {
11 | UNDO : "undo",
12 | REDO : "redo"
13 | };
14 |
15 | var self = this;
16 | var undoStack = new UndoManager.CircularStack(this.maxStackSize);
17 | var redoStack = new UndoManager.CircularStack(this.maxStackSize);
18 | var undoContext = false;
19 | var currentAction = null;
20 | var currentState = null;
21 |
22 | var onStateChange = function() {
23 | if (self.stateChanged) {
24 | self.stateChanged();
25 | }
26 | };
27 |
28 | var callAction = function(action) {
29 | currentAction = action;
30 | undoContext = true;
31 | switch (currentState) {
32 | case State.UNDO:
33 | action.undo();
34 | break;
35 | case State.REDO:
36 | action.redo();
37 | break;
38 | }
39 | undoContext = false;
40 | };
41 |
42 | /**
43 | * Register an undo operation. A call to .undo() will cause the undo
44 | * function to be executed. If you omit the second argument and the undo
45 | * function will cause the registration of another undo operation, then this
46 | * operation will be used as the redo function.
47 | *
48 | * If you provide both arguments, a call to addUndo() during an undo() or
49 | * redo() will have no effect.
50 | *
51 | *
52 | * @param {Function} undoFunc The function that should undo the changes.
53 | * @param {Function} [redoFunc] The function that should redo the undone
54 | * changes.
55 | */
56 | this.addUndo = function(undoFunc, redoFunc) {
57 | if (undoContext) {
58 | /**
59 | * If we are currently undoing an action and don't have a redo
60 | * function yet, store the undo function to the undo function, which
61 | * is in turn the redo function.
62 | */
63 | if (currentAction.redo == null && currentState == State.UNDO) {
64 | currentAction.redo = undoFunc;
65 | }
66 | } else {
67 | /**
68 | * We are not undoing right now. Store the functions as an action.
69 | */
70 | var action = {
71 | undo : undoFunc,
72 | redo : redoFunc
73 | };
74 | undoStack.push(action);
75 | // clear redo stack
76 | redoStack.clear();
77 |
78 | onStateChange();
79 | }
80 | };
81 |
82 | /**
83 | * Undoes the last action.
84 | */
85 | this.undo = function() {
86 | if (this.canUndo()) {
87 | currentState = State.UNDO;
88 | var action = undoStack.pop();
89 | callAction(action);
90 |
91 | if (action.redo) {
92 | redoStack.push(action);
93 | }
94 |
95 | onStateChange();
96 | }
97 | };
98 |
99 | /**
100 | * Redoes the last action.
101 | */
102 | this.redo = function() {
103 | if (this.canRedo()) {
104 | currentState = State.REDO;
105 | var action = redoStack.pop();
106 | callAction(action);
107 |
108 | if (action.undo) {
109 | undoStack.push(action);
110 | }
111 |
112 | onStateChange();
113 | }
114 | };
115 |
116 | /**
117 | *
118 | * @returns {Boolean} true if undo is possible, false otherwise.
119 | */
120 | this.canUndo = function() {
121 | return !undoStack.isEmpty();
122 | };
123 |
124 | /**
125 | *
126 | * @returns {Boolean} true if redo is possible, false otherwise.
127 | */
128 | this.canRedo = function() {
129 | return !redoStack.isEmpty();
130 | };
131 |
132 | /**
133 | * Resets this instance of the undo manager.
134 | */
135 | this.reset = function() {
136 | undoStack.clear();
137 | redoStack.clear();
138 | undoContext = false;
139 | currentAction = null;
140 | currentState = null;
141 |
142 | onStateChange();
143 | };
144 |
145 | /**
146 | * Event that is fired when undo or redo state changes.
147 | *
148 | * @event
149 | */
150 | this.stateChanged = function() {
151 | };
152 | }
153 |
154 | /**
155 | * Creates a new CircularStack. This is a stack implementation backed by a
156 | * circular buffer where the oldest entries automatically are overwritten when
157 | * new items are pushed onto the stack and the maximum size has been reached.
158 | *
159 | * @constructor
160 | * @param {Integer} [maxSize=32]
161 | */
162 | UndoManager.CircularStack = function(maxSize) {
163 | this.maxSize = maxSize || 32;
164 | this.buffer = [];
165 | this.nextPointer = 0;
166 | };
167 |
168 | /**
169 | * Pushes a new item onto the stack.
170 | *
171 | * @param {Any} item
172 | */
173 | UndoManager.CircularStack.prototype.push = function(item) {
174 | this.buffer[this.nextPointer] = item;
175 | this.nextPointer = (this.nextPointer + 1) % this.maxSize;
176 | };
177 |
178 | /**
179 | * Checks whether the stack is empty.
180 | *
181 | * @returns {Boolean} true if empty, false otherwise.
182 | */
183 | UndoManager.CircularStack.prototype.isEmpty = function() {
184 | if (this.buffer.length === 0) {
185 | return true;
186 | }
187 |
188 | var prevPointer = this.getPreviousPointer();
189 | if (prevPointer === null) {
190 | return true;
191 | } else {
192 | return this.buffer[prevPointer] === null;
193 | }
194 | };
195 |
196 | /**
197 | * Gets the position of the previously inserted item in the buffer.
198 | *
199 | * @private
200 | * @returns {Integer} the previous pointer position or null if no previous
201 | * exists.
202 | */
203 | UndoManager.CircularStack.prototype.getPreviousPointer = function() {
204 | if (this.nextPointer > 0) {
205 | return this.nextPointer - 1;
206 | } else {
207 | if (this.buffer.length < this.maxSize) {
208 | return null;
209 | } else {
210 | return this.maxSize - 1;
211 | }
212 | }
213 | };
214 |
215 | /**
216 | * Clears the stack.
217 | */
218 | UndoManager.CircularStack.prototype.clear = function() {
219 | this.buffer.length = 0;
220 | this.nextPointer = 0;
221 | };
222 |
223 | /**
224 | * Returns and removes the top most item of the stack.
225 | *
226 | * @returns {Any} the last inserted item or null if stack is empty.
227 | */
228 | UndoManager.CircularStack.prototype.pop = function() {
229 | if (this.isEmpty()) {
230 | return null;
231 | }
232 |
233 | var previousPointer = this.getPreviousPointer();
234 | var item = this.buffer[previousPointer];
235 | this.buffer[previousPointer] = null;
236 | this.nextPointer = previousPointer;
237 |
238 | return item;
239 | };
240 |
241 | /**
242 | * Returns but not removes the top most item of the stack.
243 | *
244 | * @returns {Any} the last inserted item or null if stack is empty.
245 | */
246 | UndoManager.CircularStack.prototype.peek = function() {
247 | if (this.isEmpty()) {
248 | return null;
249 | }
250 | return this.buffer[this.getPreviousPointer()];
251 | };
252 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/Util.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @namespace
3 | */
4 | mindmaps.Util = mindmaps.Util || {};
5 |
6 | /**
7 | * Creates a UUID in compliance with RFC4122.
8 | *
9 | * @static
10 | * @returns {String} a unique id
11 | */
12 | mindmaps.Util.createUUID = function() {
13 | // http://www.ietf.org/rfc/rfc4122.txt
14 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
15 | var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
16 | return v.toString(16);
17 | });
18 | };
19 |
20 | /**
21 | * Returns an ID used by model objects.
22 | *
23 | * @returns {String} id
24 | */
25 | mindmaps.Util.getId = function() {
26 | return mindmaps.Util.createUUID();
27 | };
28 |
29 | /**
30 | * Creates a random color.
31 | *
32 | * @returns {String} color in hex format
33 | */
34 | mindmaps.Util.randomColor = function() {
35 | // http://stackoverflow.com/questions/1484506/random-color-generator-in-javascript/5365036#5365036
36 | // return "#"+((1<<24)*Math.random()|0).toString(16);
37 |
38 | // http://paulirish.com/2009/random-hex-color-code-snippets/#comment-34808
39 | // return '#'+~~(Math.random()*(1<<24)).toString(16);
40 |
41 | // http://paulirish.com/2009/random-hex-color-code-snippets/#comment-34878
42 | return (function(h) {
43 | return '#000000'.substr(0, 7 - h.length) + h;
44 | })((~~(Math.random() * (1 << 24))).toString(16));
45 | };
46 |
47 |
48 | mindmaps.Util.getUrlParams = function() {
49 | // http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript/2880929#2880929
50 | var urlParams = {};
51 | var e,
52 | a = /\+/g, // Regex for replacing addition symbol with a space
53 | r = /([^&=]+)=?([^&]*)/g,
54 | d = function (s) { return decodeURIComponent(s.replace(a, " ")); },
55 | q = window.location.search.substring(1);
56 |
57 | while (e = r.exec(q))
58 | urlParams[d(e[1])] = d(e[2]);
59 |
60 | return urlParams;
61 | };
62 |
63 | function timeit(func, caption) {
64 | var start = new Date().getTime();
65 | func();
66 | var stop = new Date().getTime();
67 | var diff = stop - start;
68 | console.log(caption || "", diff, "ms");
69 | }
70 |
71 | mindmaps.Util.distance = function(offsetX, offsetY) {
72 | return Math.sqrt(offsetX * offsetX + offsetY * offsetY);
73 | };
74 |
75 |
76 | /**
77 | * test Default documents
78 | */
79 |
80 | function getBinaryMapWithDepth(depth) {
81 | var mm = new mindmaps.MindMap();
82 | var root = mm.root;
83 |
84 | function createTwoChildren(node, depth) {
85 | if (depth === 0) {
86 | return;
87 | }
88 |
89 | var left = mm.createNode();
90 | left.text.caption = "Node " + left.id;
91 | node.addChild(left);
92 | createTwoChildren(left, depth - 1);
93 |
94 | var right = mm.createNode();
95 | right.text.caption = "Node " + right.id;
96 | node.addChild(right);
97 | createTwoChildren(right, depth - 1);
98 | }
99 |
100 | // depth 10: about 400kb, 800kb in chrome
101 | // depth 12: about 1600kb
102 | // depth 16: 25mb
103 | var depth = depth || 10;
104 | createTwoChildren(root, depth);
105 |
106 | // generate positions for all nodes.
107 | // tree grows balanced from left to right
108 | root.offset = new mindmaps.Point(400, 400);
109 | // var offset = Math.pow(2, depth-1) * 10;
110 | var offset = 80;
111 | var c = root.children.values();
112 | setOffset(c[0], 0, -offset);
113 | setOffset(c[1], 0, offset);
114 | function setOffset(node, depth, offsetY) {
115 | node.offset = new mindmaps.Point((depth + 1) * 50, offsetY);
116 |
117 | if (node.isLeaf()) {
118 | return;
119 | }
120 |
121 | var c = node.children.values();
122 | var left = c[0];
123 | setOffset(left, depth + 1, offsetY - offsetY / 2);
124 |
125 | var right = c[1];
126 | setOffset(right, depth + 1, offsetY + offsetY / 2);
127 | }
128 |
129 | // color nodes
130 | c[0].branchColor = mindmaps.Util.randomColor();
131 | c[0].forEachDescendant(function(node) {
132 | node.branchColor = mindmaps.Util.randomColor();
133 | });
134 | c[1].branchColor = mindmaps.Util.randomColor();
135 | c[1].forEachDescendant(function(node) {
136 | node.branchColor = mindmaps.Util.randomColor();
137 | });
138 |
139 | return mm;
140 | }
141 |
142 | /**
143 | *
18 | * Adds the ability to manage elements scroll by dragging
19 | * one or more of its descendant elements. Options parameter
20 | * allow to specifically select which inner elements will
21 | * respond to the drag events.
22 | *
23 | * options properties:
24 | * ------------------------------------------------------------------------
25 | * dragSelector | jquery selector to apply to each wrapped element
26 | * | to find which will be the dragging elements.
27 | * | Defaults to '>:first' which is the first child of
28 | * | scrollable element
29 | * ------------------------------------------------------------------------
30 | * acceptPropagatedEvent| Will the dragging element accept propagated
31 | * | events? default is yes, a propagated mouse event
32 | * | on a inner element will be accepted and processed.
33 | * | If set to false, only events originated on the
34 | * | draggable elements will be processed.
35 | * ------------------------------------------------------------------------
36 | * preventDefault | Prevents the event to propagate further effectivey
37 | * | dissabling other default actions. Defaults to true
38 | * ------------------------------------------------------------------------
39 | * delegateMode | Attach the dragSelector using $.delegate() instead of $.bind()
40 | *
41 | * usage examples:
42 | * To add the scroll by drag to the element id=viewport when dragging its
43 | * first child accepting any propagated events
44 | * $('#viewport').dragscrollable();
45 | * To add the scroll by drag ability to any element div of class viewport
46 | * when dragging its first descendant of class dragMe responding only to
47 | * evcents originated on the '.dragMe' elements.
48 | * $('div.viewport').dragscrollable({dragSelector:'.dragMe:first',
49 | * acceptPropagatedEvent: false});
50 | * Notice that some 'viewports' could be nested within others but events
51 | * would not interfere as acceptPropagatedEvent is set to false.
52 | *
53 | */
54 | $.fn.dragscrollable = function(options) {
55 |
56 | var settings = $.extend({
57 | dragSelector : '>:first',
58 | acceptPropagatedEvent : true,
59 | preventDefault : true,
60 | delegateMode : false
61 | }, options || {});
62 |
63 | var dragscroll = {
64 | mouseDownHandler : function(event) {
65 | // mousedown, left click, check propagation
66 | // if (event.which != 1
67 | // || (!event.data.acceptPropagatedEvent && event.target !=
68 | // this)) {
69 | // return false;
70 | // }
71 |
72 | // fix:
73 | // http://plugins.jquery.com/content/problems-input-boxes-inside-elements-draggable-area
74 | if (event.which != 1) {
75 | return false;
76 | } else if (!event.data.acceptPropagatedEvent) {
77 | if ((event.target.localName == "input")
78 | || (event.target.localName == "textarea")) {
79 | return true;
80 | } else if (event.target != this) {
81 | return false;
82 | }
83 | }
84 |
85 | // Initial coordinates will be the last when dragging
86 | event.data.lastCoord = {
87 | left : event.clientX,
88 | top : event.clientY
89 | };
90 |
91 | $.event.add(document, "mouseup", dragscroll.mouseUpHandler,
92 | event.data);
93 | $.event.add(document, "mousemove", dragscroll.mouseMoveHandler,
94 | event.data);
95 | if (event.data.preventDefault) {
96 | event.preventDefault();
97 | return false;
98 | }
99 | },
100 | mouseMoveHandler : function(event) { // User is dragging
101 | // How much did the mouse move?
102 | var delta = {
103 | left : (event.clientX - event.data.lastCoord.left),
104 | top : (event.clientY - event.data.lastCoord.top)
105 | };
106 |
107 | // Set the scroll position relative to what ever the scroll is
108 | // now
109 | event.data.scrollable.scrollLeft(event.data.scrollable
110 | .scrollLeft()
111 | - delta.left);
112 | event.data.scrollable.scrollTop(event.data.scrollable
113 | .scrollTop()
114 | - delta.top);
115 |
116 | // Save where the cursor is
117 | event.data.lastCoord = {
118 | left : event.clientX,
119 | top : event.clientY
120 | };
121 | if (event.data.preventDefault) {
122 | event.preventDefault();
123 | return false;
124 | }
125 |
126 | },
127 | mouseUpHandler : function(event) { // Stop scrolling
128 | $.event.remove(document, "mousemove",
129 | dragscroll.mouseMoveHandler);
130 | $.event.remove(document, "mouseup", dragscroll.mouseUpHandler);
131 | if (event.data.preventDefault) {
132 | event.preventDefault();
133 | return false;
134 | }
135 | }
136 | };
137 |
138 | // set up the initial events
139 | this.each(function() {
140 | // closure object data for each scrollable element
141 | var data = {
142 | scrollable : $(this),
143 | acceptPropagatedEvent : settings.acceptPropagatedEvent,
144 | preventDefault : settings.preventDefault
145 | };
146 |
147 | // Set mouse initiating event on the desired descendant
148 | if (settings.delegateMode) {
149 | $(this).delegate(settings.dragSelector, 'mousedown', data,
150 | dragscroll.mouseDownHandler);
151 | } else {
152 | $(this).find(settings.dragSelector).bind('mousedown', data,
153 | dragscroll.mouseDownHandler);
154 | }
155 |
156 | });
157 | }; // end plugin dragscrollable
158 |
159 | })(jQuery); // confine scope
160 |
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/libs/events.js:
--------------------------------------------------------------------------------
1 | /*!
2 | // Copyright Joyent, Inc. and other Node contributors.
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a
5 | // copy of this software and associated documentation files (the
6 | // "Software"), to deal in the Software without restriction, including
7 | // without limitation the rights to use, copy, modify, merge, publish,
8 | // distribute, sublicense, and/or sell copies of the Software, and to permit
9 | // persons to whom the Software is furnished to do so, subject to the
10 | // following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included
13 | // in all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
18 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 | // USE OR OTHER DEALINGS IN THE SOFTWARE.
22 | */
23 |
24 | /*
25 | * modified 10/06/2011 (david):
26 | * - make compatabile for browser
27 | * - added augment function
28 | * - added aliases publish, subscribe, unsubscribe
29 | */
30 | var EventEmitter = function() {
31 | };
32 |
33 | // By default EventEmitters will print a warning if more than
34 | // 10 listeners are added to it. This is a useful default which
35 | // helps finding memory leaks.
36 | //
37 | EventEmitter.prototype.setMaxListeners = function(n) {
38 | if (!this._events)
39 | this._events = {};
40 | this._events.maxListeners = n;
41 | };
42 |
43 | EventEmitter.prototype.emit = function(type) {
44 | // If there is no 'error' event listener then throw.
45 | if (type === 'error') {
46 | if (!this._events
47 | || !this._events.error
48 | || (Array.isArray(this._events.error) && !this._events.error.length)) {
49 | if (arguments[1] instanceof Error) {
50 | throw arguments[1]; // Unhandled 'error' event
51 | } else {
52 | throw new Error("Uncaught, unspecified 'error' event.");
53 | }
54 | return false;
55 | }
56 | }
57 |
58 | if (!this._events)
59 | return false;
60 | var handler = this._events[type];
61 | if (!handler)
62 | return false;
63 |
64 | if (typeof handler == 'function') {
65 | switch (arguments.length) {
66 | // fast cases
67 | case 1:
68 | handler.call(this);
69 | break;
70 | case 2:
71 | handler.call(this, arguments[1]);
72 | break;
73 | case 3:
74 | handler.call(this, arguments[1], arguments[2]);
75 | break;
76 | // slower
77 | default:
78 | var args = Array.prototype.slice.call(arguments, 1);
79 | handler.apply(this, args);
80 | }
81 | return true;
82 |
83 | } else if (Array.isArray(handler)) {
84 | var args = Array.prototype.slice.call(arguments, 1);
85 |
86 | var listeners = handler.slice();
87 | for ( var i = 0, l = listeners.length; i < l; i++) {
88 | listeners[i].apply(this, args);
89 | }
90 | return true;
91 |
92 | } else {
93 | return false;
94 | }
95 | };
96 |
97 | EventEmitter.prototype.publish = EventEmitter.prototype.emit;
98 |
99 | // EventEmitter is defined in src/node_events.cc
100 | // EventEmitter.prototype.emit() is also defined there.
101 | EventEmitter.prototype.addListener = function(type, listener) {
102 | if ('function' !== typeof listener) {
103 | throw new Error('addListener only takes instances of Function');
104 | }
105 |
106 | if (!this._events)
107 | this._events = {};
108 |
109 | // To avoid recursion in the case that type == "newListeners"! Before
110 | // adding it to the listeners, first emit "newListeners".
111 | this.emit('newListener', type, listener);
112 |
113 | if (!this._events[type]) {
114 | // Optimize the case of one listener. Don't need the extra array object.
115 | this._events[type] = listener;
116 | } else if (Array.isArray(this._events[type])) {
117 |
118 | // If we've already got an array, just append.
119 | this._events[type].push(listener);
120 |
121 | // Check for listener leak
122 | if (!this._events[type].warned) {
123 | var m;
124 | if (this._events.maxListeners !== undefined) {
125 | m = this._events.maxListeners;
126 | } else {
127 | m = 10;
128 | }
129 |
130 | if (m && m > 0 && this._events[type].length > m) {
131 | this._events[type].warned = true;
132 | console.error('(node) warning: possible EventEmitter memory '
133 | + 'leak detected. %d listeners added. '
134 | + 'Use emitter.setMaxListeners() to increase limit.',
135 | this._events[type].length);
136 | console.trace();
137 | }
138 | }
139 | } else {
140 | // Adding the second element, need to change to array.
141 | this._events[type] = [ this._events[type], listener ];
142 | }
143 |
144 | return this;
145 | };
146 |
147 | EventEmitter.prototype.on = EventEmitter.prototype.subscribe = EventEmitter.prototype.addListener;
148 |
149 | EventEmitter.prototype.once = function(type, listener) {
150 | if ('function' !== typeof listener) {
151 | throw new Error('.once only takes instances of Function');
152 | }
153 |
154 | var self = this;
155 | function g() {
156 | self.removeListener(type, g);
157 | listener.apply(this, arguments);
158 | }
159 | ;
160 |
161 | g.listener = listener;
162 | self.on(type, g);
163 |
164 | return this;
165 | };
166 |
167 | EventEmitter.prototype.removeListener = function(type, listener) {
168 | if ('function' !== typeof listener) {
169 | throw new Error('removeListener only takes instances of Function');
170 | }
171 |
172 | // does not use listeners(), so no side effect of creating _events[type]
173 | if (!this._events || !this._events[type])
174 | return this;
175 |
176 | var list = this._events[type];
177 |
178 | if (Array.isArray(list)) {
179 | var position = -1;
180 | for ( var i = 0, length = list.length; i < length; i++) {
181 | if (list[i] === listener
182 | || (list[i].listener && list[i].listener === listener)) {
183 | position = i;
184 | break;
185 | }
186 | }
187 |
188 | if (position < 0)
189 | return this;
190 | list.splice(position, 1);
191 | if (list.length == 0)
192 | delete this._events[type];
193 | } else if (list === listener
194 | || (list.listener && list.listener === listener)) {
195 | delete this._events[type];
196 | }
197 |
198 | return this;
199 | };
200 |
201 | EventEmitter.prototype.unsubscribe = EventEmitter.prototype.removeListener;
202 |
203 | EventEmitter.prototype.removeAllListeners = function(type) {
204 | if (arguments.length === 0) {
205 | this._events = {};
206 | return this;
207 | }
208 |
209 | // does not use listeners(), so no side effect of creating _events[type]
210 | if (type && this._events && this._events[type])
211 | this._events[type] = null;
212 | return this;
213 | };
214 |
215 | EventEmitter.prototype.listeners = function(type) {
216 | if (!this._events)
217 | this._events = {};
218 | if (!this._events[type])
219 | this._events[type] = [];
220 | if (!Array.isArray(this._events[type])) {
221 | this._events[type] = [ this._events[type] ];
222 | }
223 | return this._events[type];
224 | };
225 |
226 | /**
227 | * Augment an object with the EventEmitter mixin
228 | *
229 | * @param {object} obj The object to be augmented
230 | */
231 | EventEmitter.mixin = function(obj) {
232 | for ( var method in EventEmitter.prototype) {
233 | if (!obj.prototype[method]) {
234 | obj.prototype[method] = EventEmitter.prototype[method];
235 | }
236 | }
237 | };
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/libs/jquery.hotkeys.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * jQuery Hotkeys Plugin
3 | * Copyright 2010, John Resig
4 | * Dual licensed under the MIT or GPL Version 2 licenses.
5 | *
6 | * Based upon the plugin by Tzury Bar Yochay:
7 | * http://github.com/tzuryby/hotkeys
8 | *
9 | * Original idea by:
10 | * Binny V A, http://www.openjs.com/scripts/events/keyboard_shortcuts/
11 | */
12 |
13 | (function(jQuery){
14 |
15 | jQuery.hotkeys = {
16 | version: "0.8",
17 |
18 | specialKeys: {
19 | 8: "backspace", 9: "tab", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause",
20 | 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home",
21 | 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del",
22 | 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7",
23 | 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/",
24 | 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8",
25 | 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 191: "/", 224: "meta"
26 | },
27 |
28 | shiftNums: {
29 | "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&",
30 | "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<",
31 | ".": ">", "/": "?", "\\": "|"
32 | }
33 | };
34 |
35 | function keyHandler( handleObj ) {
36 | // Only care when a possible input has been specified
37 | if ( typeof handleObj.data !== "string" ) {
38 | return;
39 | }
40 |
41 | var origHandler = handleObj.handler,
42 | keys = handleObj.data.toLowerCase().split(" ");
43 |
44 | handleObj.handler = function( event ) {
45 | // Don't fire in text-accepting inputs that we didn't directly bind to
46 | if ( this !== event.target && (/textarea|select/i.test( event.target.nodeName ) ||
47 | event.target.type === "text") ) {
48 | return;
49 | }
50 |
51 | // Keypress represents characters, not special keys
52 | var special = event.type !== "keypress" && jQuery.hotkeys.specialKeys[ event.which ],
53 | character = String.fromCharCode( event.which ).toLowerCase(),
54 | key, modif = "", possible = {};
55 |
56 | // check combinations (alt|ctrl|shift+anything)
57 | if ( event.altKey && special !== "alt" ) {
58 | modif += "alt+";
59 | }
60 |
61 | if ( event.ctrlKey && special !== "ctrl" ) {
62 | modif += "ctrl+";
63 | }
64 |
65 | // TODO: Need to make sure this works consistently across platforms
66 | if ( event.metaKey && !event.ctrlKey && special !== "meta" ) {
67 | modif += "meta+";
68 | }
69 |
70 | if ( event.shiftKey && special !== "shift" ) {
71 | modif += "shift+";
72 | }
73 |
74 | if ( special ) {
75 | possible[ modif + special ] = true;
76 |
77 | } else {
78 | possible[ modif + character ] = true;
79 | possible[ modif + jQuery.hotkeys.shiftNums[ character ] ] = true;
80 |
81 | // "$" can be triggered as "Shift+4" or "Shift+$" or just "$"
82 | if ( modif === "shift+" ) {
83 | possible[ jQuery.hotkeys.shiftNums[ character ] ] = true;
84 | }
85 | }
86 |
87 | for ( var i = 0, l = keys.length; i < l; i++ ) {
88 | if ( possible[ keys[i] ] ) {
89 | return origHandler.apply( this, arguments );
90 | }
91 | }
92 | };
93 | }
94 |
95 | jQuery.each([ "keydown", "keyup", "keypress" ], function() {
96 | jQuery.event.special[ this ] = { add: keyHandler };
97 | });
98 |
99 | })( jQuery );
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/js/libs/jquery.mousewheel.js:
--------------------------------------------------------------------------------
1 | /*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
2 | * Licensed under the MIT License (LICENSE.txt).
3 | *
4 | * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
5 | * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
6 | * Thanks to: Seamus Leahy for adding deltaX and deltaY
7 | *
8 | * Version: 3.0.4
9 | *
10 | * Requires: 1.2.2+
11 | */
12 |
13 | (function($) {
14 |
15 | var types = ['DOMMouseScroll', 'mousewheel'];
16 |
17 | $.event.special.mousewheel = {
18 | setup: function() {
19 | if ( this.addEventListener ) {
20 | for ( var i=types.length; i; ) {
21 | this.addEventListener( types[--i], handler, false );
22 | }
23 | } else {
24 | this.onmousewheel = handler;
25 | }
26 | },
27 |
28 | teardown: function() {
29 | if ( this.removeEventListener ) {
30 | for ( var i=types.length; i; ) {
31 | this.removeEventListener( types[--i], handler, false );
32 | }
33 | } else {
34 | this.onmousewheel = null;
35 | }
36 | }
37 | };
38 |
39 | $.fn.extend({
40 | mousewheel: function(fn) {
41 | return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
42 | },
43 |
44 | unmousewheel: function(fn) {
45 | return this.unbind("mousewheel", fn);
46 | }
47 | });
48 |
49 |
50 | function handler(event) {
51 | var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
52 | event = $.event.fix(orgEvent);
53 | event.type = "mousewheel";
54 |
55 | // Old school scrollwheel delta
56 | if ( event.wheelDelta ) { delta = event.wheelDelta/120; }
57 | if ( event.detail ) { delta = -event.detail/3; }
58 |
59 | // New school multidimensional scroll (touchpads) deltas
60 | deltaY = delta;
61 |
62 | // Gecko
63 | if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
64 | deltaY = 0;
65 | deltaX = -1*delta;
66 | }
67 |
68 | // Webkit
69 | if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
70 | if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
71 |
72 | // Add event and delta to the front of the arguments
73 | args.unshift(event, delta, deltaX, deltaY);
74 |
75 | return $.event.handle.apply(this, args);
76 | }
77 |
78 | })(jQuery);
--------------------------------------------------------------------------------
/webapps/wisemapping/mindmaps/media/downloadify.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/framasoft/framindmap/97ae33b173beca34d17bf169e91f5b7704fca75f/webapps/wisemapping/mindmaps/media/downloadify.swf
--------------------------------------------------------------------------------