mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 01:36:22 +00:00
update
snippet fields
This commit is contained in:
@@ -10,11 +10,6 @@ module.exports = {
|
||||
src:'node_modules/angular/angular.js',
|
||||
cdn:'https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js'
|
||||
},
|
||||
{
|
||||
name:'angular-ui-ace',
|
||||
src:'node_modules/@rokt33r/angular-ui-ace/src/ui-ace.js',
|
||||
cdn:'https://cdn.rawgit.com/angular-ui/ui-ace/v0.2.3/ui-ace.min.js'
|
||||
},
|
||||
{
|
||||
name:'angular-bootstrap',
|
||||
src:'node_modules/angular-bootstrap/dist/ui-bootstrap-tpls.js',
|
||||
|
||||
13
src/directives/tags.js
Normal file
13
src/directives/tags.js
Normal file
@@ -0,0 +1,13 @@
|
||||
angular.module('codexen.directives')
|
||||
.directive('tags', function () {
|
||||
return {
|
||||
restrict:'A',
|
||||
template: '<p class="tags" ng-if="tags.length">'+
|
||||
'<i class="fa fa-tags"></i> '+
|
||||
'<a ng-repeat="tag in tags" href="#">#<span ng-bind="tag.name"></span></a>'+
|
||||
'</p>',
|
||||
scope:{
|
||||
tags: '='
|
||||
}
|
||||
}
|
||||
})
|
||||
337
src/directives/ui-ace.js
Normal file
337
src/directives/ui-ace.js
Normal file
@@ -0,0 +1,337 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Binds a ACE Editor widget
|
||||
*/
|
||||
angular.module('ui.ace', [])
|
||||
.constant('uiAceConfig', {})
|
||||
.directive('uiAce', ['uiAceConfig', function (uiAceConfig) {
|
||||
|
||||
if (angular.isUndefined(window.ace)) {
|
||||
throw new Error('ui-ace need ace to work... (o rly?)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets editor options such as the wrapping mode or the syntax checker.
|
||||
*
|
||||
* The supported options are:
|
||||
*
|
||||
* <ul>
|
||||
* <li>showGutter</li>
|
||||
* <li>useWrapMode</li>
|
||||
* <li>onLoad</li>
|
||||
* <li>theme</li>
|
||||
* <li>mode</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param acee
|
||||
* @param session ACE editor session
|
||||
* @param {object} opts Options to be set
|
||||
*/
|
||||
var setOptions = function(acee, session, opts) {
|
||||
|
||||
// sets the ace worker path, if running from concatenated
|
||||
// or minified source
|
||||
if (angular.isDefined(opts.workerPath)) {
|
||||
var config = window.ace.require('ace/config');
|
||||
config.set('workerPath', opts.workerPath);
|
||||
}
|
||||
// ace requires loading
|
||||
if (angular.isDefined(opts.require)) {
|
||||
opts.require.forEach(function (n) {
|
||||
window.ace.require(n);
|
||||
});
|
||||
}
|
||||
// Boolean options
|
||||
if (angular.isDefined(opts.showGutter)) {
|
||||
acee.renderer.setShowGutter(opts.showGutter);
|
||||
}
|
||||
if (angular.isDefined(opts.useWrapMode)) {
|
||||
session.setUseWrapMode(opts.useWrapMode);
|
||||
}
|
||||
if (angular.isDefined(opts.showInvisibles)) {
|
||||
acee.renderer.setShowInvisibles(opts.showInvisibles);
|
||||
}
|
||||
if (angular.isDefined(opts.showIndentGuides)) {
|
||||
acee.renderer.setDisplayIndentGuides(opts.showIndentGuides);
|
||||
}
|
||||
if (angular.isDefined(opts.useSoftTabs)) {
|
||||
session.setUseSoftTabs(opts.useSoftTabs);
|
||||
}
|
||||
if (angular.isDefined(opts.showPrintMargin)) {
|
||||
acee.setShowPrintMargin(opts.showPrintMargin);
|
||||
}
|
||||
if (angular.isDefined(opts.maxLines)) {
|
||||
if(opts.maxLines < 0) opts.maxLines = Infinity
|
||||
acee.setOptions({
|
||||
maxLines: opts.maxLines
|
||||
})
|
||||
}
|
||||
|
||||
// commands
|
||||
if (angular.isDefined(opts.disableSearch) && opts.disableSearch) {
|
||||
acee.commands.addCommands([
|
||||
{
|
||||
name: 'unfind',
|
||||
bindKey: {
|
||||
win: 'Ctrl-F',
|
||||
mac: 'Command-F'
|
||||
},
|
||||
exec: function () {
|
||||
return false;
|
||||
},
|
||||
readOnly: true
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
// Basic options
|
||||
if (angular.isString(opts.theme)) {
|
||||
acee.setTheme('ace/theme/' + opts.theme);
|
||||
}
|
||||
if (angular.isString(opts.mode)) {
|
||||
session.setMode('ace/mode/' + opts.mode);
|
||||
}
|
||||
// Advanced options
|
||||
if (angular.isDefined(opts.firstLineNumber)) {
|
||||
if (angular.isNumber(opts.firstLineNumber)) {
|
||||
session.setOption('firstLineNumber', opts.firstLineNumber);
|
||||
} else if (angular.isFunction(opts.firstLineNumber)) {
|
||||
session.setOption('firstLineNumber', opts.firstLineNumber());
|
||||
}
|
||||
}
|
||||
|
||||
// advanced options
|
||||
var key, obj;
|
||||
if (angular.isDefined(opts.advanced)) {
|
||||
for (key in opts.advanced) {
|
||||
// create a javascript object with the key and value
|
||||
obj = { name: key, value: opts.advanced[key] };
|
||||
// try to assign the option to the ace editor
|
||||
acee.setOption(obj.name, obj.value);
|
||||
}
|
||||
}
|
||||
|
||||
// advanced options for the renderer
|
||||
if (angular.isDefined(opts.rendererOptions)) {
|
||||
for (key in opts.rendererOptions) {
|
||||
// create a javascript object with the key and value
|
||||
obj = { name: key, value: opts.rendererOptions[key] };
|
||||
// try to assign the option to the ace editor
|
||||
acee.renderer.setOption(obj.name, obj.value);
|
||||
}
|
||||
}
|
||||
|
||||
// onLoad callbacks
|
||||
angular.forEach(opts.callbacks, function (cb) {
|
||||
if (angular.isFunction(cb)) {
|
||||
cb(acee);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
restrict: 'EA',
|
||||
require: '?ngModel',
|
||||
link: function (scope, elm, attrs, ngModel) {
|
||||
|
||||
/**
|
||||
* Corresponds the uiAceConfig ACE configuration.
|
||||
* @type object
|
||||
*/
|
||||
var options = uiAceConfig.ace || {};
|
||||
|
||||
/**
|
||||
* uiAceConfig merged with user options via json in attribute or data binding
|
||||
* @type object
|
||||
*/
|
||||
var opts = angular.extend({}, options, scope.$eval(attrs.uiAce));
|
||||
|
||||
/**
|
||||
* ACE editor
|
||||
* @type object
|
||||
*/
|
||||
var acee = window.ace.edit(elm[0]);
|
||||
acee.$blockScrolling = Infinity
|
||||
|
||||
/**
|
||||
* ACE editor session.
|
||||
* @type object
|
||||
* @see [EditSession]{@link http://ace.c9.io/#nav=api&api=edit_session}
|
||||
*/
|
||||
var session = acee.getSession();
|
||||
|
||||
/**
|
||||
* Reference to a change listener created by the listener factory.
|
||||
* @function
|
||||
* @see listenerFactory.onChange
|
||||
*/
|
||||
var onChangeListener;
|
||||
|
||||
/**
|
||||
* Reference to a blur listener created by the listener factory.
|
||||
* @function
|
||||
* @see listenerFactory.onBlur
|
||||
*/
|
||||
var onBlurListener;
|
||||
|
||||
/**
|
||||
* Calls a callback by checking its existing. The argument list
|
||||
* is variable and thus this function is relying on the arguments
|
||||
* object.
|
||||
* @throws {Error} If the callback isn't a function
|
||||
*/
|
||||
var executeUserCallback = function () {
|
||||
|
||||
/**
|
||||
* The callback function grabbed from the array-like arguments
|
||||
* object. The first argument should always be the callback.
|
||||
*
|
||||
* @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments}
|
||||
* @type {*}
|
||||
*/
|
||||
var callback = arguments[0];
|
||||
|
||||
/**
|
||||
* Arguments to be passed to the callback. These are taken
|
||||
* from the array-like arguments object. The first argument
|
||||
* is stripped because that should be the callback function.
|
||||
*
|
||||
* @see [arguments]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments}
|
||||
* @type {Array}
|
||||
*/
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
if (angular.isDefined(callback)) {
|
||||
scope.$evalAsync(function () {
|
||||
if (angular.isFunction(callback)) {
|
||||
callback(args);
|
||||
} else {
|
||||
throw new Error('ui-ace use a function as callback.');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Listener factory. Until now only change listeners can be created.
|
||||
* @type object
|
||||
*/
|
||||
var listenerFactory = {
|
||||
/**
|
||||
* Creates a change listener which propagates the change event
|
||||
* and the editor session to the callback from the user option
|
||||
* onChange. It might be exchanged during runtime, if this
|
||||
* happens the old listener will be unbound.
|
||||
*
|
||||
* @param callback callback function defined in the user options
|
||||
* @see onChangeListener
|
||||
*/
|
||||
onChange: function (callback) {
|
||||
return function (e) {
|
||||
var newValue = session.getValue();
|
||||
|
||||
if (ngModel && newValue !== ngModel.$viewValue &&
|
||||
// HACK make sure to only trigger the apply outside of the
|
||||
// digest loop 'cause ACE is actually using this callback
|
||||
// for any text transformation !
|
||||
!scope.$$phase && !scope.$root.$$phase) {
|
||||
scope.$evalAsync(function () {
|
||||
ngModel.$setViewValue(newValue);
|
||||
});
|
||||
}
|
||||
|
||||
executeUserCallback(callback, e, acee);
|
||||
};
|
||||
},
|
||||
/**
|
||||
* Creates a blur listener which propagates the editor session
|
||||
* to the callback from the user option onBlur. It might be
|
||||
* exchanged during runtime, if this happens the old listener
|
||||
* will be unbound.
|
||||
*
|
||||
* @param callback callback function defined in the user options
|
||||
* @see onBlurListener
|
||||
*/
|
||||
onBlur: function (callback) {
|
||||
return function () {
|
||||
executeUserCallback(callback, acee);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
attrs.$observe('readonly', function (value) {
|
||||
acee.setReadOnly(!!value || value === '');
|
||||
});
|
||||
|
||||
// Value Blind
|
||||
if (ngModel) {
|
||||
ngModel.$formatters.push(function (value) {
|
||||
if (angular.isUndefined(value) || value === null) {
|
||||
return '';
|
||||
}
|
||||
else if (angular.isObject(value) || angular.isArray(value)) {
|
||||
throw new Error('ui-ace cannot use an object or an array as a model');
|
||||
}
|
||||
return value;
|
||||
});
|
||||
|
||||
ngModel.$render = function () {
|
||||
session.setValue(ngModel.$viewValue);
|
||||
};
|
||||
}
|
||||
|
||||
// Listen for option updates
|
||||
var updateOptions = function (current, previous) {
|
||||
if (current === previous) return;
|
||||
opts = angular.extend({}, options, scope.$eval(attrs.uiAce));
|
||||
|
||||
opts.callbacks = [ opts.onLoad ];
|
||||
if (opts.onLoad !== options.onLoad) {
|
||||
// also call the global onLoad handler
|
||||
opts.callbacks.unshift(options.onLoad);
|
||||
}
|
||||
|
||||
// EVENTS
|
||||
|
||||
// unbind old change listener
|
||||
session.removeListener('change', onChangeListener);
|
||||
|
||||
// bind new change listener
|
||||
onChangeListener = listenerFactory.onChange(opts.onChange);
|
||||
session.on('change', onChangeListener);
|
||||
|
||||
// unbind old blur listener
|
||||
//session.removeListener('blur', onBlurListener);
|
||||
acee.removeListener('blur', onBlurListener);
|
||||
|
||||
// bind new blur listener
|
||||
onBlurListener = listenerFactory.onBlur(opts.onBlur);
|
||||
acee.on('blur', onBlurListener);
|
||||
|
||||
setOptions(acee, session, opts);
|
||||
};
|
||||
|
||||
scope.$watch(attrs.uiAce, updateOptions, /* deep watch */ true);
|
||||
|
||||
// set the options here, even if we try to watch later, if this
|
||||
// line is missing things go wrong (and the tests will also fail)
|
||||
updateOptions(options);
|
||||
|
||||
elm.on('$destroy', function () {
|
||||
acee.session.$stopWorker();
|
||||
acee.destroy();
|
||||
});
|
||||
|
||||
scope.$watch(function() {
|
||||
return [elm[0].offsetWidth, elm[0].offsetHeight];
|
||||
}, function() {
|
||||
acee.resize();
|
||||
acee.renderer.updateFull();
|
||||
}, true);
|
||||
|
||||
scope.Infinity = -1
|
||||
|
||||
}
|
||||
};
|
||||
}]);
|
||||
@@ -26,7 +26,6 @@
|
||||
<script src="vendor/angular.js"></script>
|
||||
<script src="vendor/angular-sanitize.js"></script>
|
||||
<script src="vendor/angular-ui-router.js"></script>
|
||||
<script src="vendor/ui-ace.js"></script>
|
||||
<script src="vendor/ui-bootstrap-tpls.js"></script>
|
||||
<script src="vendor/select.js"></script>
|
||||
<script src="vendor/satellizer.js"></script>
|
||||
|
||||
@@ -18,9 +18,8 @@ angular.module('codexen.modals')
|
||||
|
||||
vm.submit = function () {
|
||||
var params = {
|
||||
title: vm.title,
|
||||
description: vm.description,
|
||||
prefix: vm.prefix,
|
||||
callSign: vm.callSign,
|
||||
mode: vm.mode==null?null:vm.mode.name.toLowerCase(),
|
||||
content: vm.content,
|
||||
tags: angular.isArray(vm.tags)?vm.tags.map(function (tag) { return {_id: tag._id, name: tag.name} }):[]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="new-snippet-modal">
|
||||
<div class="modal-header">
|
||||
<input ng-model="vm.title" type="title" class="form-control input-lg" placeholder="Title">
|
||||
New Snippet
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
@@ -8,7 +8,7 @@
|
||||
<textarea ng-model="vm.description" name="description" class="form-control" placeholder="Description..."></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input ng-model="vm.prefix" type="text" name="prefix" class="inline-form-control" placeholder="Prefix">
|
||||
<input ng-model="vm.callSign" type="text" name="callSign" class="inline-form-control" placeholder="Call sign">
|
||||
|
||||
<ui-select ng-model="vm.mode" style="display: inline-block;" on-select="vm.log(vm.mode.name.toLowerCase())" theme="bootstrap">
|
||||
<ui-select-match placeholder="Select Type">{{$select.selected.name}}</ui-select-match>
|
||||
@@ -18,13 +18,15 @@
|
||||
</ui-select>
|
||||
</div>
|
||||
|
||||
<div
|
||||
ui-ace="{
|
||||
mode: vm.mode.name.toLowerCase()
|
||||
<div class="form-group">
|
||||
<div
|
||||
ui-ace="{
|
||||
mode: vm.mode.name.toLowerCase()
|
||||
|
||||
}"
|
||||
ng-model="vm.content"
|
||||
></div>
|
||||
}"
|
||||
ng-model="vm.content"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<ui-select multiple tagging="vm.transform" tagging-tokens="SPACE|,|/" ng-model="vm.tags" theme="bootstrap">
|
||||
@@ -34,8 +36,6 @@
|
||||
<div><span ng-bind-html="tag.name | highlight: $select.search"></span><span ng-if="tag.isTag">(new)</span></div>
|
||||
</ui-select-choices>
|
||||
</ui-select>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
App: <a href="https://github.com/Rokt33r/codexen-app">Rokt33r/codexen-app</a><br>
|
||||
Server: <a href="https://github.com/Rokt33r/codexen-server">Rokt33r/codexen-server</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
© 2015 MAISIN&CO.,Inc.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
<div class="snippets-detail-state">
|
||||
|
||||
<div class="detail-header">
|
||||
<span class="detail-header-title">
|
||||
<small>Title : </small>
|
||||
<span ng-bind="vm.snippet.title"></span></span>
|
||||
<span class="detail-header-title"><small>call sign : </small><span ng-bind="vm.snippet.callSign"></span></span>
|
||||
<span class="detail-header-control pull-right">
|
||||
<button type="button" name="button" class="btn btn-default"><i class="fa fa-share"></i></button>
|
||||
<button type="button" name="button" class="btn btn-default"><i class="fa fa-edit"></i></button>
|
||||
@@ -18,15 +16,15 @@
|
||||
</div>
|
||||
|
||||
<div ng-if="vm.isLoaded" class="">
|
||||
<p class="tags" ng-if="vm.snippet.tags">
|
||||
<small><i class="fa fa-tags"></i></small> <a ng-repeat="tag in vm.snippet.tags" ng-bind="tag.name" href="#" class="label label-default"></a>
|
||||
</p>
|
||||
<label>Description</label>
|
||||
<p ng-bind="vm.snippet.description"></p>
|
||||
<div tags="vm.snippet.tags"></div>
|
||||
<label>Content</label>
|
||||
<div ui-ace="{
|
||||
readonly: true,
|
||||
showGutter: false,
|
||||
useWrapMode : true,
|
||||
mode:vm.snippet.mode,
|
||||
maxLines: -1,
|
||||
readOnly: true,
|
||||
rendererOptions: {
|
||||
maxLinks: Infinity
|
||||
}
|
||||
|
||||
@@ -29,14 +29,11 @@
|
||||
<img width="25" height="25" src="http://www.gravatar.com/avatar/ea0b6ad1c11700120d1af08810caa19d" alt="" />
|
||||
</div>
|
||||
<div class="media-body">
|
||||
<h4 ng-bind="snippet.title"></h4>
|
||||
<h4 ng-bind="snippet.description"></h4>
|
||||
<p class="created-at">created at <span ng-bind="snippet.createdAt"></span></p>
|
||||
</div>
|
||||
</div>
|
||||
<p ng-bind="snippet.description"></p>
|
||||
<p class="tags" ng-if="snippet.tags.length">
|
||||
<small><i class="fa fa-tags"></i></small> <a ng-repeat="tag in snippet.tags" ng-bind="tag.name" href="#" class="label label-default"></a>
|
||||
</p>
|
||||
<div tags="snippet.tags"></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -47,6 +47,8 @@ $snippet-list-item-hover-bg: #EEE;
|
||||
bottom: 0;
|
||||
left: $left-pane-width;
|
||||
right: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,13 +71,14 @@ $snippet-list-item-hover-bg: #EEE;
|
||||
.detail-body{
|
||||
padding: 5px 10px;
|
||||
.ace_editor {
|
||||
height: 500px;
|
||||
min-height: 300px;
|
||||
border: solid 1px $border-color;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.tags{
|
||||
word-break: break-all;
|
||||
a{
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user