aboutsummaryrefslogblamecommitdiff
path: root/src/console/actions/console.ts
blob: 16d33b303cad9ff6d26478fb92c643fe9a44bc78 (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                                                  
                                                           
                                                     
                                                         
                                           
                                                
                                          
                     









                                                                         
  
 


                                                   
                                             
  
                                           



                               
                                                                           
                                                                      
                                       
                    
    
  
 
                                                



                                    
                                                              
                                     
               

    
                                                            
                                    
               

    
                                                      




                                     
          
                                       

    

                                          


                                         
                       
  
                                                                 





                                        

                       
                                                                               




                                           
                                                                               
                                           










                                                         


                                          
    
  



                                  
                                             

                                      



                                                                         
                          
                                      
                               
                                               
              




                                                                   
                          
                                       
                                
                                              
              
              




                                                                     
                          
                                       
                                

                                              
              
       







                                          
 
                                 


                        
                                             









                                                                         

                                






                                          
  


                                      

                                                            



                                                 
                               










                                                 
                               
                                               






                                                                   


                                          
    
  
 
                                                            
          
                                          
    
  
 
                                                            
          
                                          
    
  






                                                                           
        













                         
                 
  
import * as messages from "../../shared/messages";
import * as actions from "./index";
import { Command } from "../../shared/Command";
import CompletionClient from "../clients/CompletionClient";
import SettingClient from "../clients/SettingClient";
import CompletionType from "../../shared/CompletionType";
import Completions from "../Completions";
import TabFlag from "../../shared/TabFlag";

const completionClient = new CompletionClient();
const settingClient = new SettingClient();

const commandDocs = {
  [Command.Set]: "Set a value of the property",
  [Command.Open]: "Open a URL or search by keywords in current tab",
  [Command.TabOpen]: "Open a URL or search by keywords in new tab",
  [Command.WindowOpen]: "Open a URL or search by keywords in new window",
  [Command.Buffer]: "Select tabs by matched keywords",
  [Command.BufferDelete]: "Close a certain tab matched by keywords",
  [Command.BuffersDelete]: "Close all tabs matched by keywords",
  [Command.Quit]: "Close the current tab",
  [Command.QuitAll]: "Close all tabs",
  [Command.AddBookmark]: "Add current page to bookmarks",
  [Command.Help]: "Open Vim Vixen help in new tab",
};

const propertyDocs: { [key: string]: string } = {
  hintchars: "hint characters on follow mode",
  smoothscroll: "smooth scroll",
  complete: "which are completed at the open page",
  colorscheme: "color scheme of the console",
};

const hide = (): actions.ConsoleAction => {
  return {
    type: actions.CONSOLE_HIDE,
  };
};

const showCommand = async (text: string): Promise<actions.ShowCommand> => {
  const completionTypes = await completionClient.getCompletionTypes();
  return {
    type: actions.CONSOLE_SHOW_COMMAND,
    completionTypes,
    text,
  };
};

const showFind = (): actions.ShowFindAction => {
  return {
    type: actions.CONSOLE_SHOW_FIND,
  };
};

const showError = (text: string): actions.ShowErrorAction => {
  return {
    type: actions.CONSOLE_SHOW_ERROR,
    text: text,
  };
};

const showInfo = (text: string): actions.ShowInfoAction => {
  return {
    type: actions.CONSOLE_SHOW_INFO,
    text: text,
  };
};

const hideCommand = (): actions.HideCommandAction => {
  window.top.postMessage(
    JSON.stringify({
      type: messages.CONSOLE_UNFOCUS,
    }),
    "*"
  );
  return {
    type: actions.CONSOLE_HIDE_COMMAND,
  };
};

const enterCommand = async (
  text: string
): Promise<actions.HideCommandAction> => {
  await browser.runtime.sendMessage({
    type: messages.CONSOLE_ENTER_COMMAND,
    text,
  });
  return hideCommand();
};

const enterFind = (text?: string): actions.HideCommandAction => {
  window.top.postMessage(
    JSON.stringify({
      type: messages.CONSOLE_ENTER_FIND,
      text,
    }),
    "*"
  );
  return hideCommand();
};

const setConsoleText = (consoleText: string): actions.SetConsoleTextAction => {
  return {
    type: actions.CONSOLE_SET_CONSOLE_TEXT,
    consoleText,
  };
};

const getCommandCompletions = (text: string): actions.SetCompletionsAction => {
  const items = Object.entries(commandDocs)
    .filter(([name]) => name.startsWith(text.trimLeft()))
    .map(([name, doc]) => ({
      caption: name,
      content: name,
      url: doc,
    }));
  const completions = [
    {
      name: "Console Command",
      items,
    },
  ];
  return {
    type: actions.CONSOLE_SET_COMPLETIONS,
    completions,
    completionSource: text,
  };
};

const getOpenCompletions = async (
  types: CompletionType[],
  original: string,
  command: Command,
  query: string
): Promise<actions.SetCompletionsAction> => {
  const completions: Completions = [];
  for (const type of types) {
    switch (type) {
      case CompletionType.SearchEngines: {
        const items = await completionClient.requestSearchEngines(query);
        if (items.length === 0) {
          break;
        }
        completions.push({
          name: "Search Engines",
          items: items.map((key) => ({
            caption: key.title,
            content: command + " " + key.title,
          })),
        });
        break;
      }
      case CompletionType.History: {
        const items = await completionClient.requestHistory(query);
        if (items.length === 0) {
          break;
        }
        completions.push({
          name: "History",
          items: items.map((item) => ({
            caption: item.title,
            content: command + " " + item.url,
            url: item.url,
          })),
        });
        break;
      }
      case CompletionType.Bookmarks: {
        const items = await completionClient.requestBookmarks(query);
        if (items.length === 0) {
          break;
        }
        completions.push({
          name: "Bookmarks",
          items: items.map((item) => ({
            caption: item.title,
            content: command + " " + item.url,
            url: item.url,
          })),
        });
        break;
      }
    }
  }

  return {
    type: actions.CONSOLE_SET_COMPLETIONS,
    completions,
    completionSource: original,
  };
};

const getTabCompletions = async (
  original: string,
  command: Command,
  query: string,
  excludePinned: boolean
): Promise<actions.SetCompletionsAction> => {
  const items = await completionClient.requestTabs(query, excludePinned);
  let completions: Completions = [];
  if (items.length > 0) {
    completions = [
      {
        name: "Buffers",
        items: items.map((item) => ({
          content: command + " " + item.url,
          caption: `${item.index}: ${
            item.flag != TabFlag.None ? item.flag : " "
          } ${item.title}`,
          url: item.url,
          icon: item.faviconUrl,
        })),
      },
    ];
  }
  return {
    type: actions.CONSOLE_SET_COMPLETIONS,
    completions,
    completionSource: original,
  };
};

const getPropertyCompletions = async (
  original: string,
  command: Command,
  query: string
): Promise<actions.SetCompletionsAction> => {
  const properties = await completionClient.getProperties();
  const items = properties
    .map((item) => {
      const desc = propertyDocs[item.name] || "";
      if (item.type === "boolean") {
        return [
          {
            caption: item.name,
            content: command + " " + item.name,
            url: "Enable " + desc,
          },
          {
            caption: "no" + item.name,
            content: command + " no" + item.name,
            url: "Disable " + desc,
          },
        ];
      } else {
        return [
          {
            caption: item.name,
            content: command + " " + item.name,
            url: "Set " + desc,
          },
        ];
      }
    })
    .reduce((acc, val) => acc.concat(val), [])
    .filter((item) => item.caption.startsWith(query));
  const completions: Completions = [{ name: "Properties", items }];
  return {
    type: actions.CONSOLE_SET_COMPLETIONS,
    completions,
    completionSource: original,
  };
};

const completionNext = (): actions.CompletionNextAction => {
  return {
    type: actions.CONSOLE_COMPLETION_NEXT,
  };
};

const completionPrev = (): actions.CompletionPrevAction => {
  return {
    type: actions.CONSOLE_COMPLETION_PREV,
  };
};

const setColorScheme = async (): Promise<actions.SetColorSchemeAction> => {
  const scheme = await settingClient.getColorScheme();
  return {
    type: actions.CONSOLE_SET_COLORSCHEME,
    colorscheme: scheme,
  };
};

export {
  hide,
  showCommand,
  showFind,
  showError,
  showInfo,
  hideCommand,
  setConsoleText,
  enterCommand,
  enterFind,
  getCommandCompletions,
  getOpenCompletions,
  getTabCompletions,
  getPropertyCompletions,
  completionNext,
  completionPrev,
  setColorScheme,
};