Skip to content

Instantly share code, notes, and snippets.

@tokland
tokland / Gemfile
Last active June 21, 2017 07:48
Get report hours from toggl.com
source "https://ruby.taobao.org"
ruby "2.3.0"
gem "activesupport"
gem "togglv8"
gem "awesome_print"
gem "trollop"
group :development do
@tokland
tokland / data-entry-contentscript.js
Created June 12, 2017 10:14
Group subsections tabs for DHIS2 dataentry
/*
Group subsections tabs (with names "section@subsection1", "section@subsection2") into a single tab "section"
Save as a contentscript in DHIS2 app customJS/CSS (https://www.dhis2.org/download/appstore/customjscss.zip)
*/
var init = function(contentEl) {
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var displayingTabs = contentEl.children().size() > 0;
var observer = new MutationObserver(function(mutations, observer) {
if (!displayingTabs && contentEl.children().size() > 0) {
@tokland
tokland / promise_map.js
Last active March 1, 2022 00:18 — forked from anvk/promises_reduce.js
Execute promises sequentially (one at at a time) and return array with the results
function promiseMap(inputValues, mapper) {
const reducer = (acc$, inputValue) =>
acc$.then(acc => mapper(inputValue).then(result => acc.push(result) && acc));
return inputValues.reduce(reducer, Promise.resolve([]));
}
/* Example */
const axios = require('axios');
/* https://github.com/eisnerd/feedback-tool + github issues
Example:
$.feedbackGithub({
token: "16222221222128357fab95ec80b56a43c9a1868b429",
issues: {
repository: "tokland/feedback-test",
title: "feedback from user",
renderBody: (body) => "my own data\n" + body,
@tokland
tokland / xfce4-save-session.sh
Created October 30, 2017 10:03
Xfce4 save session
#!/bin/sh
exec dbus-send \
--session \
--dest=org.xfce.SessionManager \
--print-reply /org/xfce/SessionManager \
org.xfce.Session.Manager.Checkpoint string:""
#!/bin/bash
#
# Record a video of a mod/s3m/xm tracker song played using milkytracker.
#
# Dependencies with versions used in parenthesis:
#
# schismtracker / milkytracker
# pulseaudio
# vnc2flv
# turbovnc
@tokland
tokland / Counter.js
Last active May 20, 2018 09:21
Avoid setState in stateful React components
/* Simple counter example. Decorate any method that returns new state, including
lifecycle component methods. */
import React from 'react';
import { action } from './action';
class Counter extends React.PureComponent {
constructor(props) {
super(props);
this.state = { value : 0 };
}
@tokland
tokland / 1simple-counter.js
Last active July 8, 2018 17:07
Declarative React Component
import React from 'react';
import { build } from "./declarative-component";
const initialState = { value: 0 };
const actions = {
decrement: (num) => state => ({ ...state, value: state.value - 1 }),
increment: (num) => state => ({ ...state, value: state.value + 1 }),
};
@tokland
tokland / escape-xpath-string.js
Last active March 31, 2022 23:07
Escape xpath string using concat
function escapeXpathString(str) {
const splitedQuotes = str.replace(/'/g, `', "'", '`);
return `concat('${splitedQuotes}', '')`;
}
@tokland
tokland / puppeteer-click-by-text.js
Last active August 11, 2023 03:48
Click link by text in Puppeteer
const puppeteer = require('puppeteer');
const escapeXpathString = str => {
const splitedQuotes = str.replace(/'/g, `', "'", '`);
return `concat('${splitedQuotes}', '')`;
};
const clickByText = async (page, text) => {
const escapedText = escapeXpathString(text);
const linkHandlers = await page.$x(`//a[contains(text(), ${escapedText})]`);