How to write a Tampermonkey script for Tampermonkey? - tampermonkey

For example, I would like to change the font, and I tried to write this:
// ==UserScript==
// #name New Userscript
// #namespace http://tampermonkey.net/
// #version 0.1
// #description try to take over the world!
// #author You
// #match chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/*
// #icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// #grant none
// ==/UserScript==
document.body.insertAdjacentHTML('beforeend', '<style>.CodeMirror-line span { font-family: "JetBrains Mono"; }</style>')
And the script doesn't run. How else do I change the font without modifying the source code of Tampermonkey or write a script for it itself?

Related

fast-rendering array of CALayers vs array of CAShapeLayers in swift

I'm writing an app in which I need to populate 500 or so layers with previously-defined bezier paths and I'm running into either PERFORMANCE or INTERACTIVITY issues depending on which route I choose. Note that I require no animation features, as the paths i draw are static:
If I use CALayers, drawing the paths to screen takes about 15 seconds (bad), but the resulting interactive experience (i.e moving around the screen) is great.
If I use CAShapeLayers, drawing the paths to screen takes a fraction of a second (good), but the interactivity is terrible.
This is my code with CALayers:
func drawPathToCALayer (myView: UIImageView, pointArray: [CGPoint], bbox: CGRect, color: UIColor) {
// step 1. create path
let path = CGPathCreateMutable()
var pathOffset = CGAffineTransformMakeTranslation( (bbox.origin.x * -1), (bbox.origin.y * -1))
CGPathAddLines(path, &pathOffset, pointArray, pointArray.count)
CGPathCloseSubpath(path)
// step 2. draw to context -- this is the part that kills the amount of time that we call this function repeatedly
UIGraphicsBeginImageContextWithOptions(bbox.size, false, 0)
CGContextAddPath(UIGraphicsGetCurrentContext(), path)
CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), color.CGColor)
CGContextFillPath(UIGraphicsGetCurrentContext())
// step 3. assign context drawing to sublayer
let sublayer = CALayer()
let strokeImage = UIGraphicsGetImageFromCurrentImageContext()
sublayer.frame = bbox
sublayer.contents = strokeImage.CGImage
UIGraphicsEndImageContext()
myView.layer.addSublayer(sublayer)
This is the code with CAShapeLayers
func drawPathToCAShapeLayer (myView: UIImageView, pointArray: [CGPoint], bbox: CGRect, color: UIColor) {
// step 1. create path
let path = CGPathCreateMutable()
var pathOffset = CGAffineTransformMakeTranslation( (bbox.origin.x * -1), (bbox.origin.y * -1))
CGPathAddLines(path, &pathOffset, pointArray, pointArray.count)
CGPathCloseSubpath(path)
// step 2. assign path to sublayer
let sublayer = CAShapeLayer()
sublayer.path = path
sublayer.fillColor = color
myView.layer.addSublayer(sublayer)
I like the succinctness and speed of the CAShapeLayer approach, but from an interactivity point of view, this route is a no go.
The question is (thanks for hanging in there), is there is a way to do a hybrid approach in which I draw to a CAShapeLayer temporarily, and use it to populate a CALayer like so?
func drawPathToHybrid (myView: UIImageView, pointArray: [CGPoint], bbox: CGRect, color: UIColor) {
// step 1. create path
let path = CGPathCreateMutable()
var pathOffset = CGAffineTransformMakeTranslation( (bbox.origin.x * -1), (bbox.origin.y * -1))
CGPathAddLines(path, &pathOffset, pointArray, pointArray.count)
CGPathCloseSubpath(path)
// step 2. assign path to sublayer
let sublayer = CALayer()
let tmplayer = CAShapeLayer()
tmplayer.path = path
tmplayer.fillColor = color
sublayer.contents = tmplayer.contents // ---> i know this doesn't work, but is there something similar I can take advantage of that doesn't rely on defining a context?
myView.layer.addSublayer(sublayer)
Or better yet, is there some other way that I can populate an array of CALayers with bezier paths to get both good INTERACTIVITY and PERFORMANCE?

Usage of ngdocs with controller properties in angularJS

I am just starting to get to grip using grunt-ngdocs for my angular application and so far so good.
But I would now like to document some properties of another documented prperty in one of my controllers.
Consider the following code:
(function() {
'use strict';
/**
* #ngdoc controller
* #name app.mymodule.controller:MyController
* #description
* A Controller
*/
angular
.module('app.mymodule')
.controller('MyController', Controller);
Controller.$inject = ['someService', 'otherService', '$state'];
function Controller(someService, otherService, $state) {
/**
* #ngdoc property
* #name vm
* #propertyOf app.mymodule.controller:MyController
* #description
* A named variable for the `this` keyword representing the ViewModel
*/
var vm = this,
searchText;
vm.customerService = customerService;
vm.fetchCollection = fetchCollection;
vm.deleteCustomer = deleteCustomer;
initialise();
function initialise() {
//logic
}
/**
* #ngdoc
* #name fetchCollection
* #methodOf app.mymodule.controller:MyController
*
* #description
* Function to retrieve records from the backend service
* #example
* vm.fetchCollection(page, perPage);
* #param {int} page The number of the page of data to be retrieved
* #param {int} perPage The number of items per page to be retrieved
* #returns {object} The response object returned from a httpPromise
*/
function fetchCollection(page, perPage){
//logic
}
function deleteCustomer(model) {
//logic
}
})();
As you can see, I have some properties hanging off the vm variable which are typically references to functions defined in the controller.
Using the ngdocs\jsdocs documentation syntax above I can get the vm property to output in my documentation folder, but I am unsure how to document the properties of the vm object itself.
Is there a sensible or recommended way to do this? I did wonder about not documenting vm altogether and just document each of the vm.xxx separately, but I'm not so sure about this!
Thanks
It is not very clear in the documentation, but you have to use the hash in the name.
Try this.
/**
* #ngdoc property
* #name app.mymodule.controller:MyController#vm
* #propertyOf app.mymodule.controller:MyController
* #description
* A named variable for the `this` keyword representing the ViewModel
*/

Document a constant using ngDoc

How would one go about documenting a constant using ngDoc? I don't see any angular specific documentation for documenting values registered with .constant, and the jsDoc syntax for constants doesn't seem to generate any actual docs when it's run through ngDoc.
Ex:
/**
* #constant
* #name WHITE
*
* #description
* The color white!
**/
module.constant( 'WHITE', '#fff' );
ngDocs currently doesn't provide a way to document constants. As you can see in its templating source code. There isnt relevant html_usage_* method.
I document constants like this, it shows a APP_CONFIG as a module then.
/**
* #ngdoc object
* #name APP_CONFIG
* #description
* constant...
* #example
* APP_CONFIG is injectable as constant (as a service even to .config())
* <pre>
* (...) .config(function ($APP_CONFIG) {
* </pre>
*/
It should be #const
/** #const */ var MY_BEER = 'stout';
/**
* My namespace's favorite kind of beer.
* #const {string}
*/
mynamespace.MY_BEER = 'stout';
/** #const */ MyClass.MY_BEER = 'stout';
/**
* Initializes the request.
* #const
*/
mynamespace.Request.prototype.initialize = function() {
// This method cannot be overridden in a subclass.
};
See the constant part http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml#Constants and the comments part http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml?showone=Comments#Comments for more informations

How to tell Stylus to not fail on missing #import

I have a project that can be packaged for 2 targets (mobile and desktop). Tho I still want to keep my source files in the same place since only a few of them are different, but the difference is too big tho to do it only with responsive method (pages missing on mobile, or totally different on desktop, ...) and I want to keep the packaged app as small as possible.
So I created a loader.mobile.styl and loader.desktop.styl, knowing that the packager will import one or the other depending on the target/platform it's building for:
TARGET='mobile' // or 'desktop' for loader.desktop.stylus
#import '_import' // my import helper
import('_application') // my application main stylus file requiring al others
and in _import.styl:
import(file)
#import file
#import file + '.' + TARGET
So the goal is, when you call import('_application') for example, to first import _application.styl and then _application.mobile.styl (or _application.desktop.styl if the target is desktop)
It is working great except that in most of the cases only the shared _application.styl or the specific _application.mobile.styl may exist and not the other.
So I am trying without success to find a way to do an import if exists with Stylus. If just something like fileExists or such was available I could do it, or a try...catch even without the catch block, so that if it fails it doesn't matter.
After some research I ended up writing a plugin which would replace #import directive by defining a custom import function. For those who it might help, here is how I did in my own case:
In file plugins.js:
var sysPath = require('path');
var fs = require('fs');
// here is where I defined some helper to know what is the currently building target
var conf = require('../config');
var plugin = function () {
return function (style) {
var nodes = this.nodes;
style.define('import', function (param) {
var target = conf.currentTarget(),
realPath = sysPath.dirname(conf.ROOT + sysPath.sep + param.filename),
baseName = param.string.replace(/\.styl$/, ''),
targetFile = baseName + '.' + target + '.styl',
file = baseName + '.styl',
res = new nodes.Root();
// first include the file (myFile.styl for example) if it exists
if (fs.existsSync(realPath + sysPath.sep + file)) {
res.push(new nodes.Import(new nodes.String(file)));
}
// then include the target specific file (myFile.mobile.styl for example) if it exists
if (fs.existsSync(realPath + sysPath.sep + targetFile)) {
res.push(new nodes.Import(new nodes.String(targetFile)));
}
return res;
});
};
};
module.exports = plugin;
in file loader.styl:
use('plugins.js')
import('application')
So then any import('xyz') would import xyz.styl if it exists and xyz.mobile.styl (or xyz.desktop.styl if desktop is the target) if it exists.

sails logging to file

Can someone provide an example of how to configure sails.js to log to a file?
It seems like it should be straightforward, but I'm having trouble finding examples online.
I'm looking at changes in the config/log.js or the config/sockets.js files.
According to the source code, for v0.9.x, you just have to set the filePath in your config/log.js:
module.exports = {
log: {
level: 'info',
filePath: 'application.log'
}
};
Logging to a file doesn't work out of the box. You need to invoke functionality in libraries two levels down. See the documentation for winston.
first install winston like so:
$ npm install winston
Then adjust config/log.js to look as follows
var winston = require('winston');
/*see the documentation for Winston: https://github.com/flatiron/winston */
var logger = new(winston.Logger)({
transports: [
new (winston.transports.Console)({}),
new (winston.transports.File)({
filename: 'logfile.log',
level: 'verbose',
json: false,
colorize: false
})
]
});
module.exports.log = {
/***************************************************************************
* *
* Valid `level` configs: i.e. the minimum log level to capture with *
* sails.log.*() *
* *
* The order of precedence for log levels from lowest to highest is: *
* silly, verbose, info, debug, warn, error *
* *
* You may also set the level to "silent" to suppress all logs. *
* *
***************************************************************************/
level: 'silly',
colorize: false,
custom: logger
};
For winston 3.x.x versions
#djsadinoff's answer not works.
Instead do:
$ npm install winston
Replace your config/log.js file with the following code in Sails.js
var winston = require('winston');
const logger = winston.createLogger({
level: 'silly',
format: winston.format.json(),
transports: [
//
// - Write to all logs with level `info` and below to `combined.log`
// - Write all logs error (and below) to `error.log`.
//
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'sails.log' })
]
});
//
// If we're not in production then log to the `console` with the format:
// `${info.level}: ${info.message} JSON.stringify({ ...rest }) `
//
if (process.env.NODE_ENV !== 'production') {
logger.add(new winston.transports.Console({
format: winston.format.simple()
}));
}
module.exports.log = {
/***************************************************************************
* *
* Valid `level` configs: i.e. the minimum log level to capture with *
* sails.log.*() *
* *
* The order of precedence for log levels from lowest to highest is: *
* silly, verbose, info, debug, warn, error *
* *
* You may also set the level to "silent" to suppress all logs. *
* *
***************************************************************************/
// Pass in our custom logger, and pass all log levels through.
custom: logger,
level: 'silly',
// Disable captain's log so it doesn't prefix or stringify our meta data.
inspect: false
};
Then do
$ sails lift

Resources