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

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

Small fix.

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