Skip to content

Instantly share code, notes, and snippets.

@PatrickJS
Last active September 27, 2018 05:57
Show Gist options
  • Save PatrickJS/6227a94d480b8c71123e1d7dd8dd2e58 to your computer and use it in GitHub Desktop.
Save PatrickJS/6227a94d480b8c71123e1d7dd8dd2e58 to your computer and use it in GitHub Desktop.
Angular 4 universal fixes for Material 2
global['document'] = {
createElement() {
return {
setAttribute: function(type) { this.type = type; },
type: '',
classList: { add: () => undefined }
};
},
documentElement: {
getBoundingClientRect: () => ({
top: 0,
left: 0,
bottom: 1000,
right: 1000,
height: 1000,
width: 1000
})
}
};
import { APP_BASE_HREF } from '@angular/common';
import { RendererFactory2, NgZone } from '@angular/core';
/*
* Material SSR Hacks
*/
import { ScrollDispatcher, LiveAnnouncer, MdButton, MdInputDirective } from '@angular/material';
import { RippleRenderer } from '@angular/material/core/ripple/ripple-renderer';
import { ViewportRuler } from
'@angular/material/core/overlay/position/viewport-ruler';
(<any>MdInputDirective).prototype._isTextarea = function ita() {
let nativeElement = this._elementRef.nativeElement;
return nativeElement ? nativeElement.tagName.toLowerCase() === 'textarea' : false;
};
(<any>MdInputDirective).prototype._isBadInput = function ibi() {
return false;
};
(<any>MdButton).prototype._isRoundButton = function irb() {
const el = this._getHostElement();
return el.attribs['md-icon-button'] ||
el.attribs['md-fab'] ||
el.attribs['md-mini-fab'];
};
(<any>RippleRenderer).prototype.setTriggerElement = function ste() {
return null;
};
(<any>LiveAnnouncer).prototype._createLiveElement = function cle() {
return {};
};
ViewportRuler.prototype._cacheViewportGeometry = function yolo() {
this._documentRect = {
top: 0,
left: 0,
bottom: 1000,
right: 1000,
height: 1000,
width: 1000
};
};
const FakeScrollDispatcher = {
scrolled() {
return {
subscribe() {}
};
},
register() {
},
deregister() {
}
};
import { MatchMedia, BaseFxDirective } from '@angular/flex-layout';
import { LayoutGapDirective } from
'@angular/flex-layout/flexbox/api/layout-gap';
(<any>MatchMedia).prototype._buildMQL = function buildMQLFix(query) {
return {
matches: true, // TODO: Match only for mobile queries
media: query,
addListener: () => {
},
removeListener: () => {
}
};
};
(<any>LayoutGapDirective).prototype._watchContentChanges = function _watchContentChanges() {
return '';
};
(<any>BaseFxDirective).prototype._getDisplayStyle = function getDisplayStyleFix() {
return '';
};
import { NoopAnimationsModule, ɵAnimationEngine, ɵAnimationRendererFactory } from '@angular/platform-browser/animations';
import { ɵServerRendererFactory2 } from '@angular/platform-server';
export function instantiateServerRendererFactory(
renderer: RendererFactory2, engine: ɵAnimationEngine, zone: NgZone) {
return new ɵAnimationRendererFactory(renderer, engine, zone);
}
const createRenderer = ɵServerRendererFactory2.prototype.createRenderer;
ɵServerRendererFactory2.prototype.createRenderer = function () {
const result = createRenderer.apply(this, arguments);
const setProperty = result.setProperty;
result.setProperty = function () {
try {
setProperty.apply(this, arguments);
} catch (e) {
if (e.message.indexOf('Found the synthetic') === -1) {
throw e;
}
}
};
return result;
}
export const ssrProviders = [
{ provide: APP_BASE_HREF, useValue: '/' },
{ provide: ScrollDispatcher, useValue: FakeScrollDispatcher },
{
provide: RendererFactory2,
useFactory: instantiateServerRendererFactory,
deps: [ɵServerRendererFactory2, ɵAnimationEngine, NgZone]
}
];
{
rules: [
{
test: /@angular(\\|\/)material/,
loader: 'imports-loader',
options: {
window: '>global',
'CSS': '>null',
navigator: '>{ userAgent: \'Chrome\' }',
document: '>global.document',
}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment