Commit c0c86c11 by Torkel Ödegaard

tech: remove bower and moved remaining bower dependencies to npm

parent 6aad2a5b
{
"directory": "public/vendor/"
}
{
"name": "grafana",
"version": "2.0.2",
"homepage": "https://github.com/grafana/grafana",
"authors": [],
"license": "Apache 2.0",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"public/vendor/",
"test",
"tests"
],
"dependencies": {
"angular-native-dragdrop": "1.2.2",
"angular-bindonce": "0.3.3",
"clipboard": "^1.5.16"
}
}
......@@ -65,9 +65,12 @@
"@types/enzyme": "^2.8.8",
"ace-builds": "^1.2.8",
"angular": "^1.6.6",
"angular-bindonce": "^0.3.1",
"angular-mocks": "^1.6.6",
"angular-native-dragdrop": "^1.2.2",
"angular-route": "^1.6.6",
"angular-sanitize": "^1.6.6",
"clipboard": "^1.7.1",
"eventemitter3": "^2.0.2",
"gaze": "^1.1.2",
"grunt-jscs": "3.0.1",
......
......@@ -25,7 +25,7 @@ function (angular, require, coreModule, kbn) {
getText: '&clipboardButton'
},
link: function(scope, elem) {
require(['vendor/clipboard/dist/clipboard'], function(Clipboard) {
require(['clipboard'], function(Clipboard) {
scope.clipboard = new Clipboard(elem[0], {
text: function() {
return scope.getText();
......
......@@ -20,8 +20,8 @@ System.config({
'angular-sanitize': 'vendor/npm/angular-sanitize/angular-sanitize.js',
"angular-ui": "vendor/angular-ui/ui-bootstrap-tpls.js",
"angular-strap": "vendor/angular-other/angular-strap.js",
"angular-dragdrop": "vendor/angular-native-dragdrop/draganddrop.js",
"angular-bindonce": "vendor/angular-bindonce/bindonce.js",
"angular-dragdrop": "vendor/npm/angular-native-dragdrop/draganddrop.js",
"angular-bindonce": "vendor/npm/angular-bindonce/bindonce.js",
"spectrum": "vendor/spectrum.js",
"bootstrap-tagsinput": "vendor/tagsinput/bootstrap-tagsinput.js",
"jquery.flot": "vendor/flot/jquery.flot",
......@@ -35,7 +35,8 @@ System.config({
"jquery.flot.gauge": "vendor/flot/jquery.flot.gauge",
"d3": "vendor/d3/d3.js",
"jquery.flot.dashes": "vendor/flot/jquery.flot.dashes",
"ace": "vendor/npm/ace-builds/src-noconflict/ace"
"ace": "vendor/npm/ace-builds/src-noconflict/ace",
"clipboard": "vendor/npm/clipboard/dist/clipboard.js"
},
packages: {
......
......@@ -29,8 +29,8 @@
'angular-sanitize': 'vendor/npm/angular-sanitize/angular-sanitize.js',
"angular-ui": "vendor/angular-ui/ui-bootstrap-tpls.js",
"angular-strap": "vendor/angular-other/angular-strap.js",
"angular-dragdrop": "vendor/angular-native-dragdrop/draganddrop.js",
"angular-bindonce": "vendor/angular-bindonce/bindonce.js",
"angular-dragdrop": "vendor/npm/angular-native-dragdrop/draganddrop.js",
"angular-bindonce": "vendor/npm/angular-bindonce/bindonce.js",
"spectrum": "vendor/spectrum.js",
"bootstrap-tagsinput": "vendor/tagsinput/bootstrap-tagsinput.js",
"jquery.flot": "vendor/flot/jquery.flot",
......@@ -45,6 +45,7 @@
"d3": "vendor/d3/d3.js",
"jquery.flot.dashes": "vendor/flot/jquery.flot.dashes",
"ace": "vendor/npm/ace-builds/src-noconflict/ace",
"clipboard": "vendor/npm/clipboard/dist/clipboard.js"
},
packages: {
......
{
"name": "angular-bindonce",
"version": "0.3.3",
"main": "bindonce.js",
"description": "Zero watchers binding directives for AngularJS",
"homepage": "https://github.com/Pasvaz/bindonce",
"author": "Pasquale Vazzana <pasqualevazzana@gmail.com>",
"repository": {
"type": "git",
"url": "https://github.com/Pasvaz/bindonce.git"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"components"
],
"dependencies": {},
"keywords": [
"angularjs",
"angular",
"directive",
"binding",
"watcher",
"bindonce"
],
"_release": "0.3.3",
"_resolution": {
"type": "version",
"tag": "0.3.3",
"commit": "0fcf71e6effc88179893c9c06baf6c6bf9037632"
},
"_source": "https://github.com/Pasvaz/bindonce.git",
"_target": "0.3.3",
"_originalSource": "angular-bindonce"
}
\ No newline at end of file
# 0.3.3 (2014-02-12)
### Features
- **bo-disabled:**
- Add support for ng-disabled/bo-disabled #110
<hr />
# 0.3.2 (2014-11-23)
### Bug Fixes
- **Angular 1.3 compatibility**
<hr />
# 0.3.1 (2014-02-12)
### Features
- **bo-bind:**
- alias for bo-text
### Bug Fixes
- **Angular Promises**
- Ensures that promises are resolved before to run binders ([b3ef1b4](https://github.com/Pasvaz/bindonce/commit/b3ef1b46edfe83f10ed455d5520027f731563f32))
### Minor improvements
- Updated Readme
<hr />
# 0.3.0 (2014-01-21)
### Features
- **bo-switch:**
- Create new directive: bo-switch ([652d0db](https://github.com/Pasvaz/bindonce/commit/652d0db04325166a180377c738a376543b5f2357))
<hr />
# 0.2.3 (2014-01-20)
### Bug Fixes
- **bo-if:**
- Ensures that we both process newly added binders from bo-if, and that
we only process each binder once ([d11f863](https://github.com/Pasvaz/bindonce/commit/e091c273bbd17603d410fecc363874f0d1e6f38e))
### Features
- **Minification:**
- add min file ([47277ee](https://github.com/Pasvaz/bindonce/commit/47277eedd092b3210de362c725a7dadcddac8e87))
- **Changelog:**
- Created a changelog file
(function () {
"use strict";
/**
* Bindonce - Zero watches binding for AngularJs
* @version v0.3.3
* @link https://github.com/Pasvaz/bindonce
* @author Pasquale Vazzana <pasqualevazzana@gmail.com>
* @license MIT License, http://www.opensource.org/licenses/MIT
*/
var bindonceModule = angular.module('pasvaz.bindonce', []);
bindonceModule.directive('bindonce', function ()
{
var toBoolean = function (value)
{
if (value && value.length !== 0)
{
var v = angular.lowercase("" + value);
value = !(v === 'f' || v === '0' || v === 'false' || v === 'no' || v === 'n' || v === '[]');
}
else
{
value = false;
}
return value;
};
var msie = parseInt((/msie (\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
if (isNaN(msie))
{
msie = parseInt((/trident\/.*; rv:(\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10);
}
var bindonceDirective =
{
restrict: "AM",
controller: ['$scope', '$element', '$attrs', '$interpolate', function ($scope, $element, $attrs, $interpolate)
{
var showHideBinder = function (elm, attr, value)
{
var show = (attr === 'show') ? '' : 'none';
var hide = (attr === 'hide') ? '' : 'none';
elm.css('display', toBoolean(value) ? show : hide);
};
var classBinder = function (elm, value)
{
if (angular.isObject(value) && !angular.isArray(value))
{
var results = [];
angular.forEach(value, function (value, index)
{
if (value) results.push(index);
});
value = results;
}
if (value)
{
elm.addClass(angular.isArray(value) ? value.join(' ') : value);
}
};
var transclude = function (transcluder, scope)
{
transcluder.transclude(scope, function (clone)
{
var parent = transcluder.element.parent();
var afterNode = transcluder.element && transcluder.element[transcluder.element.length - 1];
var parentNode = parent && parent[0] || afterNode && afterNode.parentNode;
var afterNextSibling = (afterNode && afterNode.nextSibling) || null;
angular.forEach(clone, function (node)
{
parentNode.insertBefore(node, afterNextSibling);
});
});
};
var ctrl =
{
watcherRemover: undefined,
binders: [],
group: $attrs.boName,
element: $element,
ran: false,
addBinder: function (binder)
{
this.binders.push(binder);
// In case of late binding (when using the directive bo-name/bo-parent)
// it happens only when you use nested bindonce, if the bo-children
// are not dom children the linking can follow another order
if (this.ran)
{
this.runBinders();
}
},
setupWatcher: function (bindonceValue)
{
var that = this;
this.watcherRemover = $scope.$watch(bindonceValue, function (newValue)
{
if (newValue === undefined) return;
that.removeWatcher();
that.checkBindonce(newValue);
}, true);
},
checkBindonce: function (value)
{
var that = this, promise = (value.$promise) ? value.$promise.then : value.then;
// since Angular 1.2 promises are no longer
// undefined until they don't get resolved
if (typeof promise === 'function')
{
promise(function ()
{
that.runBinders();
});
}
else
{
that.runBinders();
}
},
removeWatcher: function ()
{
if (this.watcherRemover !== undefined)
{
this.watcherRemover();
this.watcherRemover = undefined;
}
},
runBinders: function ()
{
while (this.binders.length > 0)
{
var binder = this.binders.shift();
if (this.group && this.group != binder.group) continue;
var value = binder.scope.$eval((binder.interpolate) ? $interpolate(binder.value) : binder.value);
switch (binder.attr)
{
case 'boIf':
if (toBoolean(value))
{
transclude(binder, binder.scope.$new());
}
break;
case 'boSwitch':
var selectedTranscludes, switchCtrl = binder.controller[0];
if ((selectedTranscludes = switchCtrl.cases['!' + value] || switchCtrl.cases['?']))
{
binder.scope.$eval(binder.attrs.change);
angular.forEach(selectedTranscludes, function (selectedTransclude)
{
transclude(selectedTransclude, binder.scope.$new());
});
}
break;
case 'boSwitchWhen':
var ctrl = binder.controller[0];
ctrl.cases['!' + binder.attrs.boSwitchWhen] = (ctrl.cases['!' + binder.attrs.boSwitchWhen] || []);
ctrl.cases['!' + binder.attrs.boSwitchWhen].push({ transclude: binder.transclude, element: binder.element });
break;
case 'boSwitchDefault':
var ctrl = binder.controller[0];
ctrl.cases['?'] = (ctrl.cases['?'] || []);
ctrl.cases['?'].push({ transclude: binder.transclude, element: binder.element });
break;
case 'hide':
case 'show':
showHideBinder(binder.element, binder.attr, value);
break;
case 'class':
classBinder(binder.element, value);
break;
case 'text':
binder.element.text(value);
break;
case 'html':
binder.element.html(value);
break;
case 'style':
binder.element.css(value);
break;
case 'disabled':
binder.element.prop('disabled', value);
break;
case 'src':
binder.element.attr(binder.attr, value);
if (msie) binder.element.prop('src', value);
break;
case 'attr':
angular.forEach(binder.attrs, function (attrValue, attrKey)
{
var newAttr, newValue;
if (attrKey.match(/^boAttr./) && binder.attrs[attrKey])
{
newAttr = attrKey.replace(/^boAttr/, '').replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
newValue = binder.scope.$eval(binder.attrs[attrKey]);
binder.element.attr(newAttr, newValue);
}
});
break;
case 'href':
case 'alt':
case 'title':
case 'id':
case 'value':
binder.element.attr(binder.attr, value);
break;
}
}
this.ran = true;
}
};
angular.extend(this, ctrl);
}],
link: function (scope, elm, attrs, bindonceController)
{
var value = attrs.bindonce && scope.$eval(attrs.bindonce);
if (value !== undefined)
{
bindonceController.checkBindonce(value);
}
else
{
bindonceController.setupWatcher(attrs.bindonce);
elm.bind("$destroy", bindonceController.removeWatcher);
}
}
};
return bindonceDirective;
});
angular.forEach(
[
{ directiveName: 'boShow', attribute: 'show' },
{ directiveName: 'boHide', attribute: 'hide' },
{ directiveName: 'boClass', attribute: 'class' },
{ directiveName: 'boText', attribute: 'text' },
{ directiveName: 'boBind', attribute: 'text' },
{ directiveName: 'boHtml', attribute: 'html' },
{ directiveName: 'boSrcI', attribute: 'src', interpolate: true },
{ directiveName: 'boSrc', attribute: 'src' },
{ directiveName: 'boHrefI', attribute: 'href', interpolate: true },
{ directiveName: 'boHref', attribute: 'href' },
{ directiveName: 'boAlt', attribute: 'alt' },
{ directiveName: 'boTitle', attribute: 'title' },
{ directiveName: 'boId', attribute: 'id' },
{ directiveName: 'boStyle', attribute: 'style' },
{ directiveName: 'boDisabled', attribute: 'disabled' },
{ directiveName: 'boValue', attribute: 'value' },
{ directiveName: 'boAttr', attribute: 'attr' },
{ directiveName: 'boIf', transclude: 'element', terminal: true, priority: 1000 },
{ directiveName: 'boSwitch', require: 'boSwitch', controller: function () { this.cases = {}; } },
{ directiveName: 'boSwitchWhen', transclude: 'element', priority: 800, require: '^boSwitch' },
{ directiveName: 'boSwitchDefault', transclude: 'element', priority: 800, require: '^boSwitch' }
],
function (boDirective)
{
var childPriority = 200;
return bindonceModule.directive(boDirective.directiveName, function ()
{
var bindonceDirective =
{
priority: boDirective.priority || childPriority,
transclude: boDirective.transclude || false,
terminal: boDirective.terminal || false,
require: ['^bindonce'].concat(boDirective.require || []),
controller: boDirective.controller,
compile: function (tElement, tAttrs, transclude)
{
return function (scope, elm, attrs, controllers)
{
var bindonceController = controllers[0];
var name = attrs.boParent;
if (name && bindonceController.group !== name)
{
var element = bindonceController.element.parent();
bindonceController = undefined;
var parentValue;
while (element[0].nodeType !== 9 && element.length)
{
if ((parentValue = element.data('$bindonceController'))
&& parentValue.group === name)
{
bindonceController = parentValue;
break;
}
element = element.parent();
}
if (!bindonceController)
{
throw new Error("No bindonce controller: " + name);
}
}
bindonceController.addBinder(
{
element: elm,
attr: boDirective.attribute || boDirective.directiveName,
attrs: attrs,
value: attrs[boDirective.directiveName],
interpolate: boDirective.interpolate,
group: name,
transclude: transclude,
controller: controllers.slice(1),
scope: scope
});
};
}
};
return bindonceDirective;
});
})
})();
!function(){"use strict";var e=angular.module("pasvaz.bindonce",[]);e.directive("bindonce",function(){var e=function(e){if(e&&0!==e.length){var t=angular.lowercase(""+e);e=!("f"===t||"0"===t||"false"===t||"no"===t||"n"===t||"[]"===t)}else e=!1;return e},t=parseInt((/msie (\d+)/.exec(angular.lowercase(navigator.userAgent))||[])[1],10);isNaN(t)&&(t=parseInt((/trident\/.*; rv:(\d+)/.exec(angular.lowercase(navigator.userAgent))||[])[1],10));var r={restrict:"AM",controller:["$scope","$element","$attrs","$interpolate",function(r,a,i,n){var c=function(t,r,a){var i="show"===r?"":"none",n="hide"===r?"":"none";t.css("display",e(a)?i:n)},o=function(e,t){if(angular.isObject(t)&&!angular.isArray(t)){var r=[];angular.forEach(t,function(e,t){e&&r.push(t)}),t=r}t&&e.addClass(angular.isArray(t)?t.join(" "):t)},s=function(e,t){e.transclude(t,function(t){var r=e.element.parent(),a=e.element&&e.element[e.element.length-1],i=r&&r[0]||a&&a.parentNode,n=a&&a.nextSibling||null;angular.forEach(t,function(e){i.insertBefore(e,n)})})},l={watcherRemover:void 0,binders:[],group:i.boName,element:a,ran:!1,addBinder:function(e){this.binders.push(e),this.ran&&this.runBinders()},setupWatcher:function(e){var t=this;this.watcherRemover=r.$watch(e,function(e){void 0!==e&&(t.removeWatcher(),t.checkBindonce(e))},!0)},checkBindonce:function(e){var t=this,r=e.$promise?e.$promise.then:e.then;"function"==typeof r?r(function(){t.runBinders()}):t.runBinders()},removeWatcher:function(){void 0!==this.watcherRemover&&(this.watcherRemover(),this.watcherRemover=void 0)},runBinders:function(){for(;this.binders.length>0;){var r=this.binders.shift();if(!this.group||this.group==r.group){var a=r.scope.$eval(r.interpolate?n(r.value):r.value);switch(r.attr){case"boIf":e(a)&&s(r,r.scope.$new());break;case"boSwitch":var i,l=r.controller[0];(i=l.cases["!"+a]||l.cases["?"])&&(r.scope.$eval(r.attrs.change),angular.forEach(i,function(e){s(e,r.scope.$new())}));break;case"boSwitchWhen":var u=r.controller[0];u.cases["!"+r.attrs.boSwitchWhen]=u.cases["!"+r.attrs.boSwitchWhen]||[],u.cases["!"+r.attrs.boSwitchWhen].push({transclude:r.transclude,element:r.element});break;case"boSwitchDefault":var u=r.controller[0];u.cases["?"]=u.cases["?"]||[],u.cases["?"].push({transclude:r.transclude,element:r.element});break;case"hide":case"show":c(r.element,r.attr,a);break;case"class":o(r.element,a);break;case"text":r.element.text(a);break;case"html":r.element.html(a);break;case"style":r.element.css(a);break;case"disabled":r.element.prop("disabled",a);break;case"src":r.element.attr(r.attr,a),t&&r.element.prop("src",a);break;case"attr":angular.forEach(r.attrs,function(e,t){var a,i;t.match(/^boAttr./)&&r.attrs[t]&&(a=t.replace(/^boAttr/,"").replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),i=r.scope.$eval(r.attrs[t]),r.element.attr(a,i))});break;case"href":case"alt":case"title":case"id":case"value":r.element.attr(r.attr,a)}}}this.ran=!0}};angular.extend(this,l)}],link:function(e,t,r,a){var i=r.bindonce&&e.$eval(r.bindonce);void 0!==i?a.checkBindonce(i):(a.setupWatcher(r.bindonce),t.bind("$destroy",a.removeWatcher))}};return r}),angular.forEach([{directiveName:"boShow",attribute:"show"},{directiveName:"boHide",attribute:"hide"},{directiveName:"boClass",attribute:"class"},{directiveName:"boText",attribute:"text"},{directiveName:"boBind",attribute:"text"},{directiveName:"boHtml",attribute:"html"},{directiveName:"boSrcI",attribute:"src",interpolate:!0},{directiveName:"boSrc",attribute:"src"},{directiveName:"boHrefI",attribute:"href",interpolate:!0},{directiveName:"boHref",attribute:"href"},{directiveName:"boAlt",attribute:"alt"},{directiveName:"boTitle",attribute:"title"},{directiveName:"boId",attribute:"id"},{directiveName:"boStyle",attribute:"style"},{directiveName:"boDisabled",attribute:"disabled"},{directiveName:"boValue",attribute:"value"},{directiveName:"boAttr",attribute:"attr"},{directiveName:"boIf",transclude:"element",terminal:!0,priority:1e3},{directiveName:"boSwitch",require:"boSwitch",controller:function(){this.cases={}}},{directiveName:"boSwitchWhen",transclude:"element",priority:800,require:"^boSwitch"},{directiveName:"boSwitchDefault",transclude:"element",priority:800,require:"^boSwitch"}],function(t){var r=200;return e.directive(t.directiveName,function(){var e={priority:t.priority||r,transclude:t.transclude||!1,terminal:t.terminal||!1,require:["^bindonce"].concat(t.require||[]),controller:t.controller,compile:function(e,r,a){return function(e,r,i,n){var c=n[0],o=i.boParent;if(o&&c.group!==o){var s=c.element.parent();c=void 0;for(var l;9!==s[0].nodeType&&s.length;){if((l=s.data("$bindonceController"))&&l.group===o){c=l;break}s=s.parent()}if(!c)throw new Error("No bindonce controller: "+o)}c.addBinder({element:r,attr:t.attribute||t.directiveName,attrs:i,value:i[t.directiveName],interpolate:t.interpolate,group:o,transclude:a,controller:n.slice(1),scope:e})}}};return e})})}();
\ No newline at end of file
{
"name": "angular-bindonce",
"version": "0.3.3",
"main": "bindonce.js",
"description": "Zero watchers binding directives for AngularJS",
"homepage": "https://github.com/Pasvaz/bindonce",
"author": "Pasquale Vazzana <pasqualevazzana@gmail.com>",
"repository": {
"type": "git",
"url": "https://github.com/Pasvaz/bindonce.git"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"components"
],
"dependencies": {
},
"keywords": [
"angularjs",
"angular",
"directive",
"binding",
"watcher",
"bindonce"
]
}
{
"name": "angular-bindonce",
"version": "0.3.3",
"main": "bindonce.js",
"description": "Zero watchers binding directives for AngularJS",
"homepage": "https://github.com/Pasvaz/bindonce",
"author": "Pasquale Vazzana <pasqualevazzana@gmail.com>",
"repository": {
"type": "git",
"url": "https://github.com/Pasvaz/bindonce.git"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"components"
],
"dependencies": {
},
"keywords": [
"angularjs",
"angular",
"directive",
"binding",
"watcher",
"bindonce"
]
}
{
"name": "angular-native-dragdrop",
"version": "1.2.2",
"homepage": "http://angular-dragdrop.github.io/angular-dragdrop",
"authors": [
"ganarajpr"
],
"description": "Angular HTML5 Drag and Drop directive written in pure with no dependency on JQuery.",
"main": "draganddrop.js",
"keywords": [
"angular",
"drag",
"drop",
"html5"
],
"dependencies": {
"angular": "^1.3"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"_release": "1.2.2",
"_resolution": {
"type": "version",
"tag": "1.2.2",
"commit": "e630636fdc39fef815c1c534340aa16caf76a04c"
},
"_source": "https://github.com/angular-dragdrop/angular-dragdrop.git",
"_target": "1.2.2",
"_originalSource": "angular-native-dragdrop"
}
\ No newline at end of file
/* jshint -W097 */
'use strict';
/* global require */
var jshint = require('gulp-jshint');
var stylish = require('jshint-stylish');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var gulp = require('gulp');
gulp.task('lint', function() {
return gulp.src('./draganddrop.js')
.pipe(jshint())
.pipe(jshint.reporter(stylish));
});
gulp.task('compress', function() {
return gulp.src('./draganddrop.js')
.pipe(uglify())
.pipe(rename({
extname: '.min.js'
}))
.pipe(gulp.dest('./'));
});
gulp.task('default', ['lint', 'compress']);
The MIT License
Copyright (c) 2015 Ganaraj P R, [Nebithi](http://www.nebithi.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
#Angular-DragDrop
[![npm version](http://img.shields.io/npm/v/angular-native-dragdrop.svg?style=flat)](https://npmjs.org/package/angular-native-dragdrop)
[![Build status](http://img.shields.io/travis/angular-dragdrop/angular-dragdrop.svg?style=flat)](https://travis-ci.org/angular-dragdrop/angular-dragdrop)
[![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/ganarajpr/angular-dragdrop?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
Angular-DragDrop is a angular HTML5 Drag and Drop directive written in pure with no dependency on JQuery.
This is based on the work done by Jason Turim. While this [blog post](http://jasonturim.wordpress.com/2013/09/01/angularjs-drag-and-drop/) was the inspiration for creating a native Drag and Drop solution, the intention was to create something that was more generic.
This implementation is mainly different from the one posted in the blog in the following areas :
1. Angular-DragDrop does not create an isolate scope. This has huge benefits when it comes to working with other directives. **NOTE :** It also does not pollute the scope with any variables or functions.
2. It does not depend on any kind of an ID attribute ( being either present or generated on the fly ).
3. It allows one to create channels on which different drag and drop directive combinations can work on in the same page ( more on this later ) .
Pull requests are welcome.
[Documentation](http://angular-dragdrop.github.io/angular-dragdrop/)
#Looking for Active Contributors.
This repo needs active contributers and maintainers. If you are interested in being one of the people who would like to actively maintain this repo, please let me know.
The MIT License
Copyright (c) 2014 Ganaraj P R, [Nebithi](http://www.nebithi.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
{
"name": "angular-native-dragdrop",
"version": "1.2.1",
"homepage": "http://angular-dragdrop.github.io/angular-dragdrop",
"authors": [
"ganarajpr"
],
"description": "Angular HTML5 Drag and Drop directive written in pure with no dependency on JQuery.",
"main": "draganddrop.js",
"keywords": [
"angular",
"drag",
"drop",
"html5"
],
"dependencies": {
"angular": "^1.3"
},
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}
body {
background-color: #f8f7f8;
}
.heading {
border-bottom: 1px solid #b7b7b7;
padding-bottom: 10px;
margin-bottom: 10px;
}
.topRow {
margin-bottom: 30px;
}
.on-drag-enter {
background-color : #677ba6;
}
.on-drag-enter-custom {
background-color : #d78cc7;
}
.on-drag-hover {
background-color : #3eb352;
}
.on-drag-hover-custom {
background-color : #d7a931;
}
\ No newline at end of file
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8" />
<title>Angular DragDrop (Demo)</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="css/styles.css" />
<script data-require="angular.js@1.4.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="http://pc035860.github.io/angular-highlightjs/angular-highlightjs.min.js"></script>
<script src="js/app.js"></script>
<script src="../draganddrop.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
</head>
<body >
<div class="container">
<div class="row topRow">
<h4 class="heading">
Drag and drop between the two lists.
</h4>
</div>
<h3>Beasts</h3>
<p>Left column of beasts is not draggable and accepts both beasts and priests</p>
<hr>
<div class="row" ng-controller="MainCtrl">
<div class="col-xs-6">
<ul ui-on-drop="onDrop($event,$data,men)" drag-enter-class="on-drag-enter-custom"
drop-channel="beasts,priests"
drop-validate="dropValidateHandler($drop, $event, $data)">
<li ui-draggable="false" drag="man" drag-channel="beasts"
on-drop-success="dropSuccessHandler($event,$index,men)"
ng-repeat="man in men track by $index">
{{man}}
</li>
</ul>
</div>
<div class="col-xs-6">
<ul ui-on-drop="onDrop($event,$data,women)"
drop-channel="beasts"
drop-validate="dropValidateHandler($drop, $event, $data)">
<li ui-draggable="true" drag="woman" drag-channel="beasts"
on-drop-success="dropSuccessHandler($event,$index,women)"
on-drop-failure="dropFailureHandler($event,$index,women)"
ng-repeat="woman in women track by $index">
{{woman}}
</li>
</ul>
</div>
</div>
<hr>
<h3>Priests</h3>
<hr>
<div class="row" ng-controller="MainCtrl">
<div class="col-xs-6">
<ul ui-on-drop="onDrop($event,$data,men)"
drop-channel="priests"
drop-validate="dropValidateHandler($drop, $event, $data)">
<li ui-draggable="true" drag="man"
drag-channel="priests"
on-drop-success="dropSuccessHandler($event,$index,men)"
ng-repeat="man in men track by $index">
{{man}}
</li>
</ul>
</div>
<div class="col-xs-6">
<ul ui-on-drop="onDrop($event,$data,women)"
drop-channel="priests"
drop-validate="dropValidateHandler($drop, $event, $data)">
<li ui-draggable="true" drag="woman"
drag-channel="priests"
on-drop-success="dropSuccessHandler($event,$index,women)"
ng-repeat="woman in women track by $index">
{{woman}}
</li>
</ul>
</div>
</div>
<hr>
<h3>Terrorists</h3>
<p>Each terrorist list item accepts a new terrorist. Shows inserting into a particular
position in an array.</p>
<hr>
<div class="row" ng-controller="MainCtrl">
<div class="col-xs-6">
<ul>
<li ui-draggable="true" drag="man"
drag-channel="terrorists2"
drop-validate="dropValidateHandler($drop, $event, $data)"
drag-hover-class="on-drag-hover-custom"
on-drop-success="dropSuccessHandler($event,$index,men)"
ui-on-drop="onDrop($event,$data,men,$index)" drop-channel="terrorists1"
ng-repeat="man in men track by $index">
{{man}}
</li>
</ul>
</div>
<div class="col-xs-6">
<ul>
<li ui-draggable="true" drag="woman"
drag-channel="terrorists1"
drop-validate="dropValidateHandler($drop, $event, $data)"
drag-hover-class="on-drag-hover-custom"
ui-on-drop="onDrop($event,$data,women,$index)" drop-channel="terrorists2"
on-drop-success="dropSuccessHandler($event,$index,women)"
ng-repeat="woman in women track by $index">
{{woman}}
</li>
</ul>
</div>
</div>
<hr>
<h3>Custom Drag Image</h3>
<p>You may specify a drag-image-element-id to use as the drag image. You can use the
<a href="http://www.kryogenix.org/code/browser/custom-drag-image.html" target="_blank">ghost image</a>
technique for the custom drag image.</p>
<hr>
<div class="row" ng-controller="MainCtrl">
<div class="col-xs-6">
<ul>
<li ui-draggable="true" drag="man"
drag-channel="customImage2"
drop-validate="dropValidateHandler($drop, $event, $data)"
drag-hover-class="on-drag-hover-custom"
drag-image-element-id="getCustomDragElementId($index)"
on-drop-success="dropSuccessHandler($event,$index,men)"
ui-on-drop="onDrop($event,$data,men,$index)"
drop-channel="customImage1"
ng-repeat="man in men track by $index">
{{man}}
</li>
</ul>
</div>
<div class="col-xs-6">
<ul>
<li ui-draggable="true" drag="woman"
drag-channel="customImage1"
drop-validate="dropValidateHandler($drop, $event, $data)"
drag-hover-class="on-drag-hover-custom"
drag-image-element-id="getCustomDragElementId($index)"
ui-on-drop="onDrop($event,$data,women,$index)"
drop-channel="customImage2"
on-drop-success="dropSuccessHandler($event,$index,women)"
ng-repeat="woman in women track by $index">
{{woman}}
</li>
</ul>
</div>
</div>
<div id="customDrag0" class="alert alert-info" style="max-width: 200px">Custom drag image #1</div>
<div id="customDrag1" class="alert alert-danger" style="position: absolute; top: 0; right: 0; z-index: -2; max-width: 200px">Custom drag image #2</div>
<div id="coverUp" style="position: absolute; top: 0; right: 0; z-index: -1; background-color: white; width: 200px; height: 60px"></div>
</div>
</body>
</html>
angular.module('app', [
'hljs',
'ang-drag-drop'
]).controller('MainCtrl', function($scope) {
$scope.men = [
'John',
'Jack',
'Mark',
'Ernie',
'Mike (Locked)'
];
$scope.women = [
'Jane',
'Jill',
'Betty',
'Mary'
];
$scope.addText = '';
$scope.dropValidateHandler = function($drop, $event, $data) {
if ($data === 'Mike (Locked)') {
return false;
}
if ($drop.element[0] === $event.srcElement.parentNode) {
// Don't allow moving to same container
return false;
}
return true;
};
$scope.dropSuccessHandler = function($event, index, array) {
array.splice(index, 1);
};
$scope.dropFailureHandler = function($event, index, array) {
alert(array[index] + ' could be dropped into left list!')
};
$scope.onDrop = function($event, $data, array, index) {
if (index !== undefined) {
array.splice(index, 0, $data);
} else {
array.push($data);
}
};
$scope.getCustomDragElementId = function (index) {
return 'customDrag' + (index % 2);
}
});
#Examples
##Simple Usage
<iframe style="width: 100%; height: 500px" src="http://embed.plnkr.co/5RLvCpDPoRcEk6u77dBM" frameborder="0" allowfullscreen="allowfullscreen"></iframe>
##With drop validation
<iframe style="width: 100%; height: 500px" src="http://embed.plnkr.co/xRmz4TlCvlJKxybGrhQH" frameborder="0" allowfullscreen="allowfullscreen"></iframe>
\ No newline at end of file
#Installation
##Download
Download the file [**draganddrop.min.js**](https://raw.githubusercontent.com/angular-dragdrop/angular-dragdrop/master/draganddrop.min.js) or [**draganddrop.js**](https://raw.githubusercontent.com/angular-dragdrop/angular-dragdrop/master/draganddrop.js).
##Bower
You can also install via Bower using
`bower install angular-native-dragdrop --save`
---
#Usage
##Step - 1 **Add script**
```
<script src="path/to/draganddrop.min.js"></script>
```
##Step - 2 **Include in app**
```
myApp = angular.module('myApp','ang-drag-drop');
```
##Step - 3 ***Profit!!***
# Angular Drag and Drop
**A Native ( without jquery ) Drag and Drop directive for AngularJS using HTML5 Drag and Drop**
---
##ui-draggable(expression)
Directive in module ang-drag-drop (since 1.0.5 - old module name ngDragDrop)
The ui-draggable attribute tells Angular that the element is draggable. ui-draggable takes an expression as the attribute value. The expression should evaluate to either true or false. You can toggle the draggability of an element using this expression.
###Additional Attributes
####_**drag**_(variable)
The class used to mark child elements of draggable object to be used as drag handle. Default class name is `drag-handle`
**NOTE**: If attribute is not present drag handle feature is not active.
####_**drag-handle-class**_(string)
The `drag` property is used to assign the data that needs to be passed along with the dragging element.
####_**on-drop-success**_(function)
The `on-drop-success` attribute takes a function. We can consider this to be an on-drop-success handler function. This can be useful if you need to do some post processing after the dragged element is dropped successfully on the drop site.
**NOTE**: This callback function is only called when the drop succeeds.
You can request the `drag-end` event ( very similiar to requesting the click event in `ng-click` ) by passing `$event` in the event handler.
####_**on-drop-failure**_(function)
The `on-drop-failure` attribute takes a function. We can consider this to be an on-drop-failure handler function. This can be useful if you need to do some post processing after the dragged element is dropped unsuccessfully on any drop site.
**NOTE**: This callback function is only called when the drop fails.
You can request the `drag-end` event ( very similiar to requesting the click event in `ng-click` ) by passing `$event` in the event handler.
####_**drag-channel**_(string)
The `on-drop-failure` attribute takes a function. We can consider this to be an on-drop-failure handler function. This can be useful if you need to do some post processing after the dragged element is dropped unsuccessfully on any drop site.
**NOTE**: This callback function is only called when the drop fails.
You can request the `drag-end` event ( very similiar to requesting the click event in `ng-click` ) by passing `$event` in the event handler.
###Usage
###Events
On start of dragging an Angular Event `ANGULAR_DRAG_START` is dispatched from the `$rootScope`. The event also carries carries the information about the channel in which the dragging has started.
On end of dragging an Angular Event `ANGULAR_DRAG_END` is dispatched from the `$rootScope`. The event also carries carries the information about the channel in which the dragging has started.
When hovering a draggable element on top of a drop area an Angular Event `ANGULAR_HOVER` is dispatched from the `$rootScope`. The event also carries the information about the channel in which the dragging has started.
---
##ui-on-drop(expression)
Directive in module ang-drag-drop (since 1.0.5 - old module name ngDragDrop)
The `ui-on-drop` attribute tells Angular that the element is a drop site. `ui-on-drop` takes a function as the attribute value. The function will be called when a valid dragged element is dropped in that location. A valid dragged element is one which has the same channel as the drop location.
**NOTE** : This callback function is only called when the drop succeeds.
The `ui-on-drop` callback can request additional parameters. The data that is dragged is available to the callback as $data and its channel as `$channel`. Apart from this the drop event is exposed as `$event`.
###Additional Attributes
####_**drop-channel**_(variable)
The channel that the drop site accepts. The dragged element should have the same channel as this drop site for it to be droppable at this location. It is possible to provide comma separated list of channels.
**NOTE**: Also special value of `drag-channel` attribute is available to accept dragged element with any channel value — *
####_**drop-validate**_(function)
Extra validation that makes sure that the drop site accepts the dragged element beyond having the same channel. If not defined, no extra validation is made.
**NOTE**: This callback function is called only if the channel condition is met, when the element starts being dragged
####_**drag-enter-class**_(string)
The class that will be added to the the droppable element when a dragged element ( which is droppable ) enters the drop location. The default value for this is `on-drag-enter`
####_**drag-hover-class**_(string)
The class that will be added to the drop area element when hovering with an element. The default value for this is `on-drag-hover`
###Usage
###Events
On start of dragging an Angular Event `ANGULAR_DRAG_START` is dispatched from the `$rootScope`. The event also carries carries the information about the channel in which the dragging has started.
On end of dragging an Angular Event `ANGULAR_DRAG_END` is dispatched from the `$rootScope`. The event also carries carries the information about the channel in which the dragging has started.
When hovering a draggable element on top of a drop area an Angular Event `ANGULAR_HOVER` is dispatched from the `$rootScope`. The event also carries the information about the channel in which the dragging has started.
\ No newline at end of file
!function(e){"use strict";function a(){return"ondrag"in document.createElement("a")}function n(e){e.originalEvent&&(e.dataTransfer=e.originalEvent.dataTransfer),"undefined"!=typeof e.dataTransfer&&"none"===e.dataTransfer.dropEffect&&("copy"===e.dataTransfer.effectAllowed||"move"===e.dataTransfer.effectAllowed?e.dataTransfer.dropEffect=e.dataTransfer.effectAllowed:"copyMove"!==e.dataTransfer.effectAllowed&&"copymove"!==e.dataTransfer.effectAllowed||(e.dataTransfer.dropEffect=e.ctrlKey?"copy":"move"))}if(!a())return void e.module("ang-drag-drop",[]);var r=e.module("ang-drag-drop",[]);r.directive("uiDraggable",["$parse","$rootScope","$dragImage",function(a,r,t){return function(o,d,f){function i(e){e.originalEvent&&(e.dataTransfer=e.originalEvent.dataTransfer),setTimeout(function(){d.unbind("$destroy",i)},0);var t=f.dragChannel||"defaultchannel";if(r.$broadcast("ANGULAR_DRAG_END",e,t),n(e),e.dataTransfer&&"none"!==e.dataTransfer.dropEffect){if(f.onDropSuccess){var s=a(f.onDropSuccess);o.$evalAsync(function(){s(o,{$event:e})})}}else if(e.dataTransfer&&"none"===e.dataTransfer.dropEffect&&f.onDropFailure){var l=a(f.onDropFailure);o.$evalAsync(function(){l(o,{$event:e})})}d.removeClass(c)}function s(n,r){var t;n.originalEvent&&(n.dataTransfer=n.originalEvent.dataTransfer),t=a(r),o.$apply(function(){var a,r=t(o,{$event:n});r&&e.isString(r)&&(a=document.getElementById(r),a&&n.dataTransfer.setDragImage(a,0,0))})}function l(n){n.originalEvent&&(n.dataTransfer=n.originalEvent.dataTransfer);var l=!v||u.classList.contains(g);if(l){var p=f.dragChannel||"defaultchannel",$="";f.drag&&($=o.$eval(f.drag));var m=f.dragImage||null;d.addClass(c),d.bind("$destroy",i);var T=!(document.uniqueID||window.opera);if(m&&T){var h=a(f.dragImage);o.$apply(function(){var a=h(o,{$event:n});if(a&&(e.isString(a)&&(a=t.generate(a)),a.image)){var r=a.xOffset||0,d=a.yOffset||0;n.dataTransfer.setDragImage(a.image,r,d)}})}else f.dragImageElementId&&s(n,f.dragImageElementId);var b={x:n.offsetX,y:n.offsetY},D={data:$,channel:p,offset:b},y=e.toJson(D);n.dataTransfer.setData("text",y),n.dataTransfer.effectAllowed="copyMove",r.$broadcast("ANGULAR_DRAG_START",n,p,D)}else n.preventDefault()}var g,u,v=!1,c=f.draggingClass||"on-dragging";d.attr("draggable",!1),o.$watch(f.uiDraggable,function(e){e?(d.attr("draggable",e),d.bind("dragend",i),d.bind("dragstart",l)):(d.removeAttr("draggable"),d.unbind("dragend",i),d.unbind("dragstart",l))}),e.isString(f.dragHandleClass)&&(v=!0,g=f.dragHandleClass.trim()||"drag-handle",d.bind("mousedown",function(e){u=e.target}))}}]),r.directive("uiOnDrop",["$parse","$rootScope",function(a,r){return function(t,o,d){function f(e){for(var a={x:e.offsetX,y:e.offsetY},n=e.target;n!==o[0];)if(a.x=a.x+n.offsetLeft,a.y=a.y+n.offsetTop,n=n.offsetParent,!n)return null;return a}function i(e){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation();var n=a(d.uiOnDragOver);return t.$evalAsync(function(){n(t,{$event:e,$channel:p})}),!1}function s(e){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),c--,0===c&&(t.$evalAsync(function(){b(t,{$event:e,$channel:p})}),o.addClass(m),o.removeClass(T));var n=a(d.uiOnDragLeave);t.$evalAsync(function(){n(t,{$event:e,$channel:p})})}function l(e){e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),0===c&&(t.$evalAsync(function(){h(t,{$event:e,$channel:p})}),o.removeClass(m),o.addClass(T)),c++;var n=a(d.uiOnDragEnter);t.$evalAsync(function(){n(t,{$event:e,$channel:p})}),r.$broadcast("ANGULAR_HOVER",$)}function g(r){r.originalEvent&&(r.dataTransfer=r.originalEvent.dataTransfer),r.preventDefault&&r.preventDefault(),r.stopPropagation&&r.stopPropagation();var i=r.dataTransfer.getData("text");i=e.fromJson(i);var s=f(r),l=s?{x:s.x-i.offset.x,y:s.y-i.offset.y}:null;n(r);var g=a(d.uiOnDrop);t.$evalAsync(function(){g(t,{$data:i.data,$event:r,$channel:i.channel,$position:l})}),o.removeClass(m),c=0}function u(e,a){if("*"===a)return!0;var n=new RegExp("(\\s|[,])+("+e+")(\\s|[,])+","i");return n.test(","+a+",")}function v(e){return e.originalEvent&&(e.dataTransfer=e.originalEvent.dataTransfer),e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation(),e.dataTransfer.dropEffect="none",!1}var c=0,p=d.dropChannel||"defaultchannel",$="",m=d.dragEnterClass||"on-drag-enter",T=d.dragHoverClass||"on-drag-hover",h=a(d.onDragEnter),b=a(d.onDragLeave),D=r.$on("ANGULAR_DRAG_START",function(e,n,r,f){$=r;var c=!0;if(u(r,p)||(c=!1),c&&d.dropValidate){var T=a(d.dropValidate);c=T(t,{$drop:{scope:t,element:o},$event:n,$data:f.data,$channel:f.channel})}c?(o.bind("dragover",i),o.bind("dragenter",l),o.bind("dragleave",s),o.bind("drop",g),o.addClass(m)):(o.bind("dragover",v),o.bind("dragenter",v),o.bind("dragleave",v),o.bind("drop",v),o.removeClass(m))}),y=r.$on("ANGULAR_DRAG_END",function(){o.unbind("dragover",i),o.unbind("dragenter",l),o.unbind("dragleave",s),o.unbind("drop",g),o.removeClass(T),o.removeClass(m),o.unbind("dragover",v),o.unbind("dragenter",v),o.unbind("dragleave",v),o.unbind("drop",v)});t.$on("$destroy",function(){D(),y()}),d.$observe("dropChannel",function(e){e&&(p=e)})}}]),r.constant("$dragImageConfig",{height:20,width:200,padding:10,font:"bold 11px Arial",fontColor:"#eee8d5",backgroundColor:"#93a1a1",xOffset:0,yOffset:0}),r.service("$dragImage",["$dragImageConfig",function(a){function n(e,a,n){var t=e.measureText(a).width;if(t<n.width)return a;for(;t+n.padding>n.width;)a=a.substring(0,a.length-1),t=e.measureText(a+r).width;return a+r}var r="…";this.generate=function(r,t){var o=e.extend({},a,t||{}),d=document.createElement("canvas");d.height=o.height,d.width=o.width;var f=d.getContext("2d");f.fillStyle=o.backgroundColor,f.fillRect(0,0,o.width,o.height),f.font=o.font,f.fillStyle=o.fontColor;var i=n(f,r,o);f.fillText(i,4,o.padding+4);var s=new Image;return s.src=d.toDataURL(),{image:s,xOffset:o.xOffset,yOffset:o.yOffset}}}])}(angular);
\ No newline at end of file
require('./draganddrop');
module.exports = 'ang-drag-drop';
site_name: Angular Drag and Drop
site_url: http://angular-dragdrop.github.io/angular-dragdrop/
site_description: Project documentation for angular Drag and Drop.
repo_url: https://github.com/angular-dragdrop/angular-dragdrop
theme : flatly
pages:
- 'index.md'
- 'getting-started.md'
- 'examples.md'
\ No newline at end of file
{
"name": "angular-native-dragdrop",
"version": "1.2.2",
"description": "Angular HTML5 Drag and Drop directive written in pure with no dependency on JQuery.",
"main": "index.js",
"scripts": {
"test": "gulp"
},
"repository": {
"type": "git",
"url": "https://github.com/angular-dragdrop/angular-dragdrop.git"
},
"author": "ganarajpr",
"license": "MIT",
"bugs": {
"url": "https://github.com/angular-dragdrop/angular-dragdrop/issues"
},
"homepage": "http://angular-dragdrop.github.io/angular-dragdrop",
"devDependencies": {
"gulp": "^3.8.11",
"gulp-jshint": "^1.9.2",
"gulp-rename": "^1.2.2",
"gulp-uglify": "^1.4.2",
"jshint-stylish": "^1.0.1"
}
}
{
"name": "clipboard",
"version": "1.5.16",
"description": "Modern copy to clipboard. No Flash. Just 2kb",
"license": "MIT",
"main": "dist/clipboard.js",
"ignore": [
"/.*/",
"/demo/",
"/test/",
"/.*",
"/bower.json",
"/karma.conf.js",
"/src",
"/lib"
],
"keywords": [
"clipboard",
"copy",
"cut"
],
"homepage": "https://github.com/zenorocha/clipboard.js",
"_release": "1.5.16",
"_resolution": {
"type": "version",
"tag": "v1.5.16",
"commit": "402c9ee17bed6f273bcbc7efa81874fd9a50b84c"
},
"_source": "https://github.com/zenorocha/clipboard.js.git",
"_target": "^1.5.16",
"_originalSource": "clipboard",
"_direct": true
}
\ No newline at end of file
{
"name": "clipboard",
"version": "1.5.16",
"description": "Modern copy to clipboard. No Flash. Just 2kb",
"license": "MIT",
"main": "dist/clipboard.js",
"ignore": [
"/.*/",
"/demo/",
"/test/",
"/.*",
"/bower.json",
"/karma.conf.js",
"/src",
"/lib"
],
"keywords": [
"clipboard",
"copy",
"cut"
]
}
# Contributing guide
Want to contribute to Clipboard.js? Awesome!
There are many ways you can contribute, see below.
## Opening issues
Open an issue to report bugs or to propose new features.
- Reporting bugs: describe the bug as clearly as you can, including steps to reproduce, what happened and what you were expecting to happen. Also include browser version, OS and other related software's (npm, Node.js, etc) versions when applicable.
- Proposing features: explain the proposed feature, what it should do, why it is useful, how users should use it. Give us as much info as possible so it will be easier to discuss, access and implement the proposed feature. When you're unsure about a certain aspect of the feature, feel free to leave it open for others to discuss and find an appropriate solution.
## Proposing pull requests
Pull requests are very welcome. Note that if you are going to propose drastic changes, be sure to open an issue for discussion first, to make sure that your PR will be accepted before you spend effort coding it.
Fork the Clipboard.js repository, clone it locally and create a branch for your proposed bug fix or new feature. Avoid working directly on the master branch.
Implement your bug fix or feature, write tests to cover it and make sure all tests are passing (run a final `npm test` to make sure everything is correct). Then commit your changes, push your bug fix/feature branch to the origin (your forked repo) and open a pull request to the upstream (the repository you originally forked)'s master branch.
## Documentation
Documentation is extremely important and takes a fair deal of time and effort to write and keep updated. Please submit any and all improvements you can make to the repository's docs.
## Known issues
If you're using npm@3 you'll probably face some issues related to peerDependencies.
https://github.com/npm/npm/issues/9204
// Package metadata for Meteor.js.
Package.describe({
name: "zenorocha:clipboard",
summary: "Modern copy to clipboard. No Flash. Just 2kb.",
version: "1.5.16",
git: "https://github.com/zenorocha/clipboard.js"
});
Package.onUse(function(api) {
api.addFiles("dist/clipboard.js", "client");
});
{
"name": "clipboard",
"version": "1.5.16",
"description": "Modern copy to clipboard. No Flash. Just 2kb",
"repository": "zenorocha/clipboard.js",
"license": "MIT",
"main": "lib/clipboard.js",
"keywords": [
"clipboard",
"copy",
"cut"
],
"dependencies": {
"good-listener": "^1.2.0",
"select": "^1.0.6",
"tiny-emitter": "^1.0.0"
},
"devDependencies": {
"babel-cli": "^6.5.1",
"babel-core": "^6.5.2",
"babel-plugin-transform-es2015-modules-umd": "^6.5.0",
"babel-preset-es2015": "^6.5.0",
"babelify": "^7.2.0",
"bannerify": "Vekat/bannerify#feature-option",
"browserify": "^13.0.0",
"chai": "^3.4.1",
"install": "^0.8.1",
"karma": "^1.3.0",
"karma-browserify": "^5.0.1",
"karma-chai": "^0.1.0",
"karma-mocha": "^1.2.0",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sinon": "^1.0.4",
"mocha": "^3.1.2",
"phantomjs-prebuilt": "^2.1.4",
"sinon": "^1.17.2",
"uglify-js": "^2.4.24",
"watchify": "^3.4.0"
},
"scripts": {
"build": "npm run build-debug && npm run build-min",
"build-debug": "browserify src/clipboard.js -s Clipboard -t [babelify] -p [bannerify --file .banner ] -o dist/clipboard.js",
"build-min": "uglifyjs dist/clipboard.js --comments '/!/' -m screw_ie8=true -c screw_ie8=true,unused=false -o dist/clipboard.min.js",
"build-watch": "watchify src/clipboard.js -s Clipboard -t [babelify] -o dist/clipboard.js -v",
"test": "karma start --single-run",
"prepublish": "babel src --out-dir lib"
}
}
# clipboard.js
[![Build Status](http://img.shields.io/travis/zenorocha/clipboard.js/master.svg?style=flat)](https://travis-ci.org/zenorocha/clipboard.js)
![Killing Flash](https://img.shields.io/badge/killing-flash-brightgreen.svg?style=flat)
> Modern copy to clipboard. No Flash. Just 3kb gzipped.
<a href="https://clipboardjs.com/"><img width="728" src="https://cloud.githubusercontent.com/assets/398893/16165747/a0f6fc46-349a-11e6-8c9b-c5fd58d9099c.png" alt="Demo"></a>
## Why
Copying text to the clipboard shouldn't be hard. It shouldn't require dozens of steps to configure or hundreds of KBs to load. But most of all, it shouldn't depend on Flash or any bloated framework.
That's why clipboard.js exists.
## Install
You can get it on npm.
```
npm install clipboard --save
```
Or bower, too.
```
bower install clipboard --save
```
If you're not into package management, just [download a ZIP](https://github.com/zenorocha/clipboard.js/archive/master.zip) file.
## Setup
First, include the script located on the `dist` folder or load it from [a third-party CDN provider](https://github.com/zenorocha/clipboard.js/wiki/CDN-Providers).
```html
<script src="dist/clipboard.min.js"></script>
```
Now, you need to instantiate it by [passing a DOM selector](https://github.com/zenorocha/clipboard.js/blob/master/demo/constructor-selector.html#L18), [HTML element](https://github.com/zenorocha/clipboard.js/blob/master/demo/constructor-node.html#L16-L17), or [list of HTML elements](https://github.com/zenorocha/clipboard.js/blob/master/demo/constructor-nodelist.html#L18-L19).
```js
new Clipboard('.btn');
```
Internally, we need to fetch all elements that matches with your selector and attach event listeners for each one. But guess what? If you have hundreds of matches, this operation can consume a lot of memory.
For this reason we use [event delegation](http://stackoverflow.com/questions/1687296/what-is-dom-event-delegation) which replaces multiple event listeners with just a single listener. After all, [#perfmatters](https://twitter.com/hashtag/perfmatters).
# Usage
We're living a _declarative renaissance_, that's why we decided to take advantage of [HTML5 data attributes](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes) for better usability.
### Copy text from another element
A pretty common use case is to copy content from another element. You can do that by adding a `data-clipboard-target` attribute in your trigger element.
The value you include on this attribute needs to match another's element selector.
<a href="https://clipboardjs.com/#example-target"><img width="473" alt="example-2" src="https://cloud.githubusercontent.com/assets/398893/9983467/a4946aaa-5fb1-11e5-9780-f09fcd7ca6c8.png"></a>
```html
<!-- Target -->
<input id="foo" value="https://github.com/zenorocha/clipboard.js.git">
<!-- Trigger -->
<button class="btn" data-clipboard-target="#foo">
<img src="assets/clippy.svg" alt="Copy to clipboard">
</button>
```
### Cut text from another element
Additionally, you can define a `data-clipboard-action` attribute to specify if you want to either `copy` or `cut` content.
If you omit this attribute, `copy` will be used by default.
<a href="https://clipboardjs.com/#example-action"><img width="473" alt="example-3" src="https://cloud.githubusercontent.com/assets/398893/10000358/7df57b9c-6050-11e5-9cd1-fbc51d2fd0a7.png"></a>
```html
<!-- Target -->
<textarea id="bar">Mussum ipsum cacilds...</textarea>
<!-- Trigger -->
<button class="btn" data-clipboard-action="cut" data-clipboard-target="#bar">
Cut to clipboard
</button>
```
As you may expect, the `cut` action only works on `<input>` or `<textarea>` elements.
### Copy text from attribute
Truth is, you don't even need another element to copy its content from. You can just include a `data-clipboard-text` attribute in your trigger element.
<a href="https://clipboardjs.com/#example-text"><img width="147" alt="example-1" src="https://cloud.githubusercontent.com/assets/398893/10000347/6e16cf8c-6050-11e5-9883-1c5681f9ec45.png"></a>
```html
<!-- Trigger -->
<button class="btn" data-clipboard-text="Just because you can doesn't mean you should — clipboard.js">
Copy to clipboard
</button>
```
## Events
There are cases where you'd like to show some user feedback or capture what has been selected after a copy/cut operation.
That's why we fire custom events such as `success` and `error` for you to listen and implement your custom logic.
```js
var clipboard = new Clipboard('.btn');
clipboard.on('success', function(e) {
console.info('Action:', e.action);
console.info('Text:', e.text);
console.info('Trigger:', e.trigger);
e.clearSelection();
});
clipboard.on('error', function(e) {
console.error('Action:', e.action);
console.error('Trigger:', e.trigger);
});
```
For a live demonstration, open this [site](https://clipboardjs.com/) and just your console :)
## Advanced Options
If you don't want to modify your HTML, there's a pretty handy imperative API for you to use. All you need to do is declare a function, do your thing, and return a value.
For instance, if you want to dynamically set a `target`, you'll need to return a Node.
```js
new Clipboard('.btn', {
target: function(trigger) {
return trigger.nextElementSibling;
}
});
```
If you want to dynamically set a `text`, you'll return a String.
```js
new Clipboard('.btn', {
text: function(trigger) {
return trigger.getAttribute('aria-label');
}
});
```
Also, if you are working with single page apps, you may want to manage the lifecycle of the DOM more precisely. Here's how you clean up the events and objects that we create.
```js
var clipboard = new Clipboard('.btn');
clipboard.destroy();
```
## Browser Support
This library relies on both [Selection](https://developer.mozilla.org/en-US/docs/Web/API/Selection) and [execCommand](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand) APIs. The first one is [supported by all browsers](http://caniuse.com/#search=selection) while the second one is supported in the following browsers.
| <img src="https://clipboardjs.com/assets/images/chrome.png" width="48px" height="48px" alt="Chrome logo"> | <img src="https://clipboardjs.com/assets/images/edge.png" width="48px" height="48px" alt="Edge logo"> | <img src="https://clipboardjs.com/assets/images/firefox.png" width="48px" height="48px" alt="Firefox logo"> | <img src="https://clipboardjs.com/assets/images/ie.png" width="48px" height="48px" alt="Internet Explorer logo"> | <img src="https://clipboardjs.com/assets/images/opera.png" width="48px" height="48px" alt="Opera logo"> | <img src="https://clipboardjs.com/assets/images/safari.png" width="48px" height="48px" alt="Safari logo"> |
|:---:|:---:|:---:|:---:|:---:|:---:|
| 42+ ✔ | 12+ ✔ | 41+ ✔ | 9+ ✔ | 29+ ✔ | 10+ ✔ |
The good news is that clipboard.js gracefully degrades if you need to support older browsers. All you have to do is show a tooltip saying `Copied!` when `success` event is called and `Press Ctrl+C to copy` when `error` event is called because the text is already selected.
## License
[MIT License](http://zenorocha.mit-license.org/) © Zeno Rocha
......@@ -45,6 +45,9 @@ module.exports = function(config) {
'react/dist/*.js',
'react-dom/dist/*.js',
'ngreact/ngReact.js',
'angular-bindonce/bindonce.js',
'angular-native-dragdrop/draganddrop.js',
'clipboard/dist/clipboard.js',
],
dest: '<%= srcDir %>/vendor/npm'
}
......
......@@ -97,10 +97,18 @@ amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
angular-bindonce@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/angular-bindonce/-/angular-bindonce-0.3.1.tgz#af19574abd43f608b9236a302cc5ce49d71dc9c6"
angular-mocks@^1.6.6:
version "1.6.6"
resolved "https://registry.yarnpkg.com/angular-mocks/-/angular-mocks-1.6.6.tgz#c93018e7838c6dc5ceaf1a6bcf9be13c830ea515"
angular-native-dragdrop@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/angular-native-dragdrop/-/angular-native-dragdrop-1.2.2.tgz#d646c6b75b131c48073c3f6e36a225b2726d8bae"
angular-route@^1.6.6:
version "1.6.6"
resolved "https://registry.yarnpkg.com/angular-route/-/angular-route-1.6.6.tgz#8c11748aa195c717b1b615a7e746442bfc7c61f4"
......@@ -750,6 +758,14 @@ cli@~1.0.0:
exit "0.1.2"
glob "^7.1.1"
clipboard@^1.7.1:
version "1.7.1"
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-1.7.1.tgz#360d6d6946e99a7a1fef395e42ba92b5e9b5a16b"
dependencies:
good-listener "^1.2.2"
select "^1.1.2"
tiny-emitter "^2.0.0"
cliui@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
......@@ -1046,6 +1062,10 @@ delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
delegate@^3.1.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.1.3.tgz#9a8251a777d7025faa55737bc3b071742127a9fd"
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
......@@ -1818,6 +1838,12 @@ gonzales-pe@3.4.7:
dependencies:
minimist "1.1.x"
good-listener@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
dependencies:
delegate "^3.1.2"
graceful-fs@^4.1.0, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
......@@ -4114,6 +4140,10 @@ scss-tokenizer@^0.2.3:
js-base64 "^2.1.8"
source-map "^0.4.2"
select@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0:
version "5.4.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
......@@ -4553,6 +4583,10 @@ tiny-emitter@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-1.2.0.tgz#6dc845052cb08ebefc1874723b58f24a648c3b6f"
tiny-emitter@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c"
tiny-lr@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-0.2.1.tgz#b3fdba802e5d56a33c2f6f10794b32e477ac729d"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment