mirror of https://github.com/anoshenko/rui.git
				
				
				
			Updated wasm support
This commit is contained in:
		
							parent
							
								
									b4032b31e0
								
							
						
					
					
						commit
						b26525e892
					
				|  | @ -200,7 +200,7 @@ func (app *application) startSession(params DataObject, events chan DataObject, | |||
| 
 | ||||
| 	session := newSession(app, app.nextSessionID(), "", params) | ||||
| 	session.setBrige(events, brige) | ||||
| 	if !session.setContent(app.createContentFunc(session), session) { | ||||
| 	if !session.setContent(app.createContentFunc(session)) { | ||||
| 		return nil, "" | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										280
									
								
								appWasm.go
								
								
								
								
							
							
						
						
									
										280
									
								
								appWasm.go
								
								
								
								
							|  | @ -4,6 +4,7 @@ package rui | |||
| 
 | ||||
| import ( | ||||
| 	_ "embed" | ||||
| 	"strings" | ||||
| 	"syscall/js" | ||||
| ) | ||||
| 
 | ||||
|  | @ -15,35 +16,88 @@ type wasmApp struct { | |||
| 	createContentFunc func(Session) SessionContent | ||||
| 	session           Session | ||||
| 	brige             webBrige | ||||
| 	close             chan DataObject | ||||
| } | ||||
| 
 | ||||
| func (app *wasmApp) Finish() { | ||||
| 	app.session.close() | ||||
| } | ||||
| 
 | ||||
| func (app *wasmApp) startSession(this js.Value, args []js.Value) interface{} { | ||||
| 	if app.createContentFunc == nil || len(args) == 1 { | ||||
| 		return nil | ||||
| 	} | ||||
| func wasmLog(text string) { | ||||
| 	js.Global().Call("log", text) | ||||
| } | ||||
| 
 | ||||
| 	params := ParseDataText(args[0].String()) | ||||
| 	session := newSession(app, 0, "", params) | ||||
| 	session.setBrige(make(chan DataObject), app.brige) | ||||
| 	if !session.setContent(app.createContentFunc(session), session) { | ||||
| 		return nil | ||||
| 	} | ||||
| func (app *wasmApp) handleMessage(this js.Value, args []js.Value) any { | ||||
| 	if len(args) > 0 { | ||||
| 		if obj := ParseDataText(args[0].String()); obj != nil { | ||||
| 			switch command := obj.Tag(); command { | ||||
| 			/* | ||||
| 						case "startSession": | ||||
| 							answer := "" | ||||
| 							if session, answer = app.startSession(obj, events, brige); session != nil { | ||||
| 								if !brige.writeMessage(answer) { | ||||
| 									return | ||||
| 								} | ||||
| 								session.onStart() | ||||
| 								go sessionEventHandler(session, events, brige) | ||||
| 							} | ||||
| 
 | ||||
| 	app.session = session | ||||
| 						case "reconnect": | ||||
| 							if sessionText, ok := obj.PropertyValue("session"); ok { | ||||
| 								if sessionID, err := strconv.Atoi(sessionText); err == nil { | ||||
| 									if session = app.sessions[sessionID]; session != nil { | ||||
| 										session.setBrige(events, brige) | ||||
| 										answer := allocStringBuilder() | ||||
| 										defer freeStringBuilder(answer) | ||||
| 
 | ||||
| 	answer := allocStringBuilder() | ||||
| 	defer freeStringBuilder(answer) | ||||
| 										session.writeInitScript(answer) | ||||
| 										if !brige.writeMessage(answer.String()) { | ||||
| 											return | ||||
| 										} | ||||
| 										session.onReconnect() | ||||
| 										go sessionEventHandler(session, events, brige) | ||||
| 										return | ||||
| 									} | ||||
| 									DebugLogF("Session #%d not exists", sessionID) | ||||
| 								} else { | ||||
| 									ErrorLog(`strconv.Atoi(sessionText) error: ` + err.Error()) | ||||
| 								} | ||||
| 							} else { | ||||
| 								ErrorLog(`"session" key not found`) | ||||
| 							} | ||||
| 
 | ||||
| 	session.writeInitScript(answer) | ||||
| 	answerText := answer.String() | ||||
| 							answer := "" | ||||
| 							if session, answer = app.startSession(obj, events, brige); session != nil { | ||||
| 								if !brige.writeMessage(answer) { | ||||
| 									return | ||||
| 								} | ||||
| 								session.onStart() | ||||
| 								go sessionEventHandler(session, events, brige) | ||||
| 							} | ||||
| 
 | ||||
| 	if ProtocolInDebugLog { | ||||
| 		DebugLog("Start session:") | ||||
| 		DebugLog(answerText) | ||||
| 									case "disconnect": | ||||
| 					session.onDisconnect() | ||||
| 					return | ||||
| 
 | ||||
| 				case "session-close": | ||||
| 					session.onFinish() | ||||
| 					session.App().removeSession(session.ID()) | ||||
| 					brige.close() | ||||
| 
 | ||||
| 			*/ | ||||
| 			case "answer": | ||||
| 				app.session.handleAnswer(obj) | ||||
| 
 | ||||
| 			case "imageLoaded": | ||||
| 				app.session.imageManager().imageLoaded(obj, app.session) | ||||
| 
 | ||||
| 			case "imageError": | ||||
| 				app.session.imageManager().imageLoadError(obj, app.session) | ||||
| 
 | ||||
| 			default: | ||||
| 				app.session.handleEvent(command, obj) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | @ -51,117 +105,75 @@ func (app *wasmApp) startSession(this js.Value, args []js.Value) interface{} { | |||
| func (app *wasmApp) removeSession(id int) { | ||||
| } | ||||
| 
 | ||||
| func (app *wasmApp) createSession() Session { | ||||
| 	session := newSession(app, 0, "", ParseDataText(js.Global().Call("sessionInfo", "").String())) | ||||
| 	session.setBrige(app.close, app.brige) | ||||
| 	session.setContent(app.createContentFunc(session)) | ||||
| 	return session | ||||
| } | ||||
| 
 | ||||
| func (app *wasmApp) init() { | ||||
| 
 | ||||
| 	document := js.Global().Get("document") | ||||
| 	body := document.Call("querySelector", "body") | ||||
| 
 | ||||
| 	script := document.Call("createElement", "script") | ||||
| 	script.Set("type", "text/javascript") | ||||
| 	script.Set("textContent", defaultScripts+wasmScripts) | ||||
| 	body.Call("appendChild", script) | ||||
| 
 | ||||
| 	js.Global().Set("sendMessage", js.FuncOf(app.handleMessage)) | ||||
| 
 | ||||
| 	app.close = make(chan DataObject) | ||||
| 	app.session = app.createSession() | ||||
| 
 | ||||
| 	style := document.Call("createElement", "style") | ||||
| 	css := appStyles + app.session.getCurrentTheme().cssText(app.session) | ||||
| 	css = strings.ReplaceAll(css, `\n`, "\n") | ||||
| 	css = strings.ReplaceAll(css, `\t`, "\t") | ||||
| 	style.Set("textContent", css) | ||||
| 	document.Call("querySelector", "head").Call("appendChild", style) | ||||
| 
 | ||||
| 	buffer := allocStringBuilder() | ||||
| 	defer freeStringBuilder(buffer) | ||||
| 
 | ||||
| 	div := document.Call("createElement", "div") | ||||
| 	div.Set("className", "ruiRoot") | ||||
| 	div.Set("id", "ruiRootView") | ||||
| 	viewHTML(app.session.RootView(), buffer) | ||||
| 	div.Set("innerHTML", buffer.String()) | ||||
| 	body.Call("appendChild", div) | ||||
| 
 | ||||
| 	div = document.Call("createElement", "div") | ||||
| 	div.Set("className", "ruiPopupLayer") | ||||
| 	div.Set("id", "ruiPopupLayer") | ||||
| 	div.Set("onclick", "clickOutsidePopup(event)") | ||||
| 	div.Set("style", "visibility: hidden;") | ||||
| 	body.Call("appendChild", div) | ||||
| 
 | ||||
| 	div = document.Call("createElement", "a") | ||||
| 	div.Set("id", "ruiDownloader") | ||||
| 	div.Set("download", "") | ||||
| 	div.Set("style", "display: none;") | ||||
| 	body.Call("appendChild", div) | ||||
| } | ||||
| 
 | ||||
| // StartApp - create the new wasmApp and start it
 | ||||
| func StartApp(addr string, createContentFunc func(Session) SessionContent, params AppParams) { | ||||
| 	app := new(wasmApp) | ||||
| 	app.params = params | ||||
| 	app.createContentFunc = createContentFunc | ||||
| 	SetDebugLog(wasmLog) | ||||
| 	SetErrorLog(wasmLog) | ||||
| 
 | ||||
| 	if createContentFunc == nil { | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	app := new(wasmApp) | ||||
| 	app.params = params | ||||
| 	app.createContentFunc = createContentFunc | ||||
| 	app.brige = createWasmBrige() | ||||
| 	js.Global().Set("startSession", js.FuncOf(app.startSession)) | ||||
| 
 | ||||
| 	/* | ||||
| 		script := defaultScripts + wasmScripts | ||||
| 		script = strings.ReplaceAll(script, "\\", `\\`) | ||||
| 		script = strings.ReplaceAll(script, "\n", `\n`) | ||||
| 		script = strings.ReplaceAll(script, "\t", `\t`) | ||||
| 		script = strings.ReplaceAll(script, "\"", `\"`) | ||||
| 		script = strings.ReplaceAll(script, "'", `\'`) | ||||
| 
 | ||||
| 		js.Global().Call("execScript", `document.getElementById('ruiscript').text += "`+script+`"`) | ||||
| 	*/ | ||||
| 
 | ||||
| 	document := js.Global().Get("document") | ||||
| 	body := document.Call("querySelector", "body") | ||||
| 	body.Set("innerHTML", `<div class="ruiRoot" id="ruiRootView"></div> | ||||
| <div class="ruiPopupLayer" id="ruiPopupLayer" style="visibility: hidden;" onclick="clickOutsidePopup(event)"></div> | ||||
| <a id="ruiDownloader" download style="display: none;"></a>`) | ||||
| 
 | ||||
| 	//js.Global().Call("execScript", "initSession()")
 | ||||
| 	js.Global().Call("initSession", "") | ||||
| 	//window.Call("execScript", "initSession()")
 | ||||
| 
 | ||||
| 	for true { | ||||
| 		if message, ok := app.brige.readMessage(); ok && app.session != nil { | ||||
| 			if ProtocolInDebugLog { | ||||
| 				DebugLog(message) | ||||
| 			} | ||||
| 
 | ||||
| 			if obj := ParseDataText(message); obj != nil { | ||||
| 				switch command := obj.Tag(); command { | ||||
| 				/* | ||||
| 							case "startSession": | ||||
| 								answer := "" | ||||
| 								if session, answer = app.startSession(obj, events, brige); session != nil { | ||||
| 									if !brige.writeMessage(answer) { | ||||
| 										return | ||||
| 									} | ||||
| 									session.onStart() | ||||
| 									go sessionEventHandler(session, events, brige) | ||||
| 								} | ||||
| 
 | ||||
| 							case "reconnect": | ||||
| 								if sessionText, ok := obj.PropertyValue("session"); ok { | ||||
| 									if sessionID, err := strconv.Atoi(sessionText); err == nil { | ||||
| 										if session = app.sessions[sessionID]; session != nil { | ||||
| 											session.setBrige(events, brige) | ||||
| 											answer := allocStringBuilder() | ||||
| 											defer freeStringBuilder(answer) | ||||
| 
 | ||||
| 											session.writeInitScript(answer) | ||||
| 											if !brige.writeMessage(answer.String()) { | ||||
| 												return | ||||
| 											} | ||||
| 											session.onReconnect() | ||||
| 											go sessionEventHandler(session, events, brige) | ||||
| 											return | ||||
| 										} | ||||
| 										DebugLogF("Session #%d not exists", sessionID) | ||||
| 									} else { | ||||
| 										ErrorLog(`strconv.Atoi(sessionText) error: ` + err.Error()) | ||||
| 									} | ||||
| 								} else { | ||||
| 									ErrorLog(`"session" key not found`) | ||||
| 								} | ||||
| 
 | ||||
| 								answer := "" | ||||
| 								if session, answer = app.startSession(obj, events, brige); session != nil { | ||||
| 									if !brige.writeMessage(answer) { | ||||
| 										return | ||||
| 									} | ||||
| 									session.onStart() | ||||
| 									go sessionEventHandler(session, events, brige) | ||||
| 								} | ||||
| 
 | ||||
| 										case "disconnect": | ||||
| 						session.onDisconnect() | ||||
| 						return | ||||
| 
 | ||||
| 					case "session-close": | ||||
| 						session.onFinish() | ||||
| 						session.App().removeSession(session.ID()) | ||||
| 						brige.close() | ||||
| 
 | ||||
| 				*/ | ||||
| 				case "answer": | ||||
| 					app.session.handleAnswer(obj) | ||||
| 
 | ||||
| 				case "imageLoaded": | ||||
| 					app.session.imageManager().imageLoaded(obj, app.session) | ||||
| 
 | ||||
| 				case "imageError": | ||||
| 					app.session.imageManager().imageLoadError(obj, app.session) | ||||
| 
 | ||||
| 				default: | ||||
| 					app.session.handleEvent(command, obj) | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	app.init() | ||||
| 	<-app.close | ||||
| } | ||||
| 
 | ||||
| func FinishApp() { | ||||
|  | @ -171,31 +183,3 @@ func FinishApp() { | |||
| func OpenBrowser(url string) bool { | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| func OpenBrowser(url string) bool { | ||||
| 	var err error | ||||
| 
 | ||||
| 	switch runtime.GOOS { | ||||
| 	case "linux": | ||||
| 		for _, provider := range []string{"xdg-open", "x-www-browser", "www-browser"} { | ||||
| 			if _, err = exec.LookPath(provider); err == nil { | ||||
| 				if exec.Command(provider, url).Start(); err == nil { | ||||
| 					return true | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	case "windows": | ||||
| 		err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start() | ||||
| 
 | ||||
| 	case "darwin": | ||||
| 		err = exec.Command("open", url).Start() | ||||
| 
 | ||||
| 	default: | ||||
| 		err = fmt.Errorf("unsupported platform") | ||||
| 	} | ||||
| 
 | ||||
| 	return err != nil | ||||
| } | ||||
| */ | ||||
|  |  | |||
|  | @ -14,6 +14,47 @@ window.onblur = function(event) { | |||
| 	sendMessage( "session-pause{session=" + sessionID +"}" ); | ||||
| } | ||||
| 
 | ||||
| function sessionInfo() { | ||||
| 
 | ||||
| 	const touch_screen = (('ontouchstart' in document.documentElement) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) ? "1" : "0"; | ||||
| 	var message = "startSession{touch=" + touch_screen  | ||||
| 	 | ||||
| 	const style = window.getComputedStyle(document.body); | ||||
| 	if (style) { | ||||
| 		var direction = style.getPropertyValue('direction'); | ||||
| 		if (direction) { | ||||
| 			message += ",direction=" + direction | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	const lang = window.navigator.language; | ||||
| 	if (lang) { | ||||
| 		message += ",language=\"" + lang + "\""; | ||||
| 	} | ||||
| 
 | ||||
| 	const langs = window.navigator.languages; | ||||
| 	if (langs) { | ||||
| 		message += ",languages=\"" + langs + "\""; | ||||
| 	} | ||||
| 
 | ||||
| 	const userAgent = window.navigator.userAgent | ||||
| 	if (userAgent) { | ||||
| 		message += ",user-agent=\"" + userAgent + "\""; | ||||
| 	} | ||||
| 
 | ||||
| 	const darkThemeMq = window.matchMedia("(prefers-color-scheme: dark)"); | ||||
| 	if (darkThemeMq.matches) { | ||||
| 		message += ",dark=1"; | ||||
| 	}  | ||||
| 
 | ||||
| 	const pixelRatio = window.devicePixelRatio; | ||||
| 	if (pixelRatio) { | ||||
| 		message += ",pixel-ratio=" + pixelRatio; | ||||
| 	} | ||||
| 
 | ||||
| 	return message + "}"; | ||||
| } | ||||
| 
 | ||||
| function getIntAttribute(element, tag) { | ||||
| 	let value = element.getAttribute(tag); | ||||
| 	if (value) { | ||||
|  | @ -1276,6 +1317,10 @@ function startDowndload(url, filename) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| function setTitle(title) { | ||||
| 	document.title = title; | ||||
| } | ||||
| 
 | ||||
| function setTitleColor(color) { | ||||
| 	var metas = document.getElementsByTagName('meta'); | ||||
| 	if (metas) { | ||||
|  | @ -1292,6 +1337,10 @@ function setTitleColor(color) { | |||
| 	document.getElementsByTagName('head')[0].appendChild(meta); | ||||
| } | ||||
| 
 | ||||
| function openURL(url) { | ||||
| 	window.open(url, "_blank"); | ||||
| } | ||||
| 
 | ||||
| function detailsEvent(element) { | ||||
| 	sendMessage("details-open{session=" + sessionID + ",id=" + element.id + ",open=" + (element.open ? "1}" : "0}")); | ||||
| } | ||||
|  | @ -1742,4 +1791,8 @@ function getPropertyValue(answerID, elementId, name) { | |||
| 	} | ||||
| 
 | ||||
| 	sendMessage('answer{answerID=' + answerID + ', value=""}') | ||||
| } | ||||
| 
 | ||||
| function appendStyles(styles) { | ||||
| 	document.querySelector('style').textContent += styles | ||||
| } | ||||
|  | @ -26,44 +26,7 @@ window.onload = function() { | |||
| }; | ||||
| 
 | ||||
| function socketOpen() { | ||||
| 
 | ||||
| 	const touch_screen = (('ontouchstart' in document.documentElement) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) ? "1" : "0"; | ||||
| 	var message = "startSession{touch=" + touch_screen  | ||||
| 	 | ||||
| 	const style = window.getComputedStyle(document.body); | ||||
| 	if (style) { | ||||
| 		var direction = style.getPropertyValue('direction'); | ||||
| 		if (direction) { | ||||
| 			message += ",direction=" + direction | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	const lang = window.navigator.language; | ||||
| 	if (lang) { | ||||
| 		message += ",language=\"" + lang + "\""; | ||||
| 	} | ||||
| 
 | ||||
| 	const langs = window.navigator.languages; | ||||
| 	if (langs) { | ||||
| 		message += ",languages=\"" + langs + "\""; | ||||
| 	} | ||||
| 
 | ||||
| 	const userAgent = window.navigator.userAgent | ||||
| 	if (userAgent) { | ||||
| 		message += ",user-agent=\"" + userAgent + "\""; | ||||
| 	} | ||||
| 
 | ||||
| 	const darkThemeMq = window.matchMedia("(prefers-color-scheme: dark)"); | ||||
| 	if (darkThemeMq.matches) { | ||||
| 		message += ",dark=1"; | ||||
| 	}  | ||||
| 
 | ||||
| 	const pixelRatio = window.devicePixelRatio; | ||||
| 	if (pixelRatio) { | ||||
| 		message += ",pixel-ratio=" + pixelRatio; | ||||
| 	} | ||||
| 
 | ||||
| 	sendMessage( message + "}" ); | ||||
| 	sendMessage( sessionInfo() ); | ||||
| } | ||||
| 
 | ||||
| function socketReopen() { | ||||
|  |  | |||
							
								
								
									
										43
									
								
								app_wasm.js
								
								
								
								
							
							
						
						
									
										43
									
								
								app_wasm.js
								
								
								
								
							|  | @ -1,47 +1,8 @@ | |||
| 
 | ||||
| 
 | ||||
| function initSession() { | ||||
| 
 | ||||
| 	const touch_screen = (('ontouchstart' in document.documentElement) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)) ? "1" : "0"; | ||||
| 	var message = "sessionInfo{touch=" + touch_screen  | ||||
| 	 | ||||
| 	const style = window.getComputedStyle(document.body); | ||||
| 	if (style) { | ||||
| 		var direction = style.getPropertyValue('direction'); | ||||
| 		if (direction) { | ||||
| 			message += ",direction=" + direction | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	const lang = window.navigator.language; | ||||
| 	if (lang) { | ||||
| 		message += ",language=\"" + lang + "\""; | ||||
| 	} | ||||
| 
 | ||||
| 	const langs = window.navigator.languages; | ||||
| 	if (langs) { | ||||
| 		message += ",languages=\"" + langs + "\""; | ||||
| 	} | ||||
| 
 | ||||
| 	const userAgent = window.navigator.userAgent | ||||
| 	if (userAgent) { | ||||
| 		message += ",user-agent=\"" + userAgent + "\""; | ||||
| 	} | ||||
| 
 | ||||
| 	const darkThemeMq = window.matchMedia("(prefers-color-scheme: dark)"); | ||||
| 	if (darkThemeMq.matches) { | ||||
| 		message += ",dark=1"; | ||||
| 	}  | ||||
| 
 | ||||
| 	const pixelRatio = window.devicePixelRatio; | ||||
| 	if (pixelRatio) { | ||||
| 		message += ",pixel-ratio=" + pixelRatio; | ||||
| 	} | ||||
| 
 | ||||
| 	startSession( message + "}" ); | ||||
| function log(s) { | ||||
| 	console.log(s); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| window.onfocus = function(event) { | ||||
| 	windowFocus = true | ||||
| 	sendMessage( "session-resume{session=" + sessionID +"}" ); | ||||
|  |  | |||
|  | @ -2,7 +2,6 @@ package rui | |||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"math/rand" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
|  | @ -24,7 +23,7 @@ func (session *sessionData) startDownload(file downloadFile) { | |||
| 	currentDownloadId++ | ||||
| 	id := strconv.Itoa(currentDownloadId) | ||||
| 	downloadFiles[id] = file | ||||
| 	session.runScript(fmt.Sprintf(`startDowndload("%s", "%s")`, id, file.filename)) | ||||
| 	session.runFunc("startDowndload", id, file.filename) | ||||
| } | ||||
| 
 | ||||
| func serveDownloadFile(id string, w http.ResponseWriter, r *http.Request) bool { | ||||
|  |  | |||
							
								
								
									
										13
									
								
								session.go
								
								
								
								
							
							
						
						
									
										13
									
								
								session.go
								
								
								
								
							|  | @ -67,7 +67,7 @@ type Session interface { | |||
| 
 | ||||
| 	// Content returns the SessionContent of session
 | ||||
| 	Content() SessionContent | ||||
| 	setContent(content SessionContent, self Session) bool | ||||
| 	setContent(content SessionContent) bool | ||||
| 
 | ||||
| 	// SetTitle sets the text of the browser title/tab
 | ||||
| 	SetTitle(title string) | ||||
|  | @ -91,6 +91,7 @@ type Session interface { | |||
| 	// OpenURL opens the url in the new browser tab
 | ||||
| 	OpenURL(url string) | ||||
| 
 | ||||
| 	getCurrentTheme() Theme | ||||
| 	registerAnimation(props []AnimatedProperty) string | ||||
| 
 | ||||
| 	resolveConstants(value string) (string, bool) | ||||
|  | @ -245,10 +246,10 @@ func (session *sessionData) Content() SessionContent { | |||
| 	return session.content | ||||
| } | ||||
| 
 | ||||
| func (session *sessionData) setContent(content SessionContent, self Session) bool { | ||||
| func (session *sessionData) setContent(content SessionContent) bool { | ||||
| 	if content != nil { | ||||
| 		session.content = content | ||||
| 		session.rootView = content.CreateRootView(self) | ||||
| 		session.rootView = content.CreateRootView(session) | ||||
| 		if session.rootView != nil { | ||||
| 			session.rootView.setParentID("ruiRootView") | ||||
| 			return true | ||||
|  | @ -554,11 +555,11 @@ func (session *sessionData) handleEvent(command string, data DataObject) { | |||
| 
 | ||||
| func (session *sessionData) SetTitle(title string) { | ||||
| 	title, _ = session.GetString(title) | ||||
| 	session.runScript(`document.title = "` + title + `";`) | ||||
| 	session.runFunc("setTitle", title) | ||||
| } | ||||
| 
 | ||||
| func (session *sessionData) SetTitleColor(color Color) { | ||||
| 	session.runScript(`setTitleColor("` + color.cssString() + `");`) | ||||
| 	session.runFunc("setTitleColor", color.cssString()) | ||||
| } | ||||
| 
 | ||||
| func (session *sessionData) RemoteAddr() string { | ||||
|  | @ -570,5 +571,5 @@ func (session *sessionData) OpenURL(urlStr string) { | |||
| 		ErrorLog(err.Error()) | ||||
| 		return | ||||
| 	} | ||||
| 	session.runScript(`window.open("` + urlStr + `", "_blank");`) | ||||
| 	session.runFunc("openURL", urlStr) | ||||
| } | ||||
|  |  | |||
|  | @ -325,15 +325,16 @@ func (session *sessionData) SetLanguage(lang string) { | |||
| 	if lang != session.language { | ||||
| 		session.language = lang | ||||
| 
 | ||||
| 		if session.rootView != nil { | ||||
| 		if session.rootView != nil && session.brige != nil { | ||||
| 			buffer := allocStringBuilder() | ||||
| 			defer freeStringBuilder(buffer) | ||||
| 
 | ||||
| 			buffer.WriteString(`document.getElementById('ruiRootView').innerHTML = '`) | ||||
| 			//buffer.WriteString(`document.getElementById('ruiRootView').innerHTML = '`)
 | ||||
| 			viewHTML(session.rootView, buffer) | ||||
| 			buffer.WriteString("';\nscanElementsSize();") | ||||
| 			//buffer.WriteString("';\nscanElementsSize();")
 | ||||
| 
 | ||||
| 			session.runScript(buffer.String()) | ||||
| 			//session.runScript(buffer.String())
 | ||||
| 			session.brige.updateInnerHTML("ruiRootView", buffer.String()) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
							
								
								
									
										98
									
								
								wasmBrige.go
								
								
								
								
							
							
						
						
									
										98
									
								
								wasmBrige.go
								
								
								
								
							|  | @ -3,11 +3,10 @@ | |||
| package rui | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 	"sync" | ||||
| 	"syscall/js" | ||||
| 
 | ||||
| 	"github.com/gorilla/websocket" | ||||
| ) | ||||
| 
 | ||||
| type wasmBrige struct { | ||||
|  | @ -18,11 +17,6 @@ type wasmBrige struct { | |||
| 	closed      bool | ||||
| } | ||||
| 
 | ||||
| var upgrader = websocket.Upgrader{ | ||||
| 	ReadBufferSize:  1024, | ||||
| 	WriteBufferSize: 8096, | ||||
| } | ||||
| 
 | ||||
| func createWasmBrige() webBrige { | ||||
| 	brige := new(wasmBrige) | ||||
| 	brige.queue = make(chan string, 1000) | ||||
|  | @ -30,23 +24,58 @@ func createWasmBrige() webBrige { | |||
| 	brige.answer = make(map[int]chan DataObject) | ||||
| 	brige.closed = false | ||||
| 
 | ||||
| 	js.Global().Set("sendMessage", js.FuncOf(brige.sendMessage)) | ||||
| 
 | ||||
| 	return brige | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) sendMessage(this js.Value, args []js.Value) interface{} { | ||||
| 	if len(args) > 0 { | ||||
| 		brige.queue <- args[0].String() | ||||
| func (brige *wasmBrige) startUpdateScript(htmlID string) bool { | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) finishUpdateScript(htmlID string) { | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) runFunc(funcName string, args ...any) bool { | ||||
| 	if ProtocolInDebugLog { | ||||
| 		text := funcName + "(" | ||||
| 		for i, arg := range args { | ||||
| 			if i > 0 { | ||||
| 				text += fmt.Sprintf(", `%v`", arg) | ||||
| 			} else { | ||||
| 				text += fmt.Sprintf("`%v`", arg) | ||||
| 			} | ||||
| 		} | ||||
| 		DebugLog(text + ")") | ||||
| 	} | ||||
| 	return nil | ||||
| 
 | ||||
| 	js.Global().Call(funcName, args...) | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) updateInnerHTML(htmlID, html string) { | ||||
| 	brige.runFunc("updateInnerHTML", htmlID, html) | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) appendToInnerHTML(htmlID, html string) { | ||||
| 	brige.runFunc("appendToInnerHTML", htmlID, html) | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) updateCSSProperty(htmlID, property, value string) { | ||||
| 	brige.runFunc("updateCSSProperty", htmlID, property, value) | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) updateProperty(htmlID, property string, value any) { | ||||
| 	brige.runFunc("updateProperty", htmlID, property, value) | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) removeProperty(htmlID, property string) { | ||||
| 	brige.runFunc("removeProperty", htmlID, property) | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) close() { | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) readMessage() (string, bool) { | ||||
| 	return <-brige.queue, true | ||||
| 	return "", false | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) writeMessage(script string) bool { | ||||
|  | @ -61,25 +90,36 @@ func (brige *wasmBrige) writeMessage(script string) bool { | |||
| 	return true | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) runGetterScript(script string) DataObject { | ||||
| 	brige.answerMutex.Lock() | ||||
| 	answerID := brige.answerID | ||||
| 	brige.answerID++ | ||||
| 	brige.answerMutex.Unlock() | ||||
| /* | ||||
| 	func (brige *wasmBrige) runGetterScript(script string) DataObject { | ||||
| 		brige.answerMutex.Lock() | ||||
| 		answerID := brige.answerID | ||||
| 		brige.answerID++ | ||||
| 		brige.answerMutex.Unlock() | ||||
| 
 | ||||
| 	answer := make(chan DataObject) | ||||
| 	brige.answer[answerID] = answer | ||||
| 	errorText := "" | ||||
| 		answer := make(chan DataObject) | ||||
| 		brige.answer[answerID] = answer | ||||
| 		errorText := "" | ||||
| 
 | ||||
| 	js.Global().Set("answerID", strconv.Itoa(answerID)) | ||||
| 		js.Global().Set("answerID", strconv.Itoa(answerID)) | ||||
| 
 | ||||
| 	window := js.Global().Get("window") | ||||
| 	window.Call("execScript", script) | ||||
| 		window := js.Global().Get("window") | ||||
| 		window.Call("execScript", script) | ||||
| 
 | ||||
| 	result := NewDataObject("error") | ||||
| 	result.SetPropertyValue("text", errorText) | ||||
| 	delete(brige.answer, answerID) | ||||
| 	return result | ||||
| 		result := NewDataObject("error") | ||||
| 		result.SetPropertyValue("text", errorText) | ||||
| 		delete(brige.answer, answerID) | ||||
| 		return result | ||||
| 	} | ||||
| */ | ||||
| 
 | ||||
| func (brige *wasmBrige) canvasTextMetrics(htmlID, font, text string) TextMetrics { | ||||
| 	// TODO
 | ||||
| 	return TextMetrics{} | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) htmlPropertyValue(htmlID, name string) string { | ||||
| 	return "" | ||||
| } | ||||
| 
 | ||||
| func (brige *wasmBrige) answerReceived(answer DataObject) { | ||||
|  |  | |||
|  | @ -175,7 +175,6 @@ func (brige *wsBrige) updateCSSProperty(htmlID, property, value string) { | |||
| 	} else { | ||||
| 		brige.runFunc("updateCSSProperty", htmlID, property, value) | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func (brige *wsBrige) updateProperty(htmlID, property string, value any) { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue