abstract out the text-selection logic into TextSelector