1// 2// Serial Pro browser-terminal console device. 3// 4// This is deliberately separate from SPSERIAL. SPSERIAL remains the real 5// byte-oriented UART line. SPTERM:console carries human/operator/status text 6// that must never enter the 6551 receive stream. 7// 8 9function SerialProTerminalDevice() 10{ 11 var device = this; 12 var host = null; 13 var listeners = []; 14 15 this.id = { 16 "DCODE":"SPTERM" 17 ,"hostPCODE":"SPC" 18 ,"icon":"fa fa-terminal" 19 ,"description":"Serial Pro browser terminal console" 20 }; 21 22 this.ports = { 23 "console":{ 24 "direction":"duplex" 25 ,"mime":["text/plain; charset=utf-8"] 26 ,"handler":"receive" 27 ,"description":"Serial Pro terminal operator/status console" 28 } 29 }; 30 31 function normalizeText(message) 32 { 33 var data = message && message.data!==undefined 34 ? message.data 35 : message; 36 37 if(data===undefined || data===null) 38 return ""; 39 40 return String(data); 41 } 42 43 this.bindHost = function(card) 44 { 45 host = card || null; 46 47 if(host && 48 typeof(host.bindSerialTerminalConsoleDevice)=="function") 49 host.bindSerialTerminalConsoleDevice(device); 50 51 return !!host; 52 }; 53 54 /* 55 * Pipe -> browser terminal. This is UI/status text, not serial payload. 56 */ 57 this.receive = function(message,context) 58 { 59 var text = normalizeText(message); 60 if(!text.length || !host || 61 typeof(host.serialTerminalConsoleWrite)!="function") 62 return false; 63 64 host.serialTerminalConsoleWrite( 65 text, 66 { 67 "source":"pipe" 68 ,"context":context || null 69 } 70 ); 71 return text.length; 72 }; 73 74 this.receiveText = function(text,meta) 75 { 76 text = normalizeText(text); 77 if(!text.length || !host || 78 typeof(host.serialTerminalConsoleWrite)!="function") 79 return 0; 80 81 host.serialTerminalConsoleWrite(text,meta || {}); 82 return text.length; 83 }; 84 85 /* 86 * Browser-terminal console -> connected observers. The current oTERM input 87 * remains the serial-data input; this output side is reserved for future 88 * terminal control/diagnostic commands and generic pipeConnect(). 89 */ 90 this.subscribe = function(callback) 91 { 92 if(typeof(callback)!="function") 93 return function(){}; 94 95 if(listeners.indexOf(callback)<0) 96 listeners.push(callback); 97 98 var subscribed = true; 99 return function() 100 { 101 if(!subscribed) return; 102 subscribed = false; 103 104 var index = listeners.indexOf(callback); 105 if(index>=0) listeners.splice(index,1); 106 }; 107 }; 108 109 this.transmitText = function(text,meta) 110 { 111 text = normalizeText(text); 112 var snapshot = listeners.slice(); 113 114 for(var i=0;i<snapshot.length;i++) 115 { 116 try { snapshot[i](text,meta || {}); } 117 catch(error) 118 { 119 console.error("SPTERM console subscriber failed",error); 120 } 121 } 122 123 return text.length; 124 }; 125 126 this.reset = function() 127 { 128 // Browser/operator console remains present across Apple II RESET. 129 return true; 130 }; 131}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.