Custom stroke HOWTO

What is it?
A custom stroke is just like a regular stroke, except that when a custom stroke is triggered, a piece of user created JavaScript, instead of a built-in action, is executed.

Do I need to know JavaScript to use custom stokes?
No, you are not required to know JavaScript to use custom strokes. However, basic JavaScript coding skills are needed if you want to create custom strokes.

OK, then how to use it?
It's dead simple, just copy a piece of JavaScript code from our library, then open the Mouse Stroke options page, click the Create link at the Custom Strokes section, paste the code in the Script input box, and that's it!
Now you can assign a stroke to the script then use it like other built-in strokes.

How to create my own custom strokes?
You'll need basic JavaScript coding skills to create custom strokes.

You can define you own strokes by click the Create link at the Custom Stroke section in the options page. Give it a descriptive name, then type in the script to handle your custom stroke. Scripts are common JavaScript code pieces which will be evaluated within the context of Chrome's content script sandbox, it basically means you can access DOM objects in the webpage, but you can not access JavaScript objects defined in the webpage.

You can do anything JavaScript can normally do, from DOM manipulation to AJAX request, etc.

A magic MS variable (previously _env) is made available to your script, the data structure of MS is:

MS {
  apis: A small collection of APIs, please see the API section below,
  type: String,         /* type of the stroke, including 'stroke', 'rocker' or 'wheel' */
  initevt: MouseEvent,  /* a strip down version of the DOM event that initiated the stroke ('mousedown' for all 3 types) */
  finevt: MouseEvent,   /* a strip down version of the DOM event that finished the stroke ('mouseup' for 'stroke' type, 'mousedown' for 'rocker' type and 'mousewheel' for 'wheel' type) */
  seltext: String,      /* currently selected text */

  /* 'stroke' type properties */
  stroke: Array,    /* the stroke you've just performed */
  weights: Array,   /* weights of each stroke part */
  custom: Boolean,  /* is this a user defined stroke? */

  /* 'wheel' type properties */
  wheel: String,    /* wheel direction, UP, DOWN, LEFT or RIGHT */

  /* 'rocker' type properties */
  rocker: String    /* rocker direction, LEFT -> RIGHT or RIGHT -> LEFT */
}

MS.initevt and MS.finevt contain the following data.

{
  button: Integer,  /* mouse button in a mouse event, otherwise undefined */

  target: {
    /* properties for <a> elements, or children elements of an <a> element */
    textContent: String,  /* the textContent property of the event's target */
    href: String,         /* the URL of the link element */

    /* properties for <img> elements, or any elements with a background image */
    src: String,          /* the image URL */

    /* common properties */
    nodeName: String,     /* the node name of the target, in upper case */
    id: String            /* id of the target element */
  },

  /* this is an alias of the 'target' property, exists for backward compatibility */
  srcElement: this.target
}

There is a known issue about finevt.target.

Functions in MS.apis (experimental)
MS.apis.builtin(), call built-in stroke handlers, see details below.

MS.apis.tabs.create(), pass through to chrome.tabs.create(), see here.

MS.apis.tabs.remove(), pass through to chrome.tabs.remove(), see here. You can pass an empty tab id to close the current tab.

MS.apis.windows.create(), pass through to chrome.windows.create(), see here.

MS.apis.windows.remove(), pass through to chrome.windows.remove(), see here. You can pass an empty window id to close the current window.

MS.apis.clipboard.copy(String text, Function callback), copy the text in the first argument, then call the callback function.

Call built-in stroke handlers
Since 1.9.5, you can call built-in stroke handlers from custom strokes. For example:

MS.apis.builtin('to-page-top');

This call will scroll the page to the top, just like the built-in stroke "To Page Top". The only parameter is the handler's name, the full list of available handlers are:

Navigation
	'to-page-top':			To Page Top
	'to-page-bottom':		To Page Bottom
	'scroll-up-one-page':		Scroll Up One Page
	'scroll-down-one-page':		Scroll Down One Page
	'history-back':			History Back
	'history-forward':		History Forward
	'previous-tab':			Previous Tab
	'next-tab':			Next Tab
	'first-tab':			First Tab
	'last-tab':			Last Tab
	'upper-level-in-url':		Upper Level In Url
	'increase-number-in-url':	Guess Next Page
	'decrease-number-in-url':	Guess Previous Page
	'open-homepage':		Open Homepage

Window
	'new-window':		New Window
	'close-window':		Close Window
	'maximize-window':	Maximize Window

Tab
	'new-tab':			New Tab
	'close-tab':			Close Tab
	'undo-close-tab':		Undo Close Tab
	'detach-tab':			Detach Tab
	'duplicate-tab':		Duplicate Tab
	'close-tab-to-the-left':	Close Tab To The Left
	'close-tab-to-the-right':	Close Tab To The Right
	'close-all-tabs-to-the-left':	Close All Tabs To The Left
	'close-all-tabs-to-the-right':	Close All Tabs To The Right
	'close-other-tabs':		Close Other Tabs

Link
	'open-link-in-new-window':		Open Link In New Window
	'open-link-in-new-background-tab':	Open Link In New Background Tab
	'open-link-in-new-foreground-tab':	Open Link In New Foreground Tab
	'bookmark-this-link':			Bookmark This Link

Image
	'view-image':	View Image

Bookmark
	'bookmark-this-page':	Bookmark This Page
	'remove-bookmark':	Remove Bookmark

Utilities
	'reload':		Reload
	'skip-cache-reload':	Skip Cache Reload
	'stop-page-loading':	Stop Page Loading
	'text-zoom-in':		Text Zoom In
	'text-zoom-out':	Text Zoom Out
	'text-zoom-reset':	Text Zoom Reset
	'search-selected-text':	Search Selected Text
	'view-source':		View Source
	'take-screenshot':	Take Screenshot

Other
	'mouse-stroke-options':	Mouse Stroke Options

Runs in which frames?
In webpages contain <iframe> or <frame>, you can choose to run your custom strokes in:
  1. All frames: You want to choose this one for strokes like "Hide all images".
  2. The top frame: Only in the top frame.
  3. Target frame: This is the frame from which the gesture is originally generated, suitable for strokes like "Search selected text in a new tab", "Translate selected text", etc.