void function(){ "use strict" /* * Manage and Import / Export snippets from chrome (2016) * hacked together by: http://github.com/soundyogi * inspired by: aaran etc // TODO * ALPHA / SILLY SIDE PROJECT */ let_us("execute some init tests", function(){ if(location.origin !== "chrome-devtools://devtools") throw Error("not in devtools of devtools") ok(location.origin === "chrome-devtools://devtools", 'we are in devtools of devtools, good to go') }) const state = { scriptSnippets: [], lastIdentifier: 0, gui_switches: { rename: true, format: "json", review: false } } window.state = state const style = ` ` const markup = `
Drop Files Here
    ` /* Main logic */ const app_window = create_window("menubar=false, height=700, width=700", "chrome snippets import/export") const document = app_window.document let_us("bootstrap the whole thing", function(){ init() }) function init(){ setupGUI() state.scriptSnippets = [] state.lastIdentifier = 0 state.gui_switches = { rename: true, format: "json", review: false } get_prefs( 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("review").on("change", handle_gui_switches) getID("import_files").on("change", import_files) 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) } function handle_gui_switches(ev){ const target = ev.target const opt = state.gui_switches console.log(target.value) 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() } } function update(){ render_list() } 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 a.innerHTML = snippet.name li.appendChild(a) ul.appendChild(li) }) } /* Helpers */ function import_files(event){ 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 add_snippet(fileName, content_string) } function set_pref(name, data_string){ InspectorFrontendHost.setPreference(name, data_string) } function get_prefs(cb){ InspectorFrontendHost.getPreferences(function(prefs){ cb(prefs) }) } function get_snippets(cb){ get_prefs(function(prefs){ cb(prefs.scriptSnippets) }) } function save_snippets(){ set_pref( "scriptSnippets", serialize(state.scriptSnippets) ) set_pref( "scriptSnippets_lastIdentifier", state.lastIdentifier) load_snippets() } function reset_snippets(){ prompt("DELETE ALL SNIPPETS IN DEVTOOLS? (this is not working right now)") // TODO: too risky for dev return 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 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 getDownloadFileName(count) { var abbrevCount; var d = new Date(); var fileName = 'chrome-snippets-' + count + '-'; fileName += d.getFullYear(); var month = d.getMonth() + 1; fileName += "-" + ((month < 10) ? "0" + month : month); //$NON-NLS-1$ // TODO Please note getDay() returns the day of week, // see http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.5.16 var day = d.getDate(); fileName += "-" + ((day < 10) ? "0" + day : day); //$NON-NLS-1$ var hours = d.getHours(); fileName += "T" + ((hours < 10) ? "0" + hours : hours); //$NON-NLS-1$ var minutes = d.getMinutes(); fileName += ((minutes < 10) ? "0" + minutes : minutes); var seconds = d.getSeconds(); fileName += ((seconds < 10) ? "0" + seconds : seconds); var timeZoneOffset = -d.getTimezoneOffset(); var offsetMinutes = timeZoneOffset % 60; var offsetHours = (timeZoneOffset - offsetMinutes) / 60; // TODO FIXME >= 0 ? fileName += (offsetHours > 0 ? "+" : "") + ((offsetHours < 10) ? "0" + offsetHours : offsetHours) + ((offsetMinutes < 10) ? "0" + offsetMinutes : offsetMinutes); //$NON-NLS-2$ //$NON-NLS-1$ fileName += '.json'; return fileName; } 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("export a json file", ()=>{ }) /* let_us("import a snippet from bgrins", ()=> { const brings_snippets = [ 'allcolors' ] brings_snippets.forEach(()=>{ request('https://raw.githubusercontent.com/bgrins/devtools-snippets/master/snippets/allcolors/allcolors.js', function(request){ var snippet = request.currentTarget.response || request.target.responseText; }) }) */ /* 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}` ) } } }("thank you for reading this")