From eb81d8008072e38b0d1ed2cc32554fec07222f63 Mon Sep 17 00:00:00 2001 From: Andras Belicza Date: Tue, 26 Sep 2017 11:44:37 +0200 Subject: [PATCH 01/11] Prepare development for next release. --- gwu/doc.go | 2 +- version-history/changes-v1.3.1.txt | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 version-history/changes-v1.3.1.txt diff --git a/gwu/doc.go b/gwu/doc.go index 0faba88..0f12ffc 100644 --- a/gwu/doc.go +++ b/gwu/doc.go @@ -396,7 +396,7 @@ package gwu // Gowut version information. const ( - GowutVersion = "v1.3.0" // Gowut version: "v"major.minor.maintenance[-dev] + GowutVersion = "v1.3.1-dev" // Gowut version: "v"major.minor.maintenance[-dev] GowutReleaseDate = "2017-09-26 CET" // Gowut release date GowutRelDateLayout = "2006-01-02 MST" // Gowut release date layout (for time.Parse()) ) diff --git a/version-history/changes-v1.3.1.txt b/version-history/changes-v1.3.1.txt new file mode 100644 index 0000000..fff259f --- /dev/null +++ b/version-history/changes-v1.3.1.txt @@ -0,0 +1,3 @@ + +Changes and new features in v1.3.1: +----------------------------------- From 616ae5446be52f55c4c43e31c532e0c9a464c21e Mon Sep 17 00:00:00 2001 From: Andras Belicza Date: Wed, 27 Sep 2017 10:31:19 +0200 Subject: [PATCH 02/11] Added ETypeMouseDown constant, identical to ETypeMousedown. --- gwu/event.go | 5 +++++ version-history/changes-v1.3.1.txt | 2 ++ 2 files changed, 7 insertions(+) diff --git a/gwu/event.go b/gwu/event.go index 9f8a089..f26ca20 100644 --- a/gwu/event.go +++ b/gwu/event.go @@ -55,6 +55,11 @@ const ( ETypeStateChange // State change ) +const ( + // ETypeMouseDown is identical to ETypeMousedown + ETypeMouseDown = ETypeMousedown +) + // EventCategory is the event type category. type EventCategory int diff --git a/version-history/changes-v1.3.1.txt b/version-history/changes-v1.3.1.txt index fff259f..3a111dd 100644 --- a/version-history/changes-v1.3.1.txt +++ b/version-history/changes-v1.3.1.txt @@ -1,3 +1,5 @@ Changes and new features in v1.3.1: ----------------------------------- + +-Added ETypeMouseDown constant, identical to ETypeMousedown. From 558d0395f82cf19b193efe3f33ba41859b00a7c7 Mon Sep 17 00:00:00 2001 From: Andras Belicza Date: Wed, 27 Sep 2017 12:00:16 +0200 Subject: [PATCH 03/11] Check if component is nil to avoid panic when clearing the table. Fixes #23. --- gwu/table.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gwu/table.go b/gwu/table.go index 9dd3ca8..de03298 100644 --- a/gwu/table.go +++ b/gwu/table.go @@ -166,7 +166,9 @@ func (c *tableImpl) Clear() { for _, rowComps := range c.comps { for _, c2 := range rowComps { - c2.setParent(nil) + if c2 != nil { + c2.setParent(nil) + } } } c.comps = nil From e95c55d17bb3f1f09cf5ec285cebc0965a685faa Mon Sep 17 00:00:00 2001 From: Andras Belicza Date: Wed, 27 Sep 2017 12:02:08 +0200 Subject: [PATCH 04/11] Mentioned #23 fix in version history. --- version-history/changes-v1.3.1.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/version-history/changes-v1.3.1.txt b/version-history/changes-v1.3.1.txt index 3a111dd..8adf623 100644 --- a/version-history/changes-v1.3.1.txt +++ b/version-history/changes-v1.3.1.txt @@ -3,3 +3,5 @@ Changes and new features in v1.3.1: ----------------------------------- -Added ETypeMouseDown constant, identical to ETypeMousedown. + +-Fixed an issue where Table.Clear() could panic if table contained nil components (#23). From 8140e5a95df7589736bbf44d2784d6cbaa5cab21 Mon Sep 17 00:00:00 2001 From: Andras Belicza Date: Wed, 28 Feb 2018 11:51:55 +0100 Subject: [PATCH 05/11] Add Server.SessIDCookieName() and SetSessIDCookieName() methods --- gwu/server.go | 41 ++++++++++++++++++++++++------ version-history/changes-v1.3.1.txt | 5 ++++ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/gwu/server.go b/gwu/server.go index e1f018f..9a16d08 100644 --- a/gwu/server.go +++ b/gwu/server.go @@ -62,8 +62,8 @@ const ( eraFocusComp // Focus a compnent ) -// GWU session id cookie name -const gwuSessidCookie = "gwu-sessid" +// Default GWU session id cookie name +const defaultSessIDCookieName = "gwu-sessid" // SessionHandler interface defines a callback to get notified // for certain events related to session life-cycles. @@ -192,6 +192,13 @@ type Server interface { // By setting your own hander, you will completely take over the app root. SetAppRootHandler(f AppRootHandlerFunc) + // SessIDCookieName returns the cookie name used to store the Gowut + // session ID. + SessIDCookieName() string + + // session ID. + SetSessIDCookieName(name string) + // Start starts the GUI server and waits for incoming connections. // // Sessionless window names may be specified as optional parameters @@ -222,6 +229,7 @@ type serverImpl struct { headers http.Header // Extra headers that will be added to all responses. rootHeads []string // Additional head HTML texts of the window list page (app root) appRootHandlerFunc AppRootHandlerFunc // App root handler function + sessIDCookieName string // Session ID cookie name sessMux sync.RWMutex // Mutex to protect state related to session handling } @@ -252,8 +260,15 @@ func newServerImpl(appName, addr, certFile, keyFile string) *serverImpl { addr = "localhost:3434" } - s := &serverImpl{sessionImpl: newSessionImpl(false), appName: appName, addr: addr, sessions: make(map[string]Session), - sessCreatorNames: make(map[string]string), theme: ThemeDefault} + s := &serverImpl{ + sessionImpl: newSessionImpl(false), + appName: appName, + addr: addr, + sessions: make(map[string]Session), + sessCreatorNames: make(map[string]string), + theme: ThemeDefault, + sessIDCookieName: defaultSessIDCookieName, + } if s.appName == "" { s.appPath = "/" @@ -379,10 +394,12 @@ func (s *serverImpl) addSessCookie(sess Session, w http.ResponseWriter) { // Secure: only send it over HTTPS // MaxAge: to specify the max age of the cookie in seconds, else it's a session cookie and gets deleted after the browser is closed. c := http.Cookie{ - Name: gwuSessidCookie, Value: sess.ID(), + Name: s.sessIDCookieName, + Value: sess.ID(), Path: s.appURL.EscapedPath(), - HttpOnly: true, Secure: s.secure, - MaxAge: 72 * 60 * 60, // 72 hours max age + HttpOnly: true, + Secure: s.secure, + MaxAge: 72 * 60 * 60, // 72 hours max age } http.SetCookie(w, &c) @@ -502,6 +519,14 @@ func (s *serverImpl) SetAppRootHandler(f AppRootHandlerFunc) { s.appRootHandlerFunc = f } +func (s *serverImpl) SessIDCookieName() string { + return s.sessIDCookieName +} + +func (s *serverImpl) SetSessIDCookieName(name string) { + s.sessIDCookieName = name +} + // serveStatic handles the static contents of GWU. func (s *serverImpl) serveStatic(w http.ResponseWriter, r *http.Request) { s.addHeaders(w) @@ -561,7 +586,7 @@ func (s *serverImpl) serveHTTP(w http.ResponseWriter, r *http.Request) { // Check session var sess Session - c, err := r.Cookie(gwuSessidCookie) + c, err := r.Cookie(s.sessIDCookieName) if err == nil { s.sessMux.RLock() sess = s.sessions[c.Value] diff --git a/version-history/changes-v1.3.1.txt b/version-history/changes-v1.3.1.txt index 8adf623..1f3fbd4 100644 --- a/version-history/changes-v1.3.1.txt +++ b/version-history/changes-v1.3.1.txt @@ -2,6 +2,11 @@ Changes and new features in v1.3.1: ----------------------------------- +-New SessIDCookieName() and SetSessIDCookieName() methods in Server to get / set +the cookie name used to store the Gowut session ID. Useful if you plan to run +multiple Gowut servers on the same computer with the same app path (on different ports); +you can set different session ID cookie names so they won't collide (#42). + -Added ETypeMouseDown constant, identical to ETypeMousedown. -Fixed an issue where Table.Clear() could panic if table contained nil components (#23). From 9fb00c30d9be5c4c2d7ebc21c6a26548bad20687 Mon Sep 17 00:00:00 2001 From: Andras Belicza Date: Wed, 28 Feb 2018 11:53:25 +0100 Subject: [PATCH 06/11] Change dev version from 1.3.1 to 1.4.0 --- gwu/doc.go | 2 +- version-history/{changes-v1.3.1.txt => changes-v1.4.0.txt} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename version-history/{changes-v1.3.1.txt => changes-v1.4.0.txt} (93%) diff --git a/gwu/doc.go b/gwu/doc.go index 0f12ffc..9c8a8b1 100644 --- a/gwu/doc.go +++ b/gwu/doc.go @@ -396,7 +396,7 @@ package gwu // Gowut version information. const ( - GowutVersion = "v1.3.1-dev" // Gowut version: "v"major.minor.maintenance[-dev] + GowutVersion = "v1.4.0-dev" // Gowut version: "v"major.minor.maintenance[-dev] GowutReleaseDate = "2017-09-26 CET" // Gowut release date GowutRelDateLayout = "2006-01-02 MST" // Gowut release date layout (for time.Parse()) ) diff --git a/version-history/changes-v1.3.1.txt b/version-history/changes-v1.4.0.txt similarity index 93% rename from version-history/changes-v1.3.1.txt rename to version-history/changes-v1.4.0.txt index 1f3fbd4..8922e7b 100644 --- a/version-history/changes-v1.3.1.txt +++ b/version-history/changes-v1.4.0.txt @@ -1,5 +1,5 @@ -Changes and new features in v1.3.1: +Changes and new features in v1.4.0: ----------------------------------- -New SessIDCookieName() and SetSessIDCookieName() methods in Server to get / set From 3775ac0048af8d7951986c1170a447c4e5353e5c Mon Sep 17 00:00:00 2001 From: Andras Belicza Date: Mon, 1 Oct 2018 12:30:02 +0200 Subject: [PATCH 07/11] Take body's scroll amount into account in event's mouse coordinates --- gwu/js.go | 58 +++++++++++++++++------------- version-history/changes-v1.4.0.txt | 3 ++ 2 files changed, 36 insertions(+), 25 deletions(-) diff --git a/gwu/js.go b/gwu/js.go index 70c6403..596ed6f 100644 --- a/gwu/js.go +++ b/gwu/js.go @@ -67,17 +67,17 @@ function createXmlHttp() { // Send event function se(event, etype, compId, compValue) { var xhr = createXmlHttp(); - + xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) procEresp(xhr); } - + xhr.open("POST", _pathEvent, true); // asynch call xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); - + var data=""; - + if (etype != null) data += "&" + _pEventType + "=" + etype; if (compId != null) @@ -86,11 +86,19 @@ function se(event, etype, compId, compValue) { data += "&" + _pCompValue + "=" + compValue; if (document.activeElement.id != null) data += "&" + _pFocCompId + "=" + document.activeElement.id; - + if (event != null) { if (event.clientX != null) { // Mouse data var x = event.clientX, y = event.clientY; + // Account for the amount body is scrolled: + eventDoc = (event.target && event.target.ownerDocument) || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + x += (doc && doc.scrollLeft || body && body.scrollLeft || 0) - + (doc && doc.clientLeft || body && body.clientLeft || 0); + y += (doc && doc.scrollTop || body && body.scrollTop || 0) - + (doc && doc.clientTop || body && body.clientTop || 0 ); data += "&" + _pMouseWX + "=" + x; data += "&" + _pMouseWY + "=" + y; var parent = document.getElementById(compId); @@ -102,7 +110,7 @@ function se(event, etype, compId, compValue) { data += "&" + _pMouseY + "=" + y; data += "&" + _pMouseBtn + "=" + (event.button < 4 ? event.button : 1); // IE8 and below uses 4 for middle btn } - + var modKeys; modKeys += event.altKey ? _modKeyAlt : 0; modKeys += event.ctlrKey ? _modKeyCtlr : 0; @@ -111,20 +119,20 @@ function se(event, etype, compId, compValue) { data += "&" + _pModKeys + "=" + modKeys; data += "&" + _pKeyCode + "=" + (event.which ? event.which : event.keyCode); } - + xhr.send(data); } function procEresp(xhr) { var actions = xhr.responseText.split(";"); - + if (actions.length == 0) { window.alert("No response received!"); return; } for (var i = 0; i < actions.length; i++) { var n = actions[i].split(","); - + switch (parseInt(n[0])) { case _eraDirtyComps: for (var j = 1; j < n.length; j++) @@ -153,16 +161,16 @@ function rerenderComp(compId) { var e = document.getElementById(compId); if (!e) // Component removed or not visible (e.g. on inactive tab of TabPanel) return; - + var xhr = createXmlHttp(); - + xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { // Remember focused comp which might be replaced here: var focusedCompId = document.activeElement.id; e.outerHTML = xhr.responseText; focusComp(focusedCompId); - + // Inserted JS code is not executed automatically, do it manually: // Have to "re-get" element by compId! var scripts = document.getElementById(compId).getElementsByTagName("script"); @@ -171,21 +179,21 @@ function rerenderComp(compId) { } } } - + xhr.open("POST", _pathRenderComp, false); // synch call (if async, browser specific DOM rendering errors may arise) xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); - + xhr.send(_pCompId + "=" + compId); } // Get selected indices (of an HTML select) function selIdxs(select) { var selected = ""; - + for (var i = 0; i < select.options.length; i++) if(select.options[i].selected) selected += i + ","; - + return selected; } @@ -193,10 +201,10 @@ function selIdxs(select) { function sbtnVal(event, onBtnId, offBtnId) { var onBtn = document.getElementById(onBtnId); var offBtn = document.getElementById(offBtnId); - + if (onBtn == null) return false; - + var value = onBtn == document.elementFromPoint(event.clientX, event.clientY); if (value) { onBtn.className = "gwu-SwitchButton-On-Active"; @@ -205,7 +213,7 @@ function sbtnVal(event, onBtnId, offBtnId) { onBtn.className = "gwu-SwitchButton-On-Inactive"; offBtn.className = "gwu-SwitchButton-Off-Active"; } - + return value; } @@ -247,7 +255,7 @@ var timers = new Object(); function setupTimer(compId, js, timeout, repeat, active, reset) { var timer = timers[compId]; - + if (timer != null) { var changed = timer.js != js || timer.timeout != timeout || timer.repeat != repeat || timer.reset != reset; if (!active || changed) { @@ -262,14 +270,14 @@ function setupTimer(compId, js, timeout, repeat, active, reset) { } if (!active) return; - + // Create new timer timers[compId] = timer = new Object(); timer.js = js; timer.timeout = timeout; timer.repeat = repeat; timer.reset = reset; - + // Start the timer if (timer.repeat) timer.id = setInterval(js, timeout); @@ -281,9 +289,9 @@ function checkSession(compId) { var e = document.getElementById(compId); if (!e) // Component removed or not visible (e.g. on inactive tab of TabPanel) return; - + var xhr = createXmlHttp(); - + xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { var timeoutSec = parseFloat(xhr.responseText); @@ -295,7 +303,7 @@ function checkSession(compId) { e.children[0].innerText = typeof cnvtr === 'function' ? cnvtr(timeoutSec) : convertSessTimeout(timeoutSec); } } - + xhr.open("GET", _pathSessCheck, false); // synch call (else we can't catch connection error) try { xhr.send(); diff --git a/version-history/changes-v1.4.0.txt b/version-history/changes-v1.4.0.txt index 8922e7b..cf0a745 100644 --- a/version-history/changes-v1.4.0.txt +++ b/version-history/changes-v1.4.0.txt @@ -10,3 +10,6 @@ you can set different session ID cookie names so they won't collide (#42). -Added ETypeMouseDown constant, identical to ETypeMousedown. -Fixed an issue where Table.Clear() could panic if table contained nil components (#23). + +-Mouse coordinates in events did not take the body's scroll amount into account, this is fixed now. +Event.Mouse() and Event.MouseWin() now return proper coordinates. From 6afa6655eae824c540ed484acfafb2e44c602006 Mon Sep 17 00:00:00 2001 From: Andras Belicza Date: Tue, 2 Oct 2018 22:53:39 +0200 Subject: [PATCH 08/11] Update copyright years --- _examples/showcase/showcasecore/showcasecore.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_examples/showcase/showcasecore/showcasecore.go b/_examples/showcase/showcasecore/showcasecore.go index 4543a49..7f3fa5e 100644 --- a/_examples/showcase/showcasecore/showcasecore.go +++ b/_examples/showcase/showcasecore/showcasecore.go @@ -836,7 +836,7 @@ func buildShowcaseWin(sess gwu.Session) { footer.Style().SetFullWidth().SetBorderTop2(2, gwu.BrdStyleSolid, "#cccccc") footer.Add(hiddenPan) footer.AddHConsumer() - l = gwu.NewLabel("Copyright © 2013-2017 András Belicza. All rights reserved.") + l = gwu.NewLabel("Copyright © 2013-2018 András Belicza. All rights reserved.") l.Style().SetFontStyle(gwu.FontStyleItalic).SetFontSize("95%") footer.Add(l) footer.AddHSpace(10) From bad0640abf2aa4480392b0624d9682437329afef Mon Sep 17 00:00:00 2001 From: Andras Belicza Date: Tue, 2 Oct 2018 22:55:26 +0200 Subject: [PATCH 09/11] Add Go 1.10 and 1.11 to travis config --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 4073a64..fab309f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,4 +3,6 @@ language: go go: - 1.8 - 1.9 + - 1.10 + - 1.11 - master From 1dd028997075fabfa84c736df1132df9b807bd70 Mon Sep 17 00:00:00 2001 From: Andras Belicza Date: Tue, 2 Oct 2018 23:01:59 +0200 Subject: [PATCH 10/11] Put Go 1.10 in quotes to circumvent config parsing issue --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fab309f..71e863f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,6 @@ language: go go: - 1.8 - 1.9 - - 1.10 + - "1.10" - 1.11 - master From 8fe9e5290185a6d58a2f2b55e56f4070bd071384 Mon Sep 17 00:00:00 2001 From: Andras Belicza Date: Tue, 2 Oct 2018 23:04:50 +0200 Subject: [PATCH 11/11] Gowut v1.4.0 public release. --- gwu/doc.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gwu/doc.go b/gwu/doc.go index 9c8a8b1..871fe95 100644 --- a/gwu/doc.go +++ b/gwu/doc.go @@ -396,7 +396,7 @@ package gwu // Gowut version information. const ( - GowutVersion = "v1.4.0-dev" // Gowut version: "v"major.minor.maintenance[-dev] - GowutReleaseDate = "2017-09-26 CET" // Gowut release date + GowutVersion = "v1.4.0" // Gowut version: "v"major.minor.maintenance[-dev] + GowutReleaseDate = "2018-10-02 CET" // Gowut release date GowutRelDateLayout = "2006-01-02 MST" // Gowut release date layout (for time.Parse()) )