source: project/release/3/svnwiki-folksonomy/trunk/svnwiki-folksonomy.scm @ 14990

Last change on this file since 14990 was 14990, checked in by azul, 11 years ago

Fixes.

  • Property svn:keywords set to id
File size: 10.0 KB
Line 
1; $id$
2;
3; License: GPL-3
4
5(declare (export))
6(use svnwiki-extensions-support html-stream srfi-40 stream-ext format-modular)
7
8(define (show-tags-related env)
9  (let-from-environment env (db path-in path path-out program)
10    (assert (and 'show-tags-related (string? path-in)))
11    (when (file-exists? (svnwiki-make-pathname path-in path))
12      (let ((path (if (svnwiki-is-special? #f path)
13                    (special->normal path)
14                    path))
15            (tags (stream-map
16                    (cut vector-ref <> 0)
17                    (db-get-tags-page db path-in path))))
18        (unless (stream-null? tags)
19          (svnwiki-render-bottom-div
20            env
21            (html-stream
22              ((ul class "render-bottom-div render-bottom-div-tags")
23               (stream-fold-right-delay
24                 (cut tag-related-pages env <> <>)
25                 stream-null
26                 (stream-sort
27                   tags
28                   (cut string<? <...>)))))))))))
29
30(define (tag-related-pages env tag tail)
31  (let-from-environment env (db)
32    (let ((id (random 100000)))
33      (html-stream
34        ((li class "related-pages-tag")
35         ((p class "related-pages-tag")
36          ((a href (click-show-tags env tag id) class "related-pages-tag")
37           tag
38           ;"("
39           ;(stream-length (db-get-pages-tag db tag))
40           ;")"
41           ))
42         ((ul class "related-pages" id (format #f "list-pages-~A" id) style "display:none;")))
43        "\n" ; Important: allows line breaks.
44        tail))))
45
46(define (click-show-tags env tag id)
47  (let-from-environment env (path-out-real)
48    (format #f "javascript: svnwikiTagsLoader.showTags('~A', '~A', ~A);"
49            (make-link-url path-out-real "xsvnwiki-tags" #f)
50            tag
51            id)))
52
53(svnwiki-extension-define 'render-bottom-div 'folksonomy show-tags-related)
54
55(define (folksonomy-javascript env)
56#<<EOF
57var svnwikiTagsLoader = new Object();
58
59svnwikiTagsLoader.showTags = function (url, tag, id)
60{
61  var container = document.getElementById("list-pages-" + id);
62  if (container.style.display == 'none') {
63    if (!container.hasChildNodes()) {
64      container.appendChild(svnwikiJavascript.makeElement('li', document.createTextNode("Loading ...")));
65      svnwikiJavascript.loadXml(url + '/' + tag + '.xhtml', function (xmlDoc) { svnwikiTagsLoader.updateTags(url, tag, container, xmlDoc); });
66    }
67    container.style.display = 'inline';
68  } else
69    container.style.display = 'none';
70}
71
72svnwikiTagsLoader.makeLinkFile = function (link, text)
73{
74  var linkObj = svnwikiJavascript.makeLink(link, document.createTextNode(text));
75  linkObj.setAttribute('class', 'related-pages');
76  return (svnwikiJavascript.makeElement('li', linkObj));
77}
78
79svnwikiTagsLoader.iterateListOfLinks = function (xmlDocFiles, func)
80{
81  for (var i = 0; i < xmlDocFiles.childNodes.length; i ++) {
82    if (xmlDocFiles.childNodes[i].nodeType == Node.ELEMENT_NODE) {
83      var datum = xmlDocFiles.childNodes[i].childNodes[0];
84      func(datum.getAttribute('href'), datum.firstChild.nodeValue, xmlDocFiles.childNodes[i].getAttribute('class'));
85    }
86  }
87}
88
89svnwikiTagsLoader.updateTags = function (url, tag, container, xmlDoc)
90{
91  svnwikiJavascript.cleanContent(container);
92  svnwikiTagsLoader.iterateListOfLinks(xmlDoc.getElementById("files-for-tag"),
93    function (href, name) {
94      var link = svnwikiTagsLoader.makeLinkFile(url + '/' + href + '?tag=' + tag, name);
95      link.setAttribute('class', 'related-pages');
96      container.appendChild(link);
97      container.appendChild(document.createTextNode("\n"));
98    });
99}
100
101svnwikiTagsLoader.showRelated = function (tag)
102{
103  var info = new Object;
104  info.tagsFound = new Object;
105  info.tag = tag;
106  info.div = document.getElementById("xsvnwiki-tags-related-body");
107  info.filesFound = new Array;
108  info.filesError = new Array;
109  svnwikiTagsLoader.iterateListOfLinks(document.getElementById("files-for-tag"),
110    function (href, name) {
111      info.filesFound.push(href);
112    });
113  info.filesLoaded = 0;
114  svnwikiTagsLoader.relatedUpdate(info);
115}
116
117svnwikiTagsLoader.relatedUpdate = function (info) {
118  svnwikiJavascript.cleanContent(info.div);
119
120  if (info.filesFound.length == 0) {
121    info.div.appendChild(svnwikiJavascript.makeElement('p', document.createTextNode("Ooops, we don't know how to compute the tags related to an empty tag.")));
122    return;
123  }
124
125  var p = svnwikiJavascript.makeElement('p');
126  if (info.filesLoaded == info.filesFound.length) {
127    p.appendChild(document.createTextNode("The following are tags related with the tag "));
128    p.appendChild(svnwikiJavascript.makeElement('i', document.createTextNode(info.tag)));
129    p.appendChild(document.createTextNode(":"));
130  } else {
131    p.appendChild(document.createTextNode("Loading tags for file "));
132    p.appendChild(svnwikiJavascript.makeElement('i', document.createTextNode(info.filesFound[info.filesLoaded])));
133    p.appendChild(document.createTextNode(" (" + Math.round(100 * info.filesLoaded / info.filesFound.length) + "%)"));
134  }
135  info.div.appendChild(p);
136
137  var ul = svnwikiJavascript.makeElement('ul');
138  ul.setAttribute("class", "tags-list");
139  var copy = new Array;
140  for (tag in info.tagsFound)
141    copy.push(tag);
142  copy.sort(function (a, b) { return info.tagsFound[b] - info.tagsFound[a]; });
143  for (var i in copy) {
144    var tag = copy[i];
145    var linkObj = svnwikiJavascript.makeLink(tag, document.createTextNode(tag + " (" + info.tagsFound[tag] + ")"));
146    //linkObj.setAttribute("class", "tag");
147    var li = svnwikiJavascript.makeElement('li', linkObj);
148    //li.setAttribute("class", "tag");
149    ul.appendChild(li);
150    ul.appendChild(document.createTextNode("\n"));
151  }
152  info.div.appendChild(ul);
153
154  if (info.filesError.length > 0) {
155    info.div.appendChild(svnwikiJavascript.makeElement('p', document.createTextNode("Errors were detected with the following files:")));
156    var ul = svnwikiJavascript.makeElement('ul');
157    ul.setAttribute("class", "files-list");
158    for (var i = 0; i < info.filesError.length; i ++) {
159      var li = svnwikiJavascript.makeElement('li', document.createTextNode(info.filesError[i]));
160      li.setAttribute("class", "file");
161      ul.appendChild(li);
162    }
163    info.div.appendChild(ul);
164  }
165
166  if (info.filesLoaded < info.filesFound.length) {
167    var components = String.split(info.filesFound[info.filesLoaded++], "/");
168    var last = components.pop(), file = "";
169    components.push("xsvnwiki-tags-file/" + last);
170    for (var i in components)
171      file = file + (file == "" ? "" : "/") + components[i];
172    file = file + ".xhtml";
173    svnwikiJavascript.loadXml(file, function (xmlDoc) { svnwikiTagsLoader.relatedRegister(info, xmlDoc); });
174  }
175}
176
177svnwikiTagsLoader.relatedRegister = function (info, xmlDoc) {
178  var files = xmlDoc.getElementById("tags-for-file");
179  if (files)
180    svnwikiTagsLoader.iterateListOfLinks(files,
181      function (href, name) {
182        if (name != info.tag)
183          info.tagsFound[name] = typeof(info.tagsFound[name]) == "undefined" ? 1 : info.tagsFound[name] + 1;
184      } );
185  else
186    info.filesError.push(info.filesFound[info.filesLoaded - 1]);
187  svnwikiTagsLoader.relatedUpdate(info);
188}
189
190// TODO: The list of elements to hide should not be hardcoded here!
191svnwikiTagsLoader.hideAll = function () {
192  document.getElementById('tag-list-files').style.display = 'none'
193  document.getElementById('tag-list-images').style.display = 'none'
194  document.getElementById('tag-list-googlemap').style.display = 'none'
195}
196
197svnwikiTagsLoader.displayFiles = function () {
198  svnwikiTagsLoader.hideAll()
199  document.getElementById('tag-list-files').style.display = 'inline';
200}
201
202svnwikiTagsLoader.onLoad = function (data) {
203  svnwikiJavascript.queryStringInit();
204  var view = svnwikiJavascript.queryString['view'];
205  if (!data[view])
206    return;
207  data[view]();
208}
209EOF
210)
211
212(svnwiki-extension-define 'javascript 'folksonomy folksonomy-javascript)
213
214(define (html-body-top env)
215  (let-from-environment env (db path-in path return)
216    (let ((ignore (svnwiki-ignore-errors path-in path)))
217      (assert (and 'folksonomy:html-body-top (stream? ignore)))
218      (when (and (not (is-discuss? path))
219                 (file-exists? (svnwiki-make-pathname path path-in))
220                 (not (stream-find (cut eq? 'empty-tags <>) ignore))
221                 (stream-null? (db-get-tags-page db path-in path)))
222        (make-wiki-error
223          (html-stream
224            (p (svnwiki-translate env "This page has no tags.  Please contribute to the wiki by ")
225               ((a href (get-edit-url path-in path))
226                (svnwiki-translate env "editing it"))
227               (svnwiki-translate env " and adding some."))))))))
228
229(svnwiki-extension-define 'html-body-top 'folksonomy html-body-top)
230
231(define (files-actions-links env)
232  (let-from-environment env (path path-out-real)
233    (when (and (string=? (svnwiki-basename (svnwiki-dirname path)) "xsvnwiki-tags")
234               (not (string=? (svnwiki-basename path-out-real) "xsvnwiki-all")))
235      (let-from-environment env (tags-views)
236        (unless (stream-null? tags-views)
237          (svnwiki-file-action-link
238            env
239            "javascript: svnwikiTagsLoader.displayFiles();"
240            "Files")
241          (stream-for-each
242            (lambda (data)
243              (svnwiki-file-action-link
244                env
245                (format #f "javascript: ~A" (list-ref data 2))
246                (list-ref data 1)))
247            tags-views))))))
248
249(svnwiki-extension-define 'files-actions-links 'folksonomy files-actions-links)
250
251(define (onload env)
252  (let-from-environment env (path path-out-real)
253    (when (and (string=? (svnwiki-dirname path) "xsvnwiki-tags")
254               (not (string=? (svnwiki-basename path-out-real) "xsvnwiki-all")))
255      (let-from-environment env (return tags-views)
256        (return
257          (html-stream
258            (format #f "svnwikiTagsLoader.onLoad({ ~:{~A: function () { ~A; },~}});"
259                    (stream->list
260                      (stream-map
261                        (lambda (data)
262                          (list (car data) (caddr data)))
263                        tags-views)))))))))
264
265(svnwiki-extension-define 'onload 'folksonomy onload)
Note: See TracBrowser for help on using the repository browser.