-
Notifications
You must be signed in to change notification settings - Fork 1
/
QueryInterface.coffee
executable file
·238 lines (159 loc) · 5.97 KB
/
QueryInterface.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
class exports.QueryInterface extends Framer.BaseClass
_allQueryInterfaces = [] unless _allQueryInterfaces?
# based on http://stackoverflow.com/a/5158301 by James
getParameterByName = (name) ->
if Utils.isInsideFramerCloud()
location = window.parent.location.search
else
location = window.location.search
match = RegExp("[?&]#{name}=([^&]*)").exec(location)
match and decodeURIComponent(match[1].replace(/\+/g, " "))
# based on http://stackoverflow.com/a/11654596 by ellemayo
updateQueryString = (key, value, url) ->
unless url?
if Utils.isInsideFramerCloud()
url = window.parent.location.href
else
url = window.location.href
key = key.replace("#", "%23")
value = value.replace("#", "%23") if typeof value is "string"
re = new RegExp("([?&])#{key}=.*?(&|#|$)(.*)", "gi")
hash = undefined
if re.test(url)
if typeof value isnt "undefined" and value isnt null
url.replace(re, "$1#{key}=#{value}$2$3")
else
hash = url.split("#")
url = hash[0].replace(re, "$1$3").replace(/(&|\?)$/, "")
url += "##{hash[1]}" if typeof hash[1] isnt "undefined" and hash[1] isnt null
return url
else
if typeof value isnt "undefined" and value isnt null
separator = if url.indexOf("?") isnt -1 then "&" else "?"
hash = url.split("#")
url = "#{hash[0]}#{separator}#{key}=#{value}"
url += "##{hash[1]}" if typeof hash[1] isnt "undefined" and hash[1] isnt null
return url
else url
@define "value",
get: ->
if Utils.isInsideFramerCloud()
locationPathName = window.parent.location.pathname
else
locationPathName = window.location.pathname
if getParameterByName(@key) and @fetchQuery
@value = @_parse(getParameterByName(@key), false)
else if @saveLocal is false or @loadLocal is false
if @_val is undefined or @_val is "undefined"
@default
else @_val
else if localStorage.getItem("#{locationPathName}?#{@key}=") and @loadLocal
localValue = localStorage.getItem("#{locationPathName}?#{@key}=")
if localValue is undefined or localValue is "undefined"
@reset()
else
val = @_parse(localValue, false)
else @value = @default
set: (val) ->
return if @default is undefined or @key is undefined
@_val = val = @_parse(val, true)
if @saveLocal
localStorage.setItem("#{window.location.pathname}?#{@key}=", val)
if @publish is true
newUrl = updateQueryString(@key, val)
if Utils.isFramerStudio() isnt true or @_forcePublish
try window.history.replaceState({path: newUrl}, "#{@key} changed to #{val}", newUrl)
if Utils.isInsideIframe()
try window.parent.history.replaceState({path: newUrl}, "#{@key} changed to #{val}", newUrl)
else
newUrl = updateQueryString(@key)
if Utils.isInsideIframe()
window.parent.history.replaceState({path: newUrl}, "#{@key} removed from URI", newUrl)
else if Utils.isInsideIframe() is false
window.history.replaceState({path: newUrl}, "#{@key} removed from URI", newUrl)
@define "type", get: -> typeof(@default)
@define "default",
get: -> @_default
set: (val) ->
if Utils.isInsideFramerCloud()
locationPathName = window.parent.location.pathname
else
locationPathName = window.parent.location.pathname
return if typeof val is "function" or @key is undefined
@_default = val
if localStorage.getItem("#{locationPathName}?#{@key}Default=")
savedDefault = localStorage.getItem("#{locationPathName}?#{@key}Default=")
parsedVal = val.toString()
localStorage.setItem("#{locationPathName}?#{@key}Default=", parsedVal)
if parsedVal isnt savedDefault
@reset() if Utils.isFramerStudio()
if localStorage.getItem("#{locationPathName}?#{@key}Type=")
savedType = localStorage.getItem("#{locationPathName}?#{@key}Type=")
newType = typeof val
localStorage.setItem("#{locationPathName}?#{@key}Type=", newType)
if savedType and newType isnt savedType
@reset()
constructor: (@options = {}) ->
@key = @options.key ?= undefined
@publish = @options.publish ?= true
@fetchQuery = @options.fetchQuery ?= true
@saveLocal = @options.saveLocal ?= true
@loadLocal = @options.loadLocal ?= true
@_forcePublish = false
super
_allQueryInterfaces.push(this)
@value = @value
_parse: (val, set) ->
if val is "/reset/" or val is "/default/"
val = @default
else
switch typeof @default
when "number"
if val is false or val is null or isNaN(val)
val = 0
else if val
val = Number(val)
val = @default if isNaN(val)
else val = @default
when "boolean"
switch typeof val
when "object" then val = Boolean(val)
when "undefined" then val = false
when "string"
if val.toLowerCase() is "true"
val = true
else if val.toLowerCase() is "false"
val = false
else val = true
when "number"
if val is 0 then val = false else val = true
when "string"
if val then val = val.toString() else val = @default
when "object"
if set
unless val is undefined or val is null
val = JSON.stringify(val)
else val = @default
else
unless val is undefined or val is null or val is "undefined" or val is "null"
val = JSON.parse(val)
else val = @default
return val
reset: -> @value = @default
@resetAll = ->
queryInterface.reset() for queryInterface in _allQueryInterfaces
newUrl = window.location.href.split('?')[0]
window.history.replaceState({path: newUrl},"Reset all QueryInterfaces", newUrl) if newUrl?
location.reload()
@query = ->
for queryInterface in _allQueryInterfaces
queryInterface._forcePublish = true
queryInterface.value = queryInterface.value
if Utils.isFramerStudio()
query = "?#{updateQueryString("reloader").split('?')[1]}".replace(/%22/g, "\"")
else
query =(window.location.search).replace(/%22/g, "\"")
for queryInterface in _allQueryInterfaces
queryInterface._forcePublish = false
queryInterface.value = queryInterface.value
return query