git.fiddlerwoaroof.com
Browse code

fix: solve too many pushState calls

fiddlerwoaroof authored on 14/10/2022 04:24:28
Showing 1 changed files
... ...
@@ -1,192 +1,209 @@
1 1
 root = new Vue({
2
-    el: '#container',
3
-    data: {
4
-        "pull_time": null,
5
-        "feed_urls": [],
6
-        feeds: {
7
-            feeds: []
8
-        },
9
-        collapsed: false,
10
-
11
-        current_feed: {
12
-            metadata: {
13
-                description: null,
14
-                fetch_url: null,
15
-                link: null,
16
-                title: null,
17
-            },
18
-            base_path: null,
19
-            items: [],
20
-        },
21
-
22
-        current_item: {
23
-            title: null,
24
-            date: null,
25
-            author: null,
26
-            id: null,
27
-            link: null,
28
-            content: null,
29
-        },
30
-
31
-        feed_item_counts: {},
32
-
33
-        likes: [],
34
-        show_likes: true,
2
+  el: "#container",
3
+  data: {
4
+    pull_time: null,
5
+    feed_urls: [],
6
+    feeds: {
7
+      feeds: [],
8
+    },
9
+    collapsed: false,
10
+
11
+    current_feed: {
12
+      metadata: {
13
+        description: null,
14
+        fetch_url: null,
15
+        link: null,
16
+        title: null,
17
+      },
18
+      base_path: null,
19
+      items: [],
35 20
     },
36 21
 
37
-    computed: {
38
-        feed_visible() {
39
-            return (!this.show_likes) &&
40
-                this.current_feed.metadata.title !== null &&
41
-                this.current_feed.items.length > 0;
42
-        },
43
-        
44
-        item_content() {
45
-            let result = null;
46
-            if (this.current_item.content !== null) {
47
-                result = DOMPurify.sanitize(this.current_item.content, {
48
-                    FORBID_TAG: ['style'],
49
-                    FORBID_ATTR: ['style'],
50
-                });
51
-            }
52
-            return result;
53
-        },
22
+    current_item: {
23
+      title: null,
24
+      date: null,
25
+      author: null,
26
+      id: null,
27
+      link: null,
28
+      content: null,
29
+      path: null,
30
+    },
31
+
32
+    feed_item_counts: {},
33
+
34
+    likes: [],
35
+    show_likes: true,
36
+  },
37
+
38
+  computed: {
39
+    feed_visible() {
40
+      return (
41
+        !this.show_likes &&
42
+        this.current_feed.metadata.title !== null &&
43
+        this.current_feed.items.length > 0
44
+      );
45
+    },
46
+
47
+    item_content() {
48
+      let result = null;
49
+      if (this.current_item.content !== null) {
50
+        result = DOMPurify.sanitize(this.current_item.content, {
51
+          FORBID_TAG: ["style"],
52
+          FORBID_ATTR: ["style"],
53
+        });
54
+      }
55
+      return result;
56
+    },
57
+  },
58
+
59
+  methods: {
60
+    list_likes() {
61
+      this.likes = [];
62
+      oboe("events.json").node("*", (ev) => {
63
+        let { event } = ev;
64
+        if (event === "like-item") {
65
+          this.likes.unshift(ev);
66
+        }
67
+      });
68
+      this.show_likes = !this.show_likes;
54 69
     },
55 70
 
56
-    methods: {
57
-        list_likes() {
58
-            this.likes = []
59
-            oboe('events.json')
60
-                .node('*', (ev) => {
61
-                    let {event} = ev;
62
-                    if (event === 'like-item') {
63
-                        this.likes.push(ev);
64
-                    }
65
-                });
66
-            this.show_likes = !this.show_likes;
67
-        },
68
-        
69
-        toggleCollapse() {
70
-            this.collapsed = !this.collapsed;
71
-        },
72
-        
73
-        sanitize(html) {
74
-            return DOMPurify.sanitize(html, {
75
-                FORBID_TAG: ['style'],
76
-                FORBID_ATTR: ['style'],
77
-            });
78
-        },
79
-
80
-        get_remote_feed: function (path) {
81
-            var promise = new Promise((resolve, reject) => {
82
-                window.fetch(path).then((resp) => resp.json())
83
-                    .then((data) => {
84
-                        var result = Object.assign({}, data);
85
-                        result.fetch_url = data['fetch-url'];
86
-                        result.base_path = path;
87
-                        window.history.pushState({
88
-                            'current_feed': result
89
-                        }, "", window.location.pathname);
90
-                        resolve(result);
91
-                        return promise;
92
-                    }, reject.bind(promise));
93
-            });
71
+    toggleCollapse() {
72
+      this.collapsed = !this.collapsed;
73
+    },
74
+
75
+    sanitize(html) {
76
+      return DOMPurify.sanitize(html, {
77
+        FORBID_TAG: ["style"],
78
+        FORBID_ATTR: ["style"],
79
+      });
80
+    },
81
+
82
+    get_remote_feed: function (path, shouldPushState = true) {
83
+      var promise = new Promise((resolve, reject) => {
84
+        window
85
+          .fetch(path + "index.json")
86
+          .then((resp) => resp.json())
87
+          .then((data) => {
88
+            var result = Object.assign({}, data);
89
+            result.fetch_url = data["fetch-url"];
90
+            result.base_path = path;
91
+            if (shouldPushState) {
92
+              window.history.pushState(
93
+                {
94
+                  current_feed: result,
95
+                },
96
+                "",
97
+                window.location.pathname
98
+              );
99
+            }
100
+            resolve(result);
94 101
             return promise;
95
-        },
96
-
97
-        get_feed: function (path) {
98
-            this.get_remote_feed(path)
99
-                .then((result) => Vue.set(this, 'current_feed', result))
100
-                .then(() => this.show_likes = false);
101
-        },
102
-
103
-        like(item, feed) {
104
-            fetch('https://<URL>/hub/feed_archive', {
105
-                method: 'POST',
106
-                body: JSON.stringify({
107
-                    'event': 'like-item',
108
-                    'item': item.link,
109
-                    'title': item.title,
110
-                    'author': item.author,
111
-                    'feed-title': feed.metadata.title,
112
-                    'feed-link': feed.metadata.link,
113
-                }),
114
-            });
115
-        },
116
-
117
-        get_item(path) {
118
-            window.fetch(this.current_feed.base_path + path).then((resp) => resp.json())
119
-                .then((data) => {
120
-                    fetch('https://<URL>/hub/feed_archive', {
121
-                        method: 'POST',
122
-                        body: JSON.stringify({
123
-                            'event': 'read-item',
124
-                            'item': data.link,
125
-                            'title': data.title,
126
-                            'author': data.author,
127
-                            'feed-title': this.current_feed.metadata.title,
128
-                            'feed-link': this.current_feed.metadata.link,
129
-                        }),
130
-                    });
131
-                    window.history.pushState({
132
-                        'current_feed': root.current_feed,
133
-                        'current_item': data
134
-                    }, "", window.location.pathname);
135
-                    Object.assign(this.current_item, data);
136
-                });
137
-        },
138
-
139
-        has_items(feed) {
140
-            var count = this.feed_item_counts[feed.path];
141
-            return count === undefined || (count > 0);
142
-        },
102
+          }, reject.bind(promise));
103
+      });
104
+      return promise;
105
+    },
143 106
 
107
+    get_feed: function (path) {
108
+      this.get_remote_feed(path)
109
+        .then((result) => Vue.set(this, "current_feed", result))
110
+        .then(() => (this.show_likes = false));
144 111
     },
145 112
 
146
-    ready() {
147
-        oboe('events.json')
148
-            .node('*', (ev) => {
149
-                let {event} = ev;
150
-                if (event === 'like-item') {
151
-                    this.likes.push(ev);
152
-                }
153
-            });
154
-        
155
-        window.fetch(baseUrl+'/index.json').then((resp) => resp.json())
156
-            .then(function (data) {
157
-                root.pull_time = data['pull-time'];
158
-                root.feed_urls = data['feed-urls'];
159
-                root.feeds = data.feeds;
160
-                return data;
161
-            })
162
-            .then((data) => {
163
-                root.feeds.forEach((feed) => {
164
-                    // console.log(feed);
165
-                    this.get_remote_feed(feed.path)
166
-                        .then((feed_index) => Vue.set(this.feed_item_counts, feed.path, feed_index.items.length));
167
-                });
168
-            });
113
+    like(item, feed) {
114
+      fetch("https://srv2.elangley.org/hub/feed_archive", {
115
+        method: "POST",
116
+        body: JSON.stringify({
117
+          event: "like-item",
118
+          item: item.link,
119
+          title: item.title,
120
+          author: item.author,
121
+          "feed-title": feed.metadata.title,
122
+          "feed-link": feed.metadata.link,
123
+        }),
124
+      });
125
+    },
169 126
 
127
+    get_item(path) {
128
+      window
129
+        .fetch(this.current_feed.base_path + path)
130
+        .then((resp) => resp.json())
131
+        .then((data) => {
132
+          fetch("https://srv2.elangley.org/hub/feed_archive", {
133
+            method: "POST",
134
+            body: JSON.stringify({
135
+              event: "read-item",
136
+              item: data.link,
137
+              title: data.title,
138
+              author: data.author,
139
+              "feed-title": this.current_feed.metadata.title,
140
+              "feed-link": this.current_feed.metadata.link,
141
+            }),
142
+          });
143
+          window.history.pushState(
144
+            {
145
+              current_feed: root.current_feed,
146
+              current_item: data,
147
+            },
148
+            "",
149
+            window.location.pathname
150
+          );
151
+          Object.assign(this.current_item, data);
152
+          this.current_item.path = path;
153
+        });
170 154
     },
171 155
 
156
+    has_items(feed) {
157
+      var count = this.feed_item_counts[feed.path];
158
+      return count === undefined || count > 0;
159
+    },
160
+  },
161
+
162
+  ready() {
163
+    oboe("events.json").node("*", (ev) => {
164
+      let { event } = ev;
165
+      if (event === "like-item") {
166
+        this.likes.unshift(ev);
167
+      }
168
+    });
169
+
170
+    window
171
+      .fetch(baseUrl + "/index.json")
172
+      .then((resp) => resp.json())
173
+      .then(function (data) {
174
+        root.pull_time = data["pull-time"];
175
+        root.feed_urls = data["feed-urls"];
176
+        root.feeds = data.feeds;
177
+        return data;
178
+      })
179
+      .then((data) => {
180
+        root.feeds.forEach((feed) => {
181
+          // console.log(feed);
182
+          this.get_remote_feed(feed.path, false).then((feed_index) =>
183
+            Vue.set(this.feed_item_counts, feed.path, feed_index.items.length)
184
+          );
185
+        });
186
+      });
187
+  },
172 188
 });
173 189
 
174 190
 window.onpopstate = function (ev) {
175
-    // console.log(ev);
176
-    var current_feed = ev.state.current_feed, current_item = ev.state.current_item;
191
+  // console.log(ev);
192
+  var current_feed = ev.state.current_feed,
193
+    current_item = ev.state.current_item;
177 194
 
178
-    Object.assign(root.current_feed, current_feed);
195
+  Object.assign(root.current_feed, current_feed);
179 196
 
180
-    if (current_item !== undefined) {
181
-        Object.assign(root.current_item, current_item);
182
-    }
197
+  if (current_item !== undefined) {
198
+    Object.assign(root.current_item, current_item);
199
+  }
183 200
 };
184 201
 
185
-document.addEventListener('DOMContentLoaded', function (ev) {
186
-    if (window.history.state !== null) {
187
-        Object.assign(root.current_feed, window.history.state.current_feed);
188
-        if (window.history.state.current_item !== undefined) {
189
-            Object.assign(root.current_item, window.history.state.current_item);
190
-        }
202
+document.addEventListener("DOMContentLoaded", function (ev) {
203
+  if (window.history.state !== null) {
204
+    Object.assign(root.current_feed, window.history.state.current_feed);
205
+    if (window.history.state.current_item !== undefined) {
206
+      Object.assign(root.current_item, window.history.state.current_item);
191 207
     }
208
+  }
192 209
 });