-
-
Save soundyogi/03df95505604c8351212 to your computer and use it in GitHub Desktop.
void function() { "use strict" | |
/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! WIP DO NOT USE WIP !!!!!!!!!!!!!!!!!!!!! | |
DO NOT USE THIS YET. | |
USE THE 2016 VERSION BELOW PLEASE. | |
WWWWWWWW WWWWWWWWIIIIIIIIIIPPPPPPPPPPPPPPPPP | |
W::::::W W::::::WI::::::::IP::::::::::::::::P | |
W::::::W W::::::WI::::::::IP::::::PPPPPP:::::P | |
W::::::W W::::::WII::::::IIPP:::::P P:::::P | |
W:::::W WWWWW W:::::W I::::I P::::P P:::::P | |
W:::::W W:::::W W:::::W I::::I P::::P P:::::P | |
W:::::W W:::::::W W:::::W I::::I P::::PPPPPP:::::P | |
W:::::W W:::::::::W W:::::W I::::I P:::::::::::::PP | |
W:::::W W:::::W:::::W W:::::W I::::I P::::PPPPPPPPP | |
W:::::W W:::::W W:::::W W:::::W I::::I P::::P | |
W:::::W:::::W W:::::W:::::W I::::I P::::P | |
W:::::::::W W:::::::::W I::::I P::::P | |
W:::::::W W:::::::W II::::::IIPP::::::PP | |
W:::::W W:::::W I::::::::IP::::::::P | |
W:::W W:::W I::::::::IP::::::::P | |
WWW WWW IIIIIIIIIIPPPPPPPPPP | |
* Manage and Import/Export Chrome Snippets (2018) | |
* by: http://github.com/soundyogi | |
* inspired by: https://github.com/bgrins/devtools-snippets/blob/master/import-export/chrome/devtools_import_export.js | |
*/ | |
// - Templates | |
// - Test Harness | |
// - Diy Redux | |
// - Main | |
// - Util | |
// - CSS | |
// Templates | |
// | |
function Layout({getState}){ return ` | |
<article> | |
<header><h1>Chrome Export</h1></header> | |
${sideMenu({getState})} | |
<main> | |
<h2>Current snippets buffer / state / preview: </h2> | |
${getState().scriptSnippets.forEach((snippet) => { | |
return ` | |
<li>${snippet}</li> | |
`})} | |
</main> | |
${outMenu({getState})} | |
<footer></footer> | |
</article> | |
`} | |
function sideMenu({getState}) { return ` | |
<aside> | |
<nav> | |
<h3>--> Input</h3> | |
<ul> | |
<li> | |
<label> load chrome snippets: </label> | |
<button id=${uuidv4()} onclick='dispatch(events.snippetsFetchRequested())'> (re)init </button> | |
</li> | |
<li> | |
<label> on name conflicts: </label> | |
<select onchange='( x => {console.log(x,event); dispatch(events.snippetsFetchRequested(event))} )()' id='rename'> | |
<option value='true'>Rename Import Files</option> | |
<option value="false">Overwrite Snippets</option> | |
</select> | |
</li> | |
<li> | |
<dropzone> | |
<div>Click/Drop .js or .json</div> | |
<input id="drop_files" type='file' multiple='true'/> | |
</dropzone> | |
<label>append files or replace everything? | |
<select id='append'> | |
<option value='true'>Append</option> | |
<option value="false">Replace</option> | |
</select> | |
</label> | |
</li> | |
<li> | |
import files from external sources: | |
<button id="external_bgrins">load some scripts from bgrins/devtools-snippets repo</button> | |
<button id="external_bahmutov">load some scripts from bahmutov/code-snippets repo</button> | |
</li> | |
</ul> | |
</nav> | |
</aside> | |
`}; | |
function outMenu({getState}){ return ` | |
<out> | |
<nav> | |
<h3>Output --></h3> | |
<ul> | |
<li> | |
<button id="export_snippets">export</button> | |
<select id='format'> | |
<option value="json">Single .json</option> | |
<option value="js">Multiple .js</option> | |
</select> | |
</li> | |
<li> | |
<button id="save_snippets">Save to Chrome</button> | |
</li> | |
<li> | |
<button id="reset_snippets">DELETE all on Chrome</button> | |
</li> | |
</ul> | |
</nav> | |
</out> | |
`} | |
// Test Harness | |
// | |
function log(...x) { | |
return console.log(...x) | |
} | |
function test(suiteName, f) { | |
log(`Test: ${suiteName}`) | |
f({ok}) | |
} | |
function ok(expr, msg) { | |
expr ? log(' %c!pass:' + msg, 'color:green') : log(' %c?fail:' + msg, 'color:red') | |
} | |
// INIT TEST | |
test('selftest', function(t) { | |
t.ok(true, ' I pass') | |
t.ok(false, 'I fail') | |
}) | |
test("are we inspecting devtools?", ()=>{ | |
if (location.origin !== "chrome-devtools://devtools") | |
console.log("not in devtools of devtools / please inspect devtools again with: (ctrl+shift+i)") | |
ok(location.origin === "chrome-devtools://devtools", 'we are in devtools of devtools, good to go') | |
}) | |
// Naive Redux | |
// | |
function createStore(rootReducer, initialState, storeEnhancer) { | |
const createStore = storeEnhancer | |
? storeEnhancer(_createStore) | |
: _createStore | |
; | |
return createStore(); | |
function _createStore() { | |
if (!rootReducer) throw Error('rootReducer is missing') | |
const _mapSubscribers = {} | |
const _rootReducer = rootReducer | |
const _store = { | |
dispatch: baseDispatch, | |
getState, | |
subscribe | |
} | |
let _state = initialState | |
return _store; | |
function getState() { | |
return _state | |
} | |
function subscribe(f) { | |
_mapSubscribers[uuidv4()] = f | |
} | |
function baseDispatch(action) { | |
if (!action || !action.type) throw Error("cant call dispatch without action. stupid."); | |
_state = _rootReducer(_state, action) | |
for (var subscriberKey in _mapSubscribers) | |
_mapSubscribers[subscriberKey] ? _mapSubscribers[subscriberKey]() : null; | |
return true; | |
} | |
} | |
} | |
function applyMiddleware(...middlewares) { | |
return createStore => (...args) => { | |
const store = createStore(...args) | |
let chain = [] | |
let dispatch | |
const middlewareAPI = { | |
getState: store.getState, | |
dispatch: (...args) => dispatch(...args) | |
} | |
chain = middlewares.map(middleware => middleware(middlewareAPI)) | |
dispatch = compose(...chain)(store.dispatch) | |
return { | |
...store, | |
dispatch | |
} | |
} | |
} | |
// Middleware | |
// | |
const logger = store => next => action => { | |
if(!action.type && action instanceof Function) console.log('thunk: '+action.name) | |
else { console.info('event: ', action) } | |
let result = next(action) | |
return result | |
} | |
const crashReporter = store => next => action => { | |
try { | |
return next(action) | |
} catch (err) { | |
console.error('Caught an exception!', err) | |
throw err | |
} | |
} | |
const vanillaPromise = store => next => action => { | |
if (typeof action.then !== 'function') { | |
return next(action) | |
} | |
return Promise.resolve(action).then(store.dispatch) | |
} | |
const thunk = store => next => action => | |
typeof action === 'function' | |
? action(store.dispatch, store.getState) | |
: next(action) | |
/* | |
function combineReducers(reducerObject:Object):function{} | |
Combines Reducers by returning a Reducer Reducing Reducers | |
*/ | |
function combineReducers(reducerObject){ | |
function rootReducer(state, action){ | |
const newState = {} | |
Object.keys(reducerObject).reduce( (newState, currentKey) => { | |
if(!state) state = {} | |
// if(!state[currentKey]) state[currentKey] = undefined; | |
newState[currentKey] = reducerObject[currentKey](state[currentKey], action) | |
return newState | |
}, newState) | |
return newState | |
} | |
return rootReducer | |
} | |
// Snippets 'Duck' | |
// | |
// Actions | |
// | |
const SNIPPETS_FETCH_REQUESTED = 'SNIPPETS_FETCH_REQUESTED' | |
const SNIPPETS_FETCHED = 'SNIPPETS_FETCHED' | |
const SNIPPET_ADDED = 'SNIPPET_ADDED' | |
const SNIPPET_REMOVED = 'SNIPPET_REMOVED' | |
// Action Creators / Thunk Creators | |
// | |
function snippetsFetchRequested(){ | |
return function snippetsFetchRequestedThunk(dispatch, getState){ | |
dispatch({type: SNIPPETS_FETCH_REQUESTED}) | |
InspectorFrontendHost.getPreferences(prefs=>{ | |
const lastScriptSnippets = prefs.scriptSnippets | |
const snippets = deserialize(lastScriptSnippets) | |
const lastIdentifier = prefs.scriptSnippets_lastIdentifier | |
dispatch(snippetsFetched({snippets, lastIdentifier})) | |
}) | |
} | |
} | |
function snippetsFetched(payload){ | |
return {type: SNIPPETS_FETCHED, payload} | |
} | |
function snippetAdded(){} | |
function snippetRemoved(){} | |
const actionCreators = { | |
snippetsFetchRequested, | |
snippetsFetched, | |
} | |
function import_files(event){ | |
if(!state.gui_switches.append) state.scriptSnippets = [] | |
const files = event.target.files | |
const stack = Object.keys(files) | |
.forEach((key)=>{ | |
const file = files[key] | |
const reader = new FileReader() | |
reader.fileName = file.name | |
reader.onerror = (()=> {throw Error}) | |
reader.onabort = (()=> {throw Error}) | |
reader.onload = file_loaded | |
reader.readAsText(file) | |
}) | |
function file_loaded(event){ | |
const content_string = event.target.result | |
const fileName = event.target.fileName | |
const fileNameNoExt = /(.+?)(\.[^.]*$|$)/.exec(fileName)[1] | |
const ext = /\.[0-9a-z]+$/.exec(fileName)[0] | |
if(ext === ".json") return import_json(content_string) | |
return add_snippet(fileNameNoExt, content_string) | |
} | |
} | |
function import_json(content_string){ | |
var json_data = deserialize(content_string) | |
json_data.snippets.forEach(snippet => { | |
add_snippet(snippet.name, snippet.content) | |
}) | |
} | |
function set_pref(name, data_string){ | |
InspectorFrontendHost.setPreference(name, data_string) | |
} | |
function save_snippets(){ | |
set_pref( "scriptSnippets", serialize(state.scriptSnippets) ) | |
set_pref( "scriptSnippets_lastIdentifier", state.lastIdentifier) | |
prompt('restart chrome now!') | |
} | |
function reset_snippets(){ | |
var choice = window.confirm("DELETE ALL SNIPPETS IN DEVTOOLS?") | |
if(choice) clear_chrome_snippets() | |
init() | |
} | |
function clear_chrome_snippets(){ | |
set_pref("scriptSnippets", "[]") | |
set_pref("scriptSnippets_lastIdentifier", "0") | |
} | |
function add_snippet(name, snippet_content_string){ | |
if(is_duplicate(name, state.scriptSnippets)) { | |
if(!state.gui_switches.rename) return state.scriptSnippets[name] = snippet_content_string | |
return add_snippet(name+"copy", snippet_content_string) | |
} | |
const currentIdentifier = serialize(parseInt(state.lastIdentifier)+1) | |
const new_snip = { | |
content: snippet_content_string, | |
id: currentIdentifier, | |
name: name | |
} | |
state.scriptSnippets.push( new_snip ) | |
state.lastIdentifier = currentIdentifier | |
update() | |
} | |
function external_bgrins(){ | |
const brings_snippets = [ | |
'allcolors', | |
'cachebuster', | |
'cssreload', | |
'cssprettifier', | |
'hashlink' | |
] | |
brings_snippets.forEach((snippet)=>{ | |
request('https://raw.githubusercontent.com/bgrins/devtools-snippets/master/snippets/'+snippet+'/'+snippet+'.js', function(request){ | |
const snippet_content_string = request.target.response | |
add_snippet(snippet, snippet_content_string) | |
}) | |
}) | |
} | |
function external_bahmutov(){ | |
const bahmutov_snippets = [ | |
'timing', | |
'profile-method-call', | |
'time-method-call' | |
] | |
bahmutov_snippets.forEach((snippet)=>{ | |
request('https://raw.githubusercontent.com/bahmutov/code-snippets/master/'+snippet+'.js', function(request){ | |
const snippet_content_string = request.target.response | |
add_snippet(snippet, snippet_content_string) | |
}) | |
}) | |
} | |
function export_snippets(){ | |
if(state.gui_switches.format === "json") return download_json() | |
return download_js() | |
} | |
function download_js(){ | |
state.scriptSnippets.forEach((snippet)=>{ | |
download(snippet.name+'.js', snippet.content) | |
}) | |
} | |
function download_json(){ | |
console.log("json") | |
const fileName = serialize(Date()) | |
const json_data = serialize({'snippets': state.scriptSnippets}, ['snippets', 'name', 'content'], 2) | |
download(fileName+".json", json_data) | |
} | |
// Reducer | |
// | |
const snippetsShape = { | |
scriptSnippets: [], | |
lastIdentifier: 0, | |
//ui | |
rename: true, | |
format: 'json', | |
review: false, | |
append: true | |
} | |
function snippetsReducer(state = snippetsShape, {TYPE, PL}) { | |
if(TYPE === SNIPPETS_FETCHED) return {...state, scriptSnippets: PL.snippets} | |
return state | |
} | |
// Main logic | |
// | |
const app_window = createWindow("menubar=false, width=1024, height=768", "Chrome Snippets Import/Export/Manager") | |
const store = createStore(snippetsReducer, undefined, applyMiddleware(logger,thunk,vanillaPromise,crashReporter)) | |
app_window.dispatch = store.dispatch | |
app_window.getState = store.getState | |
app_window.events = actionCreators | |
app_window.document.head.innerHTML = style(); | |
store.subscribe(function(){ | |
// console.log(JSON.stringify(store.getState())) | |
render(app_window.document.body, Layout) | |
}) | |
store.dispatch({type: 'first', payload: Date.now()}) | |
// UTIL | |
// | |
function render(mountNode, template){ | |
mountNode.innerHTML = template({getState: store.getState}); | |
} | |
function compose(...funcs) { | |
if (funcs.length === 0) { | |
return arg => arg | |
} | |
if (funcs.length === 1) { | |
return funcs[0] | |
} | |
return funcs.reduce((a, b) => (...args) => a(b(...args))) | |
} | |
function uuidv4() { | |
// RFC4122 version 4 compliant | |
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | |
var r = Math.random() * 16 | 0 | |
, v = c == 'x' ? r : (r & 0x3 | 0x8); | |
return v.toString(16); | |
}); | |
} | |
function request(url, success) { | |
var xhr = new XMLHttpRequest(); | |
xhr.open('GET', url); | |
xhr.onload = success; | |
xhr.send(); | |
return xhr; | |
} | |
function serialize(object, ...rest) { | |
if (!object) throw Error("serialize needs input") | |
return JSON.stringify(object, ...rest) | |
} | |
function deserialize(string) { | |
if (typeof string !== "string") throw Error("deserialize needs a string") | |
if (string === "") throw Error("no snippets present") | |
return JSON.parse(string) | |
} | |
function download(name, data) { | |
const Blob = new window.Blob([data],{ 'type': 'text/utf-8' }) | |
const a = app_window.document.createElement('a') | |
a.href = URL.createObjectURL(Blob) | |
a.download = name | |
a.click() | |
} | |
function is_duplicate(name, snippets_arr) { | |
const result = snippets_arr.filter(function(snippet) { | |
return snippet.name === name | |
}) | |
if (result.length === 0) return false | |
return true | |
} | |
function createWindow(options, title) { | |
const w = window.open("", "", options) | |
w.document.title = title | |
return w | |
} | |
// CSS | |
// | |
function style() { return ` | |
<style> | |
body { | |
font-family: 'Open Sans', sans-serif; | |
} | |
article { | |
display: grid; | |
grid-template-columns: auto minmax(min-content, 1fr); | |
grid-template-rows: auto minmax(min-content, 1fr) auto; | |
max-width: 800px; | |
margin: 0 auto; | |
} | |
header { | |
grid-column: 1 / span 3; | |
grid-row: 1; | |
} | |
aside { | |
grid-column: 1; | |
grid-row: 2; | |
background-color: #F0F0F2; | |
padding: 5px 10px; | |
} | |
out { | |
grid-column: 3; | |
grid-row: 2; | |
background-color: #F0F0F2; | |
padding: 5px 10px; | |
} | |
main { | |
grid-column: 2; | |
grid-row: 2; | |
align-self: start; | |
margin-left: 18px; | |
} | |
footer { | |
grid-column: 1 / span 2; | |
grid-row: 3; | |
background-color: #474F59; | |
margin-top: 20px; | |
padding: 5px 10px; | |
color: white; | |
margin-bottom: 20px; | |
} | |
#drop_files { | |
opacity: 0; | |
width: 100%; | |
height: 20vh; | |
} | |
dropzone { | |
cursor: pointer; | |
border: 1px black dotted; | |
font-weight: bold; | |
font-size: 1em; | |
text-align: center; | |
} | |
</style> | |
` | |
} | |
}("live long and prosper"); |
void function(){ | |
"use strict" | |
/* | |
222222222222222 000000000 1111111 66666666 | |
2:::::::::::::::22 00:::::::::00 1::::::1 6::::::6 | |
2::::::222222:::::2 00:::::::::::::00 1:::::::1 6::::::6 | |
2222222 2:::::2 0:::::::000:::::::0111:::::1 6::::::6 | |
2:::::2 0::::::0 0::::::0 1::::1 6::::::6 | |
2:::::2 0:::::0 0:::::0 1::::1 6::::::6 | |
2222::::2 0:::::0 0:::::0 1::::1 6::::::6 | |
22222::::::22 0:::::0 000 0:::::0 1::::l 6::::::::66666 | |
22::::::::222 0:::::0 000 0:::::0 1::::l 6::::::::::::::66 | |
2:::::22222 0:::::0 0:::::0 1::::l 6::::::66666:::::6 | |
2:::::2 0:::::0 0:::::0 1::::l 6:::::6 6:::::6 | |
2:::::2 0::::::0 0::::::0 1::::l 6:::::6 6:::::6 | |
2:::::2 2222220:::::::000:::::::0111::::::1116::::::66666::::::6 | |
2::::::2222222:::::2 00:::::::::::::00 1::::::::::1 66:::::::::::::66 | |
2::::::::::::::::::2 00:::::::::00 1::::::::::1 66:::::::::66 | |
22222222222222222222 000000000 111111111111 666666666 | |
* Manage and Import / Export snippets from chrome (2016) | |
* hacked together by: http://github.com/soundyogi | |
* inspired by: https://github.com/bgrins/devtools-snippets/blob/master/import-export/chrome/devtools_import_export.js | |
* ALPHA / SILLY SIDE PROJECT | |
*/ | |
let_us("execute some init tests", () => { | |
if(location.origin !== "chrome-devtools://devtools") throw Error("not in devtools of devtools / please inspect devtools again (ctrl+shift+i)") | |
ok(location.origin === "chrome-devtools://devtools", 'we are in devtools of devtools, good to go') | |
}) | |
const state = { | |
scriptSnippets: [], | |
} | |
window.state = state | |
const style = ` | |
<style> | |
body{ | |
margin: 0; | |
padding: 0; | |
} | |
grid { | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
-webkit-flex-flow: column; | |
} | |
column { | |
display: flex; | |
-webkit-flex-flow: column; | |
width: 30vw; | |
} | |
row { | |
display: flex; | |
-webkit-flex-flow: row; | |
width: 90vw; | |
margin-bottom: 2vh; | |
} | |
item { | |
background: tomato; | |
min-height: 13vh; | |
color: white; | |
font-weight: bold; | |
font-size: 1.5em; | |
text-align: center; | |
padding: 20px; | |
} | |
#drop_files { | |
opacity: 0; | |
width: 100%; | |
height: 20vh; | |
} | |
dropzone { | |
cursor: pointer; | |
border: 1px black dotted; | |
font-weight: bold; | |
font-size: 1em; | |
text-align: center; | |
} | |
</style> | |
` | |
const markup = ` | |
<grid> | |
<row> | |
<column> | |
<item> load chrome snippets: | |
<button id="init">(re)init</button> | |
</item> | |
</column> | |
<column> | |
<item> | |
<label>on name conflicts: | |
<select id='rename'> | |
<option value='true'>Rename Import Files</option> | |
<option value="false">Overwrite Snippets</option> | |
</select> | |
</label> | |
</item> | |
</column> | |
<column> | |
<item> | |
<button id="export_snippets">export</button> | |
<select id='format'> | |
<option value="json">Single .json</option> | |
<option value="js">Multiple .js</option> | |
</select> | |
</item> | |
</column> | |
<column> | |
<item> | |
<button id="save_snippets">Save to Chrome</button> | |
</item> | |
</column> | |
<column> | |
<item> | |
<button id="reset_snippets">DELETE all on Chrome</button> | |
</item> | |
</column> | |
</row> | |
<row> | |
<column> | |
<dropzone> | |
<div>Click/Drop .js or .json</div> | |
<input id="drop_files" type='file' multiple='true'/> | |
</dropzone> | |
<label>append files or replace everything? | |
<select id='append'> | |
<option value='true'>Append</option> | |
<option value="false">Replace</option> | |
</select> | |
</label> | |
</column> | |
<column>===== snippets preview =====<ul id="state.scriptSnippets"></ul></column> | |
<column>import files from external sources: | |
<button id="external_bgrins">load some scripts from bgrins/devtools-snippets repo</button> | |
<button id="external_bahmutov">load some scripts from bahmutov/code-snippets repo</button> | |
</column> | |
</row> | |
</grid> | |
` | |
/* Main logic | |
*/ | |
const app_window = create_window("menubar=false, height=700, width=1000", "chrome snippets import/export - ALPHA USE AT OWN RISK") | |
const document = app_window.document | |
let_us("bootstrap the whole thing", () => { | |
init() | |
}) | |
function init(){ | |
setupGUI() | |
state.scriptSnippets = [] | |
state.lastIdentifier = 0 | |
state.gui_switches = { | |
rename: true, | |
format: "json", | |
review: false, | |
append: true | |
} | |
InspectorFrontendHost.getPreferences( prefs => { | |
const lastScriptSnippets = prefs.scriptSnippets | |
state.scriptSnippets = deserialize(lastScriptSnippets) | |
state.lastIdentifier = prefs.scriptSnippets_lastIdentifier | |
update() | |
}) | |
} | |
function setupGUI(){ | |
app_window.document.body.innerHTML = style+markup | |
getID("format").on("change", handle_gui_switches) | |
getID("rename").on("change", handle_gui_switches) | |
getID("append").on("change", handle_gui_switches) | |
getID("drop_files").on("change", import_files) | |
getID("export_snippets").on("click", export_snippets) | |
getID("init").on("click", init) | |
getID("save_snippets").on("click", save_snippets) | |
getID("reset_snippets").on("click", reset_snippets) | |
getID("external_bgrins").on("click", external_bgrins) | |
getID("external_bahmutov").on("click", external_bahmutov) | |
} | |
function handle_gui_switches(ev){ | |
const target = ev.target | |
const opt = state.gui_switches | |
if(target.id === 'format') { | |
opt.format = target.value | |
return update() | |
} | |
if(target.id === 'rename') { | |
opt.rename = !target.value | |
return update() | |
} | |
if(target.id === 'review') { | |
opt.review = !opt.review | |
return update() | |
} | |
if(target.id === 'append') { | |
opt.append = !target.value | |
return update() | |
} | |
} | |
function update(){ | |
render_list() | |
console.log(state.gui_switches) | |
} | |
function render_list(){ | |
const ul = app_window.document.getElementById("state.scriptSnippets") | |
ul.innerHTML = '' | |
state.scriptSnippets.forEach((snippet)=>{ | |
const li = document.createElement('li') | |
//const a = document.createElement('a') | |
//a.href = snippet.name | |
li.innerHTML = snippet.name | |
//li.appendChild(a) | |
ul.appendChild(li) | |
}) | |
} | |
/* Helpers | |
*/ | |
function import_files(event){ | |
if(!state.gui_switches.append) state.scriptSnippets = [] | |
const files = event.target.files | |
const stack = Object.keys(files) | |
.forEach((key)=>{ | |
const file = files[key] | |
const reader = new FileReader() | |
reader.fileName = file.name | |
reader.onerror = (()=> {throw Error}) | |
reader.onabort = (()=> {throw Error}) | |
reader.onload = file_loaded | |
reader.readAsText(file) | |
}) | |
} | |
function file_loaded(event){ | |
const content_string = event.target.result | |
const fileName = event.target.fileName | |
const fileNameNoExt = /(.+?)(\.[^.]*$|$)/.exec(fileName)[1] | |
const ext = /\.[0-9a-z]+$/.exec(fileName)[0] | |
if(ext === ".json") return import_json(content_string) | |
return add_snippet(fileNameNoExt, content_string) | |
} | |
function import_json(content_string){ | |
var json_data = deserialize(content_string) | |
json_data.snippets.forEach(snippet => { | |
add_snippet(snippet.name, snippet.content) | |
}) | |
} | |
function set_pref(name, data_string){ | |
InspectorFrontendHost.setPreference(name, data_string) | |
} | |
function save_snippets(){ | |
set_pref( "scriptSnippets", serialize(state.scriptSnippets) ) | |
set_pref( "scriptSnippets_lastIdentifier", state.lastIdentifier) | |
prompt('restart chrome now!') | |
} | |
function reset_snippets(){ | |
var choice = window.confirm("DELETE ALL SNIPPETS IN DEVTOOLS?") | |
if(choice) clear_chrome_snippets() | |
init() | |
} | |
function clear_chrome_snippets(){ | |
set_pref("scriptSnippets", "[]") | |
set_pref("scriptSnippets_lastIdentifier", "0") | |
} | |
function add_snippet(name, snippet_content_string){ | |
if(is_duplicate(name, state.scriptSnippets)) { | |
if(!state.gui_switches.rename) return state.scriptSnippets[name] = snippet_content_string | |
return add_snippet(name+"copy", snippet_content_string) | |
} | |
const currentIdentifier = serialize(parseInt(state.lastIdentifier)+1) | |
const new_snip = { | |
content: snippet_content_string, | |
id: currentIdentifier, | |
name: name | |
} | |
state.scriptSnippets.push( new_snip ) | |
state.lastIdentifier = currentIdentifier | |
update() | |
} | |
function external_bgrins(){ | |
const brings_snippets = [ | |
'allcolors', | |
'cachebuster', | |
'cssreload', | |
'cssprettifier', | |
'hashlink' | |
] | |
brings_snippets.forEach((snippet)=>{ | |
request('https://raw.githubusercontent.com/bgrins/devtools-snippets/master/snippets/'+snippet+'/'+snippet+'.js', function(request){ | |
const snippet_content_string = request.target.response | |
add_snippet(snippet, snippet_content_string) | |
}) | |
}) | |
} | |
function external_bahmutov(){ | |
const bahmutov_snippets = [ | |
'timing', | |
'profile-method-call', | |
'time-method-call' | |
] | |
bahmutov_snippets.forEach((snippet)=>{ | |
request('https://raw.githubusercontent.com/bahmutov/code-snippets/master/'+snippet+'.js', function(request){ | |
const snippet_content_string = request.target.response | |
add_snippet(snippet, snippet_content_string) | |
}) | |
}) | |
} | |
function export_snippets(){ | |
if(state.gui_switches.format === "json") return download_json() | |
return download_js() | |
} | |
function download_js(){ | |
state.scriptSnippets.forEach((snippet)=>{ | |
download(snippet.name+'.js', snippet.content) | |
}) | |
} | |
function download_json(){ | |
console.log("json") | |
const fileName = serialize(Date()) | |
const json_data = serialize({'snippets': state.scriptSnippets}, ['snippets', 'name', 'content'], 2) | |
download(fileName+".json", json_data) | |
} | |
/* util & shorthand | |
*/ | |
function request(url, success) { | |
var xhr = new XMLHttpRequest(); | |
xhr.open('GET', url); | |
xhr.onload = success; | |
xhr.send(); | |
return xhr; | |
} | |
function getID(id){ | |
const element = app_window.document.getElementById(id) | |
element.on = function on(event_name, fn){ | |
this.addEventListener(event_name, fn) | |
return this | |
} | |
return element | |
} | |
function serialize(object, ...rest){ | |
if(!object) throw Error("serialize needs an object") | |
return JSON.stringify(object, ...rest) | |
} | |
function deserialize(string){ | |
if(typeof string !== "string") throw Error("deserialize needs a string") | |
if(string === "") throw Error("no snippets present") | |
return JSON.parse(string) | |
} | |
function download(name, data){ | |
const Blob = new window.Blob([data],{ | |
'type': 'text/utf-8' | |
}) | |
const a = document.createElement('a') | |
a.href = URL.createObjectURL(Blob) | |
a.download = name | |
a.click() | |
} | |
function is_duplicate(name, snippets_arr){ | |
const result = snippets_arr.filter(function(snippet){ | |
return snippet.name === name | |
}) | |
if(result.length === 0) return false | |
return true | |
} | |
function create_window(options, title){ | |
const w = window.open("", "", options) | |
w.document.title = title | |
return w | |
} | |
/* | |
* UNIT TESTS | |
*/ | |
let_us("write some tests", ()=>{ | |
// TODO | |
// TDD tests are deleted now / remove harness | |
}) | |
/* Nanoharness | |
*/ | |
function let_us(msg,f){ | |
console.log("we_will: "+msg) | |
try { f() } | |
catch (exception) { | |
console.warn(exception.stack.replace(/:(\d+):(\d+)/g, "$& (Line $1, Column $2)")) | |
} | |
} | |
function ok(expr, msg){ | |
log(expr, msg) | |
} | |
function log(expr, msg){ | |
expr ? console.log("!pass "+msg) : console.log("?fail "+msg) | |
} | |
function html_log(){ | |
const queue = [] | |
return function log(expr, msg) { | |
queue.push( expr ? `!pass ${msg}` : `?fail ${msg}` ) | |
} | |
} | |
}("goodbye and thanks for all the fish") |
Great work 👍
👍
thanks, now I hopefully have the motivation to finish it and make it a "full" snippets manager.
Id love to store them somewhere online instead of .json, I still keep losing scripts.
And more than 50+ Scripts are very unmanagable still right now.
This is awesome, thank you 👏
the new version is still in progress, please use the 2016 one until it is finished.
2016 is no more working :'(
Really? Oh no :O !!!
Let me get back to you soon...
Using version 2016, try changing function create_window
to the following:
function create_window(options, title){
var id = (new Date()).getTime();
const w = window.open('' , id, options);
w.document.title = title
return w
}
I hope this helps.
2016 is no more working :'(
Did you inpect the inpector window?
You have to open inspector: ctrl+shift+i
Then undock it in a single window
Then again: ctrl+shift+i
Now paste the manager, does it work?
I will try to finish the new one soon
Thanks a lot, great work
Great work
Open Inspector (ctrl+shift+I)
Undock Inspector in Seperate Window
Inspect Inspector (ctrl+shift+i)
Paste Script Into Console: