brookhong / Surfingkeys

Map your keys for web surfing, expand your browser with javascript and keyboard.
https://chrome.google.com/webstore/detail/surfingkeys/gfbliohnnapiefjpjlpjnehglfpaknnc
MIT License
5.28k stars 476 forks source link

How to open Omnibar with heading titles #1688

Open snowman opened 2 years ago

snowman commented 2 years ago

I can't find the heading subtype for the omnibar, nor exposed API to define a new one.

// Open Omnibar to jump to heading
mapkey(
  "oh",
  "#8Jump to Heading",
  function () {
    var headings = Array.from(
      top.document.querySelectorAll("h1,h2,h3,h4,h5,h6")
    ).map(function (h) {
      const level = +h.tagName[1]

      return {
        title: level + ". " + h.textContent,
        scrollTop: h.scrollTop
      }
    })

    Front.openOmnibar({ type: "Headings", extra: headings })
  },
  { domain: /example.com/i }
)
brookhong commented 2 years ago

The type should be UserURLs, and the extra parameter should be an array of objects like below

{
    "title": "<the title of the url>",
    "url": "<any url>"
}

for example,

mapkey('ou', '#8Open AWS services', function() {
    const services = {
        {
            "title": "EC2",
            "url": "https://cn-northwest-1.console.amazonaws.cn/ec2/v2/home?region=cn-northwest-1"
        },
        {
            "title": "Elastic Beanstalk",
            "url": "https://cn-northwest-1.console.amazonaws.cn/elasticbeanstalk/home?region=cn-northwest-1"
        },
        {
            "title": "Batch",
            "url": "https://cn-northwest-1.console.amazonaws.cn/batch/home?region=cn-northwest-1"
        }
    };
    Front.openOmnibar({type: "UserURLs", extra: services});
}, {domain: /console.amazonaws|console.aws.amazon.com/i});
snowman commented 2 years ago

Thanks for the reply,

I do NOT mean to open the URL, the heading may be plain-text.

I want to scroll to the position(scrollTop) of the heading, navigate/jump between headings by filtering the heading title.

Maybe provide a custom callback to let users define an action to run when an item is selected instead of just some predefined type.

kotatsuyaki commented 8 months ago

Based on @snowman’s snippet, I’ve found a solution using javascript: URLs.

api.mapkey(
  "oj",
  "#8Jump to Heading",
  () => {
    let headings = Array.from(
      top.document.querySelectorAll("h1,h2,h3,h4,h5,h6")
    ).filter(h => h.hasAttribute("id")).map((h) => {
      const level = +h.tagName[1];

      return {
        title: "#".repeat(level) + " " + h.textContent,
        url: `javascript:document.getElementById("${h.id}").scrollIntoView(true);`,
      };
    });

    api.Front.openOmnibar({ type: "UserURLs", extra: headings });
  },
);