PageSourceSearch

https://www.obren359.com/client_code/js/components/basket-component.js?v=1531067321959

js obren359.com collected 2026-10-06 20:41:35 UTC 17,050 bytes, 415 lines download raw bytes

1Vue.component('basket', {
2    props: [
3        'basket',
4        'source',
5        'mobile',
6        'showAbstracts',
7        'getLinkText',
8        'getDigitalLibraryLink'
9    ],
10    data: function () {
11        return {
12            editNotes: true
13        }
14    },
15    mounted: function () {
16    },
17    computed: {
18        btnStyle: function () {
19            return {
20                backgroundColor: "black",
21                color: "white",
22                height: "28px",
23                fontSize: "10px",
24                border: "none",
25                padding: "4px",
26                cursor: "pointer"
27            }
28        }
29    },
30    methods: {
31        getSectionOptions: function (articleItem, currentSection) {
32            var self = this;
33            var options = [];
34
35            if (this.basket.sections.length === 0) {
36                this.basket.sections.push({
37                    name: "Default",
38                    intro: "",
39                    items: []
40                });
41            }
42
43            this.basket.sections.filter(function (s) {
44                return s !== currentSection;
45            }
45).forEach(function (section) {
46                if (!section.items) {
47                    section.item = [];
48                }
49                options.push({
50                    title: section.name,
51                    action: function () {
52                        currentSection.items.splice(currentSection.items.indexOf(articleItem), 1);
53                        section.items.push(articleItem);
54                        self.saveBasketData();
55                    }
56                });
57            });
58
59            options.push({
60                title: "<new section>",
61                action: function () {
62                    var tag = prompt("Please enter the section name:", "");
63
64                    if (tag != null) {
65                        var section = {
66                            name: tag,
67                            intro: "",
68                            items: []
69                        };
70                        self.basket.sections.push(section);
71                        section.items.push(articleItem);
72                        self.saveBasketData();
73                    }
74                }
75            });
76
77            return options;
78        },
79        sortSections: function () {
80            this.basket.sections = this.basket.sections.sort(function (a, b) {
81                return a.name.localeCompare(b.name);
82            });
83
84            this.basket.sections.forEach(function (section) {
85                section.items = section.items.sort(function (a, b) {
86                    return a.article.number - b.article.number;
87                });
88            });
89        },
90        sortSectionsDesc: function () {
91            this.basket.sections = this.basket.sections.sort(function (a, b) {
92                return b.name.localeCompare(a.name);
93            });
94
95            this.basket.sections.forEach(function (section) {
96                section.items = section.items.sort(function (a, b) {
97                    return b.article.number - a.article.number;
98                });
99            });
100        },
101        exportBasket: function () {
102            var text = JSON.stringify(this.basket, null, 2);
103            var filename = "collection.json";
104            this.download(text, filename, "text/plain;charset=utf-8");
105        },
106        importBasket: function (e) {
107            var self = this;
108            var files = e.target.files || e.dataTransfer.files;
109            if (!files.length) return;
110            var reader = new FileReader();
111            reader.onload = function (e) {
112                if (reader.result) {
113                    self.clearAll();
114                    self.updateBasket(JSON.parse(reader.result));
115                    self.saveBasketData();
116                }
117            }
118            reader.readAsText(files[0]);
119        },
120        download: function (data, filename, type) {
121            var file = new Blob([data], {type: type});
122            if (window.navigator.msSaveOrOpenBlob) // IE10+
123                window.navigator.msSaveOrOpenBlob(file, filename);
124            else { // Others
125                var a = document.createElement("a"), url = URL.createObjectURL(file);
126                a.href = url;
127                a.download = filename;
128                document.body.appendChild(a);
129                a.click();
130                setTimeout(function () {
131                    document.body.removeChild(a);
132                    window.URL.revokeObjectURL(url);
133                }, 0);
134            }
135        },
136        clearAll: function () {
137            this.basket.id = "";
138            this.basket.intro = "";
139            this.basket.type = "359° Review";
140            this.basket.title = "New Collection";
141            this.basket.subtitle = "editor Željko Obrenović";
142            this.basket.imageUri = "images/logo.png";
143            this.basket.logoUri = "images/logo.png";
144            this.basket.iconUri = "";
145            this.basket.sections = [];
146
147            this.saveBasketData();
148        },
149        saveBasketData: function () {
150            bus.$emit("saveBasketData", {});
151        },
152        moveSectionUp: function (section) {
153            var index = this.basket.sections.indexOf(section);
154
155            if (index > 0) {
156                this.array_move(this.basket.sections, index, index - 1);
157            }
158
159            this.saveBasketData();
160        },
161        moveSectionDown: function (section) {
162            var index = this.basket.sections.indexOf(section);
163
164            if (index < this.basket.sections.length - 1) {
165                this.array_move(this.basket.sections, index, index + 1);
166                this.saveBasketData();
167            }
168
169            this.saveBasketData();
170        },
171        moveArticleUp: function (section, articleItem) {
172            var index = section.items.indexOf(articleItem);
173
174            if (index > 0) {
175                this.array_move(section.items, index, index - 1);
176                this.saveBasketData();
177            }
178
179            this.saveBasketData();
180        },
181        moveArticleDown: function (section, articleItem) {
182            var index = section.items.indexOf(articleItem);
183
184            if (index < section.items.length - 1) {
185                this.array_move(section.items, index, index + 1);
186                this.saveBasketData();
187            }
188
189            this.saveBasketData();
190        },
191        moveArticleFirst: function (section, articleItem) {
192            var index = section.items.indexOf(articleItem);
193
194            if (index > 0) {
195                this.array_move(section.items, index, 0);
196                this.saveBasketData();
197            }
198
199            this.saveBasketData();
200        },
201        moveArticleLast: function (section, articleItem) {
202            var index = section.items.indexOf(articleItem);
203
204            if (index < section.items.length - 1) {
205                this.array_move(section.items, index, section.items.length - 1);
206                this.saveBasketData();
207            }
208
209            this.saveBasketData();
210        },
211        array_move: function (arr, old_index, new_index) {
212            if (new_index >= arr.length) {
213                var k = new_index - arr.length + 1;
214                while (k--) {
215                    arr.push(undefined);
216                }
217            }
218            arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
219            return arr; // for testing
220        },
221        editIntro: function () {
222            var self = this;
223            bus.$emit('showModalEditor', {
224                object: self.basket,
225                property: "intro",
226                title: "Intro",
227                lang: "markdown",
228                onSave: function () {
229                    self.saveBasketData();
230                }
231            });
232        },
233        editAbstract: function (article) {
234            var self = this;
235            bus.$emit('showModalEditor', {
236                object: article,
237                property: "quoteAbstract",
238                title: "Abstract",
239                lang: "markdown",
240                onSave: function () {
241                    self.saveBasketData();
242                }
243            });
244        },
245        editOneLiner: function (articleItem) {
246            var self = this;
247            bus.$emit('showModalEditor', {
248                object: articleItem,
249                property: "oneLiner",
250                title: "One-liner:",
251                lang: "markdown",
252                onSave: function () {
253                    self.saveBasketData();
254                }
255            });
256        },
257        editTitle: function () {
258            var self = this;
259            bus.$emit('showModalInput', {
260                object: self.basket,
261                property: "title",
262                title: "Title:",
263                lang: "text",
264                onSave: function () {
265                    self.saveBasketData();
266                }
267            });
268        },
269        editLogo: function () {
270            var self = this;
271            bus.$emit('showModalInput', {
272                object: self.basket,
273                property: "logoUri",
274                title: "Logo URL:",
275                lang: "text",
276                onSave: function () {
277                    self.saveBasketData();
278                }
279            });
280        },
281        editSectionField: function (section, fieldName) {
282            var self = this;
283            var oldTitle = section.title;
284            bus.$emit('showModalInput', {
285                object: section,
286                property: fieldName,
287                title: fieldName.toUpperCase() + ":",
288                lang: "text",
289                onSave: function () {
290                    self.saveBasketData();
291                }
292            });
293        },
294        editSectionIntro: function (section) {
295            var self = this;
296            bus.$emit('showModalEditor', {
297                object: section,
298                property: "intro",
299                title: "Intro:",
300                lang: "markdown",
301                onSave: function () {
302                    self.saveBasketData();
303                }
304            });
305        },
306        deleteSection: function (section) {
307            this.basket.sections.splice(this.basket.sections.indexOf(section), 1);
308        },
309        sortNewestFirst: function (section) {
310            section.items = section.items.sort(function (a, b) {
311                var indexA = a.article.number;
312                var indexB = b.article.number;
313                return (indexA + b.article.year * 100) - (indexB + a.article.year * 100);
314            });
315
316            this.saveBasketData();
317        },
318        sortOldestFirst: function (section) {
319            section.items = section.items.sort(function (a, b) {
320                var indexA = a.article.number;
321                var indexB = b.article.number;
322                return (indexB + a.article.year * 100) - (indexA + b.article.year * 100);
323            });
324
325            this.saveBasketData();
326        },
327        updateBasket: function (data) {
328            if (data.id) this.basket.id = data.id;
329            if (data.type) this.basket.id = data.type;
330            if (data.title) this.basket.title = data.title;
331            if (data.subtitle) this.basket.subtitle = data.subtitle;
332            if (data.logoUri) this.basket.logoUri = data.logoUri;
333            if (data.imageUri) this.basket.imageUri = data.imageUri;
334            if (data.sections) this.basket.sections = data.sections;
335            if (data.intro) this.basket.intro = data.intro;
336        },
337        editJson: function () {
338            var self = this;
339            var jsonData = {
340                data: JSON.stringify(self.basket, null, 2)
341            };
342            bus.$emit('showModalEditor', {
343                object: jsonData,
344                property: "data",
345                title: "JSON:",
346                lang: "json",
347                onSave: function (json) {
348                    self.updateBasket(JSON.parse(json));
349                }
350            });
351        },
352        remove: function (section, articleItem) {
353            section.items.splice(section.items.indexOf(articleItem), 1);
354            this.saveBasketData();
355        }
356    },
357    template: "<div style='width=100%; max-width: 1200px;'>"
358    + "    <label><input type='checkbox' v-model='editNotes'>edit</label>"
359    + "    <button @click='saveBasketData()' class='dropbtn' :style='btnStyle'>SAVE</button>"
360    + "    <button @click='clearAll()' class='dropbtn' :style='btnStyle'>CLEAR ALL</button>"
361    + "    <label for='file-upload' class='dropbtn' :style='btnStyle'>Import...</label>"
362    + "    <input id='file-upload' type='file' @change='importBasket' style='display: none;'/>"
363    + "    <button @click='exportBasket()' class='dropbtn' :style='btnStyle'>EXPORT</button>"
364    + "    <button @click.prevent='editLogo()' class='dropbtn' :style='btnStyle'>LOGO URL...</button>"
365    + "    <button @click.prevent='editJson()' class='dropbtn' :style='btnStyle'>JSON...</button>"
366    + "    <button @click.prevent='sortSections()' class='dropbtn' :style='btnStyle'>Sort Sections</button>"
367    + "    <button @click.prevent='sortSectionsDesc()' class='dropbtn' :style='btnStyle'>Sort Sections (DESC)</button>"
368    + "    <a target='_blank' href='collection.html'>Preview...</a>"
369    + "    <span>"
370    + "        <h1>{{ basket.title }}"
371    + "        <button @click.prevent='editTitle()' class='dropbtn'>rename...</button>"
372    + "        <button @click.prevent='editIntro()' class='dropbtn'>edit intro...</button></h1>"
373    + "        <span v-html='mdToHtml(basket.intro)' style='font-size: 110%'></span>"
374    + "    </span>"
375    + "    <template v-for='section in basket.sections' style='group'>"
376    + "        <h2 v-if='editNotes' style='margin-top: 60px'>{{ section.name }}"
377    + "            <button @click='moveSectionUp(section)' class='dropbtn' :style='btnStyle'>up</button>"
378    + "            <button @click='moveSectionDown(section)' class='dropbtn' :style='btnStyle'>down</button>"
379    + "            | <button @click='editSectionField(section, \"name\")' class='dropbtn' :style='btnStyle'>rename...</button>"
380    + "            <button @click='editSectionIntro(section)' class='dropbtn' :style='btnStyle'>edit intro...</button>"
381    + "            | <button @click='sortNewestFirst(section)' class='dropbtn' :style='btnStyle'>newest first...</button>"
382    + "            <button @click='sortOldestFirst(section)' class='dropbtn' :style='btnStyle'>oldest first...</button>"
383    + "            | <button @click='deleteSection(section)' class='dropbtn' :style='btnStyle'>delete</button>"
384    + "        </h2>"
385    + "        <h2 v-if='!editNotes' style='margin-top: 60px'>{{ section.name }}</h2>"
386    + "        <span v-html='mdToHtml(section.intro)' style='font-size: 110%'></span>"
387    + "        <table style='width: 100%;'>"
388    + "        <tr v-for='(articleItem, index) in section.items'>"
389    + "            <td v-if='!mobile' style='text-align: right;' valign='top'>{{ index + 1 }}.</td>"
390    + "            <td valign='top' style='border-bottom: 1px solid grey'>"
391    + "                <article-abstract :article='articleItem.article'"
392    + "                                  :show-authors='true'"
393    + "                                  :source='source' :mobile='mobile'"
394    + "                                  :show-all-abstracts='showAbstracts'"
395    + "                                  :get-link-text='getLinkText'"
396    + "                                  :one-liner='articleItem.oneLiner'"
397    + "                                  :get-digital-library-link='getDigitalLibraryLink'>"
398    + "                </article-abstract>"
399    + "            </td>"
400    + "            <td v-if='editNotes' style='width: 350px; border-bottom: 1px solid grey'>"
401    + "                move: <button @click.stop='moveArticleUp(section, articleItem)' class='dropbtn' :style='btnStyle'>up</button>"
402    + "                <button @click.stop='moveArticleDown(section, articleItem)' class='dropbtn' :style='btnStyle'>down</button> | "
403    + "                <button @click.stop='moveArticleFirst(section, articleItem)' class='dropbtn' :style='btnStyle'>first</button>"
404    + "                <button @click.stop='moveArticleLast(section, articleItem)' class='dropbtn' :style='btnStyle'>last</button> | "
405    + "                <dropdown button-text='section...' :options='getSectionOptions(articleItem, section)' :button-style='btnStyle'></dropdown>"
406    + "                <hr/>edit: <button @click.prevent='editOneLiner(articleItem)' class='dropbtn' :style='btnStyle'>one-liner...</button>"
407    + "                <button @click.prevent='editAbstract(articleItem.article)' class='dropbtn' :style='btnStyle'>abstract...</button> | "
408    + "                <button @click.prevent='remove(section, articleItem)' class='dropbtn' :style='btnStyle'>delete</button>"
409    + "            </td>"
410    + "        </tr>"
411    + "        </table>"
412    + "    </template>"
413    + "</div>"
414})
415;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.