Skip to content

Instantly share code, notes, and snippets.

@anaisbetts
Created August 13, 2015 23:48
Show Gist options
  • Select an option

  • Save anaisbetts/3e2d846f47f52914b707 to your computer and use it in GitHub Desktop.

Select an option

Save anaisbetts/3e2d846f47f52914b707 to your computer and use it in GitHub Desktop.
ES6 + Polymer + Electron node modules
import LoadingScreen from '../../src/renderer-ng/loading-screen/loading-screen.html';
describe('The Loading Screen', function() {
beforeEach(function() {
this.fixture = new LoadingScreen();
this.fixture.id = 'fixture';
document.body.appendChild(this.fixture);
});
afterEach(function() {
document.body.removeChild(this.fixture);
});
it('should switch states when we call the method', function() {
this.fixture.showConnecting();
expect(this.fixture.screen).toBe('connecting');
});
});
<dom-module id="loading-screen">
<link rel="import" type="css" href="./loading-screen.less" />
<template>
<iron-pages id="selector" selected="{{_pageForScreen(screen)}}">
<div class="page">
<img width="362" height="102" src="offline.png" />
<span class="text_holder">
It appears you don't have an Internet connection right now.<br>
<span class="green">Slack will attempt to automatically reconnect.</span>
<br><br><center><a class="btn retry" on-click="_emitRetry">Try now</a></center>
</span>
</div>
<div class="page">
<img width="284" height="284" src="slackdown.png" /><br>
<span class="text_holder">
The Slack service appears to be unavailable. Please check <a href="http://status.slack.com" target="status">status.slack.com</a>.<br>
We'll automatically try to connect again momentarily.
<br><br><center><a class="btn retry" on-click="_emitRetry">Try now</a></center>
</span>
</div>
<div class="page">
<img width="80" height="80" src="trying.gif" />
<span class="text_holder" class="connecting">Connecting ...</span>
</div>
</iron-pages>
</template>
<x-require src="./example-component"></x-require>
</dom-module>
import {component} from '../polymer-es6';
const pageMap = {
'offline': 0,
'slackDown': 1,
'connecting': 2,
};
@component('loading-screen')
class LoadingScreen {
static properties() {
return {
screen: {
type: String,
reflectToAttribute: true
}
};
}
showOffline() {
this.screen = 'offline';
}
showSlackDown() {
this.screen = 'slackDown';
}
showConnecting() {
this.screen = 'connecting';
}
_emitRetry() {
this.fire('retry');
}
_pageForScreen(theScreen) {
return pageMap[theScreen];
}
}
import _ from 'lodash';
import Module from 'module';
import path from 'path';
import url from 'url';
// Public: Determine the filename of the current HTML import by abusing call
// stacks
//
// Returns the first file in the call-stack that ends in HTML, which in an HTML
// import script tag, will be the import.
export function filenameForImport() {
let fileName = null;
try {
throw new Error();
} catch (e) {
let htmlFileLine = _.find(e.stack.split('\n'), (x) => x.match(/\.html/i));
let theUri = url.parse(htmlFileLine.replace(/.*at /, '').replace(/:[\d].*/, ''));
fileName = decodeURIComponent(theUri.pathname);
}
if (process.platform === 'win32') {
fileName = fileName.slice(1);
}
return fileName;
}
// Private: This method registers a {Module} with the module cache directly,
// so that further calls to 'require' will return this object without actually
// attempting to load the file.
//
// filename - the fully qualified path to the file to register as
// exportObject - the value that require should return (i.e. what your module
// would normally set as module.exports)
//
// Returns nothing.
function fakeModuleLoad(filename, exportObject) {
var mod = new Module(filename, process.mainModule);
console.log(filename);
mod.filename = filename;
mod.paths = Module._nodeModulePaths(path.dirname(filename));
mod.loaded = true;
mod.exports = exportObject;
Module._cache[filename] = mod;
process.mainModule.children.push(mod);
}
// Public: This ES7 Decorator method registers a class as a Polymer component.
// This means, instead of calling Polymer, you should declare a class with a
// static method 'properties' that returns the properties of the class, and
// decorate it with this method, which will turn the class definition into a
// Polymer object and register it.
//
// This method also registers the returned constructor as a Node module, so
// that require'ing the containing HTML file will return a constructor Function
// for the new element.
export function component(name, extendName) {
return function decorator(klass) {
if (!klass.properties) {
throw new Error(`Declare a static method or property on ${klass.name} called 'properties'`);
}
let newProto = _.reduce(Object.getOwnPropertyNames(klass.prototype), (acc,x) => {
acc[x] = klass.prototype[x];
return acc;
}, {});
Object.setPrototypeOf(newProto, Object.getPrototypeOf(klass.prototype));
delete newProto.constructor;
let props = typeof(klass.properties === 'function') ?
klass.properties() : klass.properties;
newProto.is = name;
if (extendName) {
newProto.extends = extendName;
}
newProto.properties = props;
window.Polymer(newProto);
let ctor = function(...args) {
let factoryArgs = extendName ? [extendName, name] : [name];
let el = document.createElement.apply(document, factoryArgs);
if (newProto.factoryImpl) {
newProto.factoryImpl.apply(el, args);
}
return el;
};
fakeModuleLoad(filenameForImport(), ctor);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment