commit
9e89ca4253
@ -1,6 +0,0 @@ |
||||
source 'https://rubygems.org' |
||||
|
||||
group :development, :test do |
||||
gem 'jekyll', '~> 3.1.2' |
||||
gem 'jekyll-sitemap', '~> 0.11.0' |
||||
end |
||||
@ -1,43 +0,0 @@ |
||||
GEM |
||||
remote: https://rubygems.org/ |
||||
specs: |
||||
addressable (2.4.0) |
||||
colorator (0.1) |
||||
ffi (1.9.14-x64-mingw32) |
||||
jekyll (3.1.6) |
||||
colorator (~> 0.1) |
||||
jekyll-sass-converter (~> 1.0) |
||||
jekyll-watch (~> 1.1) |
||||
kramdown (~> 1.3) |
||||
liquid (~> 3.0) |
||||
mercenary (~> 0.3.3) |
||||
rouge (~> 1.7) |
||||
safe_yaml (~> 1.0) |
||||
jekyll-sass-converter (1.4.0) |
||||
sass (~> 3.4) |
||||
jekyll-sitemap (0.11.0) |
||||
addressable (~> 2.4.0) |
||||
jekyll-watch (1.4.0) |
||||
listen (~> 3.0, < 3.1) |
||||
kramdown (1.11.1) |
||||
liquid (3.0.6) |
||||
listen (3.0.8) |
||||
rb-fsevent (~> 0.9, >= 0.9.4) |
||||
rb-inotify (~> 0.9, >= 0.9.7) |
||||
mercenary (0.3.6) |
||||
rb-fsevent (0.9.7) |
||||
rb-inotify (0.9.7) |
||||
ffi (>= 0.5.0) |
||||
rouge (1.11.1) |
||||
safe_yaml (1.0.4) |
||||
sass (3.4.22) |
||||
|
||||
PLATFORMS |
||||
x64-mingw32 |
||||
|
||||
DEPENDENCIES |
||||
jekyll (~> 3.1.2) |
||||
jekyll-sitemap (~> 0.11.0) |
||||
|
||||
BUNDLED WITH |
||||
1.12.5 |
||||
@ -1,511 +0,0 @@ |
||||
/*! |
||||
* Bootstrap's Gruntfile |
||||
* http://getbootstrap.com
|
||||
* Copyright 2013-2016 Twitter, Inc. |
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/ |
||||
|
||||
module.exports = function (grunt) { |
||||
'use strict'; |
||||
|
||||
// Force use of Unix newlines
|
||||
grunt.util.linefeed = '\n'; |
||||
|
||||
RegExp.quote = function (string) { |
||||
return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&'); |
||||
}; |
||||
|
||||
var fs = require('fs'); |
||||
var path = require('path'); |
||||
var generateGlyphiconsData = require('./grunt/bs-glyphicons-data-generator.js'); |
||||
var BsLessdocParser = require('./grunt/bs-lessdoc-parser.js'); |
||||
var getLessVarsData = function () { |
||||
var filePath = path.join(__dirname, 'less/variables.less'); |
||||
var fileContent = fs.readFileSync(filePath, { encoding: 'utf8' }); |
||||
var parser = new BsLessdocParser(fileContent); |
||||
return { sections: parser.parseFile() }; |
||||
}; |
||||
var generateRawFiles = require('./grunt/bs-raw-files-generator.js'); |
||||
var generateCommonJSModule = require('./grunt/bs-commonjs-generator.js'); |
||||
var configBridge = grunt.file.readJSON('./grunt/configBridge.json', { encoding: 'utf8' }); |
||||
|
||||
Object.keys(configBridge.paths).forEach(function (key) { |
||||
configBridge.paths[key].forEach(function (val, i, arr) { |
||||
arr[i] = path.join('./docs/assets', val); |
||||
}); |
||||
}); |
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({ |
||||
|
||||
// Metadata.
|
||||
pkg: grunt.file.readJSON('package.json'), |
||||
banner: '/*!\n' + |
||||
' * Bootstrap v<%= pkg.version %> (<%= pkg.homepage %>)\n' + |
||||
' * Copyright 2011-<%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' + |
||||
' * Licensed under the <%= pkg.license %> license\n' + |
||||
' */\n', |
||||
jqueryCheck: configBridge.config.jqueryCheck.join('\n'), |
||||
jqueryVersionCheck: configBridge.config.jqueryVersionCheck.join('\n'), |
||||
|
||||
// Task configuration.
|
||||
clean: { |
||||
dist: 'dist', |
||||
docs: 'docs/dist' |
||||
}, |
||||
|
||||
jshint: { |
||||
options: { |
||||
jshintrc: 'js/.jshintrc' |
||||
}, |
||||
grunt: { |
||||
options: { |
||||
jshintrc: 'grunt/.jshintrc' |
||||
}, |
||||
src: ['Gruntfile.js', 'package.js', 'grunt/*.js'] |
||||
}, |
||||
core: { |
||||
src: 'js/*.js' |
||||
}, |
||||
test: { |
||||
options: { |
||||
jshintrc: 'js/tests/unit/.jshintrc' |
||||
}, |
||||
src: 'js/tests/unit/*.js' |
||||
}, |
||||
assets: { |
||||
src: ['docs/assets/js/src/*.js', 'docs/assets/js/*.js', '!docs/assets/js/*.min.js'] |
||||
} |
||||
}, |
||||
|
||||
jscs: { |
||||
options: { |
||||
config: 'js/.jscsrc' |
||||
}, |
||||
grunt: { |
||||
src: '<%= jshint.grunt.src %>' |
||||
}, |
||||
core: { |
||||
src: '<%= jshint.core.src %>' |
||||
}, |
||||
test: { |
||||
src: '<%= jshint.test.src %>' |
||||
}, |
||||
assets: { |
||||
options: { |
||||
requireCamelCaseOrUpperCaseIdentifiers: null |
||||
}, |
||||
src: '<%= jshint.assets.src %>' |
||||
} |
||||
}, |
||||
|
||||
concat: { |
||||
options: { |
||||
banner: '<%= banner %>\n<%= jqueryCheck %>\n<%= jqueryVersionCheck %>', |
||||
stripBanners: false |
||||
}, |
||||
bootstrap: { |
||||
src: [ |
||||
'js/transition.js', |
||||
'js/alert.js', |
||||
'js/button.js', |
||||
'js/carousel.js', |
||||
'js/collapse.js', |
||||
'js/dropdown.js', |
||||
'js/modal.js', |
||||
'js/tooltip.js', |
||||
'js/popover.js', |
||||
'js/scrollspy.js', |
||||
'js/tab.js', |
||||
'js/affix.js' |
||||
], |
||||
dest: 'dist/js/<%= pkg.name %>.js' |
||||
} |
||||
}, |
||||
|
||||
uglify: { |
||||
options: { |
||||
compress: { |
||||
warnings: false |
||||
}, |
||||
mangle: true, |
||||
preserveComments: /^!|@preserve|@license|@cc_on/i |
||||
}, |
||||
core: { |
||||
src: '<%= concat.bootstrap.dest %>', |
||||
dest: 'dist/js/<%= pkg.name %>.min.js' |
||||
}, |
||||
customize: { |
||||
src: configBridge.paths.customizerJs, |
||||
dest: 'docs/assets/js/customize.min.js' |
||||
}, |
||||
docsJs: { |
||||
src: configBridge.paths.docsJs, |
||||
dest: 'docs/assets/js/docs.min.js' |
||||
} |
||||
}, |
||||
|
||||
qunit: { |
||||
options: { |
||||
inject: 'js/tests/unit/phantom.js' |
||||
}, |
||||
files: 'js/tests/index.html' |
||||
}, |
||||
|
||||
less: { |
||||
compileCore: { |
||||
options: { |
||||
strictMath: true, |
||||
sourceMap: true, |
||||
outputSourceFiles: true, |
||||
sourceMapURL: '<%= pkg.name %>.css.map', |
||||
sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map' |
||||
}, |
||||
src: 'less/bootstrap.less', |
||||
dest: 'dist/css/<%= pkg.name %>.css' |
||||
}, |
||||
compileTheme: { |
||||
options: { |
||||
strictMath: true, |
||||
sourceMap: true, |
||||
outputSourceFiles: true, |
||||
sourceMapURL: '<%= pkg.name %>-theme.css.map', |
||||
sourceMapFilename: 'dist/css/<%= pkg.name %>-theme.css.map' |
||||
}, |
||||
src: 'less/theme.less', |
||||
dest: 'dist/css/<%= pkg.name %>-theme.css' |
||||
} |
||||
}, |
||||
|
||||
autoprefixer: { |
||||
options: { |
||||
browsers: configBridge.config.autoprefixerBrowsers |
||||
}, |
||||
core: { |
||||
options: { |
||||
map: true |
||||
}, |
||||
src: 'dist/css/<%= pkg.name %>.css' |
||||
}, |
||||
theme: { |
||||
options: { |
||||
map: true |
||||
}, |
||||
src: 'dist/css/<%= pkg.name %>-theme.css' |
||||
}, |
||||
docs: { |
||||
src: ['docs/assets/css/src/docs.css'] |
||||
}, |
||||
examples: { |
||||
expand: true, |
||||
cwd: 'docs/examples/', |
||||
src: ['**/*.css'], |
||||
dest: 'docs/examples/' |
||||
} |
||||
}, |
||||
|
||||
csslint: { |
||||
options: { |
||||
csslintrc: 'less/.csslintrc' |
||||
}, |
||||
dist: [ |
||||
'dist/css/bootstrap.css', |
||||
'dist/css/bootstrap-theme.css' |
||||
], |
||||
examples: [ |
||||
'docs/examples/**/*.css' |
||||
], |
||||
docs: { |
||||
options: { |
||||
ids: false, |
||||
'overqualified-elements': false |
||||
}, |
||||
src: 'docs/assets/css/src/docs.css' |
||||
} |
||||
}, |
||||
|
||||
cssmin: { |
||||
options: { |
||||
// TODO: disable `zeroUnits` optimization once clean-css 3.2 is released
|
||||
// and then simplify the fix for https://github.com/twbs/bootstrap/issues/14837 accordingly
|
||||
compatibility: 'ie8', |
||||
keepSpecialComments: '*', |
||||
sourceMap: true, |
||||
sourceMapInlineSources: true, |
||||
advanced: false |
||||
}, |
||||
minifyCore: { |
||||
src: 'dist/css/<%= pkg.name %>.css', |
||||
dest: 'dist/css/<%= pkg.name %>.min.css' |
||||
}, |
||||
minifyTheme: { |
||||
src: 'dist/css/<%= pkg.name %>-theme.css', |
||||
dest: 'dist/css/<%= pkg.name %>-theme.min.css' |
||||
}, |
||||
docs: { |
||||
src: [ |
||||
'docs/assets/css/ie10-viewport-bug-workaround.css', |
||||
'docs/assets/css/src/pygments-manni.css', |
||||
'docs/assets/css/src/docs.css' |
||||
], |
||||
dest: 'docs/assets/css/docs.min.css' |
||||
} |
||||
}, |
||||
|
||||
csscomb: { |
||||
options: { |
||||
config: 'less/.csscomb.json' |
||||
}, |
||||
dist: { |
||||
expand: true, |
||||
cwd: 'dist/css/', |
||||
src: ['*.css', '!*.min.css'], |
||||
dest: 'dist/css/' |
||||
}, |
||||
examples: { |
||||
expand: true, |
||||
cwd: 'docs/examples/', |
||||
src: '**/*.css', |
||||
dest: 'docs/examples/' |
||||
}, |
||||
docs: { |
||||
src: 'docs/assets/css/src/docs.css', |
||||
dest: 'docs/assets/css/src/docs.css' |
||||
} |
||||
}, |
||||
|
||||
copy: { |
||||
fonts: { |
||||
expand: true, |
||||
src: 'fonts/**', |
||||
dest: 'dist/' |
||||
}, |
||||
docs: { |
||||
expand: true, |
||||
cwd: 'dist/', |
||||
src: [ |
||||
'**/*' |
||||
], |
||||
dest: 'docs/dist/' |
||||
} |
||||
}, |
||||
|
||||
connect: { |
||||
server: { |
||||
options: { |
||||
port: 3000, |
||||
base: '.' |
||||
} |
||||
} |
||||
}, |
||||
|
||||
jekyll: { |
||||
options: { |
||||
bundleExec: true, |
||||
config: '_config.yml', |
||||
incremental: false |
||||
}, |
||||
docs: {}, |
||||
github: { |
||||
options: { |
||||
raw: 'github: true' |
||||
} |
||||
} |
||||
}, |
||||
|
||||
htmlmin: { |
||||
dist: { |
||||
options: { |
||||
collapseBooleanAttributes: true, |
||||
collapseWhitespace: true, |
||||
conservativeCollapse: true, |
||||
decodeEntities: false, |
||||
minifyCSS: { |
||||
compatibility: 'ie8', |
||||
keepSpecialComments: 0 |
||||
}, |
||||
minifyJS: true, |
||||
minifyURLs: false, |
||||
processConditionalComments: true, |
||||
removeAttributeQuotes: true, |
||||
removeComments: true, |
||||
removeOptionalAttributes: true, |
||||
removeOptionalTags: true, |
||||
removeRedundantAttributes: true, |
||||
removeScriptTypeAttributes: true, |
||||
removeStyleLinkTypeAttributes: true, |
||||
removeTagWhitespace: false, |
||||
sortAttributes: true, |
||||
sortClassName: true |
||||
}, |
||||
expand: true, |
||||
cwd: '_gh_pages', |
||||
dest: '_gh_pages', |
||||
src: [ |
||||
'**/*.html', |
||||
'!examples/**/*.html' |
||||
] |
||||
} |
||||
}, |
||||
|
||||
pug: { |
||||
options: { |
||||
pretty: true, |
||||
data: getLessVarsData |
||||
}, |
||||
customizerVars: { |
||||
src: 'docs/_pug/customizer-variables.pug', |
||||
dest: 'docs/_includes/customizer-variables.html' |
||||
}, |
||||
customizerNav: { |
||||
src: 'docs/_pug/customizer-nav.pug', |
||||
dest: 'docs/_includes/nav/customize.html' |
||||
} |
||||
}, |
||||
|
||||
htmllint: { |
||||
options: { |
||||
ignore: [ |
||||
'Attribute "autocomplete" not allowed on element "button" at this point.', |
||||
'Attribute "autocomplete" is only allowed when the input type is "color", "date", "datetime", "datetime-local", "email", "hidden", "month", "number", "password", "range", "search", "tel", "text", "time", "url", or "week".', |
||||
'Element "img" is missing required attribute "src".' |
||||
] |
||||
}, |
||||
src: '_gh_pages/**/*.html' |
||||
}, |
||||
|
||||
watch: { |
||||
src: { |
||||
files: '<%= jshint.core.src %>', |
||||
tasks: ['jshint:core', 'qunit', 'concat'] |
||||
}, |
||||
test: { |
||||
files: '<%= jshint.test.src %>', |
||||
tasks: ['jshint:test', 'qunit'] |
||||
}, |
||||
less: { |
||||
files: 'less/**/*.less', |
||||
tasks: 'less' |
||||
} |
||||
}, |
||||
|
||||
'saucelabs-qunit': { |
||||
all: { |
||||
options: { |
||||
build: process.env.TRAVIS_JOB_ID, |
||||
throttled: 10, |
||||
maxRetries: 3, |
||||
maxPollRetries: 4, |
||||
urls: ['http://127.0.0.1:3000/js/tests/index.html?hidepassed'], |
||||
browsers: grunt.file.readYAML('grunt/sauce_browsers.yml') |
||||
} |
||||
} |
||||
}, |
||||
|
||||
exec: { |
||||
npmUpdate: { |
||||
command: 'npm update' |
||||
} |
||||
}, |
||||
|
||||
compress: { |
||||
main: { |
||||
options: { |
||||
archive: 'bootstrap-<%= pkg.version %>-dist.zip', |
||||
mode: 'zip', |
||||
level: 9, |
||||
pretty: true |
||||
}, |
||||
files: [ |
||||
{ |
||||
expand: true, |
||||
cwd: 'dist/', |
||||
src: ['**'], |
||||
dest: 'bootstrap-<%= pkg.version %>-dist' |
||||
} |
||||
] |
||||
} |
||||
} |
||||
|
||||
}); |
||||
|
||||
|
||||
// These plugins provide necessary tasks.
|
||||
require('load-grunt-tasks')(grunt, { scope: 'devDependencies' }); |
||||
require('time-grunt')(grunt); |
||||
|
||||
// Docs HTML validation task
|
||||
grunt.registerTask('validate-html', ['jekyll:docs', 'htmllint']); |
||||
|
||||
var runSubset = function (subset) { |
||||
return !process.env.TWBS_TEST || process.env.TWBS_TEST === subset; |
||||
}; |
||||
var isUndefOrNonZero = function (val) { |
||||
return val === undefined || val !== '0'; |
||||
}; |
||||
|
||||
// Test task.
|
||||
var testSubtasks = []; |
||||
// Skip core tests if running a different subset of the test suite
|
||||
if (runSubset('core') && |
||||
// Skip core tests if this is a Savage build
|
||||
process.env.TRAVIS_REPO_SLUG !== 'twbs-savage/bootstrap') { |
||||
testSubtasks = testSubtasks.concat(['dist-css', 'dist-js', 'csslint:dist', 'test-js', 'docs']); |
||||
} |
||||
// Skip HTML validation if running a different subset of the test suite
|
||||
if (runSubset('validate-html') && |
||||
// Skip HTML5 validator on Travis when [skip validator] is in the commit message
|
||||
isUndefOrNonZero(process.env.TWBS_DO_VALIDATOR)) { |
||||
testSubtasks.push('validate-html'); |
||||
} |
||||
// Only run Sauce Labs tests if there's a Sauce access key
|
||||
if (typeof process.env.SAUCE_ACCESS_KEY !== 'undefined' && |
||||
// Skip Sauce if running a different subset of the test suite
|
||||
runSubset('sauce-js-unit') && |
||||
// Skip Sauce on Travis when [skip sauce] is in the commit message
|
||||
isUndefOrNonZero(process.env.TWBS_DO_SAUCE)) { |
||||
testSubtasks.push('connect'); |
||||
testSubtasks.push('saucelabs-qunit'); |
||||
} |
||||
grunt.registerTask('test', testSubtasks); |
||||
grunt.registerTask('test-js', ['jshint:core', 'jshint:test', 'jshint:grunt', 'jscs:core', 'jscs:test', 'jscs:grunt', 'qunit']); |
||||
|
||||
// JS distribution task.
|
||||
grunt.registerTask('dist-js', ['concat', 'uglify:core', 'commonjs']); |
||||
|
||||
// CSS distribution task.
|
||||
grunt.registerTask('less-compile', ['less:compileCore', 'less:compileTheme']); |
||||
grunt.registerTask('dist-css', ['less-compile', 'autoprefixer:core', 'autoprefixer:theme', 'csscomb:dist', 'cssmin:minifyCore', 'cssmin:minifyTheme']); |
||||
|
||||
// Full distribution task.
|
||||
grunt.registerTask('dist', ['clean:dist', 'dist-css', 'copy:fonts', 'dist-js']); |
||||
|
||||
// Default task.
|
||||
grunt.registerTask('default', ['clean:dist', 'copy:fonts', 'test']); |
||||
|
||||
grunt.registerTask('build-glyphicons-data', function () { generateGlyphiconsData.call(this, grunt); }); |
||||
|
||||
// task for building customizer
|
||||
grunt.registerTask('build-customizer', ['build-customizer-html', 'build-raw-files']); |
||||
grunt.registerTask('build-customizer-html', 'pug'); |
||||
grunt.registerTask('build-raw-files', 'Add scripts/less files to customizer.', function () { |
||||
var banner = grunt.template.process('<%= banner %>'); |
||||
generateRawFiles(grunt, banner); |
||||
}); |
||||
|
||||
grunt.registerTask('commonjs', 'Generate CommonJS entrypoint module in dist dir.', function () { |
||||
var srcFiles = grunt.config.get('concat.bootstrap.src'); |
||||
var destFilepath = 'dist/js/npm.js'; |
||||
generateCommonJSModule(grunt, srcFiles, destFilepath); |
||||
}); |
||||
|
||||
// Docs task.
|
||||
grunt.registerTask('docs-css', ['autoprefixer:docs', 'autoprefixer:examples', 'csscomb:docs', 'csscomb:examples', 'cssmin:docs']); |
||||
grunt.registerTask('lint-docs-css', ['csslint:docs', 'csslint:examples']); |
||||
grunt.registerTask('docs-js', ['uglify:docsJs', 'uglify:customize']); |
||||
grunt.registerTask('lint-docs-js', ['jshint:assets', 'jscs:assets']); |
||||
grunt.registerTask('docs', ['docs-css', 'lint-docs-css', 'docs-js', 'lint-docs-js', 'clean:docs', 'copy:docs', 'build-glyphicons-data', 'build-customizer']); |
||||
grunt.registerTask('docs-github', ['jekyll:github', 'htmlmin']); |
||||
|
||||
grunt.registerTask('prep-release', ['dist', 'docs', 'docs-github', 'compress']); |
||||
}; |
||||
@ -1,7 +0,0 @@ |
||||
{ |
||||
"extends" : "../js/.jshintrc", |
||||
"asi" : false, |
||||
"browser" : false, |
||||
"es3" : false, |
||||
"node" : true |
||||
} |
||||
@ -1,30 +0,0 @@ |
||||
/*! |
||||
* Bootstrap Grunt task for the CommonJS module generation |
||||
* http://getbootstrap.com
|
||||
* Copyright 2014-2015 Twitter, Inc. |
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/ |
||||
|
||||
'use strict'; |
||||
|
||||
var fs = require('fs'); |
||||
var path = require('path'); |
||||
|
||||
var COMMONJS_BANNER = '// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.\n'; |
||||
|
||||
module.exports = function generateCommonJSModule(grunt, srcFiles, destFilepath) { |
||||
var destDir = path.dirname(destFilepath); |
||||
|
||||
function srcPathToDestRequire(srcFilepath) { |
||||
var requirePath = path.relative(destDir, srcFilepath).replace(/\\/g, '/'); |
||||
return 'require(\'' + requirePath + '\')'; |
||||
} |
||||
|
||||
var moduleOutputJs = COMMONJS_BANNER + srcFiles.map(srcPathToDestRequire).join('\n'); |
||||
try { |
||||
fs.writeFileSync(destFilepath, moduleOutputJs); |
||||
} catch (err) { |
||||
grunt.fail.warn(err); |
||||
} |
||||
grunt.log.writeln('File ' + destFilepath.cyan + ' created.'); |
||||
}; |
||||
@ -1,42 +0,0 @@ |
||||
/*! |
||||
* Bootstrap Grunt task for Glyphicons data generation |
||||
* http://getbootstrap.com
|
||||
* Copyright 2014-2015 Twitter, Inc. |
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/ |
||||
|
||||
'use strict'; |
||||
|
||||
var fs = require('fs'); |
||||
|
||||
module.exports = function generateGlyphiconsData(grunt) { |
||||
// Pass encoding, utf8, so `readFileSync` will return a string instead of a
|
||||
// buffer
|
||||
var glyphiconsFile = fs.readFileSync('less/glyphicons.less', 'utf8'); |
||||
var glyphiconsLines = glyphiconsFile.split('\n'); |
||||
|
||||
// Use any line that starts with ".glyphicon-" and capture the class name
|
||||
var iconClassName = /^\.(glyphicon-[a-zA-Z0-9-]+)/; |
||||
var glyphiconsData = '# This file is generated via Grunt task. **Do not edit directly.**\n' + |
||||
'# See the \'build-glyphicons-data\' task in Gruntfile.js.\n\n'; |
||||
var glyphiconsYml = 'docs/_data/glyphicons.yml'; |
||||
for (var i = 0, len = glyphiconsLines.length; i < len; i++) { |
||||
var match = glyphiconsLines[i].match(iconClassName); |
||||
|
||||
if (match !== null) { |
||||
glyphiconsData += '- ' + match[1] + '\n'; |
||||
} |
||||
} |
||||
|
||||
// Create the `_data` directory if it doesn't already exist
|
||||
if (!fs.existsSync('docs/_data')) { |
||||
fs.mkdirSync('docs/_data'); |
||||
} |
||||
|
||||
try { |
||||
fs.writeFileSync(glyphiconsYml, glyphiconsData); |
||||
} catch (err) { |
||||
grunt.fail.warn(err); |
||||
} |
||||
grunt.log.writeln('File ' + glyphiconsYml.cyan + ' created.'); |
||||
}; |
||||
@ -1,237 +0,0 @@ |
||||
/*! |
||||
* Bootstrap Grunt task for parsing Less docstrings |
||||
* http://getbootstrap.com
|
||||
* Copyright 2014-2015 Twitter, Inc. |
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/ |
||||
|
||||
'use strict'; |
||||
|
||||
var Markdown = require('markdown-it'); |
||||
|
||||
function markdown2html(markdownString) { |
||||
var md = new Markdown(); |
||||
|
||||
// the slice removes the <p>...</p> wrapper output by Markdown processor
|
||||
return md.render(markdownString.trim()).slice(3, -5); |
||||
} |
||||
|
||||
|
||||
/* |
||||
Mini-language: |
||||
//== This is a normal heading, which starts a section. Sections group variables together.
|
||||
//## Optional description for the heading
|
||||
|
||||
//=== This is a subheading.
|
||||
|
||||
//** Optional description for the following variable. You **can** use Markdown in descriptions to discuss `<html>` stuff.
|
||||
@foo: #fff; |
||||
|
||||
//-- This is a heading for a section whose variables shouldn't be customizable
|
||||
|
||||
All other lines are ignored completely. |
||||
*/ |
||||
|
||||
|
||||
var CUSTOMIZABLE_HEADING = /^[/]{2}={2}(.*)$/; |
||||
var UNCUSTOMIZABLE_HEADING = /^[/]{2}-{2}(.*)$/; |
||||
var SUBSECTION_HEADING = /^[/]{2}={3}(.*)$/; |
||||
var SECTION_DOCSTRING = /^[/]{2}#{2}(.+)$/; |
||||
var VAR_ASSIGNMENT = /^(@[a-zA-Z0-9_-]+):[ ]*([^ ;][^;]*);[ ]*$/; |
||||
var VAR_DOCSTRING = /^[/]{2}[*]{2}(.+)$/; |
||||
|
||||
function Section(heading, customizable) { |
||||
this.heading = heading.trim(); |
||||
this.id = this.heading.replace(/\s+/g, '-').toLowerCase(); |
||||
this.customizable = customizable; |
||||
this.docstring = null; |
||||
this.subsections = []; |
||||
} |
||||
|
||||
Section.prototype.addSubSection = function (subsection) { |
||||
this.subsections.push(subsection); |
||||
}; |
||||
|
||||
function SubSection(heading) { |
||||
this.heading = heading.trim(); |
||||
this.id = this.heading.replace(/\s+/g, '-').toLowerCase(); |
||||
this.variables = []; |
||||
} |
||||
|
||||
SubSection.prototype.addVar = function (variable) { |
||||
this.variables.push(variable); |
||||
}; |
||||
|
||||
function VarDocstring(markdownString) { |
||||
this.html = markdown2html(markdownString); |
||||
} |
||||
|
||||
function SectionDocstring(markdownString) { |
||||
this.html = markdown2html(markdownString); |
||||
} |
||||
|
||||
function Variable(name, defaultValue) { |
||||
this.name = name; |
||||
this.defaultValue = defaultValue; |
||||
this.docstring = null; |
||||
} |
||||
|
||||
function Tokenizer(fileContent) { |
||||
this._lines = fileContent.split('\n'); |
||||
this._next = undefined; |
||||
} |
||||
|
||||
Tokenizer.prototype.unshift = function (token) { |
||||
if (this._next !== undefined) { |
||||
throw new Error('Attempted to unshift twice!'); |
||||
} |
||||
this._next = token; |
||||
}; |
||||
|
||||
Tokenizer.prototype._shift = function () { |
||||
// returning null signals EOF
|
||||
// returning undefined means the line was ignored
|
||||
if (this._next !== undefined) { |
||||
var result = this._next; |
||||
this._next = undefined; |
||||
return result; |
||||
} |
||||
if (this._lines.length <= 0) { |
||||
return null; |
||||
} |
||||
var line = this._lines.shift(); |
||||
var match = null; |
||||
match = SUBSECTION_HEADING.exec(line); |
||||
if (match !== null) { |
||||
return new SubSection(match[1]); |
||||
} |
||||
match = CUSTOMIZABLE_HEADING.exec(line); |
||||
if (match !== null) { |
||||
return new Section(match[1], true); |
||||
} |
||||
match = UNCUSTOMIZABLE_HEADING.exec(line); |
||||
if (match !== null) { |
||||
return new Section(match[1], false); |
||||
} |
||||
match = SECTION_DOCSTRING.exec(line); |
||||
if (match !== null) { |
||||
return new SectionDocstring(match[1]); |
||||
} |
||||
match = VAR_DOCSTRING.exec(line); |
||||
if (match !== null) { |
||||
return new VarDocstring(match[1]); |
||||
} |
||||
var commentStart = line.lastIndexOf('//'); |
||||
var varLine = commentStart === -1 ? line : line.slice(0, commentStart); |
||||
match = VAR_ASSIGNMENT.exec(varLine); |
||||
if (match !== null) { |
||||
return new Variable(match[1], match[2]); |
||||
} |
||||
return undefined; |
||||
}; |
||||
|
||||
Tokenizer.prototype.shift = function () { |
||||
while (true) { |
||||
var result = this._shift(); |
||||
if (result === undefined) { |
||||
continue; |
||||
} |
||||
return result; |
||||
} |
||||
}; |
||||
|
||||
function Parser(fileContent) { |
||||
this._tokenizer = new Tokenizer(fileContent); |
||||
} |
||||
|
||||
Parser.prototype.parseFile = function () { |
||||
var sections = []; |
||||
while (true) { |
||||
var section = this.parseSection(); |
||||
if (section === null) { |
||||
if (this._tokenizer.shift() !== null) { |
||||
throw new Error('Unexpected unparsed section of file remains!'); |
||||
} |
||||
return sections; |
||||
} |
||||
sections.push(section); |
||||
} |
||||
}; |
||||
|
||||
Parser.prototype.parseSection = function () { |
||||
var section = this._tokenizer.shift(); |
||||
if (section === null) { |
||||
return null; |
||||
} |
||||
if (!(section instanceof Section)) { |
||||
throw new Error('Expected section heading; got: ' + JSON.stringify(section)); |
||||
} |
||||
var docstring = this._tokenizer.shift(); |
||||
if (docstring instanceof SectionDocstring) { |
||||
section.docstring = docstring; |
||||
} else { |
||||
this._tokenizer.unshift(docstring); |
||||
} |
||||
this.parseSubSections(section); |
||||
|
||||
return section; |
||||
}; |
||||
|
||||
Parser.prototype.parseSubSections = function (section) { |
||||
while (true) { |
||||
var subsection = this.parseSubSection(); |
||||
if (subsection === null) { |
||||
if (section.subsections.length === 0) { |
||||
// Presume an implicit initial subsection
|
||||
subsection = new SubSection(''); |
||||
this.parseVars(subsection); |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
section.addSubSection(subsection); |
||||
} |
||||
|
||||
if (section.subsections.length === 1 && !section.subsections[0].heading && section.subsections[0].variables.length === 0) { |
||||
// Ignore lone empty implicit subsection
|
||||
section.subsections = []; |
||||
} |
||||
}; |
||||
|
||||
Parser.prototype.parseSubSection = function () { |
||||
var subsection = this._tokenizer.shift(); |
||||
if (subsection instanceof SubSection) { |
||||
this.parseVars(subsection); |
||||
return subsection; |
||||
} |
||||
this._tokenizer.unshift(subsection); |
||||
return null; |
||||
}; |
||||
|
||||
Parser.prototype.parseVars = function (subsection) { |
||||
while (true) { |
||||
var variable = this.parseVar(); |
||||
if (variable === null) { |
||||
return; |
||||
} |
||||
subsection.addVar(variable); |
||||
} |
||||
}; |
||||
|
||||
Parser.prototype.parseVar = function () { |
||||
var docstring = this._tokenizer.shift(); |
||||
if (!(docstring instanceof VarDocstring)) { |
||||
this._tokenizer.unshift(docstring); |
||||
docstring = null; |
||||
} |
||||
var variable = this._tokenizer.shift(); |
||||
if (variable instanceof Variable) { |
||||
variable.docstring = docstring; |
||||
return variable; |
||||
} |
||||
this._tokenizer.unshift(variable); |
||||
return null; |
||||
}; |
||||
|
||||
|
||||
module.exports = Parser; |
||||
@ -1,44 +0,0 @@ |
||||
/*! |
||||
* Bootstrap Grunt task for generating raw-files.min.js for the Customizer |
||||
* http://getbootstrap.com
|
||||
* Copyright 2014-2015 Twitter, Inc. |
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/ |
||||
|
||||
'use strict'; |
||||
|
||||
var fs = require('fs'); |
||||
var btoa = require('btoa'); |
||||
var glob = require('glob'); |
||||
|
||||
function getFiles(type) { |
||||
var files = {}; |
||||
var recursive = type === 'less'; |
||||
var globExpr = recursive ? '/**/*' : '/*'; |
||||
glob.sync(type + globExpr) |
||||
.filter(function (path) { |
||||
return type === 'fonts' ? true : new RegExp('\\.' + type + '$').test(path); |
||||
}) |
||||
.forEach(function (fullPath) { |
||||
var relativePath = fullPath.replace(/^[^/]+\//, ''); |
||||
files[relativePath] = type === 'fonts' ? btoa(fs.readFileSync(fullPath)) : fs.readFileSync(fullPath, 'utf8'); |
||||
}); |
||||
return 'var __' + type + ' = ' + JSON.stringify(files) + '\n'; |
||||
} |
||||
|
||||
module.exports = function generateRawFilesJs(grunt, banner) { |
||||
if (!banner) { |
||||
banner = ''; |
||||
} |
||||
var dirs = ['js', 'less', 'fonts']; |
||||
var files = banner + dirs.map(getFiles).reduce(function (combined, file) { |
||||
return combined + file; |
||||
}, ''); |
||||
var rawFilesJs = 'docs/assets/js/raw-files.min.js'; |
||||
try { |
||||
fs.writeFileSync(rawFilesJs, files); |
||||
} catch (err) { |
||||
grunt.fail.warn(err); |
||||
} |
||||
grunt.log.writeln('File ' + rawFilesJs.cyan + ' created.'); |
||||
}; |
||||
@ -1,109 +0,0 @@ |
||||
#!/usr/bin/env node
|
||||
'use strict'; |
||||
|
||||
/* globals Set */ |
||||
/*! |
||||
* Script to update version number references in the project. |
||||
* Copyright 2015 Twitter, Inc. |
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
*/ |
||||
var fs = require('fs'); |
||||
var path = require('path'); |
||||
var sh = require('shelljs'); |
||||
sh.config.fatal = true; |
||||
var sed = sh.sed; |
||||
|
||||
// Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37
|
||||
RegExp.quote = function (string) { |
||||
return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&'); |
||||
}; |
||||
RegExp.quoteReplacement = function (string) { |
||||
return string.replace(/[$]/g, '$$'); |
||||
}; |
||||
|
||||
var DRY_RUN = false; |
||||
|
||||
function walkAsync(directory, excludedDirectories, fileCallback, errback) { |
||||
if (excludedDirectories.has(path.parse(directory).base)) { |
||||
return; |
||||
} |
||||
fs.readdir(directory, function (err, names) { |
||||
if (err) { |
||||
errback(err); |
||||
return; |
||||
} |
||||
names.forEach(function (name) { |
||||
var filepath = path.join(directory, name); |
||||
fs.lstat(filepath, function (err, stats) { |
||||
if (err) { |
||||
process.nextTick(errback, err); |
||||
return; |
||||
} |
||||
if (stats.isSymbolicLink()) { |
||||
return; |
||||
} |
||||
else if (stats.isDirectory()) { |
||||
process.nextTick(walkAsync, filepath, excludedDirectories, fileCallback, errback); |
||||
} |
||||
else if (stats.isFile()) { |
||||
process.nextTick(fileCallback, filepath); |
||||
} |
||||
}); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
function replaceRecursively(directory, excludedDirectories, allowedExtensions, original, replacement) { |
||||
original = new RegExp(RegExp.quote(original), 'g'); |
||||
replacement = RegExp.quoteReplacement(replacement); |
||||
var updateFile = !DRY_RUN ? function (filepath) { |
||||
if (allowedExtensions.has(path.parse(filepath).ext)) { |
||||
sed('-i', original, replacement, filepath); |
||||
} |
||||
} : function (filepath) { |
||||
if (allowedExtensions.has(path.parse(filepath).ext)) { |
||||
console.log('FILE: ' + filepath); |
||||
} |
||||
else { |
||||
console.log('EXCLUDED:' + filepath); |
||||
} |
||||
}; |
||||
walkAsync(directory, excludedDirectories, updateFile, function (err) { |
||||
console.error('ERROR while traversing directory!:'); |
||||
console.error(err); |
||||
process.exit(1); |
||||
}); |
||||
} |
||||
|
||||
function main(args) { |
||||
if (args.length !== 2) { |
||||
console.error('USAGE: change-version old_version new_version'); |
||||
console.error('Got arguments:', args); |
||||
process.exit(1); |
||||
} |
||||
var oldVersion = args[0]; |
||||
var newVersion = args[1]; |
||||
var EXCLUDED_DIRS = new Set([ |
||||
'.git', |
||||
'node_modules', |
||||
'vendor' |
||||
]); |
||||
var INCLUDED_EXTENSIONS = new Set([ |
||||
// This extension whitelist is how we avoid modifying binary files
|
||||
'', |
||||
'.css', |
||||
'.html', |
||||
'.js', |
||||
'.json', |
||||
'.less', |
||||
'.md', |
||||
'.nuspec', |
||||
'.ps1', |
||||
'.scss', |
||||
'.txt', |
||||
'.yml' |
||||
]); |
||||
replaceRecursively('.', EXCLUDED_DIRS, INCLUDED_EXTENSIONS, oldVersion, newVersion); |
||||
} |
||||
|
||||
main(process.argv.slice(2)); |
||||
@ -1,46 +0,0 @@ |
||||
{ |
||||
"paths": { |
||||
"customizerJs": [ |
||||
"../assets/js/vendor/autoprefixer.js", |
||||
"../assets/js/vendor/less.min.js", |
||||
"../assets/js/vendor/jszip.min.js", |
||||
"../assets/js/vendor/uglify.min.js", |
||||
"../assets/js/vendor/Blob.js", |
||||
"../assets/js/vendor/FileSaver.js", |
||||
"../assets/js/raw-files.min.js", |
||||
"../assets/js/src/customizer.js" |
||||
], |
||||
"docsJs": [ |
||||
"../assets/js/vendor/holder.min.js", |
||||
"../assets/js/vendor/ZeroClipboard.min.js", |
||||
"../assets/js/vendor/anchor.min.js", |
||||
"../assets/js/src/application.js" |
||||
] |
||||
}, |
||||
"config": { |
||||
"autoprefixerBrowsers": [ |
||||
"Android 2.3", |
||||
"Android >= 4", |
||||
"Chrome >= 20", |
||||
"Firefox >= 24", |
||||
"Explorer >= 8", |
||||
"iOS >= 6", |
||||
"Opera >= 12", |
||||
"Safari >= 6" |
||||
], |
||||
"jqueryCheck": [ |
||||
"if (typeof jQuery === 'undefined') {", |
||||
" throw new Error('Bootstrap\\'s JavaScript requires jQuery')", |
||||
"}\n" |
||||
], |
||||
"jqueryVersionCheck": [ |
||||
"+function ($) {", |
||||
" 'use strict';", |
||||
" var version = $.fn.jquery.split(' ')[0].split('.')", |
||||
" if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 3)) {", |
||||
" throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4')", |
||||
" }", |
||||
"}(jQuery);\n\n" |
||||
] |
||||
} |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -1,82 +0,0 @@ |
||||
[ |
||||
# Docs: https://saucelabs.com/docs/platforms/webdriver |
||||
|
||||
{ |
||||
browserName: "safari", |
||||
platform: "OS X 10.10" |
||||
}, |
||||
{ |
||||
browserName: "chrome", |
||||
platform: "OS X 10.10" |
||||
}, |
||||
{ |
||||
browserName: "firefox", |
||||
platform: "OS X 10.10" |
||||
}, |
||||
|
||||
# Mac Opera not currently supported by Sauce Labs |
||||
|
||||
{ |
||||
browserName: "internet explorer", |
||||
version: "11", |
||||
platform: "Windows 8.1" |
||||
}, |
||||
{ |
||||
browserName: "internet explorer", |
||||
version: "10", |
||||
platform: "Windows 8" |
||||
}, |
||||
{ |
||||
browserName: "internet explorer", |
||||
version: "9", |
||||
platform: "Windows 7" |
||||
}, |
||||
{ |
||||
browserName: "internet explorer", |
||||
version: "8", |
||||
platform: "Windows 7" |
||||
}, |
||||
|
||||
# { # Unofficial |
||||
# browserName: "internet explorer", |
||||
# version: "7", |
||||
# platform: "Windows XP" |
||||
# }, |
||||
|
||||
{ |
||||
browserName: "chrome", |
||||
platform: "Windows 8.1" |
||||
}, |
||||
{ |
||||
browserName: "firefox", |
||||
platform: "Windows 8.1" |
||||
}, |
||||
|
||||
# Win Opera 15+ not currently supported by Sauce Labs |
||||
|
||||
{ |
||||
browserName: "iphone", |
||||
platform: "OS X 10.10", |
||||
version: "9.2" |
||||
}, |
||||
|
||||
# iOS Chrome not currently supported by Sauce Labs |
||||
|
||||
# Linux (unofficial) |
||||
{ |
||||
browserName: "chrome", |
||||
platform: "Linux" |
||||
}, |
||||
{ |
||||
browserName: "firefox", |
||||
platform: "Linux" |
||||
} |
||||
|
||||
# Android Chrome not currently supported by Sauce Labs |
||||
|
||||
# { # Android Browser (super-unofficial) |
||||
# browserName: "android", |
||||
# version: "4.0", |
||||
# platform: "Linux" |
||||
# } |
||||
] |
||||
@ -1,8 +0,0 @@ |
||||
$nuget = $env:NuGet |
||||
|
||||
# parse the version number out of package.json |
||||
$bsversion = ((Get-Content $env:SourcesPath\package.json) -join "`n" | ConvertFrom-Json).version |
||||
|
||||
# create packages |
||||
& $nuget pack "nuget\bootstrap.nuspec" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion |
||||
& $nuget pack "nuget\bootstrap.less.nuspec" -Verbosity detailed -NonInteractive -NoPackageAnalysis -BasePath $env:SourcesPath -Version $bsversion |
||||
@ -1,28 +0,0 @@ |
||||
<?xml version="1.0"?> |
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> |
||||
<metadata> |
||||
<id>bootstrap.less</id> |
||||
<version>3.3.7</version> |
||||
<title>Bootstrap Less</title> |
||||
<authors>Twitter, Inc.</authors> |
||||
<owners>bootstrap</owners> |
||||
<description>The most popular front-end framework for developing responsive, mobile first projects on the web.</description> |
||||
<releaseNotes>http://blog.getbootstrap.com</releaseNotes> |
||||
<summary>Bootstrap framework in Less. Includes fonts and JavaScript</summary> |
||||
<language>en-us</language> |
||||
<projectUrl>http://getbootstrap.com</projectUrl> |
||||
<iconUrl>http://getbootstrap.com/apple-touch-icon.png</iconUrl> |
||||
<licenseUrl>https://github.com/twbs/bootstrap/blob/master/LICENSE</licenseUrl> |
||||
<copyright>Copyright 2016</copyright> |
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance> |
||||
<dependencies> |
||||
<dependency id="jQuery" version="[1.9.1,4)" /> |
||||
</dependencies> |
||||
<tags>css js less mobile-first responsive front-end framework web</tags> |
||||
</metadata> |
||||
<files> |
||||
<file src="less\**\*.less" target="content\Content\bootstrap" /> |
||||
<file src="fonts\*.*" target="content\Content\fonts" /> |
||||
<file src="dist\js\bootstrap*.js" target="content\Scripts" /> |
||||
</files> |
||||
</package> |
||||
@ -1,28 +0,0 @@ |
||||
<?xml version="1.0"?> |
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> |
||||
<metadata> |
||||
<id>bootstrap</id> |
||||
<version>3.3.7</version> |
||||
<title>Bootstrap CSS</title> |
||||
<authors>Twitter, Inc.</authors> |
||||
<owners>bootstrap</owners> |
||||
<description>The most popular front-end framework for developing responsive, mobile first projects on the web.</description> |
||||
<releaseNotes>http://blog.getbootstrap.com</releaseNotes> |
||||
<summary>Bootstrap framework in CSS. Includes fonts and JavaScript</summary> |
||||
<language>en-us</language> |
||||
<projectUrl>http://getbootstrap.com</projectUrl> |
||||
<iconUrl>http://getbootstrap.com/apple-touch-icon.png</iconUrl> |
||||
<licenseUrl>https://github.com/twbs/bootstrap/blob/master/LICENSE</licenseUrl> |
||||
<copyright>Copyright 2016</copyright> |
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance> |
||||
<dependencies> |
||||
<dependency id="jQuery" version="[1.9.1,4)" /> |
||||
</dependencies> |
||||
<tags>css js less mobile-first responsive front-end framework web</tags> |
||||
</metadata> |
||||
<files> |
||||
<file src="dist\css\*.*" target="content\Content" /> |
||||
<file src="dist\fonts\*.*" target="content\fonts" /> |
||||
<file src="dist\js\bootstrap*.js" target="content\Scripts" /> |
||||
</files> |
||||
</package> |
||||
@ -1,32 +0,0 @@ |
||||
// package metadata file for Meteor.js
|
||||
|
||||
/* jshint strict:false */ |
||||
/* global Package:true */ |
||||
|
||||
Package.describe({ |
||||
name: 'twbs:bootstrap', // http://atmospherejs.com/twbs/bootstrap
|
||||
summary: 'The most popular front-end framework for developing responsive, mobile first projects on the web.', |
||||
version: '3.3.7', |
||||
git: 'https://github.com/twbs/bootstrap.git' |
||||
}); |
||||
|
||||
Package.onUse(function (api) { |
||||
api.versionsFrom('METEOR@1.0'); |
||||
api.use('jquery', 'client'); |
||||
var assets = [ |
||||
'dist/fonts/glyphicons-halflings-regular.eot', |
||||
'dist/fonts/glyphicons-halflings-regular.svg', |
||||
'dist/fonts/glyphicons-halflings-regular.ttf', |
||||
'dist/fonts/glyphicons-halflings-regular.woff', |
||||
'dist/fonts/glyphicons-halflings-regular.woff2' |
||||
]; |
||||
if (api.addAssets) { |
||||
api.addAssets(assets, 'client'); |
||||
} else { |
||||
api.addFiles(assets, 'client', { isAsset: true }); |
||||
} |
||||
api.addFiles([ |
||||
'dist/css/bootstrap.css', |
||||
'dist/js/bootstrap.js' |
||||
], 'client'); |
||||
}); |
||||
@ -1,89 +0,0 @@ |
||||
{ |
||||
"name": "bootstrap", |
||||
"description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", |
||||
"version": "3.3.7", |
||||
"keywords": [ |
||||
"css", |
||||
"less", |
||||
"mobile-first", |
||||
"responsive", |
||||
"front-end", |
||||
"framework", |
||||
"web" |
||||
], |
||||
"homepage": "http://getbootstrap.com", |
||||
"author": "Twitter, Inc.", |
||||
"scripts": { |
||||
"change-version": "node grunt/change-version.js", |
||||
"update-shrinkwrap": "npm shrinkwrap --dev && shx mv ./npm-shrinkwrap.json ./grunt/npm-shrinkwrap.json", |
||||
"test": "grunt test" |
||||
}, |
||||
"style": "dist/css/bootstrap.css", |
||||
"less": "less/bootstrap.less", |
||||
"main": "./dist/js/npm", |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "https://github.com/twbs/bootstrap.git" |
||||
}, |
||||
"bugs": { |
||||
"url": "https://github.com/twbs/bootstrap/issues" |
||||
}, |
||||
"license": "MIT", |
||||
"devDependencies": { |
||||
"btoa": "~1.1.2", |
||||
"glob": "~7.0.3", |
||||
"grunt": "~1.0.1", |
||||
"grunt-autoprefixer": "~3.0.4", |
||||
"grunt-contrib-clean": "~1.0.0", |
||||
"grunt-contrib-compress": "~1.3.0", |
||||
"grunt-contrib-concat": "~1.0.0", |
||||
"grunt-contrib-connect": "~1.0.0", |
||||
"grunt-contrib-copy": "~1.0.0", |
||||
"grunt-contrib-csslint": "~1.0.0", |
||||
"grunt-contrib-cssmin": "~1.0.0", |
||||
"grunt-contrib-htmlmin": "~1.5.0", |
||||
"grunt-contrib-jshint": "~1.0.0", |
||||
"grunt-contrib-less": "~1.3.0", |
||||
"grunt-contrib-pug": "~1.0.0", |
||||
"grunt-contrib-qunit": "~0.7.0", |
||||
"grunt-contrib-uglify": "~1.0.0", |
||||
"grunt-contrib-watch": "~1.0.0", |
||||
"grunt-csscomb": "~3.1.0", |
||||
"grunt-exec": "~1.0.0", |
||||
"grunt-html": "~8.0.1", |
||||
"grunt-jekyll": "~0.4.4", |
||||
"grunt-jscs": "~3.0.1", |
||||
"grunt-saucelabs": "~9.0.0", |
||||
"load-grunt-tasks": "~3.5.0", |
||||
"markdown-it": "^7.0.0", |
||||
"shelljs": "^0.7.0", |
||||
"shx": "^0.1.2", |
||||
"time-grunt": "^1.3.0" |
||||
}, |
||||
"engines": { |
||||
"node": ">=0.10.1" |
||||
}, |
||||
"files": [ |
||||
"dist", |
||||
"fonts", |
||||
"grunt", |
||||
"js/*.js", |
||||
"less/**/*.less", |
||||
"Gruntfile.js", |
||||
"LICENSE" |
||||
], |
||||
"jspm": { |
||||
"main": "js/bootstrap", |
||||
"shim": { |
||||
"js/bootstrap": { |
||||
"deps": "jquery", |
||||
"exports": "$" |
||||
} |
||||
}, |
||||
"files": [ |
||||
"css", |
||||
"fonts", |
||||
"js" |
||||
] |
||||
} |
||||
} |
||||
@ -0,0 +1,19 @@ |
||||
{ |
||||
"name": "jqueryui-touch-punch", |
||||
"main": "jquery.ui.touch-punch.min.js", |
||||
"ignore": [], |
||||
"dependencies": { |
||||
"jquery": ">=1.6", |
||||
"jquery-ui": ">=1.8" |
||||
}, |
||||
"homepage": "https://github.com/furf/jquery-ui-touch-punch", |
||||
"_release": "4bc0091452", |
||||
"_resolution": { |
||||
"type": "branch", |
||||
"branch": "master", |
||||
"commit": "4bc009145202d9c7483ba85f3a236a8f3470354d" |
||||
}, |
||||
"_source": "https://github.com/furf/jquery-ui-touch-punch.git", |
||||
"_target": "*", |
||||
"_originalSource": "jqueryui-touch-punch" |
||||
} |
||||
@ -0,0 +1,41 @@ |
||||
# jQuery UI Touch Punch |
||||
## Touch Event Support for jQuery UI |
||||
|
||||
> **jQuery UI Touch Punch is a small hack that enables the use of touch events on sites using the jQuery UI user interface library.** |
||||
|
||||
_[Visit the official Touch Punch website](http://touchpunch.furf.com)._ |
||||
|
||||
Currently, [jQuery UI](http://jqueryui.com/) user interface library does not support the use of touch events in their widgets and interactions. This means that the slick UI you designed and tested in your desktop browser will fail on most, if not all, touch-enabled mobile devices, because jQuery UI listens to mouse events—mouseover, mousemove and mouseout—not touch events—touchstart, touchmove and touchend. |
||||
|
||||
That's where jQuery UI Touch Punch comes in. Touch Punch works by using [simulated events](https://developer.mozilla.org/en/DOM/document.createEvent) to map [touch events](http://www.html5rocks.com/en/mobile/touch/) to their mouse event analogs. Simply include the script on your page and your touch events will be turned into their corresponding mouse events to which jQuery UI will respond as expected. |
||||
|
||||
As I said, Touch Punch is a hack. It [duck punches](http://en.wikipedia.org/wiki/Monkey_patch) some of jQuery UI's core functionality to handle the mapping of touch events. Touch Punch works with all basic implementations of jQuery UI's interactions and widgets. However, you may find more complex cases where Touch Punch fails. If so, scroll down to learn how you can file and/or fix issues. |
||||
|
||||
This code is dual licensed under the MIT or GPL Version 2 licenses and is therefore free to use, modify and/or distribute, but if you include Touch Punch in other software packages or plugins, please include an attribution to the original software and a link to [this Touch Punch website](http://touchpunch.furf.com/). |
||||
|
||||
## Using Touch Punch is as easy as 1, 2… |
||||
|
||||
Just follow these simple steps to enable touch events in your jQuery UI app: |
||||
|
||||
1. Include jQuery and jQuery UI on your page. |
||||
|
||||
```html |
||||
<script src="http://code.jquery.com/jquery.min.js"></script> |
||||
<script src="http://code.jquery.com/ui/1.8.17/jquery-ui.min.js"></script> |
||||
``` |
||||
|
||||
2. Include Touch Punch after jQuery UI and before its first use. |
||||
|
||||
Please note that if you are using jQuery UI's components, Touch Punch must be included after jquery.ui.mouse.js, as Touch Punch modifies its behavior. |
||||
|
||||
```html |
||||
<script src="jquery.ui.touch-punch.min.js"></script> |
||||
``` |
||||
|
||||
3. There is no 3. Just use jQuery UI as expected and watch it work at the touch of a finger. |
||||
|
||||
```html |
||||
<script>$('#widget').draggable();</script> |
||||
``` |
||||
|
||||
_Tested on iPad, iPhone, Android and other touch-enabled mobile devices._ |
||||
@ -0,0 +1,10 @@ |
||||
{ |
||||
"name": "jqueryui-touch-punch", |
||||
"version": "0.2.3", |
||||
"main": "jquery.ui.touch-punch.min.js", |
||||
"ignore": [], |
||||
"dependencies": { |
||||
"jquery": ">=1.6", |
||||
"jquery-ui": ">=1.8" |
||||
} |
||||
} |
||||
@ -0,0 +1,180 @@ |
||||
/*! |
||||
* jQuery UI Touch Punch 0.2.3 |
||||
* |
||||
* Copyright 2011–2014, Dave Furfero |
||||
* Dual licensed under the MIT or GPL Version 2 licenses. |
||||
* |
||||
* Depends: |
||||
* jquery.ui.widget.js |
||||
* jquery.ui.mouse.js |
||||
*/ |
||||
(function ($) { |
||||
|
||||
// Detect touch support
|
||||
$.support.touch = 'ontouchend' in document; |
||||
|
||||
// Ignore browsers without touch support
|
||||
if (!$.support.touch) { |
||||
return; |
||||
} |
||||
|
||||
var mouseProto = $.ui.mouse.prototype, |
||||
_mouseInit = mouseProto._mouseInit, |
||||
_mouseDestroy = mouseProto._mouseDestroy, |
||||
touchHandled; |
||||
|
||||
/** |
||||
* Simulate a mouse event based on a corresponding touch event |
||||
* @param {Object} event A touch event |
||||
* @param {String} simulatedType The corresponding mouse event |
||||
*/ |
||||
function simulateMouseEvent (event, simulatedType) { |
||||
|
||||
// Ignore multi-touch events
|
||||
if (event.originalEvent.touches.length > 1) { |
||||
return; |
||||
} |
||||
|
||||
event.preventDefault(); |
||||
|
||||
var touch = event.originalEvent.changedTouches[0], |
||||
simulatedEvent = document.createEvent('MouseEvents'); |
||||
|
||||
// Initialize the simulated mouse event using the touch event's coordinates
|
||||
simulatedEvent.initMouseEvent( |
||||
simulatedType, // type
|
||||
true, // bubbles
|
||||
true, // cancelable
|
||||
window, // view
|
||||
1, // detail
|
||||
touch.screenX, // screenX
|
||||
touch.screenY, // screenY
|
||||
touch.clientX, // clientX
|
||||
touch.clientY, // clientY
|
||||
false, // ctrlKey
|
||||
false, // altKey
|
||||
false, // shiftKey
|
||||
false, // metaKey
|
||||
0, // button
|
||||
null // relatedTarget
|
||||
); |
||||
|
||||
// Dispatch the simulated event to the target element
|
||||
event.target.dispatchEvent(simulatedEvent); |
||||
} |
||||
|
||||
/** |
||||
* Handle the jQuery UI widget's touchstart events |
||||
* @param {Object} event The widget element's touchstart event |
||||
*/ |
||||
mouseProto._touchStart = function (event) { |
||||
|
||||
var self = this; |
||||
|
||||
// Ignore the event if another widget is already being handled
|
||||
if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) { |
||||
return; |
||||
} |
||||
|
||||
// Set the flag to prevent other widgets from inheriting the touch event
|
||||
touchHandled = true; |
||||
|
||||
// Track movement to determine if interaction was a click
|
||||
self._touchMoved = false; |
||||
|
||||
// Simulate the mouseover event
|
||||
simulateMouseEvent(event, 'mouseover'); |
||||
|
||||
// Simulate the mousemove event
|
||||
simulateMouseEvent(event, 'mousemove'); |
||||
|
||||
// Simulate the mousedown event
|
||||
simulateMouseEvent(event, 'mousedown'); |
||||
}; |
||||
|
||||
/** |
||||
* Handle the jQuery UI widget's touchmove events |
||||
* @param {Object} event The document's touchmove event |
||||
*/ |
||||
mouseProto._touchMove = function (event) { |
||||
|
||||
// Ignore event if not handled
|
||||
if (!touchHandled) { |
||||
return; |
||||
} |
||||
|
||||
// Interaction was not a click
|
||||
this._touchMoved = true; |
||||
|
||||
// Simulate the mousemove event
|
||||
simulateMouseEvent(event, 'mousemove'); |
||||
}; |
||||
|
||||
/** |
||||
* Handle the jQuery UI widget's touchend events |
||||
* @param {Object} event The document's touchend event |
||||
*/ |
||||
mouseProto._touchEnd = function (event) { |
||||
|
||||
// Ignore event if not handled
|
||||
if (!touchHandled) { |
||||
return; |
||||
} |
||||
|
||||
// Simulate the mouseup event
|
||||
simulateMouseEvent(event, 'mouseup'); |
||||
|
||||
// Simulate the mouseout event
|
||||
simulateMouseEvent(event, 'mouseout'); |
||||
|
||||
// If the touch interaction did not move, it should trigger a click
|
||||
if (!this._touchMoved) { |
||||
|
||||
// Simulate the click event
|
||||
simulateMouseEvent(event, 'click'); |
||||
} |
||||
|
||||
// Unset the flag to allow other widgets to inherit the touch event
|
||||
touchHandled = false; |
||||
}; |
||||
|
||||
/** |
||||
* A duck punch of the $.ui.mouse _mouseInit method to support touch events. |
||||
* This method extends the widget with bound touch event handlers that |
||||
* translate touch events to mouse events and pass them to the widget's |
||||
* original mouse event handling methods. |
||||
*/ |
||||
mouseProto._mouseInit = function () { |
||||
|
||||
var self = this; |
||||
|
||||
// Delegate the touch handlers to the widget's element
|
||||
self.element.bind({ |
||||
touchstart: $.proxy(self, '_touchStart'), |
||||
touchmove: $.proxy(self, '_touchMove'), |
||||
touchend: $.proxy(self, '_touchEnd') |
||||
}); |
||||
|
||||
// Call the original $.ui.mouse init method
|
||||
_mouseInit.call(self); |
||||
}; |
||||
|
||||
/** |
||||
* Remove the touch event handlers |
||||
*/ |
||||
mouseProto._mouseDestroy = function () { |
||||
|
||||
var self = this; |
||||
|
||||
// Delegate the touch handlers to the widget's element
|
||||
self.element.unbind({ |
||||
touchstart: $.proxy(self, '_touchStart'), |
||||
touchmove: $.proxy(self, '_touchMove'), |
||||
touchend: $.proxy(self, '_touchEnd') |
||||
}); |
||||
|
||||
// Call the original $.ui.mouse destroy method
|
||||
_mouseDestroy.call(self); |
||||
}; |
||||
|
||||
})(jQuery); |
||||
@ -0,0 +1,11 @@ |
||||
/*! |
||||
* jQuery UI Touch Punch 0.2.3 |
||||
* |
||||
* Copyright 2011–2014, Dave Furfero |
||||
* Dual licensed under the MIT or GPL Version 2 licenses. |
||||
* |
||||
* Depends: |
||||
* jquery.ui.widget.js |
||||
* jquery.ui.mouse.js |
||||
*/ |
||||
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery); |
||||
@ -0,0 +1,90 @@ |
||||
'use strict';/*! |
||||
* This is a `i18n` language object. |
||||
* |
||||
* Malay (for inter-country use - see the countries mentioned in infobox`s `native to` at https://en.wikipedia.org/wiki/Malay_language)
|
||||
* |
||||
* @author |
||||
* muhdnurhidayat (Twitter: @mnh48com) |
||||
* Sascha Greuel (Twitter: @SoftCreatR) |
||||
* |
||||
* @see core/i18n.js |
||||
*/ |
||||
(function (exports) { |
||||
if (exports.ms === undefined) { |
||||
exports.ms = { |
||||
'mejs.plural-form': 0,
|
||||
'mejs.download-file': 'Muat Turun Fail',
|
||||
'mejs.install-flash': 'Anda sedang menggunakan pelayar internet yang tidak mempunyai pemain Flash. Sila aktifkan pemalam pemain Flash anda atau muat turun versi terbaru dari https://get.adobe.com/flashplayer/',
|
||||
'mejs.fullscreen': 'Skrin penuh',
|
||||
'mejs.play': 'Main', |
||||
'mejs.pause': 'Jeda',
|
||||
'mejs.time-slider': 'Lungsur Masa', |
||||
'mejs.time-help-text': 'Gunakan kekunci Anak Panah Kiri/Kanan untuk bergerak satu saat, Anak Panah Atas/Bawah untuk bergerak sepuluh saat.', |
||||
'mejs.live-broadcast' : 'Siaran Langsung',
|
||||
'mejs.volume-help-text': 'Gunakan kekunci Anak Panah Atas/Bawah untuk menguatkan atau memperlahankan bunyi.', |
||||
'mejs.unmute': 'Nyahsenyap', |
||||
'mejs.mute': 'Senyap', |
||||
'mejs.volume-slider': 'Lungsur Bunyi',
|
||||
'mejs.video-player': 'Pemain Video', |
||||
'mejs.audio-player': 'Pemain Audio',
|
||||
'mejs.captions-subtitles': 'Sarikata', |
||||
'mejs.captions-chapters': 'Bab', |
||||
'mejs.none': 'Tiada', |
||||
'mejs.afrikaans': 'Bahasa Afrikaans', |
||||
'mejs.albanian': 'Bahasa Albania', |
||||
'mejs.arabic': 'Bahasa Arab', |
||||
'mejs.belarusian': 'Bahasa Belarus', |
||||
'mejs.bulgarian': 'Bahasa Bulgaria', |
||||
'mejs.catalan': 'Bahasa Catalonia', |
||||
'mejs.chinese': 'Bahasa Cina', |
||||
'mejs.chinese-simplified': 'Bahasa Cina (Ringkas)', |
||||
'mejs.chinese-traditional': 'Bahasa Cina (Tradisional)', |
||||
'mejs.croatian': 'Bahasa Croatia', |
||||
'mejs.czech': 'Bahasa Czech', |
||||
'mejs.danish': 'Bahasa Denmark', |
||||
'mejs.dutch': 'Bahasa Belanda', |
||||
'mejs.english': 'Bahasa Inggeris', |
||||
'mejs.estonian': 'Bahasa Estonia', |
||||
'mejs.filipino': 'Bahasa Filipino', |
||||
'mejs.finnish': 'Bahasa Finland', |
||||
'mejs.french': 'Bahasa Perancis', |
||||
'mejs.galician': 'Bahasa Galicia', |
||||
'mejs.german': 'Bahasa Jerman', |
||||
'mejs.greek': 'Bahasa Greek', |
||||
'mejs.haitian-creole': 'Bahasa Kreol Haiti', |
||||
'mejs.hebrew': 'Bahasa Ibrani', |
||||
'mejs.hindi': 'Bahasa Hindi', |
||||
'mejs.hungarian': 'Bahasa Hungary', |
||||
'mejs.icelandic': 'Bahasa Iceland', |
||||
'mejs.indonesian': 'Bahasa Indonesia', |
||||
'mejs.irish': 'Bahasa Ireland', |
||||
'mejs.italian': 'Bahasa Itali', |
||||
'mejs.japanese': 'Bahasa Jepun', |
||||
'mejs.korean': 'Bahasa Korea', |
||||
'mejs.latvian': 'Bahasa Latvia', |
||||
'mejs.lithuanian': 'Bahasa Lithuania', |
||||
'mejs.macedonian': 'Bahasa Macedonia', |
||||
'mejs.malay': 'Bahasa Melayu', |
||||
'mejs.maltese': 'Bahasa Malta', |
||||
'mejs.norwegian': 'Bahasa Norway', |
||||
'mejs.persian': 'Bahasa Parsi', |
||||
'mejs.polish': 'Bahasa Poland', |
||||
'mejs.portuguese': 'Bahasa Portugis', |
||||
'mejs.romanian': 'Bahasa Romania', |
||||
'mejs.russian': 'Bahasa Rusia', |
||||
'mejs.serbian': 'Bahasa Serbia', |
||||
'mejs.slovak': 'Bahasa Slovak', |
||||
'mejs.slovenian': 'Bahasa Slovene', |
||||
'mejs.spanish': 'Bahasa Sepanyol', |
||||
'mejs.swahili': 'Bahasa Swahili', |
||||
'mejs.swedish': 'Bahasa Sweden', |
||||
'mejs.tagalog': 'Bahasa Tagalog', |
||||
'mejs.thai': 'Bahasa Thai', |
||||
'mejs.turkish': 'Bahasa Turki', |
||||
'mejs.ukrainian': 'Bahasa Ukraine', |
||||
'mejs.vietnamese': 'Bahasa Vietnam', |
||||
'mejs.welsh': 'Bahasa Wales', |
||||
'mejs.yiddish': 'Bahasa Yiddish' |
||||
}; |
||||
} |
||||
})(mejs.i18n); |
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,65 @@ |
||||
'use strict'; |
||||
|
||||
if (mejs.i18n.ca !== undefined) { |
||||
mejs.i18n.ca['mejs.speed-rate'] = 'Velocitat'; |
||||
} |
||||
if (mejs.i18n.cs !== undefined) { |
||||
mejs.i18n.cs['mejs.speed-rate'] = 'Rychlost'; |
||||
} |
||||
if (mejs.i18n.de !== undefined) { |
||||
mejs.i18n.de['mejs.speed-rate'] = 'Geschwindigkeitsrate'; |
||||
} |
||||
if (mejs.i18n.es !== undefined) { |
||||
mejs.i18n.es['mejs.speed-rate'] = 'Velocidad'; |
||||
} |
||||
if (mejs.i18n.fa !== undefined) { |
||||
mejs.i18n.fa['mejs.speed-rate'] = 'نرخ سرعت'; |
||||
} |
||||
if (mejs.i18n.fr !== undefined) { |
||||
mejs.i18n.fr['mejs.speed-rate'] = 'Vitesse'; |
||||
} |
||||
if (mejs.i18n.hr !== undefined) { |
||||
mejs.i18n.hr['mejs.speed-rate'] = 'Brzina reprodukcije'; |
||||
} |
||||
if (mejs.i18n.hu !== undefined) { |
||||
mejs.i18n.hu['mejs.speed-rate'] = 'Sebesség'; |
||||
} |
||||
if (mejs.i18n.it !== undefined) { |
||||
mejs.i18n.it['mejs.speed-rate'] = 'Velocità'; |
||||
} |
||||
if (mejs.i18n.ja !== undefined) { |
||||
mejs.i18n.ja['mejs.speed-rate'] = '高速'; |
||||
} |
||||
if (mejs.i18n.ko !== undefined) { |
||||
mejs.i18n.ko['mejs.speed-rate'] = '속도 속도'; |
||||
} |
||||
if (mejs.i18n.nl !== undefined) { |
||||
mejs.i18n.nl['mejs.speed-rate'] = 'Snelheidsgraad'; |
||||
} |
||||
if (mejs.i18n.pl !== undefined) { |
||||
mejs.i18n.pl['mejs.speed-rate'] = 'Prędkość'; |
||||
} |
||||
if (mejs.i18n.pt !== undefined) { |
||||
mejs.i18n.pt['mejs.speed-rate'] = 'Taxa de velocidade'; |
||||
} |
||||
if (mejs.i18n.ro !== undefined) { |
||||
mejs.i18n.ro['mejs.speed-rate'] = 'Viteză de viteză'; |
||||
} |
||||
if (mejs.i18n.ru !== undefined) { |
||||
mejs.i18n.ru['mejs.speed-rate'] = 'Скорость воспроизведения'; |
||||
} |
||||
if (mejs.i18n.sk !== undefined) { |
||||
mejs.i18n.sk['mejs.speed-rate'] = 'Rýchlosť'; |
||||
} |
||||
if (mejs.i18n.sv !== undefined) { |
||||
mejs.i18n.sv['mejs.speed-rate'] = 'Hastighet'; |
||||
} |
||||
if (mejs.i18n.uk !== undefined) { |
||||
mejs.i18n.uk['mejs.speed-rate'] = 'Швидкість відтворення'; |
||||
} |
||||
if (mejs.i18n.zh !== undefined) { |
||||
mejs.i18n.zh['mejs.speed-rate'] = '速度'; |
||||
} |
||||
if (mejs.i18n['zh-CN'] !== undefined) { |
||||
mejs.i18n['zh-CN']['mejs.speed-rate'] = '速度'; |
||||
} |
||||
@ -0,0 +1,94 @@ |
||||
.mejs__speed-button, |
||||
.mejs-speed-button { |
||||
position: relative; |
||||
} |
||||
|
||||
.mejs__speed-button > button, |
||||
.mejs-speed-button > button { |
||||
background: transparent; |
||||
color: #fff; |
||||
font-size: 11px; |
||||
line-height: normal; |
||||
margin: 11px 0 0; |
||||
width: 36px; |
||||
} |
||||
|
||||
.mejs__speed-selector, |
||||
.mejs-speed-selector { |
||||
background: rgba(50, 50, 50, 0.7); |
||||
border: solid 1px transparent; |
||||
border-radius: 0; |
||||
height: 150px; |
||||
left: -10px; |
||||
overflow: hidden; |
||||
padding: 0; |
||||
position: absolute; |
||||
top: -100px; |
||||
visibility: hidden; |
||||
width: 60px; |
||||
} |
||||
|
||||
.mejs__speed-selector, |
||||
.mejs-speed-selector { |
||||
visibility: visible; |
||||
} |
||||
|
||||
.mejs__speed-selector-list, |
||||
.mejs-speed-selector-list { |
||||
display: block; |
||||
list-style-type: none !important; |
||||
margin: 0; |
||||
overflow: hidden; |
||||
padding: 0; |
||||
} |
||||
|
||||
.mejs__speed-selector-list-item, |
||||
.mejs-speed-selector-list-item { |
||||
color: #fff; |
||||
display: block; |
||||
list-style-type: none !important; |
||||
margin: 0 0 6px; |
||||
overflow: hidden; |
||||
padding: 0 10px; |
||||
} |
||||
|
||||
.mejs__speed-selector-list-item:hover, |
||||
.mejs-speed-selector-list-item:hover { |
||||
background-color: rgb(200, 200, 200) !important; |
||||
background-color: rgba(255, 255, 255, 0.4) !important; |
||||
} |
||||
|
||||
.mejs__speed-selector-input, |
||||
.mejs-speed-selector-input { |
||||
clear: both; |
||||
float: left; |
||||
left: -1000px; |
||||
margin: 3px 3px 0 5px; |
||||
position: absolute; |
||||
} |
||||
|
||||
.mejs__speed-selector-label, |
||||
.mejs-speed-selector-label { |
||||
color: white; |
||||
cursor: pointer; |
||||
float: left; |
||||
font-size: 11px; |
||||
line-height: 15px; |
||||
margin-left: 5px; |
||||
padding: 4px 0 0; |
||||
width: 60px; |
||||
} |
||||
|
||||
.mejs__speed-selected, |
||||
.mejs-speed-selected { |
||||
color: rgba(33, 248, 248, 1); |
||||
} |
||||
|
||||
.mejs__speed-selector, |
||||
.mejs-speed-selector { |
||||
visibility: hidden; |
||||
} |
||||
.mejs__speed-button:hover .mejs__speed-selector, |
||||
.mejs-speed-button:hover .mejs-speed-selector { |
||||
visibility: visible; |
||||
} |
||||
@ -0,0 +1,174 @@ |
||||
/*! |
||||
* MediaElement.js |
||||
* http://www.mediaelementjs.com/
|
||||
* |
||||
* Wrapper that mimics native HTML5 MediaElement (audio and video) |
||||
* using a variety of technologies (pure JavaScript, Flash, iframe) |
||||
* |
||||
* Copyright 2010-2017, John Dyer (http://j.hn/)
|
||||
* License: MIT |
||||
* |
||||
*/(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ |
||||
'use strict'; |
||||
|
||||
mejs.i18n.en['mejs.speed-rate'] = 'Speed Rate'; |
||||
|
||||
Object.assign(mejs.MepDefaults, { |
||||
speeds: ['2.00', '1.50', '1.25', '1.00', '0.75'], |
||||
|
||||
defaultSpeed: '1.00', |
||||
|
||||
speedChar: 'x', |
||||
|
||||
speedText: null |
||||
}); |
||||
|
||||
Object.assign(MediaElementPlayer.prototype, { |
||||
buildspeed: function buildspeed(player, controls, layers, media) { |
||||
var t = this, |
||||
isNative = t.media.rendererName !== null && /(native|html5)/i.test(t.media.rendererName); |
||||
|
||||
if (!isNative) { |
||||
return; |
||||
} |
||||
|
||||
var speeds = [], |
||||
speedTitle = mejs.Utils.isString(t.options.speedText) ? t.options.speedText : mejs.i18n.t('mejs.speed-rate'), |
||||
getSpeedNameFromValue = function getSpeedNameFromValue(value) { |
||||
for (var i = 0, total = speeds.length; i < total; i++) { |
||||
if (speeds[i].value === value) { |
||||
return speeds[i].name; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
var playbackSpeed = void 0, |
||||
defaultInArray = false; |
||||
|
||||
for (var i = 0, total = t.options.speeds.length; i < total; i++) { |
||||
var s = t.options.speeds[i]; |
||||
|
||||
if (typeof s === 'string') { |
||||
speeds.push({ |
||||
name: '' + s + t.options.speedChar, |
||||
value: s |
||||
}); |
||||
|
||||
if (s === t.options.defaultSpeed) { |
||||
defaultInArray = true; |
||||
} |
||||
} else { |
||||
speeds.push(s); |
||||
if (s.value === t.options.defaultSpeed) { |
||||
defaultInArray = true; |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (!defaultInArray) { |
||||
speeds.push({ |
||||
name: t.options.defaultSpeed + t.options.speedChar, |
||||
value: t.options.defaultSpeed |
||||
}); |
||||
} |
||||
|
||||
speeds.sort(function (a, b) { |
||||
return parseFloat(b.value) - parseFloat(a.value); |
||||
}); |
||||
|
||||
t.cleanspeed(player); |
||||
|
||||
player.speedButton = document.createElement('div'); |
||||
player.speedButton.className = t.options.classPrefix + 'button ' + t.options.classPrefix + 'speed-button'; |
||||
player.speedButton.innerHTML = '<button type="button" aria-controls="' + t.id + '" title="' + speedTitle + '" ' + ('aria-label="' + speedTitle + '" tabindex="0">' + getSpeedNameFromValue(t.options.defaultSpeed) + '</button>') + ('<div class="' + t.options.classPrefix + 'speed-selector ' + t.options.classPrefix + 'offscreen">') + ('<ul class="' + t.options.classPrefix + 'speed-selector-list"></ul>') + '</div>'; |
||||
|
||||
t.addControlElement(player.speedButton, 'speed'); |
||||
|
||||
for (var _i = 0, _total = speeds.length; _i < _total; _i++) { |
||||
|
||||
var inputId = t.id + '-speed-' + speeds[_i].value; |
||||
|
||||
player.speedButton.querySelector('ul').innerHTML += '<li class="' + t.options.classPrefix + 'speed-selector-list-item">' + ('<input class="' + t.options.classPrefix + 'speed-selector-input" type="radio" name="' + t.id + '_speed"') + ('disabled="disabled" value="' + speeds[_i].value + '" id="' + inputId + '" ') + ((speeds[_i].value === t.options.defaultSpeed ? ' checked="checked"' : '') + '/>') + ('<label for="' + inputId + '" class="' + t.options.classPrefix + 'speed-selector-label') + ((speeds[_i].value === t.options.defaultSpeed ? ' ' + t.options.classPrefix + 'speed-selected' : '') + '">') + (speeds[_i].name + '</label>') + '</li>'; |
||||
} |
||||
|
||||
playbackSpeed = t.options.defaultSpeed; |
||||
|
||||
player.speedSelector = player.speedButton.querySelector('.' + t.options.classPrefix + 'speed-selector'); |
||||
|
||||
var inEvents = ['mouseenter', 'focusin'], |
||||
outEvents = ['mouseleave', 'focusout'], |
||||
radios = player.speedButton.querySelectorAll('input[type="radio"]'), |
||||
labels = player.speedButton.querySelectorAll('.' + t.options.classPrefix + 'speed-selector-label'); |
||||
|
||||
for (var _i2 = 0, _total2 = inEvents.length; _i2 < _total2; _i2++) { |
||||
player.speedButton.addEventListener(inEvents[_i2], function () { |
||||
mejs.Utils.removeClass(player.speedSelector, t.options.classPrefix + 'offscreen'); |
||||
player.speedSelector.style.height = player.speedSelector.querySelector('ul').offsetHeight; |
||||
player.speedSelector.style.top = -1 * parseFloat(player.speedSelector.offsetHeight) + 'px'; |
||||
}); |
||||
} |
||||
|
||||
for (var _i3 = 0, _total3 = outEvents.length; _i3 < _total3; _i3++) { |
||||
player.speedSelector.addEventListener(outEvents[_i3], function () { |
||||
mejs.Utils.addClass(this, t.options.classPrefix + 'offscreen'); |
||||
}); |
||||
} |
||||
|
||||
for (var _i4 = 0, _total4 = radios.length; _i4 < _total4; _i4++) { |
||||
var radio = radios[_i4]; |
||||
radio.disabled = false; |
||||
radio.addEventListener('click', function () { |
||||
var self = this, |
||||
newSpeed = self.value; |
||||
|
||||
playbackSpeed = newSpeed; |
||||
media.playbackRate = parseFloat(newSpeed); |
||||
player.speedButton.querySelector('button').innerHTML = getSpeedNameFromValue(newSpeed); |
||||
var selected = player.speedButton.querySelectorAll('.' + t.options.classPrefix + 'speed-selected'); |
||||
for (var _i5 = 0, _total5 = selected.length; _i5 < _total5; _i5++) { |
||||
mejs.Utils.removeClass(selected[_i5], t.options.classPrefix + 'speed-selected'); |
||||
} |
||||
|
||||
self.checked = true; |
||||
var siblings = mejs.Utils.siblings(self, function (el) { |
||||
return mejs.Utils.hasClass(el, t.options.classPrefix + 'speed-selector-label'); |
||||
}); |
||||
for (var j = 0, _total6 = siblings.length; j < _total6; j++) { |
||||
mejs.Utils.addClass(siblings[j], t.options.classPrefix + 'speed-selected'); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
for (var _i6 = 0, _total7 = labels.length; _i6 < _total7; _i6++) { |
||||
labels[_i6].addEventListener('click', function () { |
||||
var radio = mejs.Utils.siblings(this, function (el) { |
||||
return el.tagName === 'INPUT'; |
||||
})[0], |
||||
event = mejs.Utils.createEvent('click', radio); |
||||
radio.dispatchEvent(event); |
||||
}); |
||||
} |
||||
|
||||
player.speedSelector.addEventListener('keydown', function (e) { |
||||
e.stopPropagation(); |
||||
}); |
||||
|
||||
media.addEventListener('loadedmetadata', function () { |
||||
if (playbackSpeed) { |
||||
media.playbackRate = parseFloat(playbackSpeed); |
||||
} |
||||
}); |
||||
}, |
||||
cleanspeed: function cleanspeed(player) { |
||||
if (player) { |
||||
if (player.speedButton) { |
||||
player.speedButton.parentNode.removeChild(player.speedButton); |
||||
} |
||||
if (player.speedSelector) { |
||||
player.speedSelector.parentNode.removeChild(player.speedSelector); |
||||
} |
||||
} |
||||
} |
||||
}); |
||||
|
||||
},{}]},{},[1]); |
||||
@ -0,0 +1 @@ |
||||
.mejs-speed-button,.mejs__speed-button{position:relative}.mejs-speed-button>button,.mejs__speed-button>button{background:transparent;color:#fff;font-size:11px;line-height:normal;margin:11px 0 0;width:36px}.mejs-speed-selector,.mejs__speed-selector{background:rgba(50,50,50,.7);border:1px solid transparent;border-radius:0;height:150px;left:-10px;overflow:hidden;padding:0;position:absolute;top:-100px;width:60px;visibility:visible}.mejs-speed-selector-list,.mejs__speed-selector-list{display:block;list-style-type:none!important;margin:0;overflow:hidden;padding:0}.mejs-speed-selector-list-item,.mejs__speed-selector-list-item{color:#fff;display:block;list-style-type:none!important;margin:0 0 6px;overflow:hidden;padding:0 10px}.mejs-speed-selector-list-item:hover,.mejs__speed-selector-list-item:hover{background-color:#c8c8c8!important;background-color:hsla(0,0%,100%,.4)!important}.mejs-speed-selector-input,.mejs__speed-selector-input{clear:both;float:left;left:-1000px;margin:3px 3px 0 5px;position:absolute}.mejs-speed-selector-label,.mejs__speed-selector-label{color:#fff;cursor:pointer;float:left;font-size:11px;line-height:15px;margin-left:5px;padding:4px 0 0;width:60px}.mejs-speed-selected,.mejs__speed-selected{color:#21f8f8}.mejs-speed-selector,.mejs__speed-selector{visibility:hidden}.mejs-speed-button:hover .mejs-speed-selector,.mejs__speed-button:hover .mejs__speed-selector{visibility:visible} |
||||
@ -0,0 +1,12 @@ |
||||
/*! |
||||
* MediaElement.js |
||||
* http://www.mediaelementjs.com/
|
||||
* |
||||
* Wrapper that mimics native HTML5 MediaElement (audio and video) |
||||
* using a variety of technologies (pure JavaScript, Flash, iframe) |
||||
* |
||||
* Copyright 2010-2017, John Dyer (http://j.hn/)
|
||||
* License: MIT |
||||
* |
||||
*/ |
||||
!function e(t,s,o){function n(l,i){if(!s[l]){if(!t[l]){var a="function"==typeof require&&require;if(!i&&a)return a(l,!0);if(r)return r(l,!0);var d=new Error("Cannot find module '"+l+"'");throw d.code="MODULE_NOT_FOUND",d}var p=s[l]={exports:{}};t[l][0].call(p.exports,function(e){var s=t[l][1][e];return n(s||e)},p,p.exports,e,t,s,o)}return s[l].exports}for(var r="function"==typeof require&&require,l=0;l<o.length;l++)n(o[l]);return n}({1:[function(e,t,s){"use strict";mejs.i18n.en["mejs.speed-rate"]="Speed Rate",Object.assign(mejs.MepDefaults,{speeds:["2.00","1.50","1.25","1.00","0.75"],defaultSpeed:"1.00",speedChar:"x",speedText:null}),Object.assign(MediaElementPlayer.prototype,{buildspeed:function(e,t,s,o){var n=this;if(null!==n.media.rendererName&&/(native|html5)/i.test(n.media.rendererName)){for(var r=[],l=mejs.Utils.isString(n.options.speedText)?n.options.speedText:mejs.i18n.t("mejs.speed-rate"),i=function(e){for(var t=0,s=r.length;t<s;t++)if(r[t].value===e)return r[t].name},a=void 0,d=!1,p=0,c=n.options.speeds.length;p<c;p++){var u=n.options.speeds[p];"string"==typeof u?(r.push({name:""+u+n.options.speedChar,value:u}),u===n.options.defaultSpeed&&(d=!0)):(r.push(u),u.value===n.options.defaultSpeed&&(d=!0))}d||r.push({name:n.options.defaultSpeed+n.options.speedChar,value:n.options.defaultSpeed}),r.sort(function(e,t){return parseFloat(t.value)-parseFloat(e.value)}),n.cleanspeed(e),e.speedButton=document.createElement("div"),e.speedButton.className=n.options.classPrefix+"button "+n.options.classPrefix+"speed-button",e.speedButton.innerHTML='<button type="button" aria-controls="'+n.id+'" title="'+l+'" aria-label="'+l+'" tabindex="0">'+i(n.options.defaultSpeed)+'</button><div class="'+n.options.classPrefix+"speed-selector "+n.options.classPrefix+'offscreen"><ul class="'+n.options.classPrefix+'speed-selector-list"></ul></div>',n.addControlElement(e.speedButton,"speed");for(var f=0,v=r.length;f<v;f++){var m=n.id+"-speed-"+r[f].value;e.speedButton.querySelector("ul").innerHTML+='<li class="'+n.options.classPrefix+'speed-selector-list-item"><input class="'+n.options.classPrefix+'speed-selector-input" type="radio" name="'+n.id+'_speed"disabled="disabled" value="'+r[f].value+'" id="'+m+'" '+(r[f].value===n.options.defaultSpeed?' checked="checked"':"")+'/><label for="'+m+'" class="'+n.options.classPrefix+"speed-selector-label"+(r[f].value===n.options.defaultSpeed?" "+n.options.classPrefix+"speed-selected":"")+'">'+r[f].name+"</label></li>"}a=n.options.defaultSpeed,e.speedSelector=e.speedButton.querySelector("."+n.options.classPrefix+"speed-selector");for(var h=["mouseenter","focusin"],S=["mouseleave","focusout"],x=e.speedButton.querySelectorAll('input[type="radio"]'),b=e.speedButton.querySelectorAll("."+n.options.classPrefix+"speed-selector-label"),g=0,y=h.length;g<y;g++)e.speedButton.addEventListener(h[g],function(){mejs.Utils.removeClass(e.speedSelector,n.options.classPrefix+"offscreen"),e.speedSelector.style.height=e.speedSelector.querySelector("ul").offsetHeight,e.speedSelector.style.top=-1*parseFloat(e.speedSelector.offsetHeight)+"px"});for(var P=0,j=S.length;P<j;P++)e.speedSelector.addEventListener(S[P],function(){mejs.Utils.addClass(this,n.options.classPrefix+"offscreen")});for(var B=0,E=x.length;B<E;B++){var C=x[B];C.disabled=!1,C.addEventListener("click",function(){var t=this,s=t.value;a=s,o.playbackRate=parseFloat(s),e.speedButton.querySelector("button").innerHTML=i(s);for(var r=e.speedButton.querySelectorAll("."+n.options.classPrefix+"speed-selected"),l=0,d=r.length;l<d;l++)mejs.Utils.removeClass(r[l],n.options.classPrefix+"speed-selected");t.checked=!0;for(var p=mejs.Utils.siblings(t,function(e){return mejs.Utils.hasClass(e,n.options.classPrefix+"speed-selector-label")}),c=0,u=p.length;c<u;c++)mejs.Utils.addClass(p[c],n.options.classPrefix+"speed-selected")})}for(var U=0,q=b.length;U<q;U++)b[U].addEventListener("click",function(){var e=mejs.Utils.siblings(this,function(e){return"INPUT"===e.tagName})[0],t=mejs.Utils.createEvent("click",e);e.dispatchEvent(t)});e.speedSelector.addEventListener("keydown",function(e){e.stopPropagation()}),o.addEventListener("loadedmetadata",function(){a&&(o.playbackRate=parseFloat(a))})}},cleanspeed:function(e){e&&(e.speedButton&&e.speedButton.parentNode.removeChild(e.speedButton),e.speedSelector&&e.speedSelector.parentNode.removeChild(e.speedSelector))}})},{}]},{},[1]); |
||||
@ -0,0 +1,26 @@ |
||||
{ |
||||
"name": "multiselect", |
||||
"version": "2.5.2", |
||||
"homepage": "https://github.com/crlcu/multiselect", |
||||
"authors": [ |
||||
"Adrian Crisan <adrian.crisan88@gmail.com>" |
||||
], |
||||
"description": "jQuery multiselect plugin with two sides", |
||||
"main": "dist/js/multiselect.min.js", |
||||
"keywords": [ |
||||
"multiselect" |
||||
], |
||||
"license": "MIT", |
||||
"dependencies": { |
||||
"jquery": ">= 1.7" |
||||
}, |
||||
"_release": "2.5.2", |
||||
"_resolution": { |
||||
"type": "version", |
||||
"tag": "v2.5.2", |
||||
"commit": "5d850b4a2992dbab1cf913559da0d2398f5db30f" |
||||
}, |
||||
"_source": "https://github.com/crlcu/multiselect.git", |
||||
"_target": "*", |
||||
"_originalSource": "multiselect-two-sides" |
||||
} |
||||
@ -0,0 +1,3 @@ |
||||
/node_modules |
||||
.htaccess |
||||
.idea |
||||
@ -0,0 +1,35 @@ |
||||
# Change Log |
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. |
||||
|
||||
<a name="2.5.2"></a> |
||||
## [2.5.2](https://github.com/crlcu/multiselect/compare/v2.5.1...v2.5.2) (2018-07-10) |
||||
|
||||
|
||||
### Bug Fixes |
||||
|
||||
* [#164](https://github.com/crlcu/multiselect/issues/164) - Invalid regular expression ([541bb68](https://github.com/crlcu/multiselect/commit/541bb68)) |
||||
|
||||
|
||||
|
||||
<a name="2.5.1"></a> |
||||
## [2.5.1](https://github.com/crlcu/multiselect/compare/v2.5.0...v2.5.1) (2018-04-27) |
||||
|
||||
|
||||
### Patches |
||||
|
||||
* change the value for the main path ([22414f8](https://github.com/crlcu/multiselect/commit/22414f8)) |
||||
|
||||
### Features |
||||
|
||||
* add afterInit event ([22e1523](https://github.com/crlcu/multiselect/commit/22e1523)) |
||||
|
||||
|
||||
|
||||
<a name="2.5.0"></a> |
||||
# [2.5.0](https://github.com/crlcu/multiselect/compare/v2.4.1...v2.5.0) (2018-02-06) |
||||
|
||||
|
||||
### Features |
||||
|
||||
* now we can have different sort functions for left and right ([887ab4a](https://github.com/crlcu/multiselect/commit/887ab4a)) |
||||
@ -0,0 +1,22 @@ |
||||
The MIT License (MIT) |
||||
|
||||
Copyright (c) 2014 Adrian Crisan (adrian.crisan88@gmail.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. |
||||
@ -0,0 +1,66 @@ |
||||
multiselect |
||||
=========== |
||||
|
||||
jQuery multiselect plugin with two sides. The user can select one or more items and send them to the other side. |
||||
|
||||
# [Demo](http://crlcu.github.com/multiselect/) |
||||
|
||||
## Requirements |
||||
|
||||
- jQuery 1.7 or higher |
||||
|
||||
## Quick start |
||||
|
||||
Several quick start options are available: |
||||
|
||||
- Clone the repo: `git clone https://github.com/crlcu/multiselect.git` or |
||||
- Install with [Bower](http://bower.io): `bower install multiselect-two-sides`. |
||||
|
||||
### Usage example |
||||
|
||||
```html |
||||
<div class="row"> |
||||
<div class="col-xs-5"> |
||||
<select name="from[]" id="multiselect" class="form-control" size="8" multiple="multiple"> |
||||
<option value="1">Item 1</option> |
||||
<option value="3">Item 3</option> |
||||
<option value="2">Item 2</option> |
||||
</select> |
||||
</div> |
||||
|
||||
<div class="col-xs-2"> |
||||
<button type="button" id="multiselect_rightAll" class="btn btn-block"><i class="glyphicon glyphicon-forward"></i></button> |
||||
<button type="button" id="multiselect_rightSelected" class="btn btn-block"><i class="glyphicon glyphicon-chevron-right"></i></button> |
||||
<button type="button" id="multiselect_leftSelected" class="btn btn-block"><i class="glyphicon glyphicon-chevron-left"></i></button> |
||||
<button type="button" id="multiselect_leftAll" class="btn btn-block"><i class="glyphicon glyphicon-backward"></i></button> |
||||
</div> |
||||
|
||||
<div class="col-xs-5"> |
||||
<select name="to[]" id="multiselect_to" class="form-control" size="8" multiple="multiple"></select> |
||||
</div> |
||||
</div> |
||||
``` |
||||
|
||||
```javascript |
||||
<script type="text/javascript" src="path/to/jquery.min.js"></script> |
||||
<script type="text/javascript" src="path/to/multiselect.min.js"></script> |
||||
|
||||
<script type="text/javascript"> |
||||
jQuery(document).ready(function($) { |
||||
$('#multiselect').multiselect(); |
||||
}); |
||||
</script> |
||||
``` |
||||
|
||||
## Bugs and feature requests |
||||
|
||||
If your problem or idea is not [addressed](https://github.com/crlcu/multiselect/issues) yet, [please open a new issue](https://github.com/crlcu/multiselect/issues/new). |
||||
|
||||
## Versioning |
||||
|
||||
For transparency into release cycle and in striving to maintain backward compatibility, multiselect is maintained under [the Semantic Versioning guidelines](http://semver.org/). |
||||
|
||||
|
||||
## License |
||||
|
||||
The multiselect plugin is open-sourced software licensed under the [the MIT license](https://github.com/crlcu/multiselect/blob/master/LICENSE). |
||||
@ -0,0 +1,17 @@ |
||||
{ |
||||
"name": "multiselect", |
||||
"version": "2.5.2", |
||||
"homepage": "https://github.com/crlcu/multiselect", |
||||
"authors": [ |
||||
"Adrian Crisan <adrian.crisan88@gmail.com>" |
||||
], |
||||
"description": "jQuery multiselect plugin with two sides", |
||||
"main": "dist/js/multiselect.min.js", |
||||
"keywords": [ |
||||
"multiselect" |
||||
], |
||||
"license": "MIT", |
||||
"dependencies": { |
||||
"jquery": ">= 1.7" |
||||
} |
||||
} |
||||
@ -0,0 +1,26 @@ |
||||
.github.ribbon { |
||||
position: fixed; |
||||
display: block; |
||||
top: 40px; |
||||
right: 0; |
||||
border: 0; |
||||
z-index: 1001; |
||||
} |
||||
|
||||
.prettyprint { |
||||
padding: 10px!important; |
||||
} |
||||
|
||||
#wrap { |
||||
padding-top: 70px; |
||||
} |
||||
|
||||
#home h1 { |
||||
margin-bottom: 30px; |
||||
} |
||||
#demo, |
||||
#examples, |
||||
#support, |
||||
#download { |
||||
padding-top: 40px; |
||||
} |
||||
@ -0,0 +1,813 @@ |
||||
/* |
||||
* @license |
||||
* |
||||
* Multiselect v2.5.2 |
||||
* http://crlcu.github.io/multiselect/
|
||||
* |
||||
* Copyright (c) 2016-2018 Adrian Crisan |
||||
* Licensed under the MIT license (https://github.com/crlcu/multiselect/blob/master/LICENSE)
|
||||
*/ |
||||
|
||||
if (typeof jQuery === 'undefined') { |
||||
throw new Error('multiselect requires jQuery'); |
||||
} |
||||
|
||||
;(function ($) { |
||||
'use strict'; |
||||
|
||||
var version = $.fn.jquery.split(' ')[0].split('.'); |
||||
|
||||
if (version[0] < 2 && version[1] < 7) { |
||||
throw new Error('multiselect requires jQuery version 1.7 or higher'); |
||||
} |
||||
})(jQuery); |
||||
|
||||
;(function (factory) { |
||||
if (typeof define === 'function' && define.amd) { |
||||
// AMD. Register as an anonymous module depending on jQuery.
|
||||
define(['jquery'], factory); |
||||
} else { |
||||
// No AMD. Register plugin with global jQuery object.
|
||||
factory(jQuery); |
||||
} |
||||
}(function ($) { |
||||
'use strict'; |
||||
|
||||
var Multiselect = (function($) { |
||||
/** Multiselect object constructor |
||||
* |
||||
* @class Multiselect |
||||
* @constructor |
||||
**/ |
||||
function Multiselect( $select, settings ) { |
||||
var id = $select.prop('id'); |
||||
this.$left = $select; |
||||
this.$right = $( settings.right ).length ? $( settings.right ) : $('#' + id + '_to'); |
||||
this.actions = { |
||||
$leftAll: $( settings.leftAll ).length ? $( settings.leftAll ) : $('#' + id + '_leftAll'), |
||||
$rightAll: $( settings.rightAll ).length ? $( settings.rightAll ) : $('#' + id + '_rightAll'), |
||||
$leftSelected: $( settings.leftSelected ).length ? $( settings.leftSelected ) : $('#' + id + '_leftSelected'), |
||||
$rightSelected: $( settings.rightSelected ).length ? $( settings.rightSelected ) : $('#' + id + '_rightSelected'), |
||||
|
||||
$undo: $( settings.undo ).length ? $( settings.undo ) : $('#' + id + '_undo'), |
||||
$redo: $( settings.redo ).length ? $( settings.redo ) : $('#' + id + '_redo'), |
||||
|
||||
$moveUp: $( settings.moveUp ).length ? $( settings.moveUp ) : $('#' + id + '_move_up'), |
||||
$moveDown: $( settings.moveDown ).length ? $( settings.moveDown ) : $('#' + id + '_move_down') |
||||
}; |
||||
|
||||
delete settings.leftAll; |
||||
delete settings.leftSelected; |
||||
delete settings.right; |
||||
delete settings.rightAll; |
||||
delete settings.rightSelected; |
||||
delete settings.undo; |
||||
delete settings.redo; |
||||
delete settings.moveUp; |
||||
delete settings.moveDown; |
||||
|
||||
this.options = { |
||||
keepRenderingSort: settings.keepRenderingSort, |
||||
submitAllLeft: settings.submitAllLeft !== undefined ? settings.submitAllLeft : true, |
||||
submitAllRight: settings.submitAllRight !== undefined ? settings.submitAllRight : true, |
||||
search: settings.search, |
||||
ignoreDisabled: settings.ignoreDisabled !== undefined ? settings.ignoreDisabled : false, |
||||
matchOptgroupBy: settings.matchOptgroupBy !== undefined ? settings.matchOptgroupBy : 'label' |
||||
}; |
||||
|
||||
delete settings.keepRenderingSort, settings.submitAllLeft, settings.submitAllRight, settings.search, settings.ignoreDisabled, settings.matchOptgroupBy; |
||||
|
||||
this.callbacks = settings; |
||||
|
||||
if ( typeof this.callbacks.sort == 'function' ) { |
||||
var sort = this.callbacks.sort; |
||||
|
||||
this.callbacks.sort = { |
||||
left: sort, |
||||
right: sort, |
||||
}; |
||||
} |
||||
|
||||
this.init(); |
||||
} |
||||
|
||||
Multiselect.prototype = { |
||||
init: function() { |
||||
var self = this; |
||||
self.undoStack = []; |
||||
self.redoStack = []; |
||||
|
||||
if (self.options.keepRenderingSort) { |
||||
self.skipInitSort = true; |
||||
|
||||
if (self.callbacks.sort !== false) { |
||||
self.callbacks.sort = { |
||||
left: function(a, b) { |
||||
return $(a).data('position') > $(b).data('position') ? 1 : -1; |
||||
}, |
||||
right: function(a, b) { |
||||
return $(a).data('position') > $(b).data('position') ? 1 : -1; |
||||
}, |
||||
}; |
||||
} |
||||
|
||||
self.$left.attachIndex(); |
||||
|
||||
self.$right.each(function(i, select) { |
||||
$(select).attachIndex(); |
||||
}); |
||||
} |
||||
|
||||
if ( typeof self.callbacks.startUp == 'function' ) { |
||||
self.callbacks.startUp( self.$left, self.$right ); |
||||
} |
||||
|
||||
if ( !self.skipInitSort ) { |
||||
if ( typeof self.callbacks.sort.left == 'function' ) { |
||||
self.$left.mSort(self.callbacks.sort.left); |
||||
} |
||||
|
||||
if ( typeof self.callbacks.sort.right == 'function' ) { |
||||
self.$right.each(function(i, select) { |
||||
$(select).mSort(self.callbacks.sort.right); |
||||
}); |
||||
} |
||||
} |
||||
|
||||
// Append left filter
|
||||
if (self.options.search && self.options.search.left) { |
||||
self.options.search.$left = $(self.options.search.left); |
||||
self.$left.before(self.options.search.$left); |
||||
} |
||||
|
||||
// Append right filter
|
||||
if (self.options.search && self.options.search.right) { |
||||
self.options.search.$right = $(self.options.search.right); |
||||
self.$right.before($(self.options.search.$right)); |
||||
} |
||||
|
||||
// Initialize events
|
||||
self.events(); |
||||
if ( typeof self.callbacks.afterInit == 'function' ) { |
||||
self.callbacks.afterInit(); |
||||
} |
||||
}, |
||||
|
||||
events: function() { |
||||
var self = this; |
||||
|
||||
// Attach event to left filter
|
||||
if (self.options.search && self.options.search.$left) { |
||||
self.options.search.$left.on('keyup', function(e) { |
||||
if (self.callbacks.fireSearch(this.value)) { |
||||
var $toShow = self.$left.find('option:search("' + this.value + '")').mShow(); |
||||
var $toHide = self.$left.find('option:not(:search("' + this.value + '"))').mHide(); |
||||
var $grpHide = self.$left.find('option').closest('optgroup').mHide(); |
||||
var $grpShow = self.$left.find('option:not(.hidden)').parent('optgroup').mShow(); |
||||
} else { |
||||
self.$left.find('option, optgroup').mShow(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
// Attach event to right filter
|
||||
if (self.options.search && self.options.search.$right) { |
||||
self.options.search.$right.on('keyup', function(e) { |
||||
if (self.callbacks.fireSearch(this.value)) { |
||||
var $toShow = self.$right.find('option:search("' + this.value + '")').mShow(); |
||||
var $toHide = self.$right.find('option:not(:search("' + this.value + '"))').mHide(); |
||||
var $grpHide = self.$right.find('option').closest('optgroup').mHide(); |
||||
var $grpShow = self.$right.find('option:not(.hidden)').parent('optgroup').mShow(); |
||||
} else { |
||||
self.$right.find('option, optgroup').mShow(); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
// Select all the options from left and right side when submiting the parent form
|
||||
self.$right.closest('form').on('submit', function(e) { |
||||
if (self.options.search) { |
||||
// Clear left search input
|
||||
if (self.options.search.$left) { |
||||
self.options.search.$left.val('').trigger('keyup'); |
||||
} |
||||
|
||||
// Clear right search input
|
||||
if (self.options.search.$right) { |
||||
self.options.search.$right.val('').trigger('keyup'); |
||||
} |
||||
} |
||||
|
||||
self.$left.find('option').prop('selected', self.options.submitAllLeft); |
||||
self.$right.find('option').prop('selected', self.options.submitAllRight); |
||||
}); |
||||
|
||||
// Attach event for double clicking on options from left side
|
||||
self.$left.on('dblclick', 'option', function(e) { |
||||
e.preventDefault(); |
||||
|
||||
var $options = self.$left.find('option:selected'); |
||||
|
||||
if ( $options.length ) { |
||||
self.moveToRight($options, e); |
||||
} |
||||
}); |
||||
|
||||
// Attach event for clicking on optgroup's from left side
|
||||
self.$left.on('click', 'optgroup', function(e) { |
||||
if ($(e.target).prop('tagName') == 'OPTGROUP') { |
||||
$(this) |
||||
.children() |
||||
.prop('selected', true); |
||||
} |
||||
}); |
||||
|
||||
// Attach event for pushing ENTER on options from left side
|
||||
self.$left.on('keypress', function(e) { |
||||
if (e.keyCode === 13) { |
||||
e.preventDefault(); |
||||
|
||||
var $options = self.$left.find('option:selected'); |
||||
|
||||
if ( $options.length ) { |
||||
self.moveToRight($options, e); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
// Attach event for double clicking on options from right side
|
||||
self.$right.on('dblclick', 'option', function(e) { |
||||
e.preventDefault(); |
||||
|
||||
var $options = self.$right.find('option:selected'); |
||||
|
||||
if ( $options.length ) { |
||||
self.moveToLeft($options, e); |
||||
} |
||||
}); |
||||
|
||||
// Attach event for clicking on optgroup's from right side
|
||||
self.$right.on('click', 'optgroup', function(e) { |
||||
if ($(e.target).prop('tagName') == 'OPTGROUP') { |
||||
$(this) |
||||
.children() |
||||
.prop('selected', true); |
||||
} |
||||
}); |
||||
|
||||
// Attach event for pushing BACKSPACE or DEL on options from right side
|
||||
self.$right.on('keydown', function(e) { |
||||
if (e.keyCode === 8 || e.keyCode === 46) { |
||||
e.preventDefault(); |
||||
|
||||
var $options = self.$right.find('option:selected'); |
||||
|
||||
if ( $options.length ) { |
||||
self.moveToLeft($options, e); |
||||
} |
||||
} |
||||
}); |
||||
|
||||
// dblclick support for IE
|
||||
if ( navigator.userAgent.match(/MSIE/i) || navigator.userAgent.indexOf('Trident/') > 0 || navigator.userAgent.indexOf('Edge/') > 0) { |
||||
self.$left.dblclick(function(e) { |
||||
self.actions.$rightSelected.trigger('click'); |
||||
}); |
||||
|
||||
self.$right.dblclick(function(e) { |
||||
self.actions.$leftSelected.trigger('click'); |
||||
}); |
||||
} |
||||
|
||||
self.actions.$rightSelected.on('click', function(e) { |
||||
e.preventDefault(); |
||||
|
||||
var $options = self.$left.find('option:selected'); |
||||
|
||||
if ( $options.length ) { |
||||
self.moveToRight($options, e); |
||||
} |
||||
|
||||
$(this).blur(); |
||||
}); |
||||
|
||||
self.actions.$leftSelected.on('click', function(e) { |
||||
e.preventDefault(); |
||||
|
||||
var $options = self.$right.find('option:selected'); |
||||
|
||||
if ( $options.length ) { |
||||
self.moveToLeft($options, e); |
||||
} |
||||
|
||||
$(this).blur(); |
||||
}); |
||||
|
||||
self.actions.$rightAll.on('click', function(e) { |
||||
e.preventDefault(); |
||||
|
||||
var $options = self.$left.children(':not(span):not(.hidden)'); |
||||
|
||||
if ( $options.length ) { |
||||
self.moveToRight($options, e); |
||||
} |
||||
|
||||
$(this).blur(); |
||||
}); |
||||
|
||||
self.actions.$leftAll.on('click', function(e) { |
||||
e.preventDefault(); |
||||
|
||||
var $options = self.$right.children(':not(span):not(.hidden)'); |
||||
|
||||
if ( $options.length ) { |
||||
self.moveToLeft($options, e); |
||||
} |
||||
|
||||
$(this).blur(); |
||||
}); |
||||
|
||||
self.actions.$undo.on('click', function(e) { |
||||
e.preventDefault(); |
||||
|
||||
self.undo(e); |
||||
}); |
||||
|
||||
self.actions.$redo.on('click', function(e) { |
||||
e.preventDefault(); |
||||
|
||||
self.redo(e); |
||||
}); |
||||
|
||||
self.actions.$moveUp.on('click', function(e) { |
||||
e.preventDefault(); |
||||
|
||||
var $options = self.$right.find(':selected:not(span):not(.hidden)'); |
||||
|
||||
if ( $options.length ) { |
||||
self.moveUp($options, e); |
||||
} |
||||
|
||||
$(this).blur(); |
||||
}); |
||||
|
||||
self.actions.$moveDown.on('click', function(e) { |
||||
e.preventDefault(); |
||||
|
||||
var $options = self.$right.find(':selected:not(span):not(.hidden)'); |
||||
|
||||
if ( $options.length ) { |
||||
self.moveDown($options, e); |
||||
} |
||||
|
||||
$(this).blur(); |
||||
}); |
||||
}, |
||||
|
||||
moveToRight: function( $options, event, silent, skipStack ) { |
||||
var self = this; |
||||
|
||||
if ( typeof self.callbacks.moveToRight == 'function' ) { |
||||
return self.callbacks.moveToRight( self, $options, event, silent, skipStack ); |
||||
} |
||||
|
||||
if ( typeof self.callbacks.beforeMoveToRight == 'function' && !silent ) { |
||||
if ( !self.callbacks.beforeMoveToRight( self.$left, self.$right, $options ) ) { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
self.moveFromAtoB(self.$left, self.$right, $options, event, silent, skipStack); |
||||
|
||||
if ( !skipStack ) { |
||||
self.undoStack.push(['right', $options ]); |
||||
self.redoStack = []; |
||||
} |
||||
|
||||
if ( typeof self.callbacks.sort.right == 'function' && !silent && !self.doNotSortRight ) { |
||||
self.$right.mSort(self.callbacks.sort.right); |
||||
} |
||||
|
||||
if ( typeof self.callbacks.afterMoveToRight == 'function' && !silent ) { |
||||
self.callbacks.afterMoveToRight( self.$left, self.$right, $options ); |
||||
} |
||||
|
||||
return self; |
||||
}, |
||||
|
||||
moveToLeft: function( $options, event, silent, skipStack ) { |
||||
var self = this; |
||||
|
||||
if ( typeof self.callbacks.moveToLeft == 'function' ) { |
||||
return self.callbacks.moveToLeft( self, $options, event, silent, skipStack ); |
||||
} |
||||
|
||||
if ( typeof self.callbacks.beforeMoveToLeft == 'function' && !silent ) { |
||||
if ( !self.callbacks.beforeMoveToLeft( self.$left, self.$right, $options ) ) { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
self.moveFromAtoB(self.$right, self.$left, $options, event, silent, skipStack); |
||||
|
||||
if ( !skipStack ) { |
||||
self.undoStack.push(['left', $options ]); |
||||
self.redoStack = []; |
||||
} |
||||
|
||||
if ( typeof self.callbacks.sort.left == 'function' && !silent ) { |
||||
self.$left.mSort(self.callbacks.sort.left); |
||||
} |
||||
|
||||
if ( typeof self.callbacks.afterMoveToLeft == 'function' && !silent ) { |
||||
self.callbacks.afterMoveToLeft( self.$left, self.$right, $options ); |
||||
} |
||||
|
||||
return self; |
||||
}, |
||||
|
||||
moveFromAtoB: function( $source, $destination, $options, event, silent, skipStack ) { |
||||
var self = this; |
||||
|
||||
if ( typeof self.callbacks.moveFromAtoB == 'function' ) { |
||||
return self.callbacks.moveFromAtoB(self, $source, $destination, $options, event, silent, skipStack); |
||||
} |
||||
|
||||
$options.each(function(index, option) { |
||||
var $option = $(option); |
||||
|
||||
if (self.options.ignoreDisabled && $option.is(':disabled')) { |
||||
return true; |
||||
} |
||||
|
||||
if ($option.is('optgroup') || $option.parent().is('optgroup')) { |
||||
var $sourceGroup = $option.is('optgroup') ? $option : $option.parent(); |
||||
var optgroupSelector = 'optgroup[' + self.options.matchOptgroupBy + '="' + $sourceGroup.prop(self.options.matchOptgroupBy) + '"]'; |
||||
var $destinationGroup = $destination.find(optgroupSelector); |
||||
|
||||
if (!$destinationGroup.length) { |
||||
$destinationGroup = $sourceGroup.clone(true); |
||||
$destinationGroup.empty(); |
||||
|
||||
$destination.move($destinationGroup); |
||||
} |
||||
|
||||
if ($option.is('optgroup')) { |
||||
$destinationGroup.move($option.find('option')); |
||||
} else { |
||||
$destinationGroup.move($option); |
||||
} |
||||
|
||||
$sourceGroup.removeIfEmpty(); |
||||
} else { |
||||
$destination.move($option); |
||||
} |
||||
}); |
||||
|
||||
return self; |
||||
}, |
||||
|
||||
moveUp: function($options) { |
||||
var self = this; |
||||
|
||||
if ( typeof self.callbacks.beforeMoveUp == 'function' ) { |
||||
if ( !self.callbacks.beforeMoveUp( $options ) ) { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
$options.first().prev().before($options); |
||||
|
||||
if ( typeof self.callbacks.afterMoveUp == 'function' ) { |
||||
self.callbacks.afterMoveUp( $options ); |
||||
} |
||||
}, |
||||
|
||||
moveDown: function($options) { |
||||
var self = this; |
||||
|
||||
if ( typeof self.callbacks.beforeMoveDown == 'function' ) { |
||||
if ( !self.callbacks.beforeMoveDown( $options ) ) { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
$options.last().next().after($options); |
||||
|
||||
if ( typeof self.callbacks.afterMoveDown == 'function' ) { |
||||
self.callbacks.afterMoveDown( $options ); |
||||
} |
||||
}, |
||||
|
||||
undo: function(event) { |
||||
var self = this; |
||||
var last = self.undoStack.pop(); |
||||
|
||||
if ( last ) { |
||||
self.redoStack.push(last); |
||||
|
||||
switch(last[0]) { |
||||
case 'left': |
||||
self.moveToRight(last[1], event, false, true); |
||||
break; |
||||
case 'right': |
||||
self.moveToLeft(last[1], event, false, true); |
||||
break; |
||||
} |
||||
} |
||||
}, |
||||
|
||||
redo: function(event) { |
||||
var self = this; |
||||
var last = self.redoStack.pop(); |
||||
|
||||
if ( last ) { |
||||
self.undoStack.push(last); |
||||
|
||||
switch(last[0]) { |
||||
case 'left': |
||||
self.moveToLeft(last[1], event, false, true); |
||||
break; |
||||
case 'right': |
||||
self.moveToRight(last[1], event, false, true); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
return Multiselect; |
||||
})($); |
||||
|
||||
$.multiselect = { |
||||
defaults: { |
||||
/** will be executed once - remove from $left all options that are already in $right |
||||
* |
||||
* @method startUp |
||||
* @attribute $left jQuery object |
||||
* @attribute $right jQuery object |
||||
**/ |
||||
startUp: function( $left, $right ) { |
||||
$right.find('option').each(function(index, rightOption) { |
||||
if ($(rightOption).parent().prop('tagName') == 'OPTGROUP') { |
||||
var optgroupSelector = 'optgroup[label="' + $(rightOption).parent().attr('label') + '"]'; |
||||
$left.find(optgroupSelector + ' option[value="' + rightOption.value + '"]').each(function(index, leftOption) { |
||||
leftOption.remove(); |
||||
}); |
||||
$left.find(optgroupSelector).removeIfEmpty(); |
||||
} else { |
||||
var $option = $left.find('option[value="' + rightOption.value + '"]'); |
||||
$option.remove(); |
||||
} |
||||
}); |
||||
}, |
||||
|
||||
/** will be executed after initialize plugin |
||||
* |
||||
* @method afterInit |
||||
* |
||||
* @default true |
||||
* @return {boolean} |
||||
**/ |
||||
afterInit: function(){ return true; }, |
||||
|
||||
/** will be executed each time before moving option[s] to right |
||||
* |
||||
* IMPORTANT : this method must return boolean value |
||||
* true : continue to moveToRight method |
||||
* false : stop |
||||
* |
||||
* @method beforeMoveToRight |
||||
* @attribute $left jQuery object |
||||
* @attribute $right jQuery object |
||||
* @attribute $options HTML object (the option[s] which was selected to be moved) |
||||
* |
||||
* @default true |
||||
* @return {boolean} |
||||
**/ |
||||
beforeMoveToRight: function($left, $right, $options) { return true; }, |
||||
|
||||
/* will be executed each time after moving option[s] to right |
||||
* |
||||
* @method afterMoveToRight |
||||
* @attribute $left jQuery object |
||||
* @attribute $right jQuery object |
||||
* @attribute $options HTML object (the option[s] which was selected to be moved) |
||||
**/ |
||||
afterMoveToRight: function($left, $right, $options) {}, |
||||
|
||||
/** will be executed each time before moving option[s] to left |
||||
* |
||||
* IMPORTANT : this method must return boolean value |
||||
* true : continue to moveToRight method |
||||
* false : stop |
||||
* |
||||
* @method beforeMoveToLeft |
||||
* @attribute $left jQuery object |
||||
* @attribute $right jQuery object |
||||
* @attribute $options HTML object (the option[s] which was selected to be moved) |
||||
* |
||||
* @default true |
||||
* @return {boolean} |
||||
**/ |
||||
beforeMoveToLeft: function($left, $right, $options) { return true; }, |
||||
|
||||
/* will be executed each time after moving option[s] to left |
||||
* |
||||
* @method afterMoveToLeft |
||||
* @attribute $left jQuery object |
||||
* @attribute $right jQuery object |
||||
* @attribute $options HTML object (the option[s] which was selected to be moved) |
||||
**/ |
||||
afterMoveToLeft: function($left, $right, $options) {}, |
||||
|
||||
/** will be executed each time before moving option[s] up |
||||
* |
||||
* IMPORTANT : this method must return boolean value |
||||
* true : continue to moveUp method |
||||
* false : stop |
||||
* |
||||
* @method beforeMoveUp |
||||
* @attribute $options HTML object (the option[s] which was selected to be moved) |
||||
* |
||||
* @default true |
||||
* @return {boolean} |
||||
**/ |
||||
beforeMoveUp: function($options) { return true; }, |
||||
|
||||
/* will be executed each time after moving option[s] up |
||||
* |
||||
* @method afterMoveUp |
||||
* @attribute $left jQuery object |
||||
* @attribute $right jQuery object |
||||
* @attribute $options HTML object (the option[s] which was selected to be moved) |
||||
**/ |
||||
afterMoveUp: function($options) {}, |
||||
|
||||
/** will be executed each time before moving option[s] down |
||||
* |
||||
* IMPORTANT : this method must return boolean value |
||||
* true : continue to moveUp method |
||||
* false : stop |
||||
* |
||||
* @method beforeMoveDown |
||||
* @attribute $options HTML object (the option[s] which was selected to be moved) |
||||
* |
||||
* @default true |
||||
* @return {boolean} |
||||
**/ |
||||
beforeMoveDown: function($options) { return true; }, |
||||
|
||||
/* will be executed each time after moving option[s] down |
||||
* |
||||
* @method afterMoveUp |
||||
* @attribute $left jQuery object |
||||
* @attribute $right jQuery object |
||||
* @attribute $options HTML object (the option[s] which was selected to be moved) |
||||
**/ |
||||
afterMoveDown: function($options) {}, |
||||
|
||||
/** sort options by option text |
||||
* |
||||
* @method sort |
||||
* @attribute a HTML option |
||||
* @attribute b HTML option |
||||
* |
||||
* @return 1/-1 |
||||
**/ |
||||
sort: function(a, b) { |
||||
if (a.innerHTML == 'NA') { |
||||
return 1; |
||||
} else if (b.innerHTML == 'NA') { |
||||
return -1; |
||||
} |
||||
|
||||
return (a.innerHTML > b.innerHTML) ? 1 : -1; |
||||
}, |
||||
|
||||
/* will tell if the search can start |
||||
* |
||||
* @method fireSearch |
||||
* @attribute value String |
||||
* |
||||
* @return {boolean} |
||||
**/ |
||||
fireSearch: function(value) { |
||||
return value.length > 1; |
||||
} |
||||
} |
||||
}; |
||||
|
||||
var ua = window.navigator.userAgent; |
||||
var isIE = (ua.indexOf("MSIE ") + ua.indexOf("Trident/") + ua.indexOf("Edge/")) > -3; |
||||
var isSafari = ua.toLowerCase().indexOf("safari") > -1; |
||||
var isFirefox = ua.toLowerCase().indexOf("firefox") > -1; |
||||
|
||||
$.fn.multiselect = function( options ) { |
||||
return this.each(function() { |
||||
var $this = $(this), |
||||
data = $this.data('crlcu.multiselect'), |
||||
settings = $.extend({}, $.multiselect.defaults, $this.data(), (typeof options === 'object' && options)); |
||||
|
||||
if (!data) { |
||||
$this.data('crlcu.multiselect', (data = new Multiselect($this, settings))); |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
// append options
|
||||
// then set the selected attribute to false
|
||||
$.fn.move = function( $options ) { |
||||
this |
||||
.append($options) |
||||
.find('option') |
||||
.prop('selected', false); |
||||
|
||||
return this; |
||||
}; |
||||
|
||||
$.fn.removeIfEmpty = function() { |
||||
if (!this.children().length) { |
||||
this.remove(); |
||||
} |
||||
|
||||
return this; |
||||
}; |
||||
|
||||
$.fn.mShow = function() { |
||||
this.removeClass('hidden').show(); |
||||
|
||||
if (isIE || isSafari) { |
||||
this.each(function(index, option) { |
||||
// Remove <span> to make it compatible with IE
|
||||
if($(option).parent().is('span')) { |
||||
$(option).parent().replaceWith(option); |
||||
} |
||||
|
||||
$(option).show(); |
||||
}); |
||||
} |
||||
if(isFirefox){ |
||||
this.attr('disabled', false) |
||||
} |
||||
|
||||
return this; |
||||
}; |
||||
|
||||
$.fn.mHide = function() { |
||||
this.addClass('hidden').hide(); |
||||
|
||||
if (isIE || isSafari) { |
||||
this.each(function(index, option) { |
||||
// Wrap with <span> to make it compatible with IE
|
||||
if(!$(option).parent().is('span')) { |
||||
$(option).wrap('<span>').hide(); |
||||
} |
||||
}); |
||||
} |
||||
if(isFirefox){ |
||||
this.attr('disabled', true) |
||||
} |
||||
return this; |
||||
}; |
||||
|
||||
// sort options then reappend them to the select
|
||||
$.fn.mSort = function(callback) { |
||||
this |
||||
.children() |
||||
.sort(callback) |
||||
.appendTo(this); |
||||
|
||||
this |
||||
.find('optgroup') |
||||
.each(function(i, group) { |
||||
$(group).children() |
||||
.sort(callback) |
||||
.appendTo(group); |
||||
}) |
||||
|
||||
return this; |
||||
}; |
||||
|
||||
// attach index to children
|
||||
$.fn.attachIndex = function() { |
||||
this.children().each(function(index, option) { |
||||
var $option = $(option); |
||||
|
||||
if ($option.is('optgroup')) { |
||||
$option.children().each(function(i, children) { |
||||
$(children).data('position', i); |
||||
}); |
||||
} |
||||
|
||||
$option.data('position', index); |
||||
}); |
||||
}; |
||||
|
||||
$.expr[":"].search = function(elem, index, meta) { |
||||
var regex = new RegExp(meta[3].replace(/([^a-zA-Z0-9])/g, "\\$1"), "i"); |
||||
|
||||
return $(elem).text().match(regex); |
||||
} |
||||
})); |
||||
|
||||
File diff suppressed because one or more lines are too long
@ -0,0 +1,481 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta name="description" lang="en" content="jQuery multiselect plugin with two sides. The user can select one or more items and send them to the other side."/> |
||||
<meta name="keywords" lang="en" content="jQuery multiselect plugin" /> |
||||
|
||||
<base href="//crlcu.github.io/multiselect/" /> |
||||
|
||||
<title>jQuery multiselect plugin with two sides</title> |
||||
|
||||
<link rel="icon" type="image/x-icon" href="https://github.com/favicon.ico" /> |
||||
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" /> |
||||
<link rel="stylesheet" href="lib/google-code-prettify/prettify.css" /> |
||||
<link rel="stylesheet" href="css/style.css" /> |
||||
</head> |
||||
<body> |
||||
<a href="https://github.com/crlcu/multiselect" class="github ribbon"> |
||||
<img src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png" alt="Fork me on GitHub"> |
||||
</a> |
||||
|
||||
<div class="navbar navbar-inverse navbar-fixed-top"> |
||||
<div class="navbar-inner"> |
||||
<div class="container"> |
||||
<div class="navbar-header"> |
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> |
||||
<span class="sr-only">Toggle navigation</span> |
||||
<span class="icon-bar"></span> |
||||
<span class="icon-bar"></span> |
||||
<span class="icon-bar"></span> |
||||
</button> |
||||
<a class="navbar-brand scroll" href="#">Multiselect</a> |
||||
</div> |
||||
|
||||
<div class="collapse navbar-collapse"> |
||||
<ul class="nav navbar-nav"> |
||||
<li><a href="#" class="scroll">Home</a></li> |
||||
<li><a href="#documentation" class="scroll">Documentation</a></li> |
||||
<li><a href="#browser-support" class="scroll">Browser Support</a></li> |
||||
<li class="dropdown"> |
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Examples <span class="caret"></span ></a> |
||||
<ul class="dropdown-menu" role="menu"> |
||||
<li><a href="examples/zero-configuration.html">Zero configuration</a></li> |
||||
<li><a href="examples/data-options.html">With <code>data</code> options</a></li> |
||||
<li><a href="examples/javascript-options.html">With <code>javascript</code> options</a></li> |
||||
<li><a href="examples/search.html">With search</a></li> |
||||
<li><a href="examples/keep-rendering-sort.html">Keep rendering sort</a></li> |
||||
<li><a href="examples/undo-redo.html">Undo / Redo</a></li> |
||||
<li><a href="examples/multiple-destinations.html">Multiple destinations</a></li> |
||||
<li><a href="examples/optgroup.html">With <code>optgroup</code></a></li> |
||||
<li><a href="examples/move-up-down.html">With move <code>up</code>/<code>down</code> buttons</a></li> |
||||
</ul> |
||||
</li> |
||||
<li><a href="#download" class="scroll">Download</a></li> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div id="wrap" class="container"> |
||||
<div id="home"> |
||||
<div class="jumbotron"> |
||||
<h1>Multiselect</h1> |
||||
<p>This is a small <a href="http://jquery.com/" target="_blank">jQuery</a> plugin that helps you improve the |
||||
<strong>user experience</strong> regarding the use of multiple cross selects. |
||||
</p> |
||||
<p>It is very <strong>easy to install</strong> and can be <strong>easily customized</strong> because it has <strong>callbacks</strong> for many events, such as : |
||||
<div class="row"> |
||||
<div class="col-xs-6"> |
||||
<ul> |
||||
<li><a href="#beforeMoveToRight">beforeMoveToRight</a></li> |
||||
<li><a href="#beforeMoveToLeft">beforeMoveToLeft</a></li> |
||||
</ul> |
||||
</div> |
||||
|
||||
<div class="col-xs-6"> |
||||
<ul> |
||||
<li><a href="#afterMoveToRight">afterMoveToRight</a></li> |
||||
<li><a href="#afterMoveToLeft">afterMoveToLeft</a></li> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
</p> |
||||
<p>It also has a <a href="#sort">sort</a> function that can be defined in order of your needs for each multiple select.</p> |
||||
<p>You can <strong>fully customize</strong> it via <strong>CSS</strong>, you can extend it and have as <strong>many multi selects</strong> as you want on the page.</p> |
||||
|
||||
<p><a href="#documentation" class="btn btn-primary btn-lg">Documentation</a></p> |
||||
</div> |
||||
</div> |
||||
|
||||
<div id="documentation"> |
||||
<div class="page-header"><h3>Documentation</h3></div> |
||||
|
||||
<h4>Options:</h4> |
||||
|
||||
<table class="table table-bordered table-striped"> |
||||
<thead> |
||||
<tr> |
||||
<th>Name</th> |
||||
<th>type</th> |
||||
<th>default</th> |
||||
<th>description</th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
<tr> |
||||
<td>right</td> |
||||
<td><code>string</code> jQuery selector</td> |
||||
<td><code>multiselect_id</code>_to</td> |
||||
<td>The <code>select</code> where the options are moved to</td> |
||||
</tr> |
||||
<tr> |
||||
<td>rightSelected</td> |
||||
<td><code>string</code> jQuery selector</td> |
||||
<td><code>multiselect_id</code>_rightSelected</td> |
||||
<td>The <code>button</code> that moves selected options from left to right</td> |
||||
</tr> |
||||
<tr> |
||||
<td>rightAll</td> |
||||
<td><code>string</code> jQuery selector</td> |
||||
<td><code>multiselect_id</code>_rightAll</td> |
||||
<td>The <code>button</code> that moves all options from left to right</td> |
||||
</tr> |
||||
<tr> |
||||
<td>leftSelected</td> |
||||
<td><code>string</code> jQuery selector</td> |
||||
<td><code>multiselect_id</code>_leftSelected</td> |
||||
<td>The <code>button</code> that moves selected options from right to left</td> |
||||
</tr> |
||||
<tr> |
||||
<td>leftAll</td> |
||||
<td><code>string</code> jQuery selector</td> |
||||
<td><code>multiselect_id</code>_leftAll</td> |
||||
<td>The <code>button</code> that moves all options from right to left</td> |
||||
</tr> |
||||
<tr> |
||||
<td>undo</td> |
||||
<td><code>string</code> jQuery selector</td> |
||||
<td><code>multiselect_id</code>_undo</td> |
||||
<td>The <code>button</code> that triggers the undo action</td> |
||||
</tr> |
||||
<tr> |
||||
<td>redo</td> |
||||
<td><code>string</code> jQuery selector</td> |
||||
<td><code>multiselect_id</code>_redo</td> |
||||
<td>The <code>button</code> that triggers the redo action</td> |
||||
</tr> |
||||
<tr> |
||||
<td>moveUp</td> |
||||
<td><code>string</code> jQuery selector</td> |
||||
<td><code>multiselect_id</code>_move_up</td> |
||||
<td>The <code>button</code> that move options from right side to the top</td> |
||||
</tr> |
||||
<tr> |
||||
<td>moveDown</td> |
||||
<td><code>string</code> jQuery selector</td> |
||||
<td><code>multiselect_id</code>_move_down</td> |
||||
<td>The <code>button</code> that move options from right side to the bottom</td> |
||||
</tr> |
||||
<tr> |
||||
<td>startUp</td> |
||||
<td><code>function</code> or <code>false</code></td> |
||||
<td><code>remove</code> from left all options that are present in right</td> |
||||
<td>Whatever you want to do with <code>$left</code> and <code>$right</code> elements when the <code>multiselect</code> plugin is initialised</td> |
||||
</tr> |
||||
<tr id="sort"> |
||||
<td>sort</td> |
||||
<td><code>function</code> or <code>false</code></td> |
||||
<td><code>sort</code> options alphabetically</td> |
||||
<td>Will sort options when an action happend into right or left elements.</td> |
||||
</tr> |
||||
<tr id="beforeMoveToRight"> |
||||
<td>beforeMoveToRight</td> |
||||
<td><code>function</code></td> |
||||
<td>return <code>true</code></td> |
||||
<td> |
||||
Whatever you want to do with <code>$left</code>, <code>$right</code> and <code>$options</code> elements before they are moved to right.<br/><br/> |
||||
|
||||
<code>beforeMoveToRight: function($left, $right, $options) { ...; return Boolean; }</code>.<br/><br/> |
||||
|
||||
<ul> |
||||
<li><code>$left</code> - jQuery element pointing to left side <code>select</code> element</li> |
||||
<li><code>$right</code> - jQuery element pointing to right side <code>select</code> element</li> |
||||
<li><code>$options</code> - jQuery element containing all selected options</li> |
||||
</ul> |
||||
|
||||
Keep in mind that this function must return a boolean value.<br/> |
||||
<ul> |
||||
<li><code>true</code> will let the action to be performed</li> |
||||
<li><code>false</code> will stop the action</li> |
||||
</ul> |
||||
</td> |
||||
</tr> |
||||
<tr id="moveToRight"> |
||||
<td>moveToRight</td> |
||||
<td><code>function</code></td> |
||||
<td>return <code>this</code></td> |
||||
<td> |
||||
If you want to define your own <code>moveToRight</code> functionality you can do this by defining<br/><br/> |
||||
|
||||
<code>moveToRight: function(Multiselect, $options, event, silent, skipStack) { ... }</code><br/><br/> |
||||
|
||||
<ul> |
||||
<li><code>Multiselect</code> - current instance of multiselect</li> |
||||
<li><code>$options</code> - jQuery element containing all selected options</li> |
||||
<li><code>event</code> - the event that initialised the action</li> |
||||
<li><code>silent</code> - <code>boolean</code> that tells if you have to trigger <code>beforeMoveToRight</code> and <code>afterMoveToRight</code></li> |
||||
<li><code>skipStack</code> - <code>boolean</code> that tells if you have to handle <code>undo/redo</code> stack</li> |
||||
</ul> |
||||
</td> |
||||
</tr> |
||||
<tr id="afterMoveToRight"> |
||||
<td>afterMoveToRight</td> |
||||
<td><code>function</code></td> |
||||
<td>no action</td> |
||||
<td> |
||||
Whatever you want to do with <code>$left</code>, <code>$right</code> and <code>$options</code> elements after they are moved to right.<br/><br/> |
||||
|
||||
<code>afterMoveToRight: function($left, $right, $options) { ...; }</code><br/><br/> |
||||
|
||||
<ul> |
||||
<li><code>$left</code> - jQuery element pointing to left side <code>select</code> element</li> |
||||
<li><code>$right</code> - jQuery element pointing to right side <code>select</code> element</li> |
||||
<li><code>$options</code> - jQuery element containing all selected options</li> |
||||
</ul> |
||||
</td> |
||||
</tr> |
||||
<tr id="beforeMoveToLeft"> |
||||
<td>beforeMoveToLeft</td> |
||||
<td><code>function</code></td> |
||||
<td>return <code>true</code></td> |
||||
<td> |
||||
Whatever you want to do with <code>$left</code>, <code>$right</code> and <code>$options</code> elements before they are moved to left.<br/><br/> |
||||
|
||||
<code>beforeMoveToLeft: function($left, $right, $options) { ...; return Boolean; }</code>.<br/><br/> |
||||
|
||||
<ul> |
||||
<li><code>$left</code> - jQuery element pointing to left side <code>select</code> element</li> |
||||
<li><code>$right</code> - jQuery element pointing to right side <code>select</code> element</li> |
||||
<li><code>$options</code> - jQuery element containing all selected options</li> |
||||
</ul> |
||||
|
||||
Keep in mind that this function must return a boolean value.<br/> |
||||
<ul> |
||||
<li><code>true</code> will let the action to be performed</li> |
||||
<li><code>false</code> will stop the action</li> |
||||
</ul> |
||||
</td> |
||||
</tr> |
||||
<tr id="moveToLeft"> |
||||
<td>moveToLeft</td> |
||||
<td><code>function</code></td> |
||||
<td>return <code>this</code></td> |
||||
<td> |
||||
If you want to define your own <code>moveToLeft</code> functionality you can do this by defining<br/><br/> |
||||
|
||||
<code>moveToLeft: function(Multiselect, $options, event, silent, skipStack) { ... }</code><br/><br/> |
||||
|
||||
<ul> |
||||
<li><code>Multiselect</code> - current instance of multiselect</li> |
||||
<li><code>$options</code> - jQuery element containing all selected options</li> |
||||
<li><code>event</code> - the event that initialised the action</li> |
||||
<li><code>silent</code> - <code>boolean</code> that tells if you have to trigger <code>beforeMoveToRight</code> and <code>afterMoveToRight</code></li> |
||||
<li><code>skipStack</code> - <code>boolean</code> that tells if you have to handle <code>undo/redo</code> stack</li> |
||||
</ul> |
||||
</td> |
||||
</tr> |
||||
<tr id="afterMoveToLeft"> |
||||
<td>afterMoveToLeft</td> |
||||
<td><code>function</code></td> |
||||
<td>no action</td> |
||||
<td> |
||||
Whatever you want to do with <code>$left</code>, <code>$right</code> and <code>$options</code> elements after they are moved to right.<br/><br/> |
||||
|
||||
<code>afterMoveToLeft: function($left, $right, $options) { ...; }</code><br/><br/> |
||||
|
||||
<ul> |
||||
<li><code>$left</code> - jQuery element pointing to left side <code>select</code> element</li> |
||||
<li><code>$right</code> - jQuery element pointing to right side <code>select</code> element</li> |
||||
<li><code>$options</code> - jQuery element containing all selected options</li> |
||||
</ul> |
||||
</td> |
||||
</tr> |
||||
<tr id="beforeMoveUp"> |
||||
<td>beforeMoveUp</td> |
||||
<td><code>function</code></td> |
||||
<td>return <code>true</code></td> |
||||
<td> |
||||
Whatever you want to do with <code>$options</code> elements before they are moved up.<br/><br/> |
||||
|
||||
<code>beforeMoveUp: function( $options) { ...; return Boolean; }</code>.<br/><br/> |
||||
|
||||
<ul> |
||||
<li><code>$options</code> - jQuery element containing all selected options</li> |
||||
</ul> |
||||
|
||||
Keep in mind that this function must return a boolean value.<br/> |
||||
<ul> |
||||
<li><code>true</code> will let the action to be performed</li> |
||||
<li><code>false</code> will stop the action</li> |
||||
</ul> |
||||
</td> |
||||
</tr> |
||||
<tr id="afterMoveUp"> |
||||
<td>afterMoveUp</td> |
||||
<td><code>function</code></td> |
||||
<td>no action</td> |
||||
<td> |
||||
Whatever you want to do with <code>$options</code> elements after they are moved up.<br/><br/> |
||||
|
||||
<code>afterMoveUp: function($options) { ...; }</code><br/><br/> |
||||
|
||||
<ul> |
||||
<li><code>$options</code> - jQuery element containing all selected options</li> |
||||
</ul> |
||||
</td> |
||||
</tr> |
||||
<tr id="beforeMoveDown"> |
||||
<td>beforeMoveDown</td> |
||||
<td><code>function</code></td> |
||||
<td>return <code>true</code></td> |
||||
<td> |
||||
Whatever you want to do with <code>$options</code> elements before they are moved down.<br/><br/> |
||||
|
||||
<code>beforeMoveDown: function( $options) { ...; return Boolean; }</code>.<br/><br/> |
||||
|
||||
<ul> |
||||
<li><code>$options</code> - jQuery element containing all selected options</li> |
||||
</ul> |
||||
|
||||
Keep in mind that this function must return a boolean value.<br/> |
||||
<ul> |
||||
<li><code>true</code> will let the action to be performed</li> |
||||
<li><code>false</code> will stop the action</li> |
||||
</ul> |
||||
</td> |
||||
</tr> |
||||
<tr id="afterMoveDown"> |
||||
<td>afterMoveDown</td> |
||||
<td><code>function</code></td> |
||||
<td>no action</td> |
||||
<td> |
||||
Whatever you want to do with <code>$options</code> elements after they are moved down.<br/><br/> |
||||
|
||||
<code>afterMoveDown: function($options) { ...; }</code><br/><br/> |
||||
|
||||
<ul> |
||||
<li><code>$options</code> - jQuery element containing all selected options</li> |
||||
</ul> |
||||
</td> |
||||
</tr> |
||||
<tr> |
||||
<td>keepRenderingSort</td> |
||||
<td><code>boolean</code></td> |
||||
<td><code>false</code></td> |
||||
<td> |
||||
When you want to keep options sorted as they was rendered, <code>keepRenderingSort</code> must be <code>true</code>.<br/> |
||||
When <code>keepRenderingSort</code> is <code>true</code>, <code>sort</code> function will be ignored. |
||||
</td> |
||||
</tr> |
||||
<tr> |
||||
<td>submitAllLeft</td> |
||||
<td><code>boolean</code></td> |
||||
<td><code>true</code></td> |
||||
<td> |
||||
When you don’t want to send all options from the left side to server, <code>submitAllLeft</code> must be <code>false</code>. |
||||
</td> |
||||
</tr> |
||||
<tr> |
||||
<td>submitAllRight</td> |
||||
<td><code>boolean</code></td> |
||||
<td><code>true</code></td> |
||||
<td> |
||||
When you don’t want to send all options from the right side to server, <code>submitAllRight</code> must be <code>false</code>. |
||||
</td> |
||||
</tr> |
||||
<tr> |
||||
<td>search</td> |
||||
<td><code>Object</code></td> |
||||
<td><code>null</code></td> |
||||
<td> |
||||
When you want to have search fields for <code>left</code> and <code>right</code> elements you can do this by providing following value:<br/> |
||||
<pre class="prettyprint linenums"> |
||||
search: { |
||||
left: '<input type="text" name="q" class="form-control" placeholder="Search..." />', |
||||
right: '<input type="text" name="q" class="form-control" placeholder="Search..." />', |
||||
} |
||||
</pre> |
||||
When you want to have search field only for <code>left</code> element you can do this by providing following value:<br/> |
||||
<pre class="prettyprint linenums"> |
||||
search: { |
||||
left: '<input type="text" name="q" class="form-control" placeholder="Search..." />', |
||||
} |
||||
</pre> |
||||
</td> |
||||
</tr> |
||||
<tr id="fireSearch"> |
||||
<td>fireSearch</td> |
||||
<td><code>function</code></td> |
||||
<td>return <code>true</code> if search length is great than 1</td> |
||||
<td> |
||||
Tell to multiselect when to start applying the search.<br/><br/> |
||||
<code>fireSearch: function(value) { ...; return Boolean; }</code><br/><br/> |
||||
|
||||
<ul> |
||||
<li><code>value</code> - String search entered by the user</li> |
||||
</ul> |
||||
</td> |
||||
</tr> |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
|
||||
<div id="browser-support"> |
||||
<div class="page-header"><h3>Browser Support</h3></div> |
||||
|
||||
<h4>The following browsers are supported:</h4> |
||||
|
||||
<ul> |
||||
<li>Internet Explorer 7+</li> |
||||
<li>Google Chrome</li> |
||||
<li>Mozilla Firefox</li> |
||||
<li>Safari</li> |
||||
<li>Opera</li> |
||||
</ul> |
||||
</div> |
||||
|
||||
<div id="download"> |
||||
<div class="page-header"><h3>Download</h3></div> |
||||
|
||||
<div class="row"> |
||||
<div class="col-xs-4"> |
||||
<p><a class="btn btn-lg btn-primary" href="https://raw.github.com/crlcu/multiselect/master/dist/js/multiselect.js">Download multiselect.js</a></p> |
||||
</div> |
||||
|
||||
<div class="col-xs-4"> |
||||
<p><a class="btn btn-lg btn-success" href="https://raw.github.com/crlcu/multiselect/master/dist/js/multiselect.min.js">Download multiselect.min.js</a></p> |
||||
</div> |
||||
|
||||
<div class="col-xs-4"> |
||||
<p><a class="btn btn-lg btn-info" href="https://github.com/crlcu/multiselect/archive/master.zip">Download multiselect.zip</a></p> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> |
||||
<script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script> |
||||
|
||||
<script> |
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ |
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), |
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) |
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga'); |
||||
|
||||
ga('create', 'UA-39934286-1', 'github.com'); |
||||
ga('send', 'pageview'); |
||||
</script> |
||||
|
||||
<script type="text/javascript"> |
||||
$(document).ready(function() { |
||||
// make code pretty |
||||
window.prettyPrint && prettyPrint(); |
||||
|
||||
if ( window.location.hash ) { |
||||
scrollTo(window.location.hash); |
||||
} |
||||
|
||||
$('.nav').on('click', 'a.scroll', function(e) { |
||||
scrollTo($(this).attr('href')); |
||||
}); |
||||
}); |
||||
|
||||
function scrollTo( id ) { |
||||
if ( $(id).length ) { |
||||
$('html,body').animate({scrollTop: $(id).offset().top - 60},'slow'); |
||||
} |
||||
} |
||||
</script> |
||||
</body> |
||||
</html> |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,34 @@ |
||||
{ |
||||
"name": "multiselect-two-sides", |
||||
"version": "2.5.2", |
||||
"description": "jQuery multiselect plugin with two sides", |
||||
"main": "dist/js/multiselect.min.js", |
||||
"scripts": { |
||||
"test": "echo \"Error: no test specified\" && exit 1", |
||||
"release": "standard-version" |
||||
}, |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "git+https://github.com/crlcu/multiselect.git" |
||||
}, |
||||
"keywords": [ |
||||
"multiselect" |
||||
], |
||||
"author": "Adrian Crisan <adrian.crisan88@gmail.com>", |
||||
"license": "MIT", |
||||
"bugs": { |
||||
"url": "https://github.com/crlcu/multiselect/issues" |
||||
}, |
||||
"homepage": "https://github.com/crlcu/multiselect#readme", |
||||
"devDependencies": { |
||||
"gulp": "^3.9.1", |
||||
"gulp-rename": "^1.2.2", |
||||
"gulp-strip-debug": "^1.1.0", |
||||
"gulp-uglify": "^2.0.0", |
||||
"jasmine": "^2.5.3", |
||||
"standard-version": "^4.3.0" |
||||
}, |
||||
"dependencies": { |
||||
"jquery": ">=1.7" |
||||
} |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,36 @@ |
||||
/* |
||||
Stylesheet for HTML documents created with CKEditor. |
||||
|
||||
This stylesheet must import editor_content.css file |
||||
*/ |
||||
@import url(./editor_content.css); |
||||
|
||||
body { |
||||
color: #666; |
||||
font-family: 'Open Sans', sans-serif; |
||||
line-height: 30px; |
||||
padding: 1em; |
||||
} |
||||
|
||||
blockquote { |
||||
background: #f9f9f9; |
||||
border-left: 8px solid #ccc; |
||||
display: inline-block; |
||||
font: 14px/20px italic Times, serif; |
||||
margin: 1.5em 10px; |
||||
padding: 0.5em 10px; |
||||
quotes: "\201C" "\201D" "\2018" "\2019"; |
||||
} |
||||
|
||||
blockquote:before { |
||||
color: #ccc; |
||||
content: open-quote; |
||||
font-size: 4em; |
||||
line-height: 0.1em; |
||||
margin-right: 0.25em; |
||||
vertical-align: -0.4em; |
||||
} |
||||
|
||||
blockquote p { |
||||
display: inline; |
||||
} |
||||
@ -0,0 +1,216 @@ |
||||
/* |
||||
Stylesheet for HTML blocks created with CKEditor to embed in Chamilo pages. |
||||
*/ |
||||
|
||||
@font-face { |
||||
font-family: 'Open Sans'; |
||||
font-style: normal; |
||||
font-weight: 300; |
||||
src: local('Open Sans Light'), |
||||
local('OpenSans-Light'), |
||||
url(themes/chamilo/fonts/OpenSans-Light.woff2) format('woff2'), |
||||
url(themes/chamilo/fonts/OpenSans-Light.woff) format('woff'); |
||||
} |
||||
|
||||
@font-face { |
||||
font-family: 'Open Sans'; |
||||
font-style: normal; |
||||
font-weight: 400; |
||||
src: local('Open Sans'), |
||||
local('OpenSans'), |
||||
url(themes/chamilo/fonts/OpenSans.woff2) format('woff2'), |
||||
url(themes/chamilo/fonts/OpenSans.woff) format('woff'); |
||||
} |
||||
|
||||
@font-face { |
||||
font-family: 'Open Sans'; |
||||
font-style: normal; |
||||
font-weight: 600; |
||||
src: local('Open Sans Semibold'), |
||||
local('OpenSans-Semibold'), |
||||
url(themes/chamilo/fonts/OpenSans-Semibold.woff2) format('woff2'), |
||||
url(themes/chamilo/fonts/OpenSans-Semibold.woff) format('woff'); |
||||
} |
||||
|
||||
@font-face { |
||||
font-family: 'Open Sans'; |
||||
font-style: normal; |
||||
font-weight: 700; |
||||
src: local('Open Sans Bold'), |
||||
local('OpenSans-Bold'), |
||||
url(themes/chamilo/fonts/OpenSans-Bold.woff2) format('woff2'), |
||||
url(themes/chamilo/fonts/OpenSans-Bold.woff) format('woff'); |
||||
} |
||||
|
||||
body { |
||||
font-family: 'Open Sans', sans-serif; |
||||
} |
||||
|
||||
/* Hack for show Bootstrap alerts in CKEditor' style select */ |
||||
.cke_panel_listItem a > :first-child { |
||||
margin-bottom: 0; |
||||
} |
||||
|
||||
.ck { |
||||
display: block; |
||||
font-feature-settings: normal; |
||||
font-kerning: auto; |
||||
font-language-override: normal; |
||||
font-size-adjust: none; |
||||
font-stretch: normal; |
||||
font-style: normal; |
||||
font-synthesis: weight style; |
||||
font-variant: normal; |
||||
font-weight: normal; |
||||
line-height: 1; |
||||
} |
||||
|
||||
.ck-article { |
||||
color: #E95839; |
||||
background: url(../../main/img/document/border-title.png) repeat-x 0 80%; |
||||
font-weight: bold; |
||||
margin-bottom: 10px; |
||||
padding-bottom: 2%; |
||||
text-transform: uppercase; |
||||
} |
||||
|
||||
.ck-article:before { |
||||
content: "\f15c"; |
||||
font-family: FontAwesome; |
||||
font-weight: normal; |
||||
margin-right: 5px; |
||||
} |
||||
|
||||
.ck-paragraph-box { |
||||
background-color: #F5EEE2; |
||||
line-height: 20px; |
||||
padding: 2% 3%; |
||||
} |
||||
|
||||
.ck-title { |
||||
color: #000; |
||||
display: block; |
||||
font-weight: bold; |
||||
} |
||||
|
||||
.ck-title2 { |
||||
color: #000; |
||||
font-weight: 500; |
||||
margin-top: 0; |
||||
padding-top: 0; |
||||
position: relative; |
||||
} |
||||
|
||||
.ck-title2:after { |
||||
background-color: #E95839; |
||||
content: ""; |
||||
display: block; |
||||
height: 2px; |
||||
margin: 10px 0 0; |
||||
width: 50px; |
||||
} |
||||
|
||||
.ck-stand-out { |
||||
background-color: yellow; |
||||
} |
||||
|
||||
.ck-style1 { |
||||
background: url(../../main/img/document/hr-1.png) repeat-x 0 0; |
||||
border: 0; |
||||
height: 6px; |
||||
} |
||||
|
||||
.ck-style2 { |
||||
background: url(../../main/img/document/hr-2.png) repeat-x 0 0; |
||||
border: 0; |
||||
height: 6px; |
||||
} |
||||
|
||||
.ck-style3 { |
||||
border-top: 1px dashed #8c8b8b; |
||||
} |
||||
|
||||
.ck-style3:after { |
||||
background: #FFF; |
||||
color: #8c8b8b; |
||||
content: '\002702'; |
||||
display: inline-block; |
||||
font-size: 18px; |
||||
left: 40px; |
||||
padding: 0 3px; |
||||
position: relative; |
||||
top: -12px; |
||||
} |
||||
|
||||
.img-va-baseline { |
||||
vertical-align: baseline; |
||||
} |
||||
|
||||
.img-va-top { |
||||
vertical-align: top; |
||||
} |
||||
|
||||
.img-va-bottom { |
||||
vertical-align: bottom; |
||||
} |
||||
|
||||
.img-va-middle { |
||||
vertical-align: middle; |
||||
} |
||||
|
||||
.img-va-super { |
||||
vertical-align: super; |
||||
} |
||||
|
||||
.img-va-sub { |
||||
vertical-align: sub; |
||||
} |
||||
|
||||
.img-va-text-top { |
||||
vertical-align: text-top; |
||||
} |
||||
|
||||
.img-va-text-bottom { |
||||
vertical-align: text-bottom; |
||||
} |
||||
|
||||
figure.image { |
||||
border: 1px solid #ddd; |
||||
border-radius: 5px; |
||||
display: inline-block; |
||||
margin-bottom: 1em; |
||||
padding: 5px; |
||||
} |
||||
|
||||
.cke_widget_image.pull-right, |
||||
img.pull-right, |
||||
figure.image.pull-right { |
||||
margin-left: 1em; |
||||
} |
||||
|
||||
.cke_widget_image.pull-left, |
||||
img.pull-left, |
||||
figure.image.pull-left { |
||||
margin-right: 1em; |
||||
} |
||||
|
||||
.text-center .img-responsive { |
||||
margin-left: auto; |
||||
margin-right: auto; |
||||
} |
||||
|
||||
.cke_widget_image.pull-left figure.image, |
||||
.cke_widget_image.pull-right figure.image, |
||||
figure.image.pull-left, |
||||
figure.image.pull-right { |
||||
display: block; |
||||
} |
||||
|
||||
figure.image figcaption { |
||||
background-color: #f3f3f3; |
||||
border-radius: 0; |
||||
margin: 0; |
||||
padding-left: 5px; |
||||
padding-top: 0; |
||||
text-align: left; |
||||
} |
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue