From 13f3816dc2f7dc6346b1022d983270d137687dc4 Mon Sep 17 00:00:00 2001 From: airyland Date: Fri, 2 May 2014 21:53:29 +0800 Subject: [PATCH 1/2] moe module init --- .gitignore | 25 ++++++ .travis.yml | 19 +++++ HISTORY.md | 8 ++ Makefile | 14 ++++ README.md | 97 ++--------------------- examples/index.md | 154 ++++++++++++++++++++++++++++++++++++ index.html | 176 ----------------------------------------- jquery.sortable.js | 85 -------------------- package.json | 26 ++++++ src/jquery.sortable.js | 85 ++++++++++++++++++++ src/sortable.js | 85 ++++++++++++++++++++ tests/sortable-spec.js | 12 +++ 12 files changed, 436 insertions(+), 350 deletions(-) create mode 100644 .gitignore create mode 100644 .travis.yml create mode 100644 HISTORY.md create mode 100644 Makefile create mode 100644 examples/index.md delete mode 100644 index.html delete mode 100644 jquery.sortable.js create mode 100644 package.json create mode 100644 src/jquery.sortable.js create mode 100644 src/sortable.js create mode 100644 tests/sortable-spec.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ab01aa7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +*.iml +.idea/ +.ipr +.iws +*~ +~* +*.diff +*.patch +*.bak +.DS_Store +Thumbs.db +.project +.*proj +.svn/ +*.swp +*.swo +*.pyc +*.pyo +build +node_modules +_site +sea-modules +.cache +.build +tmp diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e5c2daf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: node_js + +node_js: + - 0.10 + +install: + - npm install mocha-browser nico + +before_script: + - git clone git://github.com/aralejs/nico-arale.git _theme + - node_modules/.bin/nico build --theme _theme -C _theme/nico.js + +script: + - node_modules/.bin/mocha-browser _site/tests/runner.html -S + +after_success: + - npm install jscoverage coveralls + - node_modules/.bin/jscoverage --encoding=utf8 src _site/src-cov + - node_modules/.bin/mocha-browser _site/tests/runner.html?cov -S -R lcov | node_modules/.bin/coveralls diff --git a/HISTORY.md b/HISTORY.md new file mode 100644 index 0000000..022d9d9 --- /dev/null +++ b/HISTORY.md @@ -0,0 +1,8 @@ +# History + +--- + +## 0.0.1 + +`tag:new` moe/sortable 初次提交 + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f69de3a --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +REPORTER = spec +install: + rm -fr _theme + git clone git://github.com/aralejs/nico-arale.git _theme + ./node_modules/.bin/nico build --theme _theme -C _theme/nico.js + +test: install + ./node_modules/.bin/mocha-browser _site/tests/runner.html -S --reporter $(REPORTER) + +test-cov: + ./node_modules/.bin/jscoverage src _site/src-cov + ./node_modules/.bin/mocha-browser _site/tests/runner.html?cov -S -R html-cov > coverage.html + +.PHONY: install test test-cov diff --git a/README.md b/README.md index a3d888f..e5ff0ea 100644 --- a/README.md +++ b/README.md @@ -1,97 +1,16 @@ -HTML5 Sortable jQuery Plugin -============================ +# sortable -**[Demos & Documentation](http://farhadi.ir/projects/html5sortable)** +--- -Features --------- -* Less than 1KB (minified and gzipped). -* Built using native HTML5 drag and drop API. -* Supports both list and grid style layouts. -* Similar API and behaviour to jquery-ui sortable plugin. -* Works in IE 5.5+, Firefox 3.5+, Chrome 3+, Safari 3+ and, Opera 12+. +[![Build Status](https://secure.travis-ci.org/aralejs/sortable.png)](https://travis-ci.org/moe/sortable) +[![Coverage Status](https://coveralls.io/repos/aralejs/sortable/badge.png?branch=master)](https://coveralls.io/r/moe/sortable) -Usage ------ -Use `sortable` method to create a sortable list: -``` javascript -$('.sortable').sortable(); -``` -Use `.sortable-dragging` and `.sortable-placeholder` CSS selectors to change the styles of a dragging item and its placeholder respectively. +// description -Use `sortupdate` event if you want to do something when the order changes (e.g. storing the new order): +--- -``` javascript -$('.sortable').sortable().bind('sortupdate', function(e, ui) { - //ui.item contains the current dragged element. - //Triggered when the user stopped sorting and the DOM position has changed. -}); -``` +## 使用说明 -Use `items` option to specifiy which items inside the element should be sortable: -``` javascript -$('.sortable').sortable({ - items: ':not(.disabled)' -}); -``` -Use `handle` option to restrict drag start to the specified element: - -``` javascript -$('.sortable').sortable({ - handle: 'h2' -}); -``` -Setting `forcePlaceholderSize` option to true, forces the placeholder to have a height: - -``` javascript -$('.sortable').sortable({ - forcePlaceholderSize: true -}); -``` - -Use `connectWith` option to create connected lists: - -``` javascript -$('#sortable1, #sortable2').sortable({ - connectWith: '.connected' -}); -``` - -To remove the sortable functionality completely: - -``` javascript -$('.sortable').sortable('destroy'); -``` - -To disable the sortable temporarily: - -``` javascript -$('.sortable').sortable('disable'); -``` - -To enable a disabled sortable: - -``` javascript -$('.sortable').sortable('enable'); -``` - -The API is compatible with jquery-ui. So you can use jquery-ui as a polyfill in older browsers: - -``` javascript -yepnope({ - test: Modernizr.draganddrop, - yep: 'jquery.sortable.js', - nope: 'jquery-ui.min.js', - complete: function() { - $('.sortable').sortable().bind('sortupdate', function(e, ui) { - //Store the new order. - } - } -}); -``` - -License -------- -Released under the MIT license. +## API diff --git a/examples/index.md b/examples/index.md new file mode 100644 index 0000000..26ff097 --- /dev/null +++ b/examples/index.md @@ -0,0 +1,154 @@ +# 演示文档 + +--- + +````html + + +
+

Sortable List

+ +
+ +
+

Sortable Grid

+ +
+ +
+

Sortable List With Disabled Items

+ +
+ +
+

Sortable List With Handles

+ +
+ +
+

Connected Sortable Lists

+ + +
+
+```` + +````javascript +seajs.use('sortable', function(sortable) { + new sortable({ + target: '#sortable1, #sortable2' + }) + new sortable({ + target: '#sortable3', + items: ':not(.disabled)' + }); + + new sortable({ + target: '#sortable-with-handles', + handle: '.handle' + }); + + new sortable({ + target: '#sortable4, #sortable5', + connectWith: '.connected' + }); + +}); +```` diff --git a/index.html b/index.html deleted file mode 100644 index 0b650db..0000000 --- a/index.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - HTML5 Sortable jQuery Plugin - - - - - -
-

HTML5 Sortable jQuery Plugin

-
-
-

Features

- -
-
-

Sortable List

- -
-
-

Sortable Grid

- -
-
-

Exclude Items

- -
-
-

Sortable List With Handles

- -
-
-

Connected Sortable Lists

- - -
- Fork me on GitHub - - - - - diff --git a/jquery.sortable.js b/jquery.sortable.js deleted file mode 100644 index 350d172..0000000 --- a/jquery.sortable.js +++ /dev/null @@ -1,85 +0,0 @@ -/* - * HTML5 Sortable jQuery Plugin - * http://farhadi.ir/projects/html5sortable - * - * Copyright 2012, Ali Farhadi - * Released under the MIT license. - */ -(function($) { -var dragging, placeholders = $(); -$.fn.sortable = function(options) { - var method = String(options); - options = $.extend({ - connectWith: false - }, options); - return this.each(function() { - if (/^enable|disable|destroy$/.test(method)) { - var items = $(this).children($(this).data('items')).attr('draggable', method == 'enable'); - if (method == 'destroy') { - items.add(this).removeData('connectWith items') - .off('dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s'); - } - return; - } - var isHandle, index, items = $(this).children(options.items); - var placeholder = $('<' + (/^ul|ol$/i.test(this.tagName) ? 'li' : 'div') + ' class="sortable-placeholder">'); - items.find(options.handle).mousedown(function() { - isHandle = true; - }).mouseup(function() { - isHandle = false; - }); - $(this).data('items', options.items) - placeholders = placeholders.add(placeholder); - if (options.connectWith) { - $(options.connectWith).add(this).data('connectWith', options.connectWith); - } - items.attr('draggable', 'true').on('dragstart.h5s', function(e) { - if (options.handle && !isHandle) { - return false; - } - isHandle = false; - var dt = e.originalEvent.dataTransfer; - dt.effectAllowed = 'move'; - dt.setData('Text', 'dummy'); - index = (dragging = $(this)).addClass('sortable-dragging').index(); - }).on('dragend.h5s', function() { - if (!dragging) { - return; - } - dragging.removeClass('sortable-dragging').show(); - placeholders.detach(); - if (index != dragging.index()) { - dragging.parent().trigger('sortupdate', {item: dragging}); - } - dragging = null; - }).not('a[href], img').on('selectstart.h5s', function() { - this.dragDrop && this.dragDrop(); - return false; - }).end().add([this, placeholder]).on('dragover.h5s dragenter.h5s drop.h5s', function(e) { - if (!items.is(dragging) && options.connectWith !== $(dragging).parent().data('connectWith')) { - return true; - } - if (e.type == 'drop') { - e.stopPropagation(); - placeholders.filter(':visible').after(dragging); - dragging.trigger('dragend.h5s'); - return false; - } - e.preventDefault(); - e.originalEvent.dataTransfer.dropEffect = 'move'; - if (items.is(this)) { - if (options.forcePlaceholderSize) { - placeholder.height(dragging.outerHeight()); - } - dragging.hide(); - $(this)[placeholder.index() < $(this).index() ? 'after' : 'before'](placeholder); - placeholders.not(placeholder).detach(); - } else if (!placeholders.is(this) && !$(this).children(options.items).length) { - placeholders.detach(); - $(this).append(placeholder); - } - return false; - }); - }); -}; -})(jQuery); diff --git a/package.json b/package.json new file mode 100644 index 0000000..3a2e65d --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "family": "moe", + "name": "sortable", + "version": "0.0.1", + "description": "make list sortable", + "homepage": "https://github.com/moer/html5sortable", + "author": "airyland", + "maintainers": [ + "airyland" + ], + "repository": { + "type": "git", + "url": "git://github.com/moer/html5sortable.git" + }, + "bugs": { + "url": "" + }, + "keywords": [], + "licenses": "MIT", + "spm": { + "output": ["sortable.js"], + "alias": {}, + "devAlias": {}, + "engines": {} + } +} \ No newline at end of file diff --git a/src/jquery.sortable.js b/src/jquery.sortable.js new file mode 100644 index 0000000..2ade9e0 --- /dev/null +++ b/src/jquery.sortable.js @@ -0,0 +1,85 @@ +/* + * HTML5 Sortable jQuery Plugin + * http://farhadi.ir/projects/html5sortable + * + * Copyright 2012, Ali Farhadi + * Released under the MIT license. + */ +(function ($) { + var dragging, placeholders = $(); + $.fn.sortable = function (options) { + var method = String(options); + options = $.extend({ + connectWith: false + }, options); + return this.each(function () { + if (/^enable|disable|destroy$/.test(method)) { + var items = $(this).children($(this).data('items')).attr('draggable', method == 'enable'); + if (method == 'destroy') { + items.add(this).removeData('connectWith items') + .off('dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s'); + } + return; + } + var isHandle, index, items = $(this).children(options.items); + var placeholder = $('<' + (/^ul|ol$/i.test(this.tagName) ? 'li' : 'div') + ' class="sortable-placeholder">'); + items.find(options.handle).mousedown(function () { + isHandle = true; + }).mouseup(function () { + isHandle = false; + }); + $(this).data('items', options.items) + placeholders = placeholders.add(placeholder); + if (options.connectWith) { + $(options.connectWith).add(this).data('connectWith', options.connectWith); + } + items.attr('draggable', 'true').on('dragstart.h5s',function (e) { + if (options.handle && !isHandle) { + return false; + } + isHandle = false; + var dt = e.originalEvent.dataTransfer; + dt.effectAllowed = 'move'; + dt.setData('Text', 'dummy'); + index = (dragging = $(this)).addClass('sortable-dragging').index(); + }).on('dragend.h5s',function () { + if (!dragging) { + return; + } + dragging.removeClass('sortable-dragging').show(); + placeholders.detach(); + if (index != dragging.index()) { + dragging.parent().trigger('sortupdate', {item: dragging}); + } + dragging = null; + }).not('a[href], img').on('selectstart.h5s',function () { + this.dragDrop && this.dragDrop(); + return false; + }).end().add([this, placeholder]).on('dragover.h5s dragenter.h5s drop.h5s', function (e) { + if (!items.is(dragging) && options.connectWith !== $(dragging).parent().data('connectWith')) { + return true; + } + if (e.type == 'drop') { + e.stopPropagation(); + placeholders.filter(':visible').after(dragging); + dragging.trigger('dragend.h5s'); + return false; + } + e.preventDefault(); + e.originalEvent.dataTransfer.dropEffect = 'move'; + if (items.is(this)) { + if (options.forcePlaceholderSize) { + placeholder.height(dragging.outerHeight()); + } + dragging.hide(); + $(this)[placeholder.index() < $(this).index() ? 'after' : 'before'](placeholder); + placeholders.not(placeholder).detach(); + } else if (!placeholders.is(this) && !$(this).children(options.items).length) { + placeholders.detach(); + $(this).append(placeholder); + } + return false; + }); + }); + }; +})(jQuery); diff --git a/src/sortable.js b/src/sortable.js new file mode 100644 index 0000000..ae4274e --- /dev/null +++ b/src/sortable.js @@ -0,0 +1,85 @@ +define(function (require, exports, module) { + var $ = jQuery; + var dragging, placeholders = $(); + var doSortable = function (options) { + var method = String(options); + options = $.extend({ + connectWith: false + }, options); + return this.each(function () { + if (/^enable|disable|destroy$/.test(method)) { + var items = $(this).children($(this).data('items')).attr('draggable', method == 'enable'); + if (method == 'destroy') { + items.add(this).removeData('connectWith items') + .off('dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s'); + } + return; + } + var isHandle, index, items = $(this).children(options.items); + var placeholder = $('<' + (/^ul|ol$/i.test(this.tagName) ? 'li' : 'div') + ' class="sortable-placeholder">'); + items.find(options.handle).mousedown(function () { + isHandle = true; + }).mouseup(function () { + isHandle = false; + }); + $(this).data('items', options.items) + placeholders = placeholders.add(placeholder); + if (options.connectWith) { + $(options.connectWith).add(this).data('connectWith', options.connectWith); + } + items.attr('draggable', 'true').on('dragstart.h5s',function (e) { + if (options.handle && !isHandle) { + return false; + } + isHandle = false; + var dt = e.originalEvent.dataTransfer; + dt.effectAllowed = 'move'; + dt.setData('Text', 'dummy'); + index = (dragging = $(this)).addClass('sortable-dragging').index(); + }).on('dragend.h5s',function () { + if (!dragging) { + return; + } + dragging.removeClass('sortable-dragging').show(); + placeholders.detach(); + if (index != dragging.index()) { + dragging.parent().trigger('sortupdate', {item: dragging}); + } + dragging = null; + }).not('a[href], img').on('selectstart.h5s',function () { + this.dragDrop && this.dragDrop(); + return false; + }).end().add([this, placeholder]).on('dragover.h5s dragenter.h5s drop.h5s', function (e) { + if (!items.is(dragging) && options.connectWith !== $(dragging).parent().data('connectWith')) { + return true; + } + if (e.type == 'drop') { + e.stopPropagation(); + placeholders.filter(':visible').after(dragging); + dragging.trigger('dragend.h5s'); + return false; + } + e.preventDefault(); + e.originalEvent.dataTransfer.dropEffect = 'move'; + if (items.is(this)) { + if (options.forcePlaceholderSize) { + placeholder.height(dragging.outerHeight()); + } + dragging.hide(); + $(this)[placeholder.index() < $(this).index() ? 'after' : 'before'](placeholder); + placeholders.not(placeholder).detach(); + } else if (!placeholders.is(this) && !$(this).children(options.items).length) { + placeholders.detach(); + $(this).append(placeholder); + } + return false; + }); + }); + }; + + var sortable = function (option) { + return doSortable.call($(option.target), option); + }; + + module.exports = sortable; +}); diff --git a/tests/sortable-spec.js b/tests/sortable-spec.js new file mode 100644 index 0000000..e290fa9 --- /dev/null +++ b/tests/sortable-spec.js @@ -0,0 +1,12 @@ +define(function(require) { + + var sortable = require('sortable'); + + describe('sortable', function() { + + it('normal usage', function() { + + }); + }); + +}); From 95c23e64a3179a94e1bdaece68bc4803723db622 Mon Sep 17 00:00:00 2001 From: airyland Date: Fri, 2 May 2014 22:01:42 +0800 Subject: [PATCH 2/2] build!0.0.1 --- dist/sortable-debug.js | 84 ++++++++++++++++++++++++++++++++++++++++++ dist/sortable.js | 1 + 2 files changed, 85 insertions(+) create mode 100644 dist/sortable-debug.js create mode 100644 dist/sortable.js diff --git a/dist/sortable-debug.js b/dist/sortable-debug.js new file mode 100644 index 0000000..3a3c890 --- /dev/null +++ b/dist/sortable-debug.js @@ -0,0 +1,84 @@ +define("moe/sortable/0.0.1/sortable-debug", [], function(require, exports, module) { + var $ = jQuery; + var dragging, placeholders = $(); + var doSortable = function(options) { + var method = String(options); + options = $.extend({ + connectWith: false + }, options); + return this.each(function() { + if (/^enable|disable|destroy$/.test(method)) { + var items = $(this).children($(this).data("items")).attr("draggable", method == "enable"); + if (method == "destroy") { + items.add(this).removeData("connectWith items").off("dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s"); + } + return; + } + var isHandle, index, items = $(this).children(options.items); + var placeholder = $("<" + (/^ul|ol$/i.test(this.tagName) ? "li" : "div") + ' class="sortable-placeholder">'); + items.find(options.handle).mousedown(function() { + isHandle = true; + }).mouseup(function() { + isHandle = false; + }); + $(this).data("items", options.items); + placeholders = placeholders.add(placeholder); + if (options.connectWith) { + $(options.connectWith).add(this).data("connectWith", options.connectWith); + } + items.attr("draggable", "true").on("dragstart.h5s", function(e) { + if (options.handle && !isHandle) { + return false; + } + isHandle = false; + var dt = e.originalEvent.dataTransfer; + dt.effectAllowed = "move"; + dt.setData("Text", "dummy"); + index = (dragging = $(this)).addClass("sortable-dragging").index(); + }).on("dragend.h5s", function() { + if (!dragging) { + return; + } + dragging.removeClass("sortable-dragging").show(); + placeholders.detach(); + if (index != dragging.index()) { + dragging.parent().trigger("sortupdate", { + item: dragging + }); + } + dragging = null; + }).not("a[href], img").on("selectstart.h5s", function() { + this.dragDrop && this.dragDrop(); + return false; + }).end().add([ this, placeholder ]).on("dragover.h5s dragenter.h5s drop.h5s", function(e) { + if (!items.is(dragging) && options.connectWith !== $(dragging).parent().data("connectWith")) { + return true; + } + if (e.type == "drop") { + e.stopPropagation(); + placeholders.filter(":visible").after(dragging); + dragging.trigger("dragend.h5s"); + return false; + } + e.preventDefault(); + e.originalEvent.dataTransfer.dropEffect = "move"; + if (items.is(this)) { + if (options.forcePlaceholderSize) { + placeholder.height(dragging.outerHeight()); + } + dragging.hide(); + $(this)[placeholder.index() < $(this).index() ? "after" : "before"](placeholder); + placeholders.not(placeholder).detach(); + } else if (!placeholders.is(this) && !$(this).children(options.items).length) { + placeholders.detach(); + $(this).append(placeholder); + } + return false; + }); + }); + }; + var sortable = function(option) { + return doSortable.call($(option.target), option); + }; + module.exports = sortable; +}); diff --git a/dist/sortable.js b/dist/sortable.js new file mode 100644 index 0000000..e1c6551 --- /dev/null +++ b/dist/sortable.js @@ -0,0 +1 @@ +define("moe/sortable/0.0.1/sortable",[],function(a,b,c){var d,e=jQuery,f=e(),g=function(a){var b=String(a);return a=e.extend({connectWith:!1},a),this.each(function(){if(/^enable|disable|destroy$/.test(b)){var c=e(this).children(e(this).data("items")).attr("draggable","enable"==b);return"destroy"==b&&c.add(this).removeData("connectWith items").off("dragstart.h5s dragend.h5s selectstart.h5s dragover.h5s dragenter.h5s drop.h5s"),void 0}var g,h,c=e(this).children(a.items),i=e("<"+(/^ul|ol$/i.test(this.tagName)?"li":"div")+' class="sortable-placeholder">');c.find(a.handle).mousedown(function(){g=!0}).mouseup(function(){g=!1}),e(this).data("items",a.items),f=f.add(i),a.connectWith&&e(a.connectWith).add(this).data("connectWith",a.connectWith),c.attr("draggable","true").on("dragstart.h5s",function(b){if(a.handle&&!g)return!1;g=!1;var c=b.originalEvent.dataTransfer;c.effectAllowed="move",c.setData("Text","dummy"),h=(d=e(this)).addClass("sortable-dragging").index()}).on("dragend.h5s",function(){d&&(d.removeClass("sortable-dragging").show(),f.detach(),h!=d.index()&&d.parent().trigger("sortupdate",{item:d}),d=null)}).not("a[href], img").on("selectstart.h5s",function(){return this.dragDrop&&this.dragDrop(),!1}).end().add([this,i]).on("dragover.h5s dragenter.h5s drop.h5s",function(b){return c.is(d)||a.connectWith===e(d).parent().data("connectWith")?"drop"==b.type?(b.stopPropagation(),f.filter(":visible").after(d),d.trigger("dragend.h5s"),!1):(b.preventDefault(),b.originalEvent.dataTransfer.dropEffect="move",c.is(this)?(a.forcePlaceholderSize&&i.height(d.outerHeight()),d.hide(),e(this)[i.index()