您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds helpful methods for dealing with Turbo Events to WaniKani Open Framework
当前为
This is a library script
that adds helpful methods to WaniKani Open Framework
for dealing with Turbo Events.
Scripts developers can use this library to simplify their workflow.
All additions are added to a new turbo
property of the wkof
object, thus accessible via wkof.turbo
.
wkof.turbo
objectThe wkof.turbo
object has the following properties and methods
(methods are all non-writable; properties are all non-writable and extensible unless noted otherwise):
boolean
true
when the listener was successfully added or false
when the inputs were invalid or the provided listener and options already exists.
true
or false
according to whether the listener was called immediately.{name: string, added: boolean}[]
name
is the name of the event and added
indicates the result of the wkof.turbo.add_event_listener(name, listener, options) operation for that listener.boolean
urls
into the options
parameter.boolean
targetIds
into the options
parameter.boolean
true
when the listener was successfully removed or false
when the inputs were invalid or when no active listener matching the parameters was found.{name: string, removed: boolean}[]
name
is the name of the event and removed
indicates the result of the wkof.turbo.remove_event_listener(name, listener, options) operation for that listener.object
object
{name: string, added: boolean}[]
boolean
id
that matches one of the provided targetIds
.boolean
boolean
boolean
boolean
boolean
boolean
boolean
object
addListener
method in the wkof.turbo.events object.add_event_listener(eventName, listener, options)
before_cache(listener, options)
before_fetch_request(listener, options)
before_fetch_response(listener, options)
before_frame_render(listener, options)
before_morph_attribute(listener, options)
before_morph_element(listener, options)
before_prefetch(listener, options)
before_render(listener, options)
before_stream_render(listener, options)
before_visit(listener, options)
click(listener, options)
fetch_request_error(listener, options)
frame_load(listener, options)
frame_missing(listener, options)
frame_render(listener, options)
load(listener, options)
morph(listener, options)
morph_element(listener, options)
render(listener, options)
submit_end(listener, options)
submit_start(listener, options)
visit(listener, options)
object
turbo:
syntax that matches the name
property (e.g. wkof.turbo.events['turbo:before-render']
).object
source
: "document"name
: "turbo:click"boolean
boolean
object
source
: "document"name
: "turbo:before-visit"boolean
boolean
object
source
: "document"name
: "turbo:visit"boolean
boolean
object
source
: "document"name
: "turbo:before-cache"boolean
boolean
object
source
: "document"name
: "turbo:before-render"boolean
boolean
object
source
: "document"name
: "turbo:render"boolean
boolean
object
source
: "document"name
: "turbo:load"boolean
boolean
object
source
: "pageRefresh"name
: "turbo:morph"boolean
boolean
object
source
: "pageRefresh"name
: "turbo:before-morph-element"boolean
boolean
object
source
: "pageRefresh"name
: "turbo:before-morph-attribute"boolean
boolean
object
source
: "pageRefresh"name
: "turbo:morph-element"boolean
boolean
object
source
: "forms"name
: "turbo:submit-start"boolean
boolean
object
source
: "forms"name
: "turbo:submit-end"boolean
boolean
object
source
: "frames"name
: "turbo:before-frame-render"boolean
boolean
object
source
: "frames"name
: "turbo:frame-render"boolean
boolean
object
source
: "frames"name
: "turbo:frame-load"boolean
boolean
object
source
: "frames"name
: "turbo:frame-missing"boolean
boolean
object
source
: "streams"name
: "turbo:before-stream-render"boolean
boolean
object
source
: "httpRequests"name
: "turbo:before-fetch-request"boolean
boolean
object
source
: "httpRequests"name
: "turbo:before-fetch-response"boolean
boolean
object
source
: "httpRequests"name
: "turbo:before-prefetch"boolean
boolean
object
source
: "httpRequests"name
: "turbo:fetch-request-error"boolean
boolean
object
object
RegExp
objects to match against the URLs for typical pages.RegExp
/^https:\/\/www\.wanikani\.com(\/dashboard.*)?\/?$/
RegExp
/^https:\/\/www\.wanikani\.com\/(radicals|kanji|vocabulary)\/.+\/?$/
RegExp
/^https:\/\/www\.wanikani\.com\/subject-lessons\/(start|[\d-]+\/\d+)\/?$/
RegExp
/^https:\/\/www\.wanikani\.com\/subject-lessons\/picker\/?$/
RegExp
/^https:\/\/www\.wanikani\.com\/subject-lessons\/[\d-]+\/quiz.*\/?$/
RegExp
/^https:\/\/www\.wanikani\.com\/subjects\/review.*\/?$/
(event: CustomEvent, url: URL)
for all events.
event
parameter is the CustomEvent object, passed directly from the triggered event.
event.type
.
event.type === 'turbo:load'
.url
parameter is a URL, which has been parsed from the event, using predetermined logic to detect the URL most likely of use to the end user. This URL is associated with the details of the triggered event, usually referencing the result or target of whatever action has transpired or is preparing to transpire.event.type
is "load" and url
is the current page URL.@match
userscript directive to https://www.wanikani.com/*
or equivalent.
urls
, dashboard
, items_pages
, lessons
, lessons_picker
, lessons_quiz
, reviews
Typical usage involves one of the following:
addListener(listener, options)
method of the specific TurboEvent
object in wkof.turbo.events that will be used.
urls
property in the object passed to the options
parameter
{urls: myUrl}
or {urls: [myUrl1, myUrl2]}
string
, a RegExp
, or an Array
or Set
consisting of a mixture of those.wkof.turbo.events.before_render.addListener(listener, {urls: 'https://www.wanikani.com/level/*'})
.listener
immediately after it is added in the case that the options
match and the page has already finished loading, according to the window.Turbo
session.(event: CustomEvent, url: string) => void
.event
parameter is a CustomEvent
constructed as follows:
new CustomEvent('load', {bubbles: false, cancelable: false, composed: false, target: document.documentElement})
.url
parameter is a URL string
of the current location, according to the window.Turbo
session.All the events provided have an optional options parameter
that functions as an extension of the AddEventListenerOptions
|EventListenerOptions
parameters
given to EventTarget.addEventListener().
The following table is a full description of the options available.
Property | Type (accepted input values) | Description |
---|---|---|
urls | string |RegExp |(string|RegExp)[] |Set<string|RegExp> |
The URLs to be verified against the URL parameter. Values provided will be coerced into RegExp objects.If not specified, the listener runs on any URL. |
targetIds | string |string[] |Set<string> |Object.<string,*> |
The target IDs to be verified against the event target ID. If not specified, the listener runs for any event target. |
useDocumentIds | boolean |
Indicates whether to check the IDs of the document element in addition to the event target for the targetIds. If not specified, defaults to false . |
timeout | string "none"|"promise"|"setTimeout"|"both" |
Added in 4.2.0 as a replacement for noTimeout (for now, specifying noTimeout: true will result in setting timeout: "none" ).Indicates when the listener should be called based on the option provided.
If not specified or not an exact match of one of the listed options, defaults to "setTimeout" . |
nocache | boolean |
Indicates whether to ignore events involving Turbo's cached pages. If not specified, defaults to false . See hotwired.dev discussion. |
noWarn | boolean |
Added in 4.2.0 as a replacement for wkof.turbo.silenceWarnings .Indicates whether to prevent logging a console warning if adding a listener after the page has loaded. If not specified, defaults to false . |
once | boolean |
Indicates that the listener should be invoked at most once after being added. If true , the listener would be automatically removed when invoked.If not specified, defaults to false . See EventTarget.addEventListener#once. |
capture | boolean |
Indicates that events of this type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree.If not specified, defaults to false . See EventTarget.addEventListener#capture. |
passive | boolean |
If true , indicates that the function specified by listener will never call preventDefault(). If a passive listener does call preventDefault() , the user agent will do nothing other than generate a console warning.If not specified, defaults to false – except that in browsers other than Safari, it defaults to true for wheel, mousewheel, touchstart, and touchmove events. See EventTarget.addEventListener#passive. |
signal | AbortSignal | The listener will be removed when the given AbortSignal object's abort() method is called.If not specified, no AbortSignal is associated with the listener. See EventTarget.addEventListener#signal. |
// ==UserScript==
// @name Wanikani Something Special
// @namespace https://www.youtube.com/watch?v=dQw4w9WgXcQ
// @version 1.0.0
// @description Does something special
// @author You Know
// @match https://www.wanikani.com/*
// @grant none
// @license MIT
// ==/UserScript==
if (!window.wkof) {
if (confirm(`${script_name} requires Wanikani Open Framework.\nDo you want to be forwarded to the installation instructions?`))
window.location.href = 'https://community.wanikani.com/t/instructions-installing-wanikani-open-framework/28549';
return;
}
// This script needs to run whenever the user is on the dashboard.
wkof.ready('TurboEvents').then(() => wkof.turbo.on.common.dashboard(main));
function main() {
// start of main script
}
// ==UserScript==
// @name Wanikani Something Special
// @namespace https://www.youtube.com/watch?v=dQw4w9WgXcQ
// @version 1.0.0
// @description Does something special
// @author You Know
// @match https://www.wanikani.com/*
// @grant none
// @license MIT
// ==/UserScript==
if (!window.wkof) {
if (confirm(`${script_name} requires Wanikani Open Framework.\nDo you want to be forwarded to the installation instructions?`))
window.location.href = 'https://community.wanikani.com/t/instructions-installing-wanikani-open-framework/28549';
return;
}
wkof.ready('TurboEvents').then(configureTurbo);
function configureTurbo() {
// This example needs to run whenever the user is in a reviews session or lessons quiz. So this
// example will use RegEx objects conviently provided by this library.
const options = {
urls: [
wkof.turbo.common.locations.reviews,
wkof.turbo.common.locations.lessons_quiz
]
};
// These are the events most often of use for general purpose scripts
// See the special case note about 'load' in the preceding section.
const eventList = ['load', wkof.turbo.events.load];
// Setup the listener
wkof.turbo.add_event_listeners(eventList, main, options);
}
function main() {
// start of main script
}
// Make sure the events are fully loaded before starting any configuration of this library.
wkof.ready('TurboEvents').then(configurePageHandler);
// The listener is passed an `event` and `url` argument for all events added via this library.
function myFunction(event, url) {
console.log(`myFunction() has run for event "${event.type}" with url ${url}`);
}
function configurePageHandler() {
// Run the callback on "turbo:click" on any page.
wkof.turbo.events.click.addListener(myFunction);
const options1 = {
// Run the listener on the dashboard and on individual radical, kanji, or vocab pages.
urls: [wkof.turbo.common.locations.dashboard, wkof.turbo.common.locations.items_pages],
// Do not show warnings about adding listeners after the page has loaded.
noWarn: true
};
// Run the listener on the "turbo:before-visit" event.
wkof.turbo.add_event_listener(wkof.turbo.events.before_visit, myFunction, options1);
// The above line is equivalent to either of the following two lines.
// These will both return false because the listener has already been added with these options.
wkof.turbo.events.before_visit.addListener(myFunction, options1);
wkof.turbo.events["turbo:before-visit"].addListener(myFunction, options1);
// Add a listener with the same options to the "turbo:visit" event.
wkof.turbo.events.visit.addListener(myFunction, options1);
// Run the callback on initial page load, turbo:before-render, and turbo:frame_render.
// See the special case note about "load" in the preceding section.
let eventList = ['load', wkof.turbo.events.before_render, wkof.turbo.events.frame_render];
const options2 = {
// Run the callback on the lessons picker page.
urls: wkof.turbo.common.locations.lessons_picker,
// Automatically remove the event after firing once
once: true,
// Ignore events for Turbo's cached version of pages.
nocache: true,
// Do not show warnings about adding listeners after the page has loaded.
noWarn: true,
// Disable the built-in feature that delays the callback execution until the next macrotask.
timeout: 'none'
};
// The first parameter can be an array including either the Turbo event object that is provided
// (wkof.turbo.events.before_render) or the string itself ("turbo:before-render").
// Note that two new listeners are added in this example, one for each **Turbo** event.
wkof.turbo.add_event_listeners(eventList, myFunction, options2);
// returned array is [
// {name: "load", added: false},
// {name: "turbo:before-render", added: true},
// {name: "turbo:frame-render", added: true}
// ]
// Remove a single listener by using
// `wkof.turbo.remove_event_listener(eventName, listener, options)`.
// In this scenario, the result would be [false, true, true], since the "load" event does not
// create a listener. However, if a "turbo:before-render" or "turbo:frame-render" event has
// fired between creating the listener and making the following call, the respective loop
// condition or conditions would also return false because the listener or listeners would
// have already been removed due to using the `once: true` option during creation.
eventList.map(eventName => {
// The listener and options must both match the existing listener or the removal will fail.
// The listener must be reference equal, but the options can just have equivalent values.
let equivalentOptions = {urls: wkof.turbo.common.locations.lessons_picker,
once: true, nocache: true, noWarn: true, timeout: 'none'};
return wkof.turbo.remove_event_listener(eventName, myFunction, equivalentOptions);
// this could alternatively be done in the following way:
return wkof.turbo.events[eventName].removeListener(myFunction, equivalentOptions);
});
// Listeners still active: "turbo:click", "turbo:before-visit", and "turbo:visit"
// The `remove_event_listeners` can remove multiple at once, however the options must all match.
eventList = ["turbo:click", "turbo:before-visit", "turbo:visit"];
wkof.turbo.remove_event_listeners(eventList, myFunction, options1);
// returned array is [
// {"name": "turbo:click", "removed": false},
// {"name": "turbo:before-visit", "removed": true},
// {"name": "turbo:visit", "removed": true}
// ]
// "turbo:click" was not removed because the options did not match. The following will work:
wkof.turbo.events.click.removeListener(myFunction);
// Add a listener for all turbo events on any URL.
// `Object.entries(wkof.turbo.events)` or `Object.values(wkof.turbo.events)` function the same.
eventList = wkof.turbo.events;
wkof.turbo.add_event_listeners(eventList, myFunction);
// returned array is [
// {"name": "turbo:click", "added": true},
// {"name": "turbo:before-visit", "added": true},
// {"name": "turbo:visit", "added": true},
// {"name": "turbo:before-cache", "added": true},
// {"name": "turbo:before-render", "added": true},
// {"name": "turbo:render", "added": true},
// {"name": "turbo:load", "added": true},
// {"name": "turbo:morph", "added": true},
// {"name": "turbo:before-morph-element", "added": true},
// {"name": "turbo:before-morph-attribute", "added": true},
// {"name": "turbo:morph-element", "added": true},
// {"name": "turbo:submit-start", "added": true},
// {"name": "turbo:submit-end", "added": true},
// {"name": "turbo:before-frame-render", "added": true},
// {"name": "turbo:frame-render", "added": true},
// {"name": "turbo:frame-load", "added": true},
// {"name": "turbo:frame-missing", "added": true},
// {"name": "turbo:before-stream-render", "added": true},
// {"name": "turbo:before-fetch-request", "added": true},
// {"name": "turbo:before-fetch-response", "added": true},
// {"name": "turbo:before-prefetch", "added": true},
// {"name": "turbo:fetch-request-error", "added": true}
// ]
}