/[suikacvs]/webroot/swe/scripts/sw-sami.js
Suika

Contents of /webroot/swe/scripts/sw-sami.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (hide annotations) (download) (as text)
Mon Sep 21 10:49:24 2009 UTC (15 years, 2 months ago) by wakaba
Branch: MAIN
Changes since 1.4: +62 -14 lines
File MIME type: application/javascript
++ swe/lib/suikawiki/ChangeLog	21 Sep 2009 10:48:30 -0000
	* main.pl: Allow non-POST pings.

2009-09-21  Wakaba  <wakaba@suika.fam.cx>

++ swe/scripts/ChangeLog	21 Sep 2009 10:48:59 -0000
	* sw-sami.js: Added related/unrelated pings to neighbor links.

2009-09-21  Wakaba  <wakaba@suika.fam.cx>

1 wakaba 1.1 if (!self.SW) self.SW = {};
2    
3     SW.CurrentDocument = new SAMI.Class (function () {
4     var self = this;
5     var path = location.pathname;
6     path = path.replace (/;([^;\/]*)$/, function (_, v) {
7     self.param = decodeURIComponent (v.replace (/\+/g, '%2F'));
8     return '';
9     });
10     path = path.replace (/\$([^$\/]*)$/, function (_, v) {
11     self.dollar = decodeURIComponent (v.replace (/\+/g, '%2F'));
12     return '';
13     });
14     path = path.replace (/\/([^\/]*)$/, function (_, v) {
15     self.name = decodeURIComponent (v.replace (/\+/g, '%2F'));
16     return '';
17     });
18     path = path.replace (/\/([^\/]*)$/, function (_, v) {
19     self.area = decodeURIComponent (v.replace (/\+/g, '%2F'));
20     return '';
21     });
22     this.wikiPath = path;
23     }, {
24     constructURL: function (area, name, dollar, param) {
25     var p = this.wikiPath;
26    
27     area = area || this.area;
28     p += '/' + encodeURIComponent (area).replace (/%2F/g, '+');
29    
30     name = name || this.name;
31     p += '/' + encodeURIComponent (name).replace (/%2F/g, '+');
32    
33     dollar = dollar === undefined ? this.dollar : dollar;
34     if (dollar != null) p += '$' + encodeURIComponent (dollar).replace (/%2F/g, '+');
35    
36     param = param === undefined ? this.param : param;
37     if (param != null) p += ';' + encodeURIComponent (param).replace (/%2F/g, '+');
38    
39     return p;
40     } // constructURL
41     }); // CurrentDocument
42    
43 wakaba 1.4 SW.CurrentDocument.getDocumentId = function () {
44     var el = document.body;
45     if (!el) return null;
46    
47     var value = el.getAttribute ('data-doc-id');
48     if (!value) return null;
49    
50     return parseInt (value);
51     }; // getDocumentId
52    
53 wakaba 1.1 SW.CurrentDocument.getInstance = function () {
54     if (!SW.CurrentDocument._instance) {
55     SW.CurrentDocument._instance = new SW.CurrentDocument;
56     }
57     return SW.CurrentDocument._instance;
58     }; // getInstance
59    
60     SW.SearchResult = new SAMI.Class (function (source) {
61     this.parse (source);
62     }, {
63     parse: function (source) {
64     this.entries = new SAMI.List (source.split (/\x0D?\x0A/)).map (function (v) {
65     if (v == '') return;
66     return new SW.SearchResult.Entry (v.split (/\t/, 3));
67     }).grep (function (v) { return v });
68     }, // parse
69    
70     toOL: function () {
71     var ol = document.createElement ('ol');
72     this.entries.forEach (function (entry) {
73     ol.appendChild (entry.toLI ());
74     });
75     return ol;
76     } // toOL
77     }); // SearchResult
78    
79     SW.SearchResult.Entry = new SAMI.Class (function (v) {
80 wakaba 1.5 this.score = v[0];
81     this.docId = v[1];
82     this.docName = v[2];
83 wakaba 1.1 }, {
84     toLI: function () {
85     var li = document.createElement ('li');
86     li.innerHTML = '<a href="">xxx</a>';
87     li.firstChild.firstChild.data = this.docName;
88     li.firstChild.href = SW.CurrentDocument.getInstance ().constructURL
89     ('n', this.docName, this.docId);
90     return li;
91     } // toLI
92 wakaba 1.4 }); // SearchResult.Entry
93    
94 wakaba 1.5 SW.Neighbors = new SAMI.Class (function (id, source) {
95     this.documentId = id;
96 wakaba 1.4 this.parse (source);
97     }, {
98     parse: function (source) {
99 wakaba 1.5 var id = this.documentId;
100 wakaba 1.4 this.entries = new SAMI.List (source.split (/\x0D?\x0A/)).map (function (v) {
101     if (v == '') return;
102 wakaba 1.5 return new SW.Neighbors.Entry (v.split (/\t/, 2), id);
103 wakaba 1.4 }).grep (function (v) { return v });
104     }, // parse
105    
106 wakaba 1.5 toUL: function () {
107     var ol = document.createElement ('ul');
108     this.entries.forEach (function (entry) {
109     ol.appendChild (entry.toLI ());
110     });
111     return ol;
112     } // toUL
113 wakaba 1.4 }); // Neighbors
114 wakaba 1.1
115 wakaba 1.5 SW.Neighbors.Entry = new SAMI.Class (function (v, id) {
116     this.docId = v[0];
117     this.docName = v[1];
118     this.sourceDocId = id;
119     }, {
120     toLI: function () {
121     var self = this;
122     var doc = SW.CurrentDocument.getInstance ();
123    
124     var li = document.createElement ('li');
125     li.innerHTML = '<a href="">xxx</a> <button type=button>X</button>';
126     var a = li.firstChild;
127     a.firstChild.data = this.docName;
128     a.href = doc.constructURL ('n', this.docName, this.docId);
129    
130     // XXX We don't use the real |ping| attribute for now since there
131     // is no reliable way to know whether the browser does or does not
132     // send ping and therefore we have to send the ping using a custom
133     // script code anyway.
134    
135     // Use |GET| method instead of |POST| method to not require Basic auth.
136     a.onclick = function () {
137     var pingURL = doc.constructURL
138     ('i', self.sourceDocId, null, 'related-' + self.docId);
139     new SAMI.XHR (pingURL).get ();
140    
141     var url = a.href;
142     setTimeout (function () {
143     location.href = url;
144     }, 500);
145    
146     return false;
147     }; // a.onclick
148    
149     var button = li.lastChild;
150     button.onclick = function () {
151     var pingURL = doc.constructURL
152     ('i', self.sourceDocId, null, 'unrelated-' + self.docId);
153     new SAMI.XHR (pingURL).get ();
154     li.parentNode.removeChild (li);
155     }; // button.onclick
156    
157     return li;
158     } // toLI
159     }); // Neighbors.Entry
160    
161 wakaba 1.2 SW.PageContents = new SAMI.Class (function () {
162     this.footer = document.getElementsByTagName ('footer')[0];
163     }, {
164     insertSection: function (sectionId, content) {
165     var sectionName = {
166 wakaba 1.4 'search-results': 'Related pages',
167     'neighbors': 'Nearby'
168 wakaba 1.2 }[sectionId] || sectionId;
169     var section = document.createElement ('section');
170     section.id = sectionId;
171     var h = document.createElement ('h2');
172     h.innerHTML = 'xxx';
173     h.firstChild.data = sectionName;
174     section.appendChild (h);
175     section.appendChild (content);
176     document.body.insertBefore (section, this.footer);
177     } // insertSection
178     }); // PageContents
179    
180     SW.PageContents.getInstance = function () {
181     if (!this._instance) {
182     this._instance = new SW.PageContents;
183     }
184     return this._instance;
185     }; // getInstance
186    
187 wakaba 1.3 var CanvasInstructions = new SAMI.Class(function (canvas) {
188     this.canvas = canvas;
189     }, {
190     clear: function () {
191     this.canvas.width = this.canvas.width;
192     }, // clear
193    
194     processText: function (text) {
195     text = text.replace (/^<!--/, '').replace (/-->$/, '');
196     this.processLines (text.split(/\x0D\x0A?|\x0A/));
197     }, // processText
198    
199     processLines: function (lines) {
200     var ctx = this.canvas.getContext ('2d');
201     for (var i = 0; i < lines.length; i++) {
202     var ev = lines[i].split (/,/);
203     if (ev[0] == 'lineTo') {
204     var x = parseFloat (ev[1]);
205     var y = parseFloat (ev[2]);
206     ctx.lineTo (x, y);
207     ctx.stroke ();
208     // ctx.closePath ();
209     // ctx.beginPath ();
210     // ctx.moveTo (x, y);
211     } else if (ev[0] == 'moveTo') {
212     var x = parseFloat (ev[1]);
213     var y = parseFloat (ev[2]);
214     ctx.moveTo (x, y);
215     } else if (ev[0] == 'strokeStyle' || ev[0] == 'lineWidth') {
216     ctx.closePath ();
217     ctx.beginPath ();
218     ctx[ev[0]] = ev[1];
219     }
220     }
221     } // processLines
222     }); // CanvasInstructions
223    
224     SW.Drawings = {};
225     SAMI.Class.addClassMethods (SW.Drawings, {
226     drawCanvases: function () {
227     var canvases = SAMI.Node.getElementsByClassName (document.body, 'swe-canvas-instructions');
228     canvases.forEach(function (canvas) {
229     var script = canvas.firstChild;
230     if (!script) return;
231     if (script.nodeName.toLowerCase () != 'script') return;
232     if (script.type != 'image/x-canvas-instructions+text') return;
233     var text = SAMI.Element.getTextContent (script);
234     new CanvasInstructions (canvas).processText (text);
235     });
236     } // drawCanvases
237     }); // SW.Drawings
238    
239 wakaba 1.1 SW.init = function () {
240     var doc = SW.CurrentDocument.getInstance ();
241     if (doc.area == 'n') {
242     var searchURL = doc.constructURL (null, null, null, 'search');
243    
244     new SAMI.XHR (searchURL, function () {
245     var sr = new SW.SearchResult (this.getText ());
246     if (sr.entries.list.length) {
247     var ol = sr.toOL ();
248 wakaba 1.2 SW.PageContents.getInstance ().insertSection ('search-results', ol);
249 wakaba 1.1 }
250     }).get ();
251 wakaba 1.4
252     if (location.href.match(/-temp/)) { // XXX
253    
254     var id = SW.CurrentDocument.getDocumentId ();
255     if (id) {
256     var neighborsURL = doc.constructURL ('i', id, null, 'neighbors');
257     new SAMI.XHR (neighborsURL, function () {
258 wakaba 1.5 var sr = new SW.Neighbors (id, this.getText ());
259 wakaba 1.4 if (sr.entries.list.length) {
260 wakaba 1.5 var ol = sr.toUL ();
261 wakaba 1.4 SW.PageContents.getInstance ().insertSection ('neighbors', ol);
262     }
263     }).get ();
264     }
265    
266     }
267 wakaba 1.3
268     SW.Drawings.drawCanvases ();
269 wakaba 1.1 }
270    
271     }; // init

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24