var bricks = window.bricks || {}; bricks.get_current_language=function(){ var lang = navigator.language.substring(0, 2); if (bricks.app){ if (bricks.app.lang) return bricks.app.lang; bricks.app.lang = lang; return lang; } return; } bricks.app = null; /* all type of bind action's desc has the following attributes: actiontype:'bricks', wid: event: target: datawidget: datascript: datamethod: datakwargs: rtdata: conform: and each type of binds specified attributes list following urlwidget action: mode:, options:{ method: params:{}, url: } bricks action: mode:, options:{ "widgettype":"gg", ... } method action: method: params: for methods kwargs script action: script: params: registerfunction action: rfname: params: event action: dispatch_event: params: */ bricks.uuid = function(){ try{ var d = crypto.randomUUID(); var lst = d.split('-'); return lst.join(''); } catch(e) { const vv = '1234567890qwertyuiopasdfghjklzxcvbnm'; var ret = ''; for (var i=0;i<30;i++){ var j = parseInt(Math.random() * vv.length); ret = ret + vv[j]; } console.log('uuid() return', ret); return ret; } } bricks.deviceid = function(appname){ var deviceid = appname + 'deviceid'; var id = localStorage.getItem(deviceid); if (!id){ id = bricks.uuid(); localStorage.setItem(deviceid, id); } return id; } bricks.str2data = function(s, d){ /* fmt like 'my name is ${name}, ${age:type}' type can be: int, str, json */ funcs = { 'json':JSON.stringify } var regex = /\${(\w+)(?::(int|str|json))?}/; var match = s.match(regex) if (match){ var key = match[1]; var typ = match[2]; var ss = '${' + key; if (typ != ''){ ss += ':' + typ; } ss += '}'; if (s == ss){ if (!d.hasOwnProperty(key)){ return null; } if (typ == ''){ return d[key]; } var f = funcs[typ]; if (f){ return f(d[key]); } return d[key]; } return s.replace(regex, (k, key, typ) => { if (d.hasOwnProperty(key)){ var f = funcs[typ]; if (f){ return f(d[key]); } return d[key]; } return ''; }); } return s; } bricks.apply_data = function(desc, data){ if (bricks.is_empty(data)){ return desc; } var tmpl = JSON.stringify(desc); var s = bricks.obj_fmtstr(data, tmpl); return JSON.parse(s); } bricks.widgetBuild = async function(desc, widget, data){ if (! widget){ widget = bricks.Body; } var klassname = desc.widgettype; var base_url = widget.baseURI; while (klassname == 'urlwidget'){ if (data){ desc = bricks.apply_data(desc, data); } let url = bricks.absurl(desc.options.url, widget); base_url = url; let method = desc.options.method || 'GET'; let opts = desc.options.params || {}; var jc = new bricks.HttpJson(); var desc1 = await jc.httpcall(url, { "method":method, "params":opts}); if (!desc1) return; desc = desc1; klassname = desc.widgettype; } if (data){ desc = bricks.apply_data(desc, data); } if (!desc.widgettype){ console.log('widgettype is null', desc); return null; } let klass = bricks.Factory.get(desc.widgettype); if (! klass){ console.log('widgetBuild():', desc.widgettype, 'not registered', bricks.Factory.widgets_kw); return null; } var options = desc.options || {}; options.baseURI = base_url; let w = new klass(options); if (! w){ console.log('w is null'); } if (desc.id){ w.set_id(desc.id); } if (w.is_container() && desc.subwidgets){ for (let i=0; i{ if (bricks.Factory.isWidgetType(c, typename)) return c; var sc = get_by_typename(typename, c, downward); if (sc) return sc; }); console.log('get_by_typename() return null,', typename, fromw, downward) return null; } var p = fromw.parent; if (! p) { console.log('get_by_typename() return null,', typename, fromw, downward) return null; } if (bricks.Factory.isWidgetType(p, typename)) return p; return get_by_typename(p, typename, downward); }; if (!idset) { return from_widget; } const parts = idset.split('.', 2); var downward = true; var typename = ''; var id = parts[0]; var w; if (id.startsWith('-')){ downward = false; id = id.substring(1); } if (id.startsWith('@')){ typename = id.substring(1); } if (typename != ''){ w = get_by_typename(typename, from_widget, downward); } else { w = get_by_id(id, from_widget, downward); } if (!w) return null; if (!parts[1]){ console.log('idset=',idset, 'id=', id, w); } return bricks.getWidgetById(parts[1], w); } bricks.getWidgetByIdOld = function(id, from_widget){ if (!from_widget){ from_widget = bricks.Body; } if (! id){ return from_widget; } if (typeof(id) != 'string') return id; var ids = id.split('.'); var el = from_widget.dom_element; var new_el = null; var j = 0; for (var i=0; i< ids.length; i++){ if (i == 0){ if (ids[i] == 'self'){ el = from_widget.dom_element; continue; } if (ids[i]=='root'){ el = bricks.app.root.dom_element; continue; } if (ids[i]=='app' || ids[i] == 'body'){ return bricks.app; } if (ids[i] == 'window'){ el = bricks.Body.dom_element; continue; } } try { if (ids[i][0] == '-'){ var wid = substr(1, ids[i].length - 1) new_el = el.closest('#' + wid); } else { new_el = el.querySelector('#' + ids[i]); } } catch(err){ bricks.debug('getWidgetById():i=', ids[i], id, 'not found', err); return null; } if ( new_el == null ){ bricks.debug('getWidgetById():', id, from_widget, 'el=', el, 'id=', ids[i]); return null; } el = new_el; } if (typeof(el.bricks_widget) !== 'undefined'){ return el.bricks_widget; } bricks.debug('********', id, 'el=', el, 'found, but not a bricks class with dom element'); return el; } bricks.App = class extends bricks.Layout { constructor(opts){ /* opts = { appname: debug:false, true, 'server' login_url: "charsize: "language": "i18n":{ "url":'rrr', "default_lang":'en' }, "widget":{ "widgettype":"Text", "options":{ } } } */ super(opts); bricks.app = this; this.docks = []; bricks.bug = opts.debug || false; bricks.Body = this; this.deviceid = bricks.deviceid(opts.appname || 'appname'); this.login_url = opts.login_url || '/rbac/userpassword_login.ui'; this.charsize = this.opts.charsize || 20; this.keyevent_blocked = false; this.char_size = this.observable('charsize', this.charsize); if (this.opts.language){ this.lang = this.opts.language; } else { this.lang = navigator.language.substring(0,2); } this.lang_x = this.observable('lang', this.lang); this.zindex = 10000; this.textList = []; var i18n_opts = opts.i18n || { url:'/i18n_getmsgs', i18n_path: 'i18n', lang:this.lang }; this.i18n = new bricks.I18n(i18n_opts); this.session_id = null; this.tooltip = new bricks.Tooltip({otext:'',i18n:true, wrap:true}); this.tooltip.hide(); this.add_widget(this.tooltip); this._Width = this.dom_element.offsetWidth; this._Height = this.dom_element.offsetHeight; this.video_stream = null; this.audio_stream = null; this.video_devices = null this.vpos = null; document.addEventListener('keydown', this.key_down_action.bind(this)); this.screen_orient = window.screen.orientation.type; window.screen.orientation.addEventListener('change', () => { this.screen_orient = window.screen.orientation.type; this.bind('orient_changed', this.screen_orient); }); this.mwins = []; this.wins_panel = null; } show_windows_panel(event){ console.log('event=', event); event.preventDefault(); event.stopPropagation() var opts = bricks.get_popup_default_options(); opts.auto_open = false; this.wins_panel = new bricks.WindowsPanel(opts); this.wins_panel.open(); } get_color(){ return getComputedStyle(this.dom_element).color; return parseRGB(colorStr); } get_bgcolor(){ return getComputedStyle(this.dom_element).backgroundColor; return parseRGB(colorStr); } get_blinkcolor(){ var color, bgcolor, blinkcolor; color = parseRGB(this.get_color()); bgcolor = parseRGB(this.get_bgcolor()); console.log('color=', color, 'bgcolor=', bgcolor); function short1of3(x, y){ if (x < y) { return x + (y - x) / 3; } else { return x - (x - y) / 3; } } var r = short1of3(color.r, bgcolor.r); var g = short1of3(color.g, bgcolor.g); var b = short1of3(color.b, bgcolor.b); var bc = bricks.obj_fmtstr({r:r, g:g, b:b}, "rgb(${r}, ${g}, ${b})"); console.log('color=', color, 'bgcolor=', bgcolor, 'bc=', bc); return bc; } async getCameras() { try { const devices = await navigator.mediaDevices.enumerateDevices(); this.video_devices = devices.filter(device => device.kind === 'videoinput'); } catch (error) { console.error('获取摄像头数量出错:', error); } } async start_media(opts){ /* opts: type:device or 'widget' widgetid: widget: audio:true, video:true vpos: */ } async stop_media(media_stream){ } async start_camera(vpos) { if (typeof(vpos) == 'undefined') vpos = 0; if (this.video_devices === null){ await this.getCameras(); } if (vpos == this.vpos) return; this.vpos = vpos; if (this.video_stream){ this.video_stream.getTracks().forEach(track => { track.stop(); }); } if (navigator.mediaDevices.getUserMedia) { var x = { deviceId: this.video_devices[vpos].deviceId }; this.video_stream = await navigator.mediaDevices.getUserMedia({ video: x }); } else { console.log("Webcam access is not supported in this browser."); } } async start_mic() { if (this.audio_stream) return; if (navigator.mediaDevices.getUserMedia) { this.audio_stream = navigator.mediaDevices.getUserMedia({ audio: true }); } else { console.log("mic access is not supported in this browser."); this.stream = null; } } new_zindex(){ const v = this.zindex; this.zindex = v + 1; return v; } screenHeight(){ return this.dom_element.clientHeight; } screenWidth(){ return this.dom_element.clientWidth; } create(){ this.dom_element = document.getElementsByTagName('body')[0]; this.set_baseURI(this.dom_element.baseURI); } save_session(session){ this.session_id = session; } get_session(){ return this.session_id; } async build(){ await this.i18n.change_lang(this.lang) var opts = bricks.extend({}, this.opts.widget); var w = await bricks.widgetBuild(opts, bricks.Body); if (!w){ bricks.debug('w=', w, 'Body=', bricks.Body, 'Factory=', bricks.Factory) } return w; } async run(){ await (this.change_language(this.lang)); var w = await this.build(); this.root = w; if (!w){ bricks.debug('w=', w, 'Body=', bricks.Body, 'Factory=', bricks.Factory) return null; } bricks.Body.add_widget(w); bricks.Body.down_level(); } textsize_bigger(){ this.charsize = this.charsize * 1.05; this.char_size.set(this.charsize); } textsize_smaller(){ this.charsize = this.charsize * 0.95; this.char_size.set(this.charsize); } text_resize(){ for (var i=0;i