Skip to content

Commit b3bc366

Browse files
committed
feat: dynamic title (page title - site title - URL)
* src/js: * ansi_parser.js * import b2u for converting site title * add AnsiParser.STATE_OSC (4) * AnsiParser.feed() * add case handling for sequence "OSC 2 ; Pt ST/BEL" (Change Window Title to Pt) for site title * term_buf.js * TermBuf() * add attrs titleBase & titleSite & titleConn & title for building dynamic title * add and use TermBuf.setTitle() for updating window title * ansi_parser.js AnsiParser.feed() * pttchrome.js * App() 'focus' event * App.onConnect() * use TermBuf.title for getting the title instead * term_view.js TermView.titleTimer() * pttchrome.js App() 'focus' event
1 parent 5fe32e6 commit b3bc366

File tree

4 files changed

+73
-3
lines changed

4 files changed

+73
-3
lines changed

src/js/ansi_parser.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// Parser for ANSI escape sequence
22

3+
import { b2u } from './string_util';
4+
35
export function AnsiParser(termbuf) {
46
this.termbuf = termbuf;
57
this.state = AnsiParser.STATE_TEXT;
@@ -10,6 +12,7 @@ AnsiParser.STATE_TEXT = 0;
1012
AnsiParser.STATE_ESC = 1;
1113
AnsiParser.STATE_CSI = 2;
1214
AnsiParser.STATE_C1 = 3;
15+
AnsiParser.STATE_OSC = 4;
1316

1417
AnsiParser.prototype.feed = function(data) {
1518
var term = this.termbuf;
@@ -217,6 +220,49 @@ AnsiParser.prototype.feed = function(data) {
217220
this.esc += ch;
218221
}
219222
break;
223+
case AnsiParser.STATE_OSC:
224+
if (ch == '\\' && this.esc[this.esc.length - 1] == '\x1b') {
225+
// ST = ESC \
226+
this.esc.pop();
227+
ch = '\x07';
228+
}
229+
if (ch == '\x07') {
230+
var params=this.esc.split(';');
231+
var firstChar = '';
232+
if (params[0] && (params[0].charAt(0)<'0' || params[0].charAt(0)>'9')) {
233+
if (firstChar) { // unknown OSC
234+
//dump('unknown OSC: ' + this.esc + ch + '\n');
235+
this.state = AnsiParser.STATE_TEXT;
236+
this.esc = '';
237+
break;
238+
}
239+
}
240+
for (var j=0; j<params.length - 1; ++j) {
241+
if ( params[j] )
242+
params[j] = parseInt(params[j], 10);
243+
else
244+
params[j] = 0;
245+
}
246+
switch (params[0]) {
247+
case 2:
248+
if (params[1] == '?')
249+
; // elicits a response; not implemented
250+
else {
251+
let title = params[1];
252+
if (this.termbuf.view.charset != 'UTF-8')
253+
title = b2u(title);
254+
this.termbuf.setTitle({site: title});
255+
}
256+
break;
257+
default:
258+
//dump('unknown OSC: ' + this.esc + ch + '\n');
259+
}
260+
this.state = AnsiParser.STATE_TEXT;
261+
this.esc = '';
262+
} else {
263+
this.esc += ch;
264+
}
265+
break;
220266
case AnsiParser.STATE_C1:
221267
var C1_End = true;
222268
var C1_Char = [' ', '#', '%', '(', ')', '*', '+', '-', '.', '/'];
@@ -269,6 +315,8 @@ AnsiParser.prototype.feed = function(data) {
269315
case AnsiParser.STATE_ESC:
270316
if (ch == '[')
271317
this.state=AnsiParser.STATE_CSI;
318+
else if (ch == ']')
319+
this.state=AnsiParser.STATE_OSC;
272320
else {
273321
this.state=AnsiParser.STATE_C1;
274322
--i;

src/js/pttchrome.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export const App = function() {
115115
if (self.view.titleTimer) {
116116
self.view.titleTimer.cancel();
117117
self.view.titleTimer = null;
118-
document.title = self.connectedUrl.site;
118+
self.view.buf.setTitle();
119119
self.view.notif.close();
120120
}
121121
}, false);
@@ -234,6 +234,7 @@ App.prototype.onConnect = function() {
234234
console.info("pttchrome onConnect");
235235
this.connectState = 1;
236236
this.updateTabIcon('connect');
237+
this.view.buf.setTitle({conn: this.connectedUrl.site}),
237238
this.idleTime = 0;
238239
var self = this;
239240
this.timerEverySec = setTimer(true, function() {

src/js/term_buf.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,10 @@ export function TermBuf(cols, rows) {
257257
//this.keyWordLine[rows]=false;
258258
}
259259
this.BBSWin = document.getElementById('BBSWindow');
260+
this.titleBase = process.env.PTTCHROME_PAGE_TITLE;
261+
this.titleSite = null;
262+
this.titleConn = null;
263+
document.title = this.title = this.titleBase;
260264
}
261265

262266
TermBuf.prototype = {
@@ -1201,6 +1205,23 @@ TermBuf.prototype = {
12011205
clearHighlight: function(){
12021206
this.nowHighlight = -1;
12031207
this.mouseCursor = 0;
1208+
},
1209+
1210+
setTitle: function(part) {
1211+
if (part.site !== undefined) {
1212+
this.titleSite = part.site;
1213+
}
1214+
if (part.conn !== undefined) {
1215+
this.titleConn = part.conn;
1216+
}
1217+
let title = this.titleBase;
1218+
if (this.titleSite) {
1219+
title += ' - ' + this.titleSite;
1220+
}
1221+
if (this.titleConn) {
1222+
title += ' - ' + this.titleConn;
1223+
}
1224+
document.title = this.title = title;
12041225
}
12051226
};
12061227

src/js/term_view.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -727,10 +727,10 @@ TermView.prototype = {
727727
this.titleTimer = null;
728728
}
729729
this.titleTimer = setTimer(true, function() {
730-
if (document.title == app.connectedUrl.site) {
730+
if (document.title == this.buf.title) {
731731
document.title = title + ' ' + app.waterball.message;
732732
} else {
733-
document.title = app.connectedUrl.site;
733+
document.title = this.buf.title;
734734
}
735735
}, 1500);
736736
var options = {

0 commit comments

Comments
 (0)