-
-
Notifications
You must be signed in to change notification settings - Fork 576
[enhancement] - Don't clear terminal on resize #148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Can you show code (or demo) where you use the terminal? And what is PJAX? |
Hey Jakob, Sorry to lag on this! I built you a demo of PJAX working with terminal, but it clears when you resize the window. PJAX is this: It's a great way of using HTML5 pushState tech to have no page loads, but have deep linkable URL's. If you send me your email address, I can show you the development site that I have this tech working on for one of our clients. It's a super advanced version of Terminal using PJAX. My email is drew@funkhaus.us. Thanks! |
You're not using terminal and Pjax as it should be used. As for terminal use api provided. As for History API I sugest differnt library that alow for callbacks. Also in your code you don't have full change on back button only url and image change the command entered stay the same. In order to have proper state you need to use export_view / import_view functions. Here is the code I've came up with (that use HTML5-History-API library which is just a polyfill so it use raw HistoryAPI) $(function() {
var save_state = [];
var terminal = $('#term').terminal(function(command, term) {
var cmd = $.terminal.splitCommand(command);
if (cmd.name == 'open') {
term.pause();
$.get(cmd.args[0], function(result) {
term.echo(result, {raw:true}).resume();
save_state.push(term.export_view());
history.pushState(save_state.length-1, null, cmd.args[0]);
}, 'text');
} else {
// store all other commands
save_state.push(term.export_view());
history.pushState(save_state.length-1, null, '/' + cmd.name + '/' + cmd.args.join('/'));
}
});
save_state.push(terminal.export_view());
$(window).on('popstate', function(e) {
if (save_state.length) {
terminal.import_view(save_state[history.state || 0]);
}
});
$('.links a').click(function(e) {
terminal.exec('open "' + $(this).attr('href') + '"');
return false;
});
});
|
I can add this to the terminal, it can store state just before next command be executed and it can store urls based on user function: $('...').terminal(function(cmd, term) {
}, {
historyState: true,
historyStateUrlMapper: function(command) {
// whatever that function return, will be stored as url, default will be
// default can be "real url" + command.replace(/\s+/g, '/');
// if the value is null the url will not be stored, so it will act as filter.
}
}); So your code in this case will be just: $('...').terminal({
open: function(url) {
var self = this.pause();
$.get(url, function(result) {
self.echo(result, {raw:true}).resume();
}, 'text');
}
}, {
historyState: true,
historyStateUrlMapper: function(command) {
if (command.match(/^open/)) {
return command.replace(/^[^\s]+\s*/, '');
}
}
}); |
That second historyState code is great. I can see that being very useful. I will look into using that. Are you going to bake that into the main Terminal code, or is this just for my use case? But is it possible to somehow disable Terminal from clearing all content on resize? Even just point me to the right place in the code, so I can hack it for my needs right now. I agree that PJAX isn't great, I do wish it had proper callbacks and could return data, rather than forcing it to go to a selector. Thanks! |
I can make that historyState into terminal 0.9, nice feature, I don't have much features to add to new version of terminal. to disable clear in the terminal you need to comment out that line: |
Hey Jakob, Any ideas on when you might release 0.9? I want to start using this History feature on our project. Thanks! |
I can add that history feature when I find some time, and then you will be able to grab it from devel branch. |
I've added the feature to devel branch. |
Hey Jakob, I've been using this, and it's great! Quick question: Say I echo some HTML via AJAX like you have above. Let's say its a grid of thumbnail images, and set the state via your new feature. Next, I click on the thumbnail, and via AJAX I replace that thumbnail with a video. How do you recommend I deal with that state change? I can't echo out a new command, because I want that video to replace the image, not echo onto a new line. Currently I'm just setting that history.pushState() manually on click, but I was wondering if I could do it smarter through this new Terminal feature you added? Thanks again! This is a great plugin! |
You don't do that with terminal. Maybe I can pushState on import_view and add flag that will prevent that to that function so popstate will be able to use import without pushing state. Do you use import/export to change image to video? Because that is the only way to change lines dynamically that will keep terminal internal state. |
I don't currently use import/export. I didn't think that would let me dynamically change part of a page? |
Export give you access to internal array of lines, that are redraw on refresh. I can prepare demo how to modify lines. |
Thanks! It would be great to see an example of export, change content, then import it back into view. |
I've been playing with this today. I've made it so that, on click of an image, I export the view, and then I can use the HTML and edit it. But I struggle to then import it back to the correct line. The image clicked might be 3 lines previous. |
The code will be: $('.selector').terminal(function(cmd, term) {
if (cmd == 'foo') {
term.echo('<img src="/some/image.png" data-replace="/some/other/image.png">', {
raw: true
});
}
}).on('click', 'img', function() {
var self = $(this);
// get index of the line you just click on
var index = self.parents('.terminal-output > div').index();
// you can also use $.terminal.active()
var terminal = self.parents('.terminal').terminal();
var view = terminal.export_view();
var line = view.lines[index][0]; // index 0 is a string 1 is options for the line
view.lines[index][0] = line.replace(self.attr('src'), self.data('replace'));
terminal.import_view(view).save_state();
}); I came into a problem that lines in export/import was using shallow copy ( |
If I use save_state() like you have it on the last line above, what URL does it save in the pushState? |
In my case none, but you can pass arguments to that function |
If you're interested, I think I remove historyState and use hash change, it's much better because it keep state when you refresh. Here is the code, right now outside of terminal: $(function() {
var state = [];
var save = false; // don't change hash onInit
var process_hash = true;
var terminal = $('body').terminal($.noop, {
onAfterCommand: function(term, command) {
if (!$.isArray(commands)) {
commands = [];
}
state.push(term.export_view());
commands.push([state.length-1, command]);
if (save) {
// don't call hashchange on this change
process_hash = false;
location.hash = JSON.stringify(commands);
setTimeout(function() {
process_hash = true;
}, 100);
}
},
onInit: function(term) {
state.push(term.export_view());
},
onBlur: function() {
return false;
}
});
$(window).hashchange(function() {
if (process_hash) {
try {
if (location.hash) {
commands = $.parseJSON(location.hash.replace(/^#/, ''));
} else {
commands = [];
}
if (commands.length) {
var json_state = commands[commands.length-1];
if (state[json_state[0]]) {
terminal.import_view(state[json_state[0]]);
} else {
// don't change hash with this exec
save = false;
terminal.exec(json_state[1]);
// undocumented terminal fire this event
terminal.bind('resume.hash', function() {
save = true;
terminal.unbind('resume.hash');
});
}
} else if (state[0]) {
terminal.import_view(state[0]);
}
} catch(e) {
terminal.exception(e);
}
}
});
var commands;
function exec_hash() {
if (location.hash) {
try {
commands = $.parseJSON(location.hash.replace(/^#/, ''));
$.each(commands, function(i, command) {
try {
terminal.exec(command[1]);
} catch(e) {
var cmd = $.terminal.escape_brackets(command);
var msg = "Error while exec with command " + cmd;
terminal.error(msg).error(e.stack);
}
});
} catch (e) {
//invalid json - ignore
}
}
}
exec_hash();
save = true;
}); It use jQuery hashchange and I've added onAfterCommand callback (I dind't push onAfterCommand into devel branch yet). I not sure if I should put that code into terminal. Maybe I should just put it as example. |
Here is demo http://terminal.jcubic.pl/latest.html (it use uncommited jquery.terminal-src.js file). |
Hey Jakob,
It would be great to be able to set resize:false, and have the terminal not clear it's contents on resize.
I'm loading in content to the divs created by an empty echo using PJAX, and they get cleared by resize function.
Thanks,
Drew
The text was updated successfully, but these errors were encountered: