UNPKG

foam-framework

Version:
251 lines (233 loc) 6.46 kB
/** * @license * Copyright 2015 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 */ CLASS({ name: 'CodeSnippetView', package: 'foam.flow', extends: 'foam.flow.Element', requires: [ 'foam.ui.ActionButton', 'foam.flow.CodeView', 'foam.flow.CodeSnippet' ], imports: [ 'actionButtonName', 'codeViewName', 'codeViewLoadState$' ], exports: [ 'codeViewLoadState$' ], constants: { ELEMENT_NAME: 'code-snippet' }, properties: [ { model_: 'StringProperty', name: 'extraClassName', defaultValue: 'loading' }, { model_: 'StringProperty', name: 'mode', defaultValue: 'read-write' }, { model_: 'BooleanProperty', name: 'showActions', defaultValue: true }, { model_: 'BooleanProperty', name: 'scroll', defaultValue: true }, { model_: 'StringProperty', name: 'codeViewLoadState', defaultValue: 'unloaded', postSet: function(old, nu) { if ( old === nu ) return; this.onCodeViewLoadStateChanged(); } }, { model_: 'StringProperty', name: 'codeViewName', defaultValue: 'foam.flow.CodeView' }, { model_: 'ModelProperty', name: 'actionButtonName', defaultValue: 'foam.ui.ActionButton' } ], methods: [ { name: 'init', code: function() { this.SUPER.apply(this, arguments); // TODO(markdittmer): Should be able to use foam.ui.ModeProperty here // but it doesn't seem to be working. It should eliminate the need for // a postSet. Events.dynamic(function() { this.srcView; this.mode; this.scroll; if ( ! this.srcView ) return; this.srcView.mode = this.mode; this.srcView.scroll = this.scroll; }.bind(this)); } }, { name: 'isLoadedOrFailed', code: function() { var state = this.codeViewLoadState; return state === 'loaded' || state === 'failed'; } } ], listeners: [ { name: 'onCodeViewLoadFailed', isFramed: true, code: function(_, topics) { console.warn('Failed to load code view: ' + this.codeViewName); this.codeViewName = 'foam.flow.CodeView'; this.extraClassName = ''; this.updateHTML(); } }, { name: 'onCodeViewLoadStateChanged', code: function() { if ( this.codeViewLoadState !== 'failed' ) return; this.onCodeViewLoadFailed(); } }, { name: 'onEditActionFlareStateChanged', code: function(_, __, ___, nu) { if ( nu === 'default' ) { this.enterReadWriteMode_(); this.editView.halo.state_$.removeListener(this.onEditActionFlareStateChanged); } } }, { name: 'enterReadWriteMode_', code: function() { // Button should hide before editor changes modes. this.editView.className = (this.editView.className || '') + ' hide'; this.mode = 'read-write'; } } ], actions: [ { name: 'edit', iconUrl: 'https://www.gstatic.com/images/icons/material/system/1x/mode_edit_black_18dp.png', isEnabled: function() { return this.mode === 'read-only'; }, isAvailable: function() { return this.mode === 'read-only'; }, code: function() { // TODO(markdittmer): Components involved in animated reactive updates // should be better decoupled. For now, use halo as indicator that we // need to synchronize with a flare state change. if ( this.editView.halo ) { this.editView.halo.state_$.addListener(this.onEditActionFlareStateChanged); return; } this.enterReadWriteMode_(); } } ], templates: [ function toInnerHTML() {/* <% this.setClass('loading', function() { this.codeViewLoadState; return ! this.isLoadedOrFailed(); }.bind(this), this.id); %> <% if ( this.data.title ) { %> <heading>{{{this.data.title}}}</heading> <% } %> $$src{ model_: this.codeViewName } <% if ( this.showActions ) { %> <actions> $$edit{ model_: this.actionButtonName, className: 'actionButton editButton', color: 'black', font: '20px Roboto, Arial', alpha: 1.0, radius: 15, background: '#F7CB4D' } </actions> <% } %> */}, function CSS() {/* code-snippet { display: block; position: relative; } code-snippet.loading * { display: none; } code-snippet.loading heading { display: initial; } code-sample code-snippet actions, code-snippet actions { position: absolute; right: 30px; bottom: -15px; z-index: 15; } code-snippet canvas.editButton { background: rgba(0,0,0,0); box-shadow: 2px 2px 7px #aaa; border-radius: 50%; } code-snippet canvas.editButton.hide { display: none; } @media not print { aside code-sample code-snippet heading, code-sample code-snippet heading, code-snippet heading { background: initial; padding: 5px 20px; font-size: 18px; border-top: 1px solid #E0E0E0; } aside code-sample code-snippet heading, code-sample code-snippet heading, code-snippet heading { z-index: 10; position: relative; } code-snippet heading::after { bottom: -4px; content: ''; height: 4px; left: 0; position: absolute; right: 0; background-image: -webkit-linear-gradient(top,rgba(0,0,0,.12) 0%,rgba(0,0,0,0) 100%); background-image: linear-gradient(to bottom,rgba(0,0,0,.12) 0%,rgba(0,0,0,0) 100%); } } @media print { aside code-sample code-snippet heading, code-sample code-snippet heading, code-snippet heading { margin: 3pt; font-size: 13pt; } } */} ] });