From ad8f1acdbd265b72c783750c73414b9029192f7f Mon Sep 17 00:00:00 2001 From: Jeremy Dormitzer Date: Wed, 7 Feb 2018 08:39:12 -0500 Subject: [PATCH] Improve the build process; add Makefile --- .gitignore | 3 +- Makefile | 16 ++++ ext/js/browser-polyfill.min.js.map | 1 - ext/manifest.json | 2 - ext/sidebar.html | 1 - project.clj | 77 +++++++++++++------ .../looped_in/background.cljs | 0 src/{ => background}/looped_in/content.cljs | 0 src/{ => lib}/looped_in/components.cljs | 0 src/{ => lib}/looped_in/hackernews.cljs | 0 src/{ => lib}/looped_in/logging.cljs | 0 src/{ => lib}/looped_in/promises.cljs | 0 src/{ => sidebar}/looped_in/sidebar.cljs | 0 13 files changed, 72 insertions(+), 28 deletions(-) create mode 100644 Makefile delete mode 100644 ext/js/browser-polyfill.min.js.map rename src/{ => background}/looped_in/background.cljs (100%) rename src/{ => background}/looped_in/content.cljs (100%) rename src/{ => lib}/looped_in/components.cljs (100%) rename src/{ => lib}/looped_in/hackernews.cljs (100%) rename src/{ => lib}/looped_in/logging.cljs (100%) rename src/{ => lib}/looped_in/promises.cljs (100%) rename src/{ => sidebar}/looped_in/sidebar.cljs (100%) diff --git a/.gitignore b/.gitignore index 3e6bf14..c713f5c 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ pom.xml.asc .hg/ ext/js/generated/ .cljs_rhino_repl -profiles.clj \ No newline at end of file +profiles.clj +dist \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..388b67a --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +dev : + lein cljsbuild once + rm -rf ext/js/generated/out-* + +prod : + lein with-profile prod cljsbuild once + rm -rf ext/js/generated/out-* + +package : clean prod + (cd ext; zip -r looped-in.zip * -x "*.DS_Store") + mkdir -p dist + mv ext/looped-in.zip dist + +clean : + rm -rf ext/js/generated + rm -rf dist diff --git a/ext/js/browser-polyfill.min.js.map b/ext/js/browser-polyfill.min.js.map deleted file mode 100644 index 0f3c266..0000000 --- a/ext/js/browser-polyfill.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["browser-polyfill.js"],"names":["global","factory","define","amd","exports","module","mod","browser","apiMetadata","keys","length","Error","DefaultWeakMap","WeakMap","constructor","createItem","items","get","key","has","set","isThenable","value","then","makeCallback","promise","metadata","callbackArgs","chrome","runtime","lastError","reject","singleCallbackArg","resolve","wrapAsyncFunction","name","pluralizeArguments","numArgs","target","args","minArgs","maxArgs","Promise","wrapMethod","method","wrapper","Proxy","apply","targetMethod","thisObj","call","hasOwnProperty","Function","bind","Object","prototype","wrapObject","wrappers","cache","create","handlers","prop","defineProperty","configurable","enumerable","desc","Reflect","deleteProperty","onMessageWrappers","listener","message","sender","sendResponse","result","error","console","staticWrappers","onMessage","wrapperMap","addListener","hasListener","removeListener","targetObject","assign"],"mappings":"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","file":"browser-polyfill.min.js","sourcesContent":["(function (global, factory) {\n if (typeof define === \"function\" && define.amd) {\n define(\"webextension-polyfill\", [\"module\"], factory);\n } else if (typeof exports !== \"undefined\") {\n factory(module);\n } else {\n var mod = {\n exports: {}\n };\n factory(mod);\n global.browser = mod.exports;\n }\n})(this, function (module) {\n /* webextension-polyfill - v0.2.1 - Mon Jan 08 2018 10:05:36 */\n /* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */\n /* vim: set sts=2 sw=2 et tw=80: */\n /* This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\n \"use strict\";\n\n if (typeof browser === \"undefined\") {\n // Wrapping the bulk of this polyfill in a one-time-use function is a minor\n // optimization for Firefox. Since Spidermonkey does not fully parse the\n // contents of a function until the first time it's called, and since it will\n // never actually need to be called, this allows the polyfill to be included\n // in Firefox nearly for free.\n const wrapAPIs = () => {\n // NOTE: apiMetadata is associated to the content of the api-metadata.json file\n // at build time by replacing the following \"include\" with the content of the\n // JSON file.\n const apiMetadata = {\n \"alarms\": {\n \"clear\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"clearAll\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"get\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"getAll\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n }\n },\n \"bookmarks\": {\n \"create\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"export\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"get\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getChildren\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getRecent\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getTree\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"getSubTree\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"import\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"move\": {\n \"minArgs\": 2,\n \"maxArgs\": 2\n },\n \"remove\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"removeTree\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"search\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"update\": {\n \"minArgs\": 2,\n \"maxArgs\": 2\n }\n },\n \"browserAction\": {\n \"getBadgeBackgroundColor\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getBadgeText\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getPopup\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getTitle\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"setIcon\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n }\n },\n \"commands\": {\n \"getAll\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n }\n },\n \"contextMenus\": {\n \"update\": {\n \"minArgs\": 2,\n \"maxArgs\": 2\n },\n \"remove\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"removeAll\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n }\n },\n \"cookies\": {\n \"get\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getAll\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getAllCookieStores\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"remove\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"set\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n }\n },\n \"devtools\": {\n \"inspectedWindow\": {\n \"eval\": {\n \"minArgs\": 1,\n \"maxArgs\": 2\n }\n },\n \"panels\": {\n \"create\": {\n \"minArgs\": 3,\n \"maxArgs\": 3,\n \"singleCallbackArg\": true\n }\n }\n },\n \"downloads\": {\n \"download\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"cancel\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"erase\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getFileIcon\": {\n \"minArgs\": 1,\n \"maxArgs\": 2\n },\n \"open\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"pause\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"removeFile\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"resume\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"search\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"show\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n }\n },\n \"extension\": {\n \"isAllowedFileSchemeAccess\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"isAllowedIncognitoAccess\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n }\n },\n \"history\": {\n \"addUrl\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getVisits\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"deleteAll\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"deleteRange\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"deleteUrl\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"search\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n }\n },\n \"i18n\": {\n \"detectLanguage\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getAcceptLanguages\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n }\n },\n \"idle\": {\n \"queryState\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n }\n },\n \"management\": {\n \"get\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getAll\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"getSelf\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"uninstallSelf\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n }\n },\n \"notifications\": {\n \"clear\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"create\": {\n \"minArgs\": 1,\n \"maxArgs\": 2\n },\n \"getAll\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"getPermissionLevel\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"update\": {\n \"minArgs\": 2,\n \"maxArgs\": 2\n }\n },\n \"pageAction\": {\n \"getPopup\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getTitle\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"hide\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"setIcon\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"show\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n }\n },\n \"runtime\": {\n \"getBackgroundPage\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"getBrowserInfo\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"getPlatformInfo\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"openOptionsPage\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"requestUpdateCheck\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"sendMessage\": {\n \"minArgs\": 1,\n \"maxArgs\": 3\n },\n \"sendNativeMessage\": {\n \"minArgs\": 2,\n \"maxArgs\": 2\n },\n \"setUninstallURL\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n }\n },\n \"storage\": {\n \"local\": {\n \"clear\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"get\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"getBytesInUse\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"remove\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"set\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n }\n },\n \"managed\": {\n \"get\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"getBytesInUse\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n }\n },\n \"sync\": {\n \"clear\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"get\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"getBytesInUse\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"remove\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"set\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n }\n }\n },\n \"tabs\": {\n \"create\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"captureVisibleTab\": {\n \"minArgs\": 0,\n \"maxArgs\": 2\n },\n \"detectLanguage\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"duplicate\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"executeScript\": {\n \"minArgs\": 1,\n \"maxArgs\": 2\n },\n \"get\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getCurrent\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n },\n \"getZoom\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"getZoomSettings\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"highlight\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"insertCSS\": {\n \"minArgs\": 1,\n \"maxArgs\": 2\n },\n \"move\": {\n \"minArgs\": 2,\n \"maxArgs\": 2\n },\n \"reload\": {\n \"minArgs\": 0,\n \"maxArgs\": 2\n },\n \"remove\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"query\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"removeCSS\": {\n \"minArgs\": 1,\n \"maxArgs\": 2\n },\n \"sendMessage\": {\n \"minArgs\": 2,\n \"maxArgs\": 3\n },\n \"setZoom\": {\n \"minArgs\": 1,\n \"maxArgs\": 2\n },\n \"setZoomSettings\": {\n \"minArgs\": 1,\n \"maxArgs\": 2\n },\n \"update\": {\n \"minArgs\": 1,\n \"maxArgs\": 2\n }\n },\n \"webNavigation\": {\n \"getAllFrames\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"getFrame\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n }\n },\n \"webRequest\": {\n \"handlerBehaviorChanged\": {\n \"minArgs\": 0,\n \"maxArgs\": 0\n }\n },\n \"windows\": {\n \"create\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"get\": {\n \"minArgs\": 1,\n \"maxArgs\": 2\n },\n \"getAll\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"getCurrent\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"getLastFocused\": {\n \"minArgs\": 0,\n \"maxArgs\": 1\n },\n \"remove\": {\n \"minArgs\": 1,\n \"maxArgs\": 1\n },\n \"update\": {\n \"minArgs\": 2,\n \"maxArgs\": 2\n }\n }\n };\n\n if (Object.keys(apiMetadata).length === 0) {\n throw new Error(\"api-metadata.json has not been included in browser-polyfill\");\n }\n\n /**\n * A WeakMap subclass which creates and stores a value for any key which does\n * not exist when accessed, but behaves exactly as an ordinary WeakMap\n * otherwise.\n *\n * @param {function} createItem\n * A function which will be called in order to create the value for any\n * key which does not exist, the first time it is accessed. The\n * function receives, as its only argument, the key being created.\n */\n class DefaultWeakMap extends WeakMap {\n constructor(createItem, items = undefined) {\n super(items);\n this.createItem = createItem;\n }\n\n get(key) {\n if (!this.has(key)) {\n this.set(key, this.createItem(key));\n }\n\n return super.get(key);\n }\n }\n\n /**\n * Returns true if the given object is an object with a `then` method, and can\n * therefore be assumed to behave as a Promise.\n *\n * @param {*} value The value to test.\n * @returns {boolean} True if the value is thenable.\n */\n const isThenable = value => {\n return value && typeof value === \"object\" && typeof value.then === \"function\";\n };\n\n /**\n * Creates and returns a function which, when called, will resolve or reject\n * the given promise based on how it is called:\n *\n * - If, when called, `chrome.runtime.lastError` contains a non-null object,\n * the promise is rejected with that value.\n * - If the function is called with exactly one argument, the promise is\n * resolved to that value.\n * - Otherwise, the promise is resolved to an array containing all of the\n * function's arguments.\n *\n * @param {object} promise\n * An object containing the resolution and rejection functions of a\n * promise.\n * @param {function} promise.resolve\n * The promise's resolution function.\n * @param {function} promise.rejection\n * The promise's rejection function.\n * @param {object} metadata\n * Metadata about the wrapped method which has created the callback.\n * @param {integer} metadata.maxResolvedArgs\n * The maximum number of arguments which may be passed to the\n * callback created by the wrapped async function.\n *\n * @returns {function}\n * The generated callback function.\n */\n const makeCallback = (promise, metadata) => {\n return (...callbackArgs) => {\n if (chrome.runtime.lastError) {\n promise.reject(chrome.runtime.lastError);\n } else if (metadata.singleCallbackArg || callbackArgs.length === 1) {\n promise.resolve(callbackArgs[0]);\n } else {\n promise.resolve(callbackArgs);\n }\n };\n };\n\n /**\n * Creates a wrapper function for a method with the given name and metadata.\n *\n * @param {string} name\n * The name of the method which is being wrapped.\n * @param {object} metadata\n * Metadata about the method being wrapped.\n * @param {integer} metadata.minArgs\n * The minimum number of arguments which must be passed to the\n * function. If called with fewer than this number of arguments, the\n * wrapper will raise an exception.\n * @param {integer} metadata.maxArgs\n * The maximum number of arguments which may be passed to the\n * function. If called with more than this number of arguments, the\n * wrapper will raise an exception.\n * @param {integer} metadata.maxResolvedArgs\n * The maximum number of arguments which may be passed to the\n * callback created by the wrapped async function.\n *\n * @returns {function(object, ...*)}\n * The generated wrapper function.\n */\n const wrapAsyncFunction = (name, metadata) => {\n const pluralizeArguments = numArgs => numArgs == 1 ? \"argument\" : \"arguments\";\n\n return function asyncFunctionWrapper(target, ...args) {\n if (args.length < metadata.minArgs) {\n throw new Error(`Expected at least ${metadata.minArgs} ${pluralizeArguments(metadata.minArgs)} for ${name}(), got ${args.length}`);\n }\n\n if (args.length > metadata.maxArgs) {\n throw new Error(`Expected at most ${metadata.maxArgs} ${pluralizeArguments(metadata.maxArgs)} for ${name}(), got ${args.length}`);\n }\n\n return new Promise((resolve, reject) => {\n target[name](...args, makeCallback({ resolve, reject }, metadata));\n });\n };\n };\n\n /**\n * Wraps an existing method of the target object, so that calls to it are\n * intercepted by the given wrapper function. The wrapper function receives,\n * as its first argument, the original `target` object, followed by each of\n * the arguments passed to the orginal method.\n *\n * @param {object} target\n * The original target object that the wrapped method belongs to.\n * @param {function} method\n * The method being wrapped. This is used as the target of the Proxy\n * object which is created to wrap the method.\n * @param {function} wrapper\n * The wrapper function which is called in place of a direct invocation\n * of the wrapped method.\n *\n * @returns {Proxy}\n * A Proxy object for the given method, which invokes the given wrapper\n * method in its place.\n */\n const wrapMethod = (target, method, wrapper) => {\n return new Proxy(method, {\n apply(targetMethod, thisObj, args) {\n return wrapper.call(thisObj, target, ...args);\n }\n });\n };\n\n let hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);\n\n /**\n * Wraps an object in a Proxy which intercepts and wraps certain methods\n * based on the given `wrappers` and `metadata` objects.\n *\n * @param {object} target\n * The target object to wrap.\n *\n * @param {object} [wrappers = {}]\n * An object tree containing wrapper functions for special cases. Any\n * function present in this object tree is called in place of the\n * method in the same location in the `target` object tree. These\n * wrapper methods are invoked as described in {@see wrapMethod}.\n *\n * @param {object} [metadata = {}]\n * An object tree containing metadata used to automatically generate\n * Promise-based wrapper functions for asynchronous. Any function in\n * the `target` object tree which has a corresponding metadata object\n * in the same location in the `metadata` tree is replaced with an\n * automatically-generated wrapper function, as described in\n * {@see wrapAsyncFunction}\n *\n * @returns {Proxy}\n */\n const wrapObject = (target, wrappers = {}, metadata = {}) => {\n let cache = Object.create(null);\n\n let handlers = {\n has(target, prop) {\n return prop in target || prop in cache;\n },\n\n get(target, prop, receiver) {\n if (prop in cache) {\n return cache[prop];\n }\n\n if (!(prop in target)) {\n return undefined;\n }\n\n let value = target[prop];\n\n if (typeof value === \"function\") {\n // This is a method on the underlying object. Check if we need to do\n // any wrapping.\n\n if (typeof wrappers[prop] === \"function\") {\n // We have a special-case wrapper for this method.\n value = wrapMethod(target, target[prop], wrappers[prop]);\n } else if (hasOwnProperty(metadata, prop)) {\n // This is an async method that we have metadata for. Create a\n // Promise wrapper for it.\n let wrapper = wrapAsyncFunction(prop, metadata[prop]);\n value = wrapMethod(target, target[prop], wrapper);\n } else {\n // This is a method that we don't know or care about. Return the\n // original method, bound to the underlying object.\n value = value.bind(target);\n }\n } else if (typeof value === \"object\" && value !== null && (hasOwnProperty(wrappers, prop) || hasOwnProperty(metadata, prop))) {\n // This is an object that we need to do some wrapping for the children\n // of. Create a sub-object wrapper for it with the appropriate child\n // metadata.\n value = wrapObject(value, wrappers[prop], metadata[prop]);\n } else {\n // We don't need to do any wrapping for this property,\n // so just forward all access to the underlying object.\n Object.defineProperty(cache, prop, {\n configurable: true,\n enumerable: true,\n get() {\n return target[prop];\n },\n set(value) {\n target[prop] = value;\n }\n });\n\n return value;\n }\n\n cache[prop] = value;\n return value;\n },\n\n set(target, prop, value, receiver) {\n if (prop in cache) {\n cache[prop] = value;\n } else {\n target[prop] = value;\n }\n return true;\n },\n\n defineProperty(target, prop, desc) {\n return Reflect.defineProperty(cache, prop, desc);\n },\n\n deleteProperty(target, prop) {\n return Reflect.deleteProperty(cache, prop);\n }\n };\n\n return new Proxy(target, handlers);\n };\n\n /**\n * Creates a set of wrapper functions for an event object, which handles\n * wrapping of listener functions that those messages are passed.\n *\n * A single wrapper is created for each listener function, and stored in a\n * map. Subsequent calls to `addListener`, `hasListener`, or `removeListener`\n * retrieve the original wrapper, so that attempts to remove a\n * previously-added listener work as expected.\n *\n * @param {DefaultWeakMap} wrapperMap\n * A DefaultWeakMap object which will create the appropriate wrapper\n * for a given listener function when one does not exist, and retrieve\n * an existing one when it does.\n *\n * @returns {object}\n */\n const wrapEvent = wrapperMap => ({\n addListener(target, listener, ...args) {\n target.addListener(wrapperMap.get(listener), ...args);\n },\n\n hasListener(target, listener) {\n return target.hasListener(wrapperMap.get(listener));\n },\n\n removeListener(target, listener) {\n target.removeListener(wrapperMap.get(listener));\n }\n });\n\n const onMessageWrappers = new DefaultWeakMap(listener => {\n if (typeof listener !== \"function\") {\n return listener;\n }\n\n /**\n * Wraps a message listener function so that it may send responses based on\n * its return value, rather than by returning a sentinel value and calling a\n * callback. If the listener function returns a Promise, the response is\n * sent when the promise either resolves or rejects.\n *\n * @param {*} message\n * The message sent by the other end of the channel.\n * @param {object} sender\n * Details about the sender of the message.\n * @param {function(*)} sendResponse\n * A callback which, when called with an arbitrary argument, sends\n * that value as a response.\n * @returns {boolean}\n * True if the wrapped listener returned a Promise, which will later\n * yield a response. False otherwise.\n */\n return function onMessage(message, sender, sendResponse) {\n let result = listener(message, sender);\n\n if (isThenable(result)) {\n result.then(sendResponse, error => {\n console.error(error);\n sendResponse(error);\n });\n\n return true;\n } else if (result !== undefined) {\n sendResponse(result);\n }\n };\n });\n\n const staticWrappers = {\n runtime: {\n onMessage: wrapEvent(onMessageWrappers)\n }\n };\n\n // Create a new empty object and copy the properties of the original chrome object\n // to prevent a Proxy violation exception for the devtools API getter\n // (which is a read-only non-configurable property on the original target).\n const targetObject = Object.assign({}, chrome);\n\n return wrapObject(targetObject, staticWrappers, apiMetadata);\n };\n\n // The build process adds a UMD wrapper around this file, which makes the\n // `module` variable available.\n module.exports = wrapAPIs(); // eslint-disable-line no-undef\n } else {\n module.exports = browser; // eslint-disable-line no-undef\n }\n});\n//# sourceMappingURL=browser-polyfill.js.map\n"]} \ No newline at end of file diff --git a/ext/manifest.json b/ext/manifest.json index b170d30..b4035ec 100644 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -12,7 +12,6 @@ "background": { "scripts": [ "js/browser-polyfill.min.js", - "js/generated/out/cljs_base.js", "js/generated/background.js" ] }, @@ -25,7 +24,6 @@ "matches": [""], "js": [ "js/browser-polyfill.min.js", - "js/generated/out/cljs_base.js", "js/generated/content.js" ] } diff --git a/ext/sidebar.html b/ext/sidebar.html index f713948..d7316a2 100644 --- a/ext/sidebar.html +++ b/ext/sidebar.html @@ -6,7 +6,6 @@ - diff --git a/project.clj b/project.clj index d762df7..2119e3a 100644 --- a/project.clj +++ b/project.clj @@ -9,26 +9,57 @@ [org.clojure/core.match "0.3.0-alpha5"] [cljs-ajax "0.7.3"]] :plugins [[lein-cljsbuild "1.1.7"]] - :clean-targets ["ext/js/generated"] - :aliases {"build" ["do" "clean" ["cljsbuild" "once"]]} - :cljsbuild - {:builds - {:main - {:source-paths ["src"] - :compiler {:optimizations :simple - :pretty-print true - :source-map true - :output-dir "ext/js/generated/out" - :closure-output-charset "us-ascii" - :modules {:background - {:output-to "ext/js/generated/background.js" - :entries #{"looped-in.background"}} - :content - {:output-to "ext/js/generated/content.js" - :entries #{"looped-in.content"}} - :sidebar - {:output-to "ext/js/generated/sidebar.js" - :entries #{"looped-in.sidebar"}}}}}}} - :profiles {:dev {:dependencies [[com.cemerick/piggieback "0.2.2"] - [org.clojure/tools.nrepl "0.2.10"]] - :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}}) + :profiles {:cljs-shared + {:cljsbuild + {:builds + {:background + {:source-paths ["src/background" "src/lib"] + :compiler {:output-dir "ext/js/generated/out-background" + :closure-output-charset "us-ascii" + :main looped-in.background + :output-to "ext/js/generated/background.js"}} + :content + {:source-paths ["src/content" "src/lib"] + :compiler {:output-dir "ext/js/generated/out-content" + :closure-output-charset "us-ascii" + :main looped-in.content + :output-to "ext/js/generated/content.js"}} + :sidebar + {:source-paths ["src/sidebar" "src/lib"] + :compiler {:output-dir "ext/js/generated/out-sidebar" + :closure-output-charset "us-ascii" + :main looped-in.sidebar + :output-to "ext/js/generated/sidebar.js"}}}}} + :dev [:cljs-shared + {:cljsbuild + {:builds + {:background + {:compiler {:optimizations :whitespace + :pretty-print true + :source-map "ext/js/generated/background.js.map"}} + :content + {:compiler {:optimizations :whitespace + :pretty-print true + :source-map "ext/js/generated/content.js.map"}} + :sidebar + {:compiler {:optimizations :whitespace + :pretty-print true + :source-map "ext/js/generated/sidebar.js.map"}}}}} + {:dependencies [[com.cemerick/piggieback "0.2.2"] + [org.clojure/tools.nrepl "0.2.10"]] + :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}] + :prod [:cljs-shared + {:cljbuilds + {:builds + {:background + {:compiler {:optimizations :simple + :pretty-print false + :source-map false}} + :content + {:compiler {:optimizations :simple + :pretty-print false + :source-map false}} + :sidebar + {:compiler {:optimizations :simple + :pretty-print false + :source-map false}}}}}]}) diff --git a/src/looped_in/background.cljs b/src/background/looped_in/background.cljs similarity index 100% rename from src/looped_in/background.cljs rename to src/background/looped_in/background.cljs diff --git a/src/looped_in/content.cljs b/src/background/looped_in/content.cljs similarity index 100% rename from src/looped_in/content.cljs rename to src/background/looped_in/content.cljs diff --git a/src/looped_in/components.cljs b/src/lib/looped_in/components.cljs similarity index 100% rename from src/looped_in/components.cljs rename to src/lib/looped_in/components.cljs diff --git a/src/looped_in/hackernews.cljs b/src/lib/looped_in/hackernews.cljs similarity index 100% rename from src/looped_in/hackernews.cljs rename to src/lib/looped_in/hackernews.cljs diff --git a/src/looped_in/logging.cljs b/src/lib/looped_in/logging.cljs similarity index 100% rename from src/looped_in/logging.cljs rename to src/lib/looped_in/logging.cljs diff --git a/src/looped_in/promises.cljs b/src/lib/looped_in/promises.cljs similarity index 100% rename from src/looped_in/promises.cljs rename to src/lib/looped_in/promises.cljs diff --git a/src/looped_in/sidebar.cljs b/src/sidebar/looped_in/sidebar.cljs similarity index 100% rename from src/looped_in/sidebar.cljs rename to src/sidebar/looped_in/sidebar.cljs