update components

This commit is contained in:
Luke Pulverenti 2015-07-13 17:26:11 -04:00
parent 697257670c
commit 02ae9ec81e
123 changed files with 13600 additions and 531 deletions

View File

@ -35,6 +35,12 @@
<div>
<br />
<ul data-role="listview" class="ulForm">
<li class="fldAutomaticUpdates">
<div data-role="controlgroup">
<input type="checkbox" id="chkEnableAutomaticServerUpdates" data-mini="true" />
<label for="chkEnableAutomaticServerUpdates">${OptionEnableAutomaticServerUpdates}</label>
</div>
</li>
<li>
<label for="selectAutomaticUpdateLevel">${LabelAutomaticUpdateLevel}</label>
<select name="selectAutomaticUpdateLevel" id="selectAutomaticUpdateLevel">

View File

@ -0,0 +1,24 @@
{
"name": "fastclick",
"main": "lib/fastclick.js",
"ignore": [
"**/.*",
"component.json",
"package.json",
"Makefile",
"tests",
"examples"
],
"homepage": "https://github.com/ftlabs/fastclick",
"version": "1.0.6",
"_release": "1.0.6",
"_resolution": {
"type": "version",
"tag": "v1.0.6",
"commit": "2ac7258407619398005ca720596f0d36ce66a6c8"
},
"_source": "git://github.com/ftlabs/fastclick.git",
"_target": "~1.0.6",
"_originalSource": "fastclick",
"_direct": true
}

View File

@ -0,0 +1,22 @@
Copyright (c) 2014 The Financial Times Ltd.
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.

View File

@ -0,0 +1,12 @@
{
"name": "fastclick",
"main": "lib/fastclick.js",
"ignore": [
"**/.*",
"component.json",
"package.json",
"Makefile",
"tests",
"examples"
]
}

View File

@ -1,6 +1,6 @@
{
"name": "iron-autogrow-textarea",
"version": "1.0.2",
"version": "1.0.3",
"description": "A textarea element that automatically grows with input",
"authors": [
"The Polymer Authors"
@ -26,6 +26,7 @@
"iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
"iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
"iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0",
"iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
"polymer": "Polymer/polymer#^1.0.0"
},
"devDependencies": {
@ -36,11 +37,11 @@
"paper-styles": "PolymerElements/paper-styles#^1.0.0",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.2",
"_release": "1.0.3",
"_resolution": {
"type": "version",
"tag": "v1.0.2",
"commit": "1697690de3010aa7b4d3557e7f3fa582e82dee6a"
"tag": "v1.0.3",
"commit": "9eae088ce72a31b0baf44e6cdc183e5b73014af5"
},
"_source": "git://github.com/PolymerElements/iron-autogrow-textarea.git",
"_target": "^1.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "iron-autogrow-textarea",
"version": "1.0.2",
"version": "1.0.3",
"description": "A textarea element that automatically grows with input",
"authors": [
"The Polymer Authors"
@ -26,6 +26,7 @@
"iron-behaviors": "PolymerElements/iron-behaviors#^1.0.0",
"iron-flex-layout": "PolymerElements/iron-flex-layout#^1.0.0",
"iron-validatable-behavior": "PolymerElements/iron-validatable-behavior#^1.0.0",
"iron-form-element-behavior": "PolymerElements/iron-form-element-behavior#^1.0.0",
"polymer": "Polymer/polymer#^1.0.0"
},
"devDependencies": {

View File

@ -12,6 +12,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<link rel="import" href="../iron-behaviors/iron-control-state.html">
<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">
<link rel="import" href="../iron-validatable-behavior/iron-validatable-behavior.html">
<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
<!--
`iron-autogrow-textarea` is an element containing a textarea that grows in height as more
@ -56,6 +57,7 @@ this element's `bind-value` instead for imperative updates.
border: none;
resize: none;
background: inherit;
color: inherit;
/* see comments in template */
width: 100%;
height: 100%;
@ -78,7 +80,6 @@ this element's `bind-value` instead for imperative updates.
autocomplete$="[[autocomplete]]"
autofocus$="[[autofocus]]"
inputmode$="[[inputmode]]"
name$="[[name]]"
placeholder$="[[placeholder]]"
readonly$="[[readonly]]"
required$="[[required]]"
@ -95,6 +96,7 @@ this element's `bind-value` instead for imperative updates.
is: 'iron-autogrow-textarea',
behaviors: [
Polymer.IronFormElementBehavior,
Polymer.IronValidatableBehavior,
Polymer.IronControlState
],
@ -166,6 +168,15 @@ this element's `bind-value` instead for imperative updates.
type: String
},
/**
* The value for this input, same as `bindValue`
*/
value: {
notify: true,
type: String,
computed: '_computeValue(bindValue)'
},
/**
* Bound to the textarea's `placeholder` attribute.
*/
@ -202,11 +213,36 @@ this element's `bind-value` instead for imperative updates.
/**
* Returns the underlying textarea.
* @type HTMLTextAreaElement
*/
get textarea() {
return this.$.textarea;
},
/**
* Returns true if `value` is valid. The validator provided in `validator`
* will be used first, if it exists; otherwise, the `textarea`'s validity
* is used.
* @return {boolean} True if the value is valid.
*/
validate: function() {
// Empty, non-required input is valid.
if (!this.required && this.value == '') {
this.invalid = false;
return true;
}
var valid;
if (this.hasValidator()) {
valid = Polymer.IronValidatableBehavior.validate.call(this, this.value);
} else {
valid = this.$.textarea.validity.valid;
this.invalid = !valid;
}
this.fire('iron-input-validate');
return valid;
},
_update: function() {
this.$.mirror.innerHTML = this._valueForMirror();
@ -261,6 +297,10 @@ this element's `bind-value` instead for imperative updates.
_updateCached: function() {
this.$.mirror.innerHTML = this._constrain(this.tokens);
},
_computeValue: function() {
return this.bindValue;
}
})
</script>

View File

@ -120,6 +120,17 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
});
suite('validation', function() {
test('a required textarea with no text is invalid', function() {
var input = fixture('basic');
input.required = true;
assert.isFalse(input.validate());
input.bindValue = 'batman';
assert.isTrue(input.validate());
});
});
</script>
</body>

View File

@ -23,14 +23,14 @@
"paper-styles": "polymerelements/paper-styles#^1.0.0",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"homepage": "https://github.com/polymerelements/iron-flex-layout",
"homepage": "https://github.com/PolymerElements/iron-flex-layout",
"_release": "1.0.2",
"_resolution": {
"type": "version",
"tag": "v1.0.2",
"commit": "50bcecf40ab23caa7c2cd90030555e00c5ba7154"
},
"_source": "git://github.com/polymerelements/iron-flex-layout.git",
"_source": "git://github.com/PolymerElements/iron-flex-layout.git",
"_target": "^1.0.0",
"_originalSource": "polymerelements/iron-flex-layout"
"_originalSource": "PolymerElements/iron-flex-layout"
}

View File

@ -1,6 +1,6 @@
{
"name": "iron-validatable-behavior",
"version": "1.0.2",
"version": "1.0.3",
"description": "Provides a behavior for an element that validates user input",
"authors": "The Polymer Authors",
"keywords": [
@ -32,11 +32,11 @@
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.2",
"_release": "1.0.3",
"_resolution": {
"type": "version",
"tag": "1.0.2",
"commit": "a4fc340fdb268e274f312dadedd0633b025ac3a4"
"tag": "v1.0.3",
"commit": "714ac9f09f9d7d5f6f792a38bb15970adaacb264"
},
"_source": "git://github.com/PolymerElements/iron-validatable-behavior.git",
"_target": "^1.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "iron-validatable-behavior",
"version": "1.0.2",
"version": "1.0.3",
"description": "Provides a behavior for an element that validates user input",
"authors": "The Polymer Authors",
"keywords": [

View File

@ -91,7 +91,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* @return {boolean} True if `values` is valid.
*/
validate: function(values) {
var valid = this._validator && this._validator.validate(values);
var valid = true;
if (this.hasValidator()) {
valid = this._validator.validate(values);
}
this.invalid = !valid;
return valid;
}

View File

@ -45,6 +45,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
assert.isFalse(node.hasAttribute('aria-invalid'), 'aria-invalid is unset');
});
test('validate() is true if a validator isn\'t set', function() {
var node = fixture('basic');
var valid = node.validate();
assert.isTrue(valid);
});
});
</script>

View File

@ -0,0 +1,43 @@
{
"name": "jstree",
"version": "3.1.1",
"main": [
"./dist/jstree.js",
"./dist/themes/default/style.css"
],
"ignore": [
"**/.*",
"docs",
"demo",
"libs",
"node_modules",
"test",
"libs",
"jstree.jquery.json",
"gruntfile.js",
"package.json",
"bower.json",
"component.json",
"LICENCE-MIT",
"README.md"
],
"dependencies": {
"jquery": ">=1.9.1"
},
"keywords": [
"ui",
"tree",
"jstree"
],
"homepage": "https://github.com/vakata/jstree",
"_release": "3.1.1",
"_resolution": {
"type": "version",
"tag": "3.1.1",
"commit": "5bece5844889b6eec71ae794824578aac2136461"
},
"_source": "git://github.com/vakata/jstree.git",
"_target": "~3.1.1",
"_originalSource": "jstree",
"_direct": true
}

View File

@ -0,0 +1,22 @@
Copyright (c) 2014 Ivan Bozhanov
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.

View File

@ -0,0 +1,32 @@
{
"name": "jstree",
"version": "3.1.1",
"main" : [
"./dist/jstree.js",
"./dist/themes/default/style.css"
],
"ignore": [
"**/.*",
"docs",
"demo",
"libs",
"node_modules",
"test",
"libs",
"jstree.jquery.json",
"gruntfile.js",
"package.json",
"bower.json",
"component.json",
"LICENCE-MIT",
"README.md"
],
"dependencies": {
"jquery": ">=1.9.1"
},
"keywords": [
"ui",
"tree",
"jstree"
]
}

View File

@ -0,0 +1,44 @@
{
"name": "vakata/jstree",
"description": "jsTree is jquery plugin, that provides interactive trees.",
"type": "component",
"homepage": "http://jstree.com",
"license": "MIT",
"support": {
"issues": "https://github.com/vakata/jstree/issues",
"forum": "https://groups.google.com/forum/#!forum/jstree",
"source": "https://github.com/vakata/jstree"
},
"authors": [
{
"name": "Ivan Bozhanov",
"email": "jstree@jstree.com"
}
],
"require": {
"robloach/component-installer": "*",
"components/jquery": ">=1.9.1"
},
"extra": {
"component": {
"scripts": [
"dist/jstree.js"
],
"styles": [
"dist/themes/default/style.css"
],
"images": [
"dist/themes/default/32px.png",
"dist/themes/default/40px.png",
"dist/themes/default/throbber.gif"
],
"files": [
"dist/jstree.min.js",
"dist/themes/default/style.min.css",
"dist/themes/default/32px.png",
"dist/themes/default/40px.png",
"dist/themes/default/throbber.gif"
]
}
}
}

View File

@ -0,0 +1,14 @@
/*globals jQuery, define, exports, require, window, document, postMessage */
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'));
}
else {
factory(jQuery);
}
}(function ($, undefined) {
"use strict";

View File

@ -0,0 +1,764 @@
/**
* ### Checkbox plugin
*
* This plugin renders checkbox icons in front of each node, making multiple selection much easier.
* It also supports tri-state behavior, meaning that if a node has a few of its children checked it will be rendered as undetermined, and state will be propagated up.
*/
/*globals jQuery, define, exports, require, document */
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define('jstree.checkbox', ['jquery','jstree'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'), require('jstree'));
}
else {
factory(jQuery, jQuery.jstree);
}
}(function ($, jstree, undefined) {
"use strict";
if($.jstree.plugins.checkbox) { return; }
var _i = document.createElement('I');
_i.className = 'jstree-icon jstree-checkbox';
_i.setAttribute('role', 'presentation');
/**
* stores all defaults for the checkbox plugin
* @name $.jstree.defaults.checkbox
* @plugin checkbox
*/
$.jstree.defaults.checkbox = {
/**
* a boolean indicating if checkboxes should be visible (can be changed at a later time using `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`.
* @name $.jstree.defaults.checkbox.visible
* @plugin checkbox
*/
visible : true,
/**
* a boolean indicating if checkboxes should cascade down and have an undetermined state. Defaults to `true`.
* @name $.jstree.defaults.checkbox.three_state
* @plugin checkbox
*/
three_state : true,
/**
* a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`.
* @name $.jstree.defaults.checkbox.whole_node
* @plugin checkbox
*/
whole_node : true,
/**
* a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`.
* @name $.jstree.defaults.checkbox.keep_selected_style
* @plugin checkbox
*/
keep_selected_style : true,
/**
* This setting controls how cascading and undetermined nodes are applied.
* If 'up' is in the string - cascading up is enabled, if 'down' is in the string - cascading down is enabled, if 'undetermined' is in the string - undetermined nodes will be used.
* If `three_state` is set to `true` this setting is automatically set to 'up+down+undetermined'. Defaults to ''.
* @name $.jstree.defaults.checkbox.cascade
* @plugin checkbox
*/
cascade : '',
/**
* This setting controls if checkbox are bound to the general tree selection or to an internal array maintained by the checkbox plugin. Defaults to `true`, only set to `false` if you know exactly what you are doing.
* @name $.jstree.defaults.checkbox.tie_selection
* @plugin checkbox
*/
tie_selection : true
};
$.jstree.plugins.checkbox = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
this._data.checkbox.uto = false;
this._data.checkbox.selected = [];
if(this.settings.checkbox.three_state) {
this.settings.checkbox.cascade = 'up+down+undetermined';
}
this.element
.on("init.jstree", $.proxy(function () {
this._data.checkbox.visible = this.settings.checkbox.visible;
if(!this.settings.checkbox.keep_selected_style) {
this.element.addClass('jstree-checkbox-no-clicked');
}
if(this.settings.checkbox.tie_selection) {
this.element.addClass('jstree-checkbox-selection');
}
}, this))
.on("loading.jstree", $.proxy(function () {
this[ this._data.checkbox.visible ? 'show_checkboxes' : 'hide_checkboxes' ]();
}, this));
if(this.settings.checkbox.cascade.indexOf('undetermined') !== -1) {
this.element
.on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree', $.proxy(function () {
// only if undetermined is in setting
if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }
this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50);
}, this));
}
if(!this.settings.checkbox.tie_selection) {
this.element
.on('model.jstree', $.proxy(function (e, data) {
var m = this._model.data,
p = m[data.parent],
dpc = data.nodes,
i, j;
for(i = 0, j = dpc.length; i < j; i++) {
m[dpc[i]].state.checked = (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked);
if(m[dpc[i]].state.checked) {
this._data.checkbox.selected.push(dpc[i]);
}
}
}, this));
}
if(this.settings.checkbox.cascade.indexOf('up') !== -1 || this.settings.checkbox.cascade.indexOf('down') !== -1) {
this.element
.on('model.jstree', $.proxy(function (e, data) {
var m = this._model.data,
p = m[data.parent],
dpc = data.nodes,
chd = [],
c, i, j, k, l, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;
if(s.indexOf('down') !== -1) {
// apply down
if(p.state[ t ? 'selected' : 'checked' ]) {
for(i = 0, j = dpc.length; i < j; i++) {
m[dpc[i]].state[ t ? 'selected' : 'checked' ] = true;
}
this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(dpc);
}
else {
for(i = 0, j = dpc.length; i < j; i++) {
if(m[dpc[i]].state[ t ? 'selected' : 'checked' ]) {
for(k = 0, l = m[dpc[i]].children_d.length; k < l; k++) {
m[m[dpc[i]].children_d[k]].state[ t ? 'selected' : 'checked' ] = true;
}
this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(m[dpc[i]].children_d);
}
}
}
}
if(s.indexOf('up') !== -1) {
// apply up
for(i = 0, j = p.children_d.length; i < j; i++) {
if(!m[p.children_d[i]].children.length) {
chd.push(m[p.children_d[i]].parent);
}
}
chd = $.vakata.array_unique(chd);
for(k = 0, l = chd.length; k < l; k++) {
p = m[chd[k]];
while(p && p.id !== '#') {
c = 0;
for(i = 0, j = p.children.length; i < j; i++) {
c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
}
if(c === j) {
p.state[ t ? 'selected' : 'checked' ] = true;
this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
tmp = this.get_node(p, true);
if(tmp && tmp.length) {
tmp.attr('aria-selected', true).children('.jstree-anchor').addClass( t ? 'jstree-clicked' : 'jstree-checked');
}
}
else {
break;
}
p = this.get_node(p.parent);
}
}
}
this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected);
}, this))
.on(this.settings.checkbox.tie_selection ? 'select_node.jstree' : 'check_node.jstree', $.proxy(function (e, data) {
var obj = data.node,
m = this._model.data,
par = this.get_node(obj.parent),
dom = this.get_node(obj, true),
i, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;
// apply down
if(s.indexOf('down') !== -1) {
this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d));
for(i = 0, j = obj.children_d.length; i < j; i++) {
tmp = m[obj.children_d[i]];
tmp.state[ t ? 'selected' : 'checked' ] = true;
if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
tmp.original.state.undetermined = false;
}
}
}
// apply up
if(s.indexOf('up') !== -1) {
while(par && par.id !== '#') {
c = 0;
for(i = 0, j = par.children.length; i < j; i++) {
c += m[par.children[i]].state[ t ? 'selected' : 'checked' ];
}
if(c === j) {
par.state[ t ? 'selected' : 'checked' ] = true;
this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id);
tmp = this.get_node(par, true);
if(tmp && tmp.length) {
tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
}
}
else {
break;
}
par = this.get_node(par.parent);
}
}
// apply down (process .children separately?)
if(s.indexOf('down') !== -1 && dom.length) {
dom.find('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', true);
}
}, this))
.on(this.settings.checkbox.tie_selection ? 'deselect_all.jstree' : 'uncheck_all.jstree', $.proxy(function (e, data) {
var obj = this.get_node('#'),
m = this._model.data,
i, j, tmp;
for(i = 0, j = obj.children_d.length; i < j; i++) {
tmp = m[obj.children_d[i]];
if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
tmp.original.state.undetermined = false;
}
}
}, this))
.on(this.settings.checkbox.tie_selection ? 'deselect_node.jstree' : 'uncheck_node.jstree', $.proxy(function (e, data) {
var obj = data.node,
dom = this.get_node(obj, true),
i, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;
if(obj && obj.original && obj.original.state && obj.original.state.undetermined) {
obj.original.state.undetermined = false;
}
// apply down
if(s.indexOf('down') !== -1) {
for(i = 0, j = obj.children_d.length; i < j; i++) {
tmp = this._model.data[obj.children_d[i]];
tmp.state[ t ? 'selected' : 'checked' ] = false;
if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
tmp.original.state.undetermined = false;
}
}
}
// apply up
if(s.indexOf('up') !== -1) {
for(i = 0, j = obj.parents.length; i < j; i++) {
tmp = this._model.data[obj.parents[i]];
tmp.state[ t ? 'selected' : 'checked' ] = false;
if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
tmp.original.state.undetermined = false;
}
tmp = this.get_node(obj.parents[i], true);
if(tmp && tmp.length) {
tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked');
}
}
}
tmp = [];
for(i = 0, j = this._data[ t ? 'core' : 'checkbox' ].selected.length; i < j; i++) {
// apply down + apply up
if(
(s.indexOf('down') === -1 || $.inArray(this._data[ t ? 'core' : 'checkbox' ].selected[i], obj.children_d) === -1) &&
(s.indexOf('up') === -1 || $.inArray(this._data[ t ? 'core' : 'checkbox' ].selected[i], obj.parents) === -1)
) {
tmp.push(this._data[ t ? 'core' : 'checkbox' ].selected[i]);
}
}
this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(tmp);
// apply down (process .children separately?)
if(s.indexOf('down') !== -1 && dom.length) {
dom.find('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked').parent().attr('aria-selected', false);
}
}, this));
}
if(this.settings.checkbox.cascade.indexOf('up') !== -1) {
this.element
.on('delete_node.jstree', $.proxy(function (e, data) {
// apply up (whole handler)
var p = this.get_node(data.parent),
m = this._model.data,
i, j, c, tmp, t = this.settings.checkbox.tie_selection;
while(p && p.id !== '#') {
c = 0;
for(i = 0, j = p.children.length; i < j; i++) {
c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
}
if(c === j) {
p.state[ t ? 'selected' : 'checked' ] = true;
this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
tmp = this.get_node(p, true);
if(tmp && tmp.length) {
tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
}
}
else {
break;
}
p = this.get_node(p.parent);
}
}, this))
.on('move_node.jstree', $.proxy(function (e, data) {
// apply up (whole handler)
var is_multi = data.is_multi,
old_par = data.old_parent,
new_par = this.get_node(data.parent),
m = this._model.data,
p, c, i, j, tmp, t = this.settings.checkbox.tie_selection;
if(!is_multi) {
p = this.get_node(old_par);
while(p && p.id !== '#') {
c = 0;
for(i = 0, j = p.children.length; i < j; i++) {
c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
}
if(c === j) {
p.state[ t ? 'selected' : 'checked' ] = true;
this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
tmp = this.get_node(p, true);
if(tmp && tmp.length) {
tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
}
}
else {
break;
}
p = this.get_node(p.parent);
}
}
p = new_par;
while(p && p.id !== '#') {
c = 0;
for(i = 0, j = p.children.length; i < j; i++) {
c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
}
if(c === j) {
if(!p.state[ t ? 'selected' : 'checked' ]) {
p.state[ t ? 'selected' : 'checked' ] = true;
this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
tmp = this.get_node(p, true);
if(tmp && tmp.length) {
tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
}
}
}
else {
if(p.state[ t ? 'selected' : 'checked' ]) {
p.state[ t ? 'selected' : 'checked' ] = false;
this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_remove_item(this._data[ t ? 'core' : 'checkbox' ].selected, p.id);
tmp = this.get_node(p, true);
if(tmp && tmp.length) {
tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked');
}
}
else {
break;
}
}
p = this.get_node(p.parent);
}
}, this));
}
};
/**
* set the undetermined state where and if necessary. Used internally.
* @private
* @name _undetermined()
* @plugin checkbox
*/
this._undetermined = function () {
if(this.element === null) { return; }
var i, j, k, l, o = {}, m = this._model.data, t = this.settings.checkbox.tie_selection, s = this._data[ t ? 'core' : 'checkbox' ].selected, p = [], tt = this;
for(i = 0, j = s.length; i < j; i++) {
if(m[s[i]] && m[s[i]].parents) {
for(k = 0, l = m[s[i]].parents.length; k < l; k++) {
if(o[m[s[i]].parents[k]] === undefined && m[s[i]].parents[k] !== '#') {
o[m[s[i]].parents[k]] = true;
p.push(m[s[i]].parents[k]);
}
}
}
}
// attempt for server side undetermined state
this.element.find('.jstree-closed').not(':has(.jstree-children)')
.each(function () {
var tmp = tt.get_node(this), tmp2;
if(!tmp.state.loaded) {
if(tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) {
if(o[tmp.id] === undefined && tmp.id !== '#') {
o[tmp.id] = true;
p.push(tmp.id);
}
for(k = 0, l = tmp.parents.length; k < l; k++) {
if(o[tmp.parents[k]] === undefined && tmp.parents[k] !== '#') {
o[tmp.parents[k]] = true;
p.push(tmp.parents[k]);
}
}
}
}
else {
for(i = 0, j = tmp.children_d.length; i < j; i++) {
tmp2 = m[tmp.children_d[i]];
if(!tmp2.state.loaded && tmp2.original && tmp2.original.state && tmp2.original.state.undetermined && tmp2.original.state.undetermined === true) {
if(o[tmp2.id] === undefined && tmp2.id !== '#') {
o[tmp2.id] = true;
p.push(tmp2.id);
}
for(k = 0, l = tmp2.parents.length; k < l; k++) {
if(o[tmp2.parents[k]] === undefined && tmp2.parents[k] !== '#') {
o[tmp2.parents[k]] = true;
p.push(tmp2.parents[k]);
}
}
}
}
}
});
this.element.find('.jstree-undetermined').removeClass('jstree-undetermined');
for(i = 0, j = p.length; i < j; i++) {
if(!m[p[i]].state[ t ? 'selected' : 'checked' ]) {
s = this.get_node(p[i], true);
if(s && s.length) {
s.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-undetermined');
}
}
}
};
this.redraw_node = function(obj, deep, is_callback, force_render) {
obj = parent.redraw_node.apply(this, arguments);
if(obj) {
var i, j, tmp = null;
for(i = 0, j = obj.childNodes.length; i < j; i++) {
if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
tmp = obj.childNodes[i];
break;
}
}
if(tmp) {
if(!this.settings.checkbox.tie_selection && this._model.data[obj.id].state.checked) { tmp.className += ' jstree-checked'; }
tmp.insertBefore(_i.cloneNode(false), tmp.childNodes[0]);
}
}
if(!is_callback && this.settings.checkbox.cascade.indexOf('undetermined') !== -1) {
if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }
this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50);
}
return obj;
};
/**
* show the node checkbox icons
* @name show_checkboxes()
* @plugin checkbox
*/
this.show_checkboxes = function () { this._data.core.themes.checkboxes = true; this.get_container_ul().removeClass("jstree-no-checkboxes"); };
/**
* hide the node checkbox icons
* @name hide_checkboxes()
* @plugin checkbox
*/
this.hide_checkboxes = function () { this._data.core.themes.checkboxes = false; this.get_container_ul().addClass("jstree-no-checkboxes"); };
/**
* toggle the node icons
* @name toggle_checkboxes()
* @plugin checkbox
*/
this.toggle_checkboxes = function () { if(this._data.core.themes.checkboxes) { this.hide_checkboxes(); } else { this.show_checkboxes(); } };
/**
* checks if a node is in an undetermined state
* @name is_undetermined(obj)
* @param {mixed} obj
* @return {Boolean}
*/
this.is_undetermined = function (obj) {
obj = this.get_node(obj);
var s = this.settings.checkbox.cascade, i, j, t = this.settings.checkbox.tie_selection, d = this._data[ t ? 'core' : 'checkbox' ].selected, m = this._model.data;
if(!obj || obj.state[ t ? 'selected' : 'checked' ] === true || s.indexOf('undetermined') === -1 || (s.indexOf('down') === -1 && s.indexOf('up') === -1)) {
return false;
}
if(!obj.state.loaded && obj.original.state.undetermined === true) {
return true;
}
for(i = 0, j = obj.children_d.length; i < j; i++) {
if($.inArray(obj.children_d[i], d) !== -1 || (!m[obj.children_d[i]].state.loaded && m[obj.children_d[i]].original.state.undetermined)) {
return true;
}
}
return false;
};
this.activate_node = function (obj, e) {
if(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) {
e.ctrlKey = true;
}
if(this.settings.checkbox.tie_selection || (!this.settings.checkbox.whole_node && !$(e.target).hasClass('jstree-checkbox'))) {
return parent.activate_node.call(this, obj, e);
}
if(this.is_disabled(obj)) {
return false;
}
if(this.is_checked(obj)) {
this.uncheck_node(obj, e);
}
else {
this.check_node(obj, e);
}
this.trigger('activate_node', { 'node' : this.get_node(obj) });
};
/**
* check a node (only if tie_selection in checkbox settings is false, otherwise select_node will be called internally)
* @name check_node(obj)
* @param {mixed} obj an array can be used to check multiple nodes
* @trigger check_node.jstree
* @plugin checkbox
*/
this.check_node = function (obj, e) {
if(this.settings.checkbox.tie_selection) { return this.select_node(obj, false, true, e); }
var dom, t1, t2, th;
if($.isArray(obj)) {
obj = obj.slice();
for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
this.check_node(obj[t1], e);
}
return true;
}
obj = this.get_node(obj);
if(!obj || obj.id === '#') {
return false;
}
dom = this.get_node(obj, true);
if(!obj.state.checked) {
obj.state.checked = true;
this._data.checkbox.selected.push(obj.id);
if(dom && dom.length) {
dom.children('.jstree-anchor').addClass('jstree-checked');
}
/**
* triggered when an node is checked (only if tie_selection in checkbox settings is false)
* @event
* @name check_node.jstree
* @param {Object} node
* @param {Array} selected the current selection
* @param {Object} event the event (if any) that triggered this check_node
* @plugin checkbox
*/
this.trigger('check_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e });
}
};
/**
* uncheck a node (only if tie_selection in checkbox settings is false, otherwise deselect_node will be called internally)
* @name uncheck_node(obj)
* @param {mixed} obj an array can be used to uncheck multiple nodes
* @trigger uncheck_node.jstree
* @plugin checkbox
*/
this.uncheck_node = function (obj, e) {
if(this.settings.checkbox.tie_selection) { return this.deselect_node(obj, false, e); }
var t1, t2, dom;
if($.isArray(obj)) {
obj = obj.slice();
for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
this.uncheck_node(obj[t1], e);
}
return true;
}
obj = this.get_node(obj);
if(!obj || obj.id === '#') {
return false;
}
dom = this.get_node(obj, true);
if(obj.state.checked) {
obj.state.checked = false;
this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, obj.id);
if(dom.length) {
dom.children('.jstree-anchor').removeClass('jstree-checked');
}
/**
* triggered when an node is unchecked (only if tie_selection in checkbox settings is false)
* @event
* @name uncheck_node.jstree
* @param {Object} node
* @param {Array} selected the current selection
* @param {Object} event the event (if any) that triggered this uncheck_node
* @plugin checkbox
*/
this.trigger('uncheck_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e });
}
};
/**
* checks all nodes in the tree (only if tie_selection in checkbox settings is false, otherwise select_all will be called internally)
* @name check_all()
* @trigger check_all.jstree, changed.jstree
* @plugin checkbox
*/
this.check_all = function () {
if(this.settings.checkbox.tie_selection) { return this.select_all(); }
var tmp = this._data.checkbox.selected.concat([]), i, j;
this._data.checkbox.selected = this._model.data['#'].children_d.concat();
for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) {
if(this._model.data[this._data.checkbox.selected[i]]) {
this._model.data[this._data.checkbox.selected[i]].state.checked = true;
}
}
this.redraw(true);
/**
* triggered when all nodes are checked (only if tie_selection in checkbox settings is false)
* @event
* @name check_all.jstree
* @param {Array} selected the current selection
* @plugin checkbox
*/
this.trigger('check_all', { 'selected' : this._data.checkbox.selected });
};
/**
* uncheck all checked nodes (only if tie_selection in checkbox settings is false, otherwise deselect_all will be called internally)
* @name uncheck_all()
* @trigger uncheck_all.jstree
* @plugin checkbox
*/
this.uncheck_all = function () {
if(this.settings.checkbox.tie_selection) { return this.deselect_all(); }
var tmp = this._data.checkbox.selected.concat([]), i, j;
for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) {
if(this._model.data[this._data.checkbox.selected[i]]) {
this._model.data[this._data.checkbox.selected[i]].state.checked = false;
}
}
this._data.checkbox.selected = [];
this.element.find('.jstree-checked').removeClass('jstree-checked');
/**
* triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false)
* @event
* @name uncheck_all.jstree
* @param {Object} node the previous selection
* @param {Array} selected the current selection
* @plugin checkbox
*/
this.trigger('uncheck_all', { 'selected' : this._data.checkbox.selected, 'node' : tmp });
};
/**
* checks if a node is checked (if tie_selection is on in the settings this function will return the same as is_selected)
* @name is_checked(obj)
* @param {mixed} obj
* @return {Boolean}
* @plugin checkbox
*/
this.is_checked = function (obj) {
if(this.settings.checkbox.tie_selection) { return this.is_selected(obj); }
obj = this.get_node(obj);
if(!obj || obj.id === '#') { return false; }
return obj.state.checked;
};
/**
* get an array of all checked nodes (if tie_selection is on in the settings this function will return the same as get_selected)
* @name get_checked([full])
* @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
* @return {Array}
* @plugin checkbox
*/
this.get_checked = function (full) {
if(this.settings.checkbox.tie_selection) { return this.get_selected(full); }
return full ? $.map(this._data.checkbox.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.checkbox.selected;
};
/**
* get an array of all top level checked nodes (ignoring children of checked nodes) (if tie_selection is on in the settings this function will return the same as get_top_selected)
* @name get_top_checked([full])
* @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
* @return {Array}
* @plugin checkbox
*/
this.get_top_checked = function (full) {
if(this.settings.checkbox.tie_selection) { return this.get_top_selected(full); }
var tmp = this.get_checked(true),
obj = {}, i, j, k, l;
for(i = 0, j = tmp.length; i < j; i++) {
obj[tmp[i].id] = tmp[i];
}
for(i = 0, j = tmp.length; i < j; i++) {
for(k = 0, l = tmp[i].children_d.length; k < l; k++) {
if(obj[tmp[i].children_d[k]]) {
delete obj[tmp[i].children_d[k]];
}
}
}
tmp = [];
for(i in obj) {
if(obj.hasOwnProperty(i)) {
tmp.push(i);
}
}
return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp;
};
/**
* get an array of all bottom level checked nodes (ignoring selected parents) (if tie_selection is on in the settings this function will return the same as get_bottom_selected)
* @name get_bottom_checked([full])
* @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
* @return {Array}
* @plugin checkbox
*/
this.get_bottom_checked = function (full) {
if(this.settings.checkbox.tie_selection) { return this.get_bottom_selected(full); }
var tmp = this.get_checked(true),
obj = [], i, j;
for(i = 0, j = tmp.length; i < j; i++) {
if(!tmp[i].children.length) {
obj.push(tmp[i].id);
}
}
return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj;
};
this.load_node = function (obj, callback) {
var k, l, i, j, c, tmp;
if(!$.isArray(obj) && !this.settings.checkbox.tie_selection) {
tmp = this.get_node(obj);
if(tmp && tmp.state.loaded) {
for(k = 0, l = tmp.children_d.length; k < l; k++) {
if(this._model.data[tmp.children_d[k]].state.checked) {
c = true;
this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, tmp.children_d[k]);
}
}
}
}
return parent.load_node.apply(this, arguments);
};
this.get_state = function () {
var state = parent.get_state.apply(this, arguments);
if(this.settings.checkbox.tie_selection) { return state; }
state.checkbox = this._data.checkbox.selected.slice();
return state;
};
this.set_state = function (state, callback) {
var res = parent.set_state.apply(this, arguments);
if(res && state.checkbox) {
if(!this.settings.checkbox.tie_selection) {
this.uncheck_all();
var _this = this;
$.each(state.checkbox, function (i, v) {
_this.check_node(v);
});
}
delete state.checkbox;
this.set_state(state, callback);
return false;
}
return res;
};
};
// include the checkbox plugin by default
// $.jstree.defaults.plugins.push("checkbox");
}));

View File

@ -0,0 +1,631 @@
/**
* ### Contextmenu plugin
*
* Shows a context menu when a node is right-clicked.
*/
/*globals jQuery, define, exports, require, document */
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define('jstree.contextmenu', ['jquery','jstree'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'), require('jstree'));
}
else {
factory(jQuery, jQuery.jstree);
}
}(function ($, jstree, undefined) {
"use strict";
if($.jstree.plugins.contextmenu) { return; }
/**
* stores all defaults for the contextmenu plugin
* @name $.jstree.defaults.contextmenu
* @plugin contextmenu
*/
$.jstree.defaults.contextmenu = {
/**
* a boolean indicating if the node should be selected when the context menu is invoked on it. Defaults to `true`.
* @name $.jstree.defaults.contextmenu.select_node
* @plugin contextmenu
*/
select_node : true,
/**
* a boolean indicating if the menu should be shown aligned with the node. Defaults to `true`, otherwise the mouse coordinates are used.
* @name $.jstree.defaults.contextmenu.show_at_node
* @plugin contextmenu
*/
show_at_node : true,
/**
* an object of actions, or a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too).
*
* Each action consists of a key (a unique name) and a value which is an object with the following properties (only label and action are required):
*
* * `separator_before` - a boolean indicating if there should be a separator before this item
* * `separator_after` - a boolean indicating if there should be a separator after this item
* * `_disabled` - a boolean indicating if this action should be disabled
* * `label` - a string - the name of the action (could be a function returning a string)
* * `action` - a function to be executed if this item is chosen
* * `icon` - a string, can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class
* * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2)
* * `shortcut_label` - shortcut label (like for example `F2` for rename)
*
* @name $.jstree.defaults.contextmenu.items
* @plugin contextmenu
*/
items : function (o, cb) { // Could be an object directly
return {
"create" : {
"separator_before" : false,
"separator_after" : true,
"_disabled" : false, //(this.check("create_node", data.reference, {}, "last")),
"label" : "Create",
"action" : function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
inst.create_node(obj, {}, "last", function (new_node) {
setTimeout(function () { inst.edit(new_node); },0);
});
}
},
"rename" : {
"separator_before" : false,
"separator_after" : false,
"_disabled" : false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")),
"label" : "Rename",
/*
"shortcut" : 113,
"shortcut_label" : 'F2',
"icon" : "glyphicon glyphicon-leaf",
*/
"action" : function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
inst.edit(obj);
}
},
"remove" : {
"separator_before" : false,
"icon" : false,
"separator_after" : false,
"_disabled" : false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")),
"label" : "Delete",
"action" : function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
if(inst.is_selected(obj)) {
inst.delete_node(inst.get_selected());
}
else {
inst.delete_node(obj);
}
}
},
"ccp" : {
"separator_before" : true,
"icon" : false,
"separator_after" : false,
"label" : "Edit",
"action" : false,
"submenu" : {
"cut" : {
"separator_before" : false,
"separator_after" : false,
"label" : "Cut",
"action" : function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
if(inst.is_selected(obj)) {
inst.cut(inst.get_top_selected());
}
else {
inst.cut(obj);
}
}
},
"copy" : {
"separator_before" : false,
"icon" : false,
"separator_after" : false,
"label" : "Copy",
"action" : function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
if(inst.is_selected(obj)) {
inst.copy(inst.get_top_selected());
}
else {
inst.copy(obj);
}
}
},
"paste" : {
"separator_before" : false,
"icon" : false,
"_disabled" : function (data) {
return !$.jstree.reference(data.reference).can_paste();
},
"separator_after" : false,
"label" : "Paste",
"action" : function (data) {
var inst = $.jstree.reference(data.reference),
obj = inst.get_node(data.reference);
inst.paste(obj);
}
}
}
}
};
}
};
$.jstree.plugins.contextmenu = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
var last_ts = 0, cto = null, ex, ey;
this.element
.on("contextmenu.jstree", ".jstree-anchor", $.proxy(function (e, data) {
e.preventDefault();
last_ts = e.ctrlKey ? +new Date() : 0;
if(data || cto) {
last_ts = (+new Date()) + 10000;
}
if(cto) {
clearTimeout(cto);
}
if(!this.is_loading(e.currentTarget)) {
this.show_contextmenu(e.currentTarget, e.pageX, e.pageY, e);
}
}, this))
.on("click.jstree", ".jstree-anchor", $.proxy(function (e) {
if(this._data.contextmenu.visible && (!last_ts || (+new Date()) - last_ts > 250)) { // work around safari & macOS ctrl+click
$.vakata.context.hide();
}
last_ts = 0;
}, this))
.on("touchstart.jstree", ".jstree-anchor", function (e) {
if(!e.originalEvent || !e.originalEvent.changedTouches || !e.originalEvent.changedTouches[0]) {
return;
}
ex = e.pageX;
ey = e.pageY;
cto = setTimeout(function () {
$(e.currentTarget).trigger('contextmenu', true);
}, 750);
})
.on('touchmove.vakata.jstree', function (e) {
if(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.pageX) > 50 || Math.abs(ey - e.pageY) > 50)) {
clearTimeout(cto);
}
})
.on('touchend.vakata.jstree', function (e) {
if(cto) {
clearTimeout(cto);
}
});
/*
if(!('oncontextmenu' in document.body) && ('ontouchstart' in document.body)) {
var el = null, tm = null;
this.element
.on("touchstart", ".jstree-anchor", function (e) {
el = e.currentTarget;
tm = +new Date();
$(document).one("touchend", function (e) {
e.target = document.elementFromPoint(e.originalEvent.targetTouches[0].pageX - window.pageXOffset, e.originalEvent.targetTouches[0].pageY - window.pageYOffset);
e.currentTarget = e.target;
tm = ((+(new Date())) - tm);
if(e.target === el && tm > 600 && tm < 1000) {
e.preventDefault();
$(el).trigger('contextmenu', e);
}
el = null;
tm = null;
});
});
}
*/
$(document).on("context_hide.vakata.jstree", $.proxy(function () { this._data.contextmenu.visible = false; }, this));
};
this.teardown = function () {
if(this._data.contextmenu.visible) {
$.vakata.context.hide();
}
parent.teardown.call(this);
};
/**
* prepare and show the context menu for a node
* @name show_contextmenu(obj [, x, y])
* @param {mixed} obj the node
* @param {Number} x the x-coordinate relative to the document to show the menu at
* @param {Number} y the y-coordinate relative to the document to show the menu at
* @param {Object} e the event if available that triggered the contextmenu
* @plugin contextmenu
* @trigger show_contextmenu.jstree
*/
this.show_contextmenu = function (obj, x, y, e) {
obj = this.get_node(obj);
if(!obj || obj.id === '#') { return false; }
var s = this.settings.contextmenu,
d = this.get_node(obj, true),
a = d.children(".jstree-anchor"),
o = false,
i = false;
if(s.show_at_node || x === undefined || y === undefined) {
o = a.offset();
x = o.left;
y = o.top + this._data.core.li_height;
}
if(this.settings.contextmenu.select_node && !this.is_selected(obj)) {
this.activate_node(obj, e);
}
i = s.items;
if($.isFunction(i)) {
i = i.call(this, obj, $.proxy(function (i) {
this._show_contextmenu(obj, x, y, i);
}, this));
}
if($.isPlainObject(i)) {
this._show_contextmenu(obj, x, y, i);
}
};
/**
* show the prepared context menu for a node
* @name _show_contextmenu(obj, x, y, i)
* @param {mixed} obj the node
* @param {Number} x the x-coordinate relative to the document to show the menu at
* @param {Number} y the y-coordinate relative to the document to show the menu at
* @param {Number} i the object of items to show
* @plugin contextmenu
* @trigger show_contextmenu.jstree
* @private
*/
this._show_contextmenu = function (obj, x, y, i) {
var d = this.get_node(obj, true),
a = d.children(".jstree-anchor");
$(document).one("context_show.vakata.jstree", $.proxy(function (e, data) {
var cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu';
$(data.element).addClass(cls);
}, this));
this._data.contextmenu.visible = true;
$.vakata.context.show(a, { 'x' : x, 'y' : y }, i);
/**
* triggered when the contextmenu is shown for a node
* @event
* @name show_contextmenu.jstree
* @param {Object} node the node
* @param {Number} x the x-coordinate of the menu relative to the document
* @param {Number} y the y-coordinate of the menu relative to the document
* @plugin contextmenu
*/
this.trigger('show_contextmenu', { "node" : obj, "x" : x, "y" : y });
};
};
// contextmenu helper
(function ($) {
var right_to_left = false,
vakata_context = {
element : false,
reference : false,
position_x : 0,
position_y : 0,
items : [],
html : "",
is_visible : false
};
$.vakata.context = {
settings : {
hide_onmouseleave : 0,
icons : true
},
_trigger : function (event_name) {
$(document).triggerHandler("context_" + event_name + ".vakata", {
"reference" : vakata_context.reference,
"element" : vakata_context.element,
"position" : {
"x" : vakata_context.position_x,
"y" : vakata_context.position_y
}
});
},
_execute : function (i) {
i = vakata_context.items[i];
return i && (!i._disabled || ($.isFunction(i._disabled) && !i._disabled({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }))) && i.action ? i.action.call(null, {
"item" : i,
"reference" : vakata_context.reference,
"element" : vakata_context.element,
"position" : {
"x" : vakata_context.position_x,
"y" : vakata_context.position_y
}
}) : false;
},
_parse : function (o, is_callback) {
if(!o) { return false; }
if(!is_callback) {
vakata_context.html = "";
vakata_context.items = [];
}
var str = "",
sep = false,
tmp;
if(is_callback) { str += "<"+"ul>"; }
$.each(o, function (i, val) {
if(!val) { return true; }
vakata_context.items.push(val);
if(!sep && val.separator_before) {
str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + ">&#160;<"+"/a><"+"/li>";
}
sep = false;
str += "<"+"li class='" + (val._class || "") + (val._disabled === true || ($.isFunction(val._disabled) && val._disabled({ "item" : val, "reference" : vakata_context.reference, "element" : vakata_context.element })) ? " vakata-contextmenu-disabled " : "") + "' "+(val.shortcut?" data-shortcut='"+val.shortcut+"' ":'')+">";
str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "'>";
if($.vakata.context.settings.icons) {
str += "<"+"i ";
if(val.icon) {
if(val.icon.indexOf("/") !== -1 || val.icon.indexOf(".") !== -1) { str += " style='background:url(\"" + val.icon + "\") center center no-repeat' "; }
else { str += " class='" + val.icon + "' "; }
}
str += "><"+"/i><"+"span class='vakata-contextmenu-sep'>&#160;<"+"/span>";
}
str += ($.isFunction(val.label) ? val.label({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }) : val.label) + (val.shortcut?' <span class="vakata-contextmenu-shortcut vakata-contextmenu-shortcut-'+val.shortcut+'">'+ (val.shortcut_label || '') +'</span>':'') + "<"+"/a>";
if(val.submenu) {
tmp = $.vakata.context._parse(val.submenu, true);
if(tmp) { str += tmp; }
}
str += "<"+"/li>";
if(val.separator_after) {
str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'style="margin-left:0px;"') + ">&#160;<"+"/a><"+"/li>";
sep = true;
}
});
str = str.replace(/<li class\='vakata-context-separator'\><\/li\>$/,"");
if(is_callback) { str += "</ul>"; }
/**
* triggered on the document when the contextmenu is parsed (HTML is built)
* @event
* @plugin contextmenu
* @name context_parse.vakata
* @param {jQuery} reference the element that was right clicked
* @param {jQuery} element the DOM element of the menu itself
* @param {Object} position the x & y coordinates of the menu
*/
if(!is_callback) { vakata_context.html = str; $.vakata.context._trigger("parse"); }
return str.length > 10 ? str : false;
},
_show_submenu : function (o) {
o = $(o);
if(!o.length || !o.children("ul").length) { return; }
var e = o.children("ul"),
x = o.offset().left + o.outerWidth(),
y = o.offset().top,
w = e.width(),
h = e.height(),
dw = $(window).width() + $(window).scrollLeft(),
dh = $(window).height() + $(window).scrollTop();
// може да се спести е една проверка - дали няма някой от класовете вече нагоре
if(right_to_left) {
o[x - (w + 10 + o.outerWidth()) < 0 ? "addClass" : "removeClass"]("vakata-context-left");
}
else {
o[x + w + 10 > dw ? "addClass" : "removeClass"]("vakata-context-right");
}
if(y + h + 10 > dh) {
e.css("bottom","-1px");
}
e.show();
},
show : function (reference, position, data) {
var o, e, x, y, w, h, dw, dh, cond = true;
if(vakata_context.element && vakata_context.element.length) {
vakata_context.element.width('');
}
switch(cond) {
case (!position && !reference):
return false;
case (!!position && !!reference):
vakata_context.reference = reference;
vakata_context.position_x = position.x;
vakata_context.position_y = position.y;
break;
case (!position && !!reference):
vakata_context.reference = reference;
o = reference.offset();
vakata_context.position_x = o.left + reference.outerHeight();
vakata_context.position_y = o.top;
break;
case (!!position && !reference):
vakata_context.position_x = position.x;
vakata_context.position_y = position.y;
break;
}
if(!!reference && !data && $(reference).data('vakata_contextmenu')) {
data = $(reference).data('vakata_contextmenu');
}
if($.vakata.context._parse(data)) {
vakata_context.element.html(vakata_context.html);
}
if(vakata_context.items.length) {
vakata_context.element.appendTo("body");
e = vakata_context.element;
x = vakata_context.position_x;
y = vakata_context.position_y;
w = e.width();
h = e.height();
dw = $(window).width() + $(window).scrollLeft();
dh = $(window).height() + $(window).scrollTop();
if(right_to_left) {
x -= (e.outerWidth() - $(reference).outerWidth());
if(x < $(window).scrollLeft() + 20) {
x = $(window).scrollLeft() + 20;
}
}
if(x + w + 20 > dw) {
x = dw - (w + 20);
}
if(y + h + 20 > dh) {
y = dh - (h + 20);
}
vakata_context.element
.css({ "left" : x, "top" : y })
.show()
.find('a').first().focus().parent().addClass("vakata-context-hover");
vakata_context.is_visible = true;
/**
* triggered on the document when the contextmenu is shown
* @event
* @plugin contextmenu
* @name context_show.vakata
* @param {jQuery} reference the element that was right clicked
* @param {jQuery} element the DOM element of the menu itself
* @param {Object} position the x & y coordinates of the menu
*/
$.vakata.context._trigger("show");
}
},
hide : function () {
if(vakata_context.is_visible) {
vakata_context.element.hide().find("ul").hide().end().find(':focus').blur().end().detach();
vakata_context.is_visible = false;
/**
* triggered on the document when the contextmenu is hidden
* @event
* @plugin contextmenu
* @name context_hide.vakata
* @param {jQuery} reference the element that was right clicked
* @param {jQuery} element the DOM element of the menu itself
* @param {Object} position the x & y coordinates of the menu
*/
$.vakata.context._trigger("hide");
}
}
};
$(function () {
right_to_left = $("body").css("direction") === "rtl";
var to = false;
vakata_context.element = $("<ul class='vakata-context'></ul>");
vakata_context.element
.on("mouseenter", "li", function (e) {
e.stopImmediatePropagation();
if($.contains(this, e.relatedTarget)) {
// премахнато заради delegate mouseleave по-долу
// $(this).find(".vakata-context-hover").removeClass("vakata-context-hover");
return;
}
if(to) { clearTimeout(to); }
vakata_context.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end();
$(this)
.siblings().find("ul").hide().end().end()
.parentsUntil(".vakata-context", "li").addBack().addClass("vakata-context-hover");
$.vakata.context._show_submenu(this);
})
// тестово - дали не натоварва?
.on("mouseleave", "li", function (e) {
if($.contains(this, e.relatedTarget)) { return; }
$(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover");
})
.on("mouseleave", function (e) {
$(this).find(".vakata-context-hover").removeClass("vakata-context-hover");
if($.vakata.context.settings.hide_onmouseleave) {
to = setTimeout(
(function (t) {
return function () { $.vakata.context.hide(); };
}(this)), $.vakata.context.settings.hide_onmouseleave);
}
})
.on("click", "a", function (e) {
e.preventDefault();
//})
//.on("mouseup", "a", function (e) {
if(!$(this).blur().parent().hasClass("vakata-context-disabled") && $.vakata.context._execute($(this).attr("rel")) !== false) {
$.vakata.context.hide();
}
})
.on('keydown', 'a', function (e) {
var o = null;
switch(e.which) {
case 13:
case 32:
e.type = "mouseup";
e.preventDefault();
$(e.currentTarget).trigger(e);
break;
case 37:
if(vakata_context.is_visible) {
vakata_context.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children('a').focus();
e.stopImmediatePropagation();
e.preventDefault();
}
break;
case 38:
if(vakata_context.is_visible) {
o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first();
if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last(); }
o.addClass("vakata-context-hover").children('a').focus();
e.stopImmediatePropagation();
e.preventDefault();
}
break;
case 39:
if(vakata_context.is_visible) {
vakata_context.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children('a').focus();
e.stopImmediatePropagation();
e.preventDefault();
}
break;
case 40:
if(vakata_context.is_visible) {
o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first();
if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first(); }
o.addClass("vakata-context-hover").children('a').focus();
e.stopImmediatePropagation();
e.preventDefault();
}
break;
case 27:
$.vakata.context.hide();
e.preventDefault();
break;
default:
//console.log(e.which);
break;
}
})
.on('keydown', function (e) {
e.preventDefault();
var a = vakata_context.element.find('.vakata-contextmenu-shortcut-' + e.which).parent();
if(a.parent().not('.vakata-context-disabled')) {
a.click();
}
});
$(document)
.on("mousedown.vakata.jstree", function (e) {
if(vakata_context.is_visible && !$.contains(vakata_context.element[0], e.target)) {
$.vakata.context.hide();
}
})
.on("context_show.vakata.jstree", function (e, data) {
vakata_context.element.find("li:has(ul)").children("a").addClass("vakata-context-parent");
if(right_to_left) {
vakata_context.element.addClass("vakata-context-rtl").css("direction", "rtl");
}
// also apply a RTL class?
vakata_context.element.find("ul").hide().end();
});
});
}($));
// $.jstree.defaults.plugins.push("contextmenu");
}));

View File

@ -0,0 +1,545 @@
/**
* ### Drag'n'drop plugin
*
* Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations.
*/
/*globals jQuery, define, exports, require, document */
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define('jstree.dnd', ['jquery','jstree'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'), require('jstree'));
}
else {
factory(jQuery, jQuery.jstree);
}
}(function ($, jstree, undefined) {
"use strict";
if($.jstree.plugins.dnd) { return; }
/**
* stores all defaults for the drag'n'drop plugin
* @name $.jstree.defaults.dnd
* @plugin dnd
*/
$.jstree.defaults.dnd = {
/**
* a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`.
* @name $.jstree.defaults.dnd.copy
* @plugin dnd
*/
copy : true,
/**
* a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`.
* @name $.jstree.defaults.dnd.open_timeout
* @plugin dnd
*/
open_timeout : 500,
/**
* a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the nodes about to be dragged as an argument (array) - return `false` to prevent dragging
* @name $.jstree.defaults.dnd.is_draggable
* @plugin dnd
*/
is_draggable : true,
/**
* a boolean indicating if checks should constantly be made while the user is dragging the node (as opposed to checking only on drop), default is `true`
* @name $.jstree.defaults.dnd.check_while_dragging
* @plugin dnd
*/
check_while_dragging : true,
/**
* a boolean indicating if nodes from this tree should only be copied with dnd (as opposed to moved), default is `false`
* @name $.jstree.defaults.dnd.always_copy
* @plugin dnd
*/
always_copy : false,
/**
* when dropping a node "inside", this setting indicates the position the node should go to - it can be an integer or a string: "first" (same as 0) or "last", default is `0`
* @name $.jstree.defaults.dnd.inside_pos
* @plugin dnd
*/
inside_pos : 0,
/**
* when starting the drag on a node that is selected this setting controls if all selected nodes are dragged or only the single node, default is `true`, which means all selected nodes are dragged when the drag is started on a selected node
* @name $.jstree.defaults.dnd.drag_selection
* @plugin dnd
*/
drag_selection : true,
/**
* controls whether dnd works on touch devices. If left as boolean true dnd will work the same as in desktop browsers, which in some cases may impair scrolling. If set to boolean false dnd will not work on touch devices. There is a special third option - string "selected" which means only selected nodes can be dragged on touch devices.
* @name $.jstree.defaults.dnd.touch
* @plugin dnd
*/
touch : true,
/**
* controls whether items can be dropped anywhere on the node, not just on the anchor, by default only the node anchor is a valid drop target. Works best with the wholerow plugin. If enabled on mobile depending on the interface it might be hard for the user to cancel the drop, since the whole tree container will be a valid drop target.
* @name $.jstree.defaults.dnd.large_drop_target
* @plugin dnd
*/
large_drop_target : false,
/**
* controls whether a drag can be initiated from any part of the node and not just the text/icon part, works best with the wholerow plugin. Keep in mind it can cause problems with tree scrolling on mobile depending on the interface - in that case set the touch option to "selected".
* @name $.jstree.defaults.dnd.large_drag_target
* @plugin dnd
*/
large_drag_target : false
};
// TODO: now check works by checking for each node individually, how about max_children, unique, etc?
$.jstree.plugins.dnd = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
this.element
.on('mousedown.jstree touchstart.jstree', this.settings.dnd.large_drag_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) {
if(this.settings.dnd.large_drag_target && $(e.target).closest('.jstree-node')[0] !== e.currentTarget) {
return true;
}
if(e.type === "touchstart" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).closest('.jstree-node').children('.jstree-anchor').hasClass('jstree-clicked')))) {
return true;
}
var obj = this.get_node(e.target),
mlt = this.is_selected(obj) && this.settings.dnd.drag_selection ? this.get_top_selected().length : 1,
txt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget));
if(this.settings.core.force_text) {
txt = $.vakata.html.escape(txt);
}
if(obj && obj.id && obj.id !== "#" && (e.which === 1 || e.type === "touchstart") &&
(this.settings.dnd.is_draggable === true || ($.isFunction(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, (mlt > 1 ? this.get_top_selected(true) : [obj]))))
) {
this.element.trigger('mousedown.jstree');
return $.vakata.dnd.start(e, { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_top_selected() : [obj.id] }, '<div id="jstree-dnd" class="jstree-' + this.get_theme() + ' jstree-' + this.get_theme() + '-' + this.get_theme_variant() + ' ' + ( this.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ) + '"><i class="jstree-icon jstree-er"></i>' + txt + '<ins class="jstree-copy" style="display:none;">+</ins></div>');
}
}, this));
};
};
$(function() {
// bind only once for all instances
var lastmv = false,
laster = false,
opento = false,
marker = $('<div id="jstree-marker">&#160;</div>').hide(); //.appendTo('body');
$(document)
.on('dnd_start.vakata.jstree', function (e, data) {
lastmv = false;
if(!data || !data.data || !data.data.jstree) { return; }
marker.appendTo('body'); //.show();
})
.on('dnd_move.vakata.jstree', function (e, data) {
if(opento) { clearTimeout(opento); }
if(!data || !data.data || !data.data.jstree) { return; }
// if we are hovering the marker image do nothing (can happen on "inside" drags)
if(data.event.target.id && data.event.target.id === 'jstree-marker') {
return;
}
var ins = $.jstree.reference(data.event.target),
ref = false,
off = false,
rel = false,
tmp, l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm;
// if we are over an instance
if(ins && ins._data && ins._data.dnd) {
marker.attr('class', 'jstree-' + ins.get_theme() + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ));
data.helper
.children().attr('class', 'jstree-' + ins.get_theme() + ' jstree-' + ins.get_theme() + '-' + ins.get_theme_variant() + ' ' + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' ))
.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'show' : 'hide' ]();
// if are hovering the container itself add a new root node
if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && ins.get_container_ul().children().length === 0) {
ok = true;
for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {
ok = ok && ins.check( (data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)) ) ? "copy_node" : "move_node"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), '#', 'last', { 'dnd' : true, 'ref' : ins.get_node('#'), 'pos' : 'i', 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) });
if(!ok) { break; }
}
if(ok) {
lastmv = { 'ins' : ins, 'par' : '#', 'pos' : 'last' };
marker.hide();
data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok');
return;
}
}
else {
// if we are hovering a tree node
ref = ins.settings.dnd.large_drop_target ? $(data.event.target).closest('.jstree-node').children('.jstree-anchor') : $(data.event.target).closest('.jstree-anchor');
if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) {
off = ref.offset();
rel = data.event.pageY - off.top;
h = ref.outerHeight();
if(rel < h / 3) {
o = ['b', 'i', 'a'];
}
else if(rel > h - h / 3) {
o = ['a', 'i', 'b'];
}
else {
o = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a'];
}
$.each(o, function (j, v) {
switch(v) {
case 'b':
l = off.left - 6;
t = off.top;
p = ins.get_parent(ref);
i = ref.parent().index();
break;
case 'i':
ip = ins.settings.dnd.inside_pos;
tm = ins.get_node(ref.parent());
l = off.left - 2;
t = off.top + h / 2 + 1;
p = tm.id;
i = ip === 'first' ? 0 : (ip === 'last' ? tm.children.length : Math.min(ip, tm.children.length));
break;
case 'a':
l = off.left - 6;
t = off.top + h;
p = ins.get_parent(ref);
i = ref.parent().index() + 1;
break;
}
ok = true;
for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) {
op = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? "copy_node" : "move_node";
ps = i;
if(op === "move_node" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) {
pr = ins.get_node(p);
if(ps > $.inArray(data.data.nodes[t1], pr.children)) {
ps -= 1;
}
}
ok = ok && ( (ins && ins.settings && ins.settings.dnd && ins.settings.dnd.check_while_dragging === false) || ins.check(op, (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), p, ps, { 'dnd' : true, 'ref' : ins.get_node(ref.parent()), 'pos' : v, 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }) );
if(!ok) {
if(ins && ins.last_error) { laster = ins.last_error(); }
break;
}
}
if(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) {
opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout);
}
if(ok) {
lastmv = { 'ins' : ins, 'par' : p, 'pos' : v === 'i' && ip === 'last' && i === 0 && !ins.is_loaded(tm) ? 'last' : i };
marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show();
data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok');
laster = {};
o = true;
return false;
}
});
if(o === true) { return; }
}
}
}
lastmv = false;
data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er');
marker.hide();
})
.on('dnd_scroll.vakata.jstree', function (e, data) {
if(!data || !data.data || !data.data.jstree) { return; }
marker.hide();
lastmv = false;
data.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er');
})
.on('dnd_stop.vakata.jstree', function (e, data) {
if(opento) { clearTimeout(opento); }
if(!data || !data.data || !data.data.jstree) { return; }
marker.hide().detach();
var i, j, nodes = [];
if(lastmv) {
for(i = 0, j = data.data.nodes.length; i < j; i++) {
nodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i];
}
lastmv.ins[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'copy_node' : 'move_node' ](nodes, lastmv.par, lastmv.pos, false, false, false, data.data.origin);
}
else {
i = $(data.event.target).closest('.jstree');
if(i.length && laster && laster.error && laster.error === 'check') {
i = i.jstree(true);
if(i) {
i.settings.core.error.call(this, laster);
}
}
}
})
.on('keyup.jstree keydown.jstree', function (e, data) {
data = $.vakata.dnd._get();
if(data && data.data && data.data.jstree) {
data.helper.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey))) ? 'show' : 'hide' ]();
}
});
});
// helpers
(function ($) {
$.vakata.html = {
div : $('<div />'),
escape : function (str) {
return $.vakata.html.div.text(str).html();
},
strip : function (str) {
return $.vakata.html.div.empty().append($.parseHTML(str)).text();
}
};
// private variable
var vakata_dnd = {
element : false,
target : false,
is_down : false,
is_drag : false,
helper : false,
helper_w: 0,
data : false,
init_x : 0,
init_y : 0,
scroll_l: 0,
scroll_t: 0,
scroll_e: false,
scroll_i: false,
is_touch: false
};
$.vakata.dnd = {
settings : {
scroll_speed : 10,
scroll_proximity : 20,
helper_left : 5,
helper_top : 10,
threshold : 5,
threshold_touch : 50
},
_trigger : function (event_name, e) {
var data = $.vakata.dnd._get();
data.event = e;
$(document).triggerHandler("dnd_" + event_name + ".vakata", data);
},
_get : function () {
return {
"data" : vakata_dnd.data,
"element" : vakata_dnd.element,
"helper" : vakata_dnd.helper
};
},
_clean : function () {
if(vakata_dnd.helper) { vakata_dnd.helper.remove(); }
if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; }
vakata_dnd = {
element : false,
target : false,
is_down : false,
is_drag : false,
helper : false,
helper_w: 0,
data : false,
init_x : 0,
init_y : 0,
scroll_l: 0,
scroll_t: 0,
scroll_e: false,
scroll_i: false,
is_touch: false
};
$(document).off("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag);
$(document).off("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop);
},
_scroll : function (init_only) {
if(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) {
if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; }
return false;
}
if(!vakata_dnd.scroll_i) {
vakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100);
return false;
}
if(init_only === true) { return false; }
var i = vakata_dnd.scroll_e.scrollTop(),
j = vakata_dnd.scroll_e.scrollLeft();
vakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed);
vakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed);
if(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) {
/**
* triggered on the document when a drag causes an element to scroll
* @event
* @plugin dnd
* @name dnd_scroll.vakata
* @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
* @param {DOM} element the DOM element being dragged
* @param {jQuery} helper the helper shown next to the mouse
* @param {jQuery} event the element that is scrolling
*/
$.vakata.dnd._trigger("scroll", vakata_dnd.scroll_e);
}
},
start : function (e, data, html) {
if(e.type === "touchstart" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
e.pageX = e.originalEvent.changedTouches[0].pageX;
e.pageY = e.originalEvent.changedTouches[0].pageY;
e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
}
if(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); }
try {
e.currentTarget.unselectable = "on";
e.currentTarget.onselectstart = function() { return false; };
if(e.currentTarget.style) { e.currentTarget.style.MozUserSelect = "none"; }
} catch(ignore) { }
vakata_dnd.init_x = e.pageX;
vakata_dnd.init_y = e.pageY;
vakata_dnd.data = data;
vakata_dnd.is_down = true;
vakata_dnd.element = e.currentTarget;
vakata_dnd.target = e.target;
vakata_dnd.is_touch = e.type === "touchstart";
if(html !== false) {
vakata_dnd.helper = $("<div id='vakata-dnd'></div>").html(html).css({
"display" : "block",
"margin" : "0",
"padding" : "0",
"position" : "absolute",
"top" : "-2000px",
"lineHeight" : "16px",
"zIndex" : "10000"
});
}
$(document).on("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag);
$(document).on("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop);
return false;
},
drag : function (e) {
if(e.type === "touchmove" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
e.pageX = e.originalEvent.changedTouches[0].pageX;
e.pageY = e.originalEvent.changedTouches[0].pageY;
e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
}
if(!vakata_dnd.is_down) { return; }
if(!vakata_dnd.is_drag) {
if(
Math.abs(e.pageX - vakata_dnd.init_x) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) ||
Math.abs(e.pageY - vakata_dnd.init_y) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold)
) {
if(vakata_dnd.helper) {
vakata_dnd.helper.appendTo("body");
vakata_dnd.helper_w = vakata_dnd.helper.outerWidth();
}
vakata_dnd.is_drag = true;
/**
* triggered on the document when a drag starts
* @event
* @plugin dnd
* @name dnd_start.vakata
* @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
* @param {DOM} element the DOM element being dragged
* @param {jQuery} helper the helper shown next to the mouse
* @param {Object} event the event that caused the start (probably mousemove)
*/
$.vakata.dnd._trigger("start", e);
}
else { return; }
}
var d = false, w = false,
dh = false, wh = false,
dw = false, ww = false,
dt = false, dl = false,
ht = false, hl = false;
vakata_dnd.scroll_t = 0;
vakata_dnd.scroll_l = 0;
vakata_dnd.scroll_e = false;
$($(e.target).parentsUntil("body").addBack().get().reverse())
.filter(function () {
return (/^auto|scroll$/).test($(this).css("overflow")) &&
(this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth);
})
.each(function () {
var t = $(this), o = t.offset();
if(this.scrollHeight > this.offsetHeight) {
if(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; }
if(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; }
}
if(this.scrollWidth > this.offsetWidth) {
if(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; }
if(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; }
}
if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) {
vakata_dnd.scroll_e = $(this);
return false;
}
});
if(!vakata_dnd.scroll_e) {
d = $(document); w = $(window);
dh = d.height(); wh = w.height();
dw = d.width(); ww = w.width();
dt = d.scrollTop(); dl = d.scrollLeft();
if(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; }
if(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; }
if(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; }
if(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; }
if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) {
vakata_dnd.scroll_e = d;
}
}
if(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); }
if(vakata_dnd.helper) {
ht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10);
hl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10);
if(dh && ht + 25 > dh) { ht = dh - 50; }
if(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); }
vakata_dnd.helper.css({
left : hl + "px",
top : ht + "px"
});
}
/**
* triggered on the document when a drag is in progress
* @event
* @plugin dnd
* @name dnd_move.vakata
* @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
* @param {DOM} element the DOM element being dragged
* @param {jQuery} helper the helper shown next to the mouse
* @param {Object} event the event that caused this to trigger (most likely mousemove)
*/
$.vakata.dnd._trigger("move", e);
return false;
},
stop : function (e) {
if(e.type === "touchend" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) {
e.pageX = e.originalEvent.changedTouches[0].pageX;
e.pageY = e.originalEvent.changedTouches[0].pageY;
e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset);
}
if(vakata_dnd.is_drag) {
/**
* triggered on the document when a drag stops (the dragged element is dropped)
* @event
* @plugin dnd
* @name dnd_stop.vakata
* @param {Mixed} data any data supplied with the call to $.vakata.dnd.start
* @param {DOM} element the DOM element being dragged
* @param {jQuery} helper the helper shown next to the mouse
* @param {Object} event the event that caused the stop
*/
$.vakata.dnd._trigger("stop", e);
}
else {
if(e.type === "touchend" && e.target === vakata_dnd.target) {
var to = setTimeout(function () { $(e.target).click(); }, 100);
$(e.target).one('click', function() { if(to) { clearTimeout(to); } });
}
}
$.vakata.dnd._clean();
return false;
}
};
}($));
// include the dnd plugin by default
// $.jstree.defaults.plugins.push("dnd");
}));

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,100 @@
/**
* ### Massload plugin
*
* Adds massload functionality to jsTree, so that multiple nodes can be loaded in a single request (only useful with lazy loading).
*/
/*globals jQuery, define, exports, require, document */
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define('jstree.massload', ['jquery','jstree'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'), require('jstree'));
}
else {
factory(jQuery, jQuery.jstree);
}
}(function ($, jstree, undefined) {
"use strict";
if($.jstree.plugins.massload) { return; }
/**
* massload configuration
*
* It is possible to set this to a standard jQuery-like AJAX config.
* In addition to the standard jQuery ajax options here you can supply functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node IDs need to be loaded, the return value of those functions will be used.
*
* You can also set this to a function, that function will receive the node IDs being loaded as argument and a second param which is a function (callback) which should be called with the result.
*
* Both the AJAX and the function approach rely on the same return value - an object where the keys are the node IDs, and the value is the children of that node as an array.
*
* {
* "id1" : [{ "text" : "Child of ID1", "id" : "c1" }, { "text" : "Another child of ID1", "id" : "c2" }],
* "id2" : [{ "text" : "Child of ID2", "id" : "c3" }]
* }
*
* @name $.jstree.defaults.massload
* @plugin massload
*/
$.jstree.defaults.massload = null;
$.jstree.plugins.massload = function (options, parent) {
this.init = function (el, options) {
parent.init.call(this, el, options);
this._data.massload = {};
};
this._load_nodes = function (nodes, callback, is_callback) {
var s = this.settings.massload;
if(is_callback && !$.isEmptyObject(this._data.massload)) {
return parent._load_nodes.call(this, nodes, callback, is_callback);
}
if($.isFunction(s)) {
return s.call(this, nodes, $.proxy(function (data) {
if(data) {
for(var i in data) {
if(data.hasOwnProperty(i)) {
this._data.massload[i] = data[i];
}
}
}
parent._load_nodes.call(this, nodes, callback, is_callback);
}, this));
}
if(typeof s === 'object' && s && s.url) {
s = $.extend(true, {}, s);
if($.isFunction(s.url)) {
s.url = s.url.call(this, nodes);
}
if($.isFunction(s.data)) {
s.data = s.data.call(this, nodes);
}
return $.ajax(s)
.done($.proxy(function (data,t,x) {
if(data) {
for(var i in data) {
if(data.hasOwnProperty(i)) {
this._data.massload[i] = data[i];
}
}
}
parent._load_nodes.call(this, nodes, callback, is_callback);
}, this))
.fail($.proxy(function (f) {
parent._load_nodes.call(this, nodes, callback, is_callback);
}, this));
}
return parent._load_nodes.call(this, nodes, callback, is_callback);
};
this._load_node = function (obj, callback) {
var d = this._data.massload[obj.id];
if(d) {
return this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(function () { return this.nodeType !== 3; }) : d, function (status) {
callback.call(this, status);
delete this._data.massload[obj.id];
});
}
return parent._load_node.call(this, obj, callback);
};
};
}));

View File

@ -0,0 +1,419 @@
/**
* ### Search plugin
*
* Adds search functionality to jsTree.
*/
/*globals jQuery, define, exports, require, document */
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define('jstree.search', ['jquery','jstree'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'), require('jstree'));
}
else {
factory(jQuery, jQuery.jstree);
}
}(function ($, jstree, undefined) {
"use strict";
if($.jstree.plugins.search) { return; }
/**
* stores all defaults for the search plugin
* @name $.jstree.defaults.search
* @plugin search
*/
$.jstree.defaults.search = {
/**
* a jQuery-like AJAX config, which jstree uses if a server should be queried for results.
*
* A `str` (which is the search string) parameter will be added with the request, an optional `inside` parameter will be added if the search is limited to a node id. The expected result is a JSON array with nodes that need to be opened so that matching nodes will be revealed.
* Leave this setting as `false` to not query the server. You can also set this to a function, which will be invoked in the instance's scope and receive 3 parameters - the search string, the callback to call with the array of nodes to load, and the optional node ID to limit the search to
* @name $.jstree.defaults.search.ajax
* @plugin search
*/
ajax : false,
/**
* Indicates if the search should be fuzzy or not (should `chnd3` match `child node 3`). Default is `false`.
* @name $.jstree.defaults.search.fuzzy
* @plugin search
*/
fuzzy : false,
/**
* Indicates if the search should be case sensitive. Default is `false`.
* @name $.jstree.defaults.search.case_sensitive
* @plugin search
*/
case_sensitive : false,
/**
* Indicates if the tree should be filtered (by default) to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers).
* This setting can be changed at runtime when calling the search method. Default is `false`.
* @name $.jstree.defaults.search.show_only_matches
* @plugin search
*/
show_only_matches : false,
/**
* Indicates if the children of matched element are shown (when show_only_matches is true)
* This setting can be changed at runtime when calling the search method. Default is `false`.
* @name $.jstree.defaults.search.show_only_matches_children
* @plugin search
*/
show_only_matches_children : false,
/**
* Indicates if all nodes opened to reveal the search result, should be closed when the search is cleared or a new search is performed. Default is `true`.
* @name $.jstree.defaults.search.close_opened_onclear
* @plugin search
*/
close_opened_onclear : true,
/**
* Indicates if only leaf nodes should be included in search results. Default is `false`.
* @name $.jstree.defaults.search.search_leaves_only
* @plugin search
*/
search_leaves_only : false,
/**
* If set to a function it wil be called in the instance's scope with two arguments - search string and node (where node will be every node in the structure, so use with caution).
* If the function returns a truthy value the node will be considered a match (it might not be displayed if search_only_leaves is set to true and the node is not a leaf). Default is `false`.
* @name $.jstree.defaults.search.search_callback
* @plugin search
*/
search_callback : false
};
$.jstree.plugins.search = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
this._data.search.str = "";
this._data.search.dom = $();
this._data.search.res = [];
this._data.search.opn = [];
this._data.search.som = false;
this._data.search.smc = false;
this.element
.on('before_open.jstree', $.proxy(function (e, data) {
var i, j, f, r = this._data.search.res, s = [], o = $();
if(r && r.length) {
this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')));
this._data.search.dom.children(".jstree-anchor").addClass('jstree-search');
if(this._data.search.som && this._data.search.res.length) {
for(i = 0, j = r.length; i < j; i++) {
s = s.concat(this.get_node(r[i]).parents);
}
s = $.vakata.array_remove_item($.vakata.array_unique(s),'#');
o = s.length ? $(this.element[0].querySelectorAll('#' + $.map(s, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))) : $();
this.element.find(".jstree-node").hide().filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
o = o.add(this._data.search.dom);
if(this._data.search.smc) {
this._data.search.dom.children(".jstree-children").find(".jstree-node").show();
}
o.parentsUntil(".jstree").addBack().show()
.filter(".jstree-children").each(function () { $(this).children(".jstree-node:visible").eq(-1).addClass("jstree-last"); });
}
}
}, this))
.on("search.jstree", $.proxy(function (e, data) {
if(this._data.search.som) {
if(data.nodes.length) {
this.element.find(".jstree-node").hide().filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
if(this._data.search.smc) {
data.nodes.children(".jstree-children").find(".jstree-node").show();
}
data.nodes.parentsUntil(".jstree").addBack().show()
.filter(".jstree-children").each(function () { $(this).children(".jstree-node:visible").eq(-1).addClass("jstree-last"); });
}
}
}, this))
.on("clear_search.jstree", $.proxy(function (e, data) {
if(this._data.search.som && data.nodes.length) {
this.element.find(".jstree-node").css("display","").filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last');
}
}, this));
};
/**
* used to search the tree nodes for a given string
* @name search(str [, skip_async])
* @param {String} str the search string
* @param {Boolean} skip_async if set to true server will not be queried even if configured
* @param {Boolean} show_only_matches if set to true only matching nodes will be shown (keep in mind this can be very slow on large trees or old browsers)
* @param {mixed} inside an optional node to whose children to limit the search
* @param {Boolean} append if set to true the results of this search are appended to the previous search
* @plugin search
* @trigger search.jstree
*/
this.search = function (str, skip_async, show_only_matches, inside, append, show_only_matches_children) {
if(str === false || $.trim(str.toString()) === "") {
return this.clear_search();
}
inside = this.get_node(inside);
inside = inside && inside.id ? inside.id : null;
str = str.toString();
var s = this.settings.search,
a = s.ajax ? s.ajax : false,
m = this._model.data,
f = null,
r = [],
p = [], i, j;
if(this._data.search.res.length && !append) {
this.clear_search();
}
if(show_only_matches === undefined) {
show_only_matches = s.show_only_matches;
}
if(show_only_matches_children === undefined) {
show_only_matches_children = s.show_only_matches_children;
}
if(!skip_async && a !== false) {
if($.isFunction(a)) {
return a.call(this, str, $.proxy(function (d) {
if(d && d.d) { d = d.d; }
this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () {
this.search(str, true, show_only_matches, inside, append);
}, true);
}, this), inside);
}
else {
a = $.extend({}, a);
if(!a.data) { a.data = {}; }
a.data.str = str;
if(inside) {
a.data.inside = inside;
}
return $.ajax(a)
.fail($.proxy(function () {
this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'search', 'id' : 'search_01', 'reason' : 'Could not load search parents', 'data' : JSON.stringify(a) };
this.settings.core.error.call(this, this._data.core.last_error);
}, this))
.done($.proxy(function (d) {
if(d && d.d) { d = d.d; }
this._load_nodes(!$.isArray(d) ? [] : $.vakata.array_unique(d), function () {
this.search(str, true, show_only_matches, inside, append);
}, true);
}, this));
}
}
if(!append) {
this._data.search.str = str;
this._data.search.dom = $();
this._data.search.res = [];
this._data.search.opn = [];
this._data.search.som = show_only_matches;
this._data.search.smc = show_only_matches_children;
}
f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy });
$.each(m[inside ? inside : '#'].children_d, function (ii, i) {
var v = m[i];
if(v.text && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) ) {
r.push(i);
p = p.concat(v.parents);
}
});
if(r.length) {
p = $.vakata.array_unique(p);
this._search_open(p);
if(!append) {
this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')));
this._data.search.res = r;
}
else {
this._data.search.dom = this._data.search.dom.add($(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))));
this._data.search.res = $.vakata.array_unique(this._data.search.res.concat(r));
}
this._data.search.dom.children(".jstree-anchor").addClass('jstree-search');
}
/**
* triggered after search is complete
* @event
* @name search.jstree
* @param {jQuery} nodes a jQuery collection of matching nodes
* @param {String} str the search string
* @param {Array} res a collection of objects represeing the matching nodes
* @plugin search
*/
this.trigger('search', { nodes : this._data.search.dom, str : str, res : this._data.search.res, show_only_matches : show_only_matches });
};
/**
* used to clear the last search (removes classes and shows all nodes if filtering is on)
* @name clear_search()
* @plugin search
* @trigger clear_search.jstree
*/
this.clear_search = function () {
this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search");
if(this.settings.search.close_opened_onclear) {
this.close_node(this._data.search.opn, 0);
}
/**
* triggered after search is complete
* @event
* @name clear_search.jstree
* @param {jQuery} nodes a jQuery collection of matching nodes (the result from the last search)
* @param {String} str the search string (the last search string)
* @param {Array} res a collection of objects represeing the matching nodes (the result from the last search)
* @plugin search
*/
this.trigger('clear_search', { 'nodes' : this._data.search.dom, str : this._data.search.str, res : this._data.search.res });
this._data.search.str = "";
this._data.search.res = [];
this._data.search.opn = [];
this._data.search.dom = $();
};
/**
* opens nodes that need to be opened to reveal the search results. Used only internally.
* @private
* @name _search_open(d)
* @param {Array} d an array of node IDs
* @plugin search
*/
this._search_open = function (d) {
var t = this;
$.each(d.concat([]), function (i, v) {
if(v === "#") { return true; }
try { v = $('#' + v.replace($.jstree.idregex,'\\$&'), t.element); } catch(ignore) { }
if(v && v.length) {
if(t.is_closed(v)) {
t._data.search.opn.push(v[0].id);
t.open_node(v, function () { t._search_open(d); }, 0);
}
}
});
};
};
// helpers
(function ($) {
// from http://kiro.me/projects/fuse.html
$.vakata.search = function(pattern, txt, options) {
options = options || {};
options = $.extend({}, $.vakata.search.defaults, options);
if(options.fuzzy !== false) {
options.fuzzy = true;
}
pattern = options.caseSensitive ? pattern : pattern.toLowerCase();
var MATCH_LOCATION = options.location,
MATCH_DISTANCE = options.distance,
MATCH_THRESHOLD = options.threshold,
patternLen = pattern.length,
matchmask, pattern_alphabet, match_bitapScore, search;
if(patternLen > 32) {
options.fuzzy = false;
}
if(options.fuzzy) {
matchmask = 1 << (patternLen - 1);
pattern_alphabet = (function () {
var mask = {},
i = 0;
for (i = 0; i < patternLen; i++) {
mask[pattern.charAt(i)] = 0;
}
for (i = 0; i < patternLen; i++) {
mask[pattern.charAt(i)] |= 1 << (patternLen - i - 1);
}
return mask;
}());
match_bitapScore = function (e, x) {
var accuracy = e / patternLen,
proximity = Math.abs(MATCH_LOCATION - x);
if(!MATCH_DISTANCE) {
return proximity ? 1.0 : accuracy;
}
return accuracy + (proximity / MATCH_DISTANCE);
};
}
search = function (text) {
text = options.caseSensitive ? text : text.toLowerCase();
if(pattern === text || text.indexOf(pattern) !== -1) {
return {
isMatch: true,
score: 0
};
}
if(!options.fuzzy) {
return {
isMatch: false,
score: 1
};
}
var i, j,
textLen = text.length,
scoreThreshold = MATCH_THRESHOLD,
bestLoc = text.indexOf(pattern, MATCH_LOCATION),
binMin, binMid,
binMax = patternLen + textLen,
lastRd, start, finish, rd, charMatch,
score = 1,
locations = [];
if (bestLoc !== -1) {
scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold);
bestLoc = text.lastIndexOf(pattern, MATCH_LOCATION + patternLen);
if (bestLoc !== -1) {
scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold);
}
}
bestLoc = -1;
for (i = 0; i < patternLen; i++) {
binMin = 0;
binMid = binMax;
while (binMin < binMid) {
if (match_bitapScore(i, MATCH_LOCATION + binMid) <= scoreThreshold) {
binMin = binMid;
} else {
binMax = binMid;
}
binMid = Math.floor((binMax - binMin) / 2 + binMin);
}
binMax = binMid;
start = Math.max(1, MATCH_LOCATION - binMid + 1);
finish = Math.min(MATCH_LOCATION + binMid, textLen) + patternLen;
rd = new Array(finish + 2);
rd[finish + 1] = (1 << i) - 1;
for (j = finish; j >= start; j--) {
charMatch = pattern_alphabet[text.charAt(j - 1)];
if (i === 0) {
rd[j] = ((rd[j + 1] << 1) | 1) & charMatch;
} else {
rd[j] = ((rd[j + 1] << 1) | 1) & charMatch | (((lastRd[j + 1] | lastRd[j]) << 1) | 1) | lastRd[j + 1];
}
if (rd[j] & matchmask) {
score = match_bitapScore(i, j - 1);
if (score <= scoreThreshold) {
scoreThreshold = score;
bestLoc = j - 1;
locations.push(bestLoc);
if (bestLoc > MATCH_LOCATION) {
start = Math.max(1, 2 * MATCH_LOCATION - bestLoc);
} else {
break;
}
}
}
}
if (match_bitapScore(i + 1, MATCH_LOCATION) > scoreThreshold) {
break;
}
lastRd = rd;
}
return {
isMatch: bestLoc >= 0,
score: score
};
};
return txt === true ? { 'search' : search } : search(txt);
};
$.vakata.search.defaults = {
location : 0,
distance : 100,
threshold : 0.6,
fuzzy : false,
caseSensitive : false
};
}($));
// include the search plugin by default
// $.jstree.defaults.plugins.push("search");
}));

View File

@ -0,0 +1,74 @@
/**
* ### Sort plugin
*
* Automatically sorts all siblings in the tree according to a sorting function.
*/
/*globals jQuery, define, exports, require */
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define('jstree.sort', ['jquery','jstree'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'), require('jstree'));
}
else {
factory(jQuery, jQuery.jstree);
}
}(function ($, jstree, undefined) {
"use strict";
if($.jstree.plugins.sort) { return; }
/**
* the settings function used to sort the nodes.
* It is executed in the tree's context, accepts two nodes as arguments and should return `1` or `-1`.
* @name $.jstree.defaults.sort
* @plugin sort
*/
$.jstree.defaults.sort = function (a, b) {
//return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : this.get_type(a) >= this.get_type(b);
return this.get_text(a) > this.get_text(b) ? 1 : -1;
};
$.jstree.plugins.sort = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
this.element
.on("model.jstree", $.proxy(function (e, data) {
this.sort(data.parent, true);
}, this))
.on("rename_node.jstree create_node.jstree", $.proxy(function (e, data) {
this.sort(data.parent || data.node.parent, false);
this.redraw_node(data.parent || data.node.parent, true);
}, this))
.on("move_node.jstree copy_node.jstree", $.proxy(function (e, data) {
this.sort(data.parent, false);
this.redraw_node(data.parent, true);
}, this));
};
/**
* used to sort a node's children
* @private
* @name sort(obj [, deep])
* @param {mixed} obj the node
* @param {Boolean} deep if set to `true` nodes are sorted recursively.
* @plugin sort
* @trigger search.jstree
*/
this.sort = function (obj, deep) {
var i, j;
obj = this.get_node(obj);
if(obj && obj.children && obj.children.length) {
obj.children.sort($.proxy(this.settings.sort, this));
if(deep) {
for(i = 0, j = obj.children_d.length; i < j; i++) {
this.sort(obj.children_d[i], false);
}
}
}
};
};
// include the sort plugin by default
// $.jstree.defaults.plugins.push("sort");
}));

View File

@ -0,0 +1,125 @@
/**
* ### State plugin
*
* Saves the state of the tree (selected nodes, opened nodes) on the user's computer using available options (localStorage, cookies, etc)
*/
/*globals jQuery, define, exports, require */
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define('jstree.state', ['jquery','jstree'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'), require('jstree'));
}
else {
factory(jQuery, jQuery.jstree);
}
}(function ($, jstree, undefined) {
"use strict";
if($.jstree.plugins.state) { return; }
var to = false;
/**
* stores all defaults for the state plugin
* @name $.jstree.defaults.state
* @plugin state
*/
$.jstree.defaults.state = {
/**
* A string for the key to use when saving the current tree (change if using multiple trees in your project). Defaults to `jstree`.
* @name $.jstree.defaults.state.key
* @plugin state
*/
key : 'jstree',
/**
* A space separated list of events that trigger a state save. Defaults to `changed.jstree open_node.jstree close_node.jstree`.
* @name $.jstree.defaults.state.events
* @plugin state
*/
events : 'changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree',
/**
* Time in milliseconds after which the state will expire. Defaults to 'false' meaning - no expire.
* @name $.jstree.defaults.state.ttl
* @plugin state
*/
ttl : false,
/**
* A function that will be executed prior to restoring state with one argument - the state object. Can be used to clear unwanted parts of the state.
* @name $.jstree.defaults.state.filter
* @plugin state
*/
filter : false
};
$.jstree.plugins.state = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
var bind = $.proxy(function () {
this.element.on(this.settings.state.events, $.proxy(function () {
if(to) { clearTimeout(to); }
to = setTimeout($.proxy(function () { this.save_state(); }, this), 100);
}, this));
/**
* triggered when the state plugin is finished restoring the state (and immediately after ready if there is no state to restore).
* @event
* @name state_ready.jstree
* @plugin state
*/
this.trigger('state_ready');
}, this);
this.element
.on("ready.jstree", $.proxy(function (e, data) {
this.element.one("restore_state.jstree", bind);
if(!this.restore_state()) { bind(); }
}, this));
};
/**
* save the state
* @name save_state()
* @plugin state
*/
this.save_state = function () {
var st = { 'state' : this.get_state(), 'ttl' : this.settings.state.ttl, 'sec' : +(new Date()) };
$.vakata.storage.set(this.settings.state.key, JSON.stringify(st));
};
/**
* restore the state from the user's computer
* @name restore_state()
* @plugin state
*/
this.restore_state = function () {
var k = $.vakata.storage.get(this.settings.state.key);
if(!!k) { try { k = JSON.parse(k); } catch(ex) { return false; } }
if(!!k && k.ttl && k.sec && +(new Date()) - k.sec > k.ttl) { return false; }
if(!!k && k.state) { k = k.state; }
if(!!k && $.isFunction(this.settings.state.filter)) { k = this.settings.state.filter.call(this, k); }
if(!!k) {
this.element.one("set_state.jstree", function (e, data) { data.instance.trigger('restore_state', { 'state' : $.extend(true, {}, k) }); });
this.set_state(k);
return true;
}
return false;
};
/**
* clear the state on the user's computer
* @name clear_state()
* @plugin state
*/
this.clear_state = function () {
return $.vakata.storage.del(this.settings.state.key);
};
};
(function ($, undefined) {
$.vakata.storage = {
// simply specifying the functions in FF throws an error
set : function (key, val) { return window.localStorage.setItem(key, val); },
get : function (key) { return window.localStorage.getItem(key); },
del : function (key) { return window.localStorage.removeItem(key); }
};
}($));
// include the state plugin by default
// $.jstree.defaults.plugins.push("state");
}));

View File

@ -0,0 +1,236 @@
/**
* ### Types plugin
*
* Makes it possible to add predefined types for groups of nodes, which make it possible to easily control nesting rules and icon for each group.
*/
/*globals jQuery, define, exports, require */
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define('jstree.types', ['jquery','jstree'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'), require('jstree'));
}
else {
factory(jQuery, jQuery.jstree);
}
}(function ($, jstree, undefined) {
"use strict";
if($.jstree.plugins.types) { return; }
/**
* An object storing all types as key value pairs, where the key is the type name and the value is an object that could contain following keys (all optional).
*
* * `max_children` the maximum number of immediate children this node type can have. Do not specify or set to `-1` for unlimited.
* * `max_depth` the maximum number of nesting this node type can have. A value of `1` would mean that the node can have children, but no grandchildren. Do not specify or set to `-1` for unlimited.
* * `valid_children` an array of node type strings, that nodes of this type can have as children. Do not specify or set to `-1` for no limits.
* * `icon` a string - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class. Omit to use the default icon from your theme.
*
* There are two predefined types:
*
* * `#` represents the root of the tree, for example `max_children` would control the maximum number of root nodes.
* * `default` represents the default node - any settings here will be applied to all nodes that do not have a type specified.
*
* @name $.jstree.defaults.types
* @plugin types
*/
$.jstree.defaults.types = {
'#' : {},
'default' : {}
};
$.jstree.plugins.types = function (options, parent) {
this.init = function (el, options) {
var i, j;
if(options && options.types && options.types['default']) {
for(i in options.types) {
if(i !== "default" && i !== "#" && options.types.hasOwnProperty(i)) {
for(j in options.types['default']) {
if(options.types['default'].hasOwnProperty(j) && options.types[i][j] === undefined) {
options.types[i][j] = options.types['default'][j];
}
}
}
}
}
parent.init.call(this, el, options);
this._model.data['#'].type = '#';
};
this.refresh = function (skip_loading, forget_state) {
parent.refresh.call(this, skip_loading, forget_state);
this._model.data['#'].type = '#';
};
this.bind = function () {
this.element
.on('model.jstree', $.proxy(function (e, data) {
var m = this._model.data,
dpc = data.nodes,
t = this.settings.types,
i, j, c = 'default';
for(i = 0, j = dpc.length; i < j; i++) {
c = 'default';
if(m[dpc[i]].original && m[dpc[i]].original.type && t[m[dpc[i]].original.type]) {
c = m[dpc[i]].original.type;
}
if(m[dpc[i]].data && m[dpc[i]].data.jstree && m[dpc[i]].data.jstree.type && t[m[dpc[i]].data.jstree.type]) {
c = m[dpc[i]].data.jstree.type;
}
m[dpc[i]].type = c;
if(m[dpc[i]].icon === true && t[c].icon !== undefined) {
m[dpc[i]].icon = t[c].icon;
}
}
m['#'].type = '#';
}, this));
parent.bind.call(this);
};
this.get_json = function (obj, options, flat) {
var i, j,
m = this._model.data,
opt = options ? $.extend(true, {}, options, {no_id:false}) : {},
tmp = parent.get_json.call(this, obj, opt, flat);
if(tmp === false) { return false; }
if($.isArray(tmp)) {
for(i = 0, j = tmp.length; i < j; i++) {
tmp[i].type = tmp[i].id && m[tmp[i].id] && m[tmp[i].id].type ? m[tmp[i].id].type : "default";
if(options && options.no_id) {
delete tmp[i].id;
if(tmp[i].li_attr && tmp[i].li_attr.id) {
delete tmp[i].li_attr.id;
}
if(tmp[i].a_attr && tmp[i].a_attr.id) {
delete tmp[i].a_attr.id;
}
}
}
}
else {
tmp.type = tmp.id && m[tmp.id] && m[tmp.id].type ? m[tmp.id].type : "default";
if(options && options.no_id) {
tmp = this._delete_ids(tmp);
}
}
return tmp;
};
this._delete_ids = function (tmp) {
if($.isArray(tmp)) {
for(var i = 0, j = tmp.length; i < j; i++) {
tmp[i] = this._delete_ids(tmp[i]);
}
return tmp;
}
delete tmp.id;
if(tmp.li_attr && tmp.li_attr.id) {
delete tmp.li_attr.id;
}
if(tmp.a_attr && tmp.a_attr.id) {
delete tmp.a_attr.id;
}
if(tmp.children && $.isArray(tmp.children)) {
tmp.children = this._delete_ids(tmp.children);
}
return tmp;
};
this.check = function (chk, obj, par, pos, more) {
if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; }
obj = obj && obj.id ? obj : this.get_node(obj);
par = par && par.id ? par : this.get_node(par);
var m = obj && obj.id ? (more && more.origin ? more.origin : $.jstree.reference(obj.id)) : null, tmp, d, i, j;
m = m && m._model && m._model.data ? m._model.data : null;
switch(chk) {
case "create_node":
case "move_node":
case "copy_node":
if(chk !== 'move_node' || $.inArray(obj.id, par.children) === -1) {
tmp = this.get_rules(par);
if(tmp.max_children !== undefined && tmp.max_children !== -1 && tmp.max_children === par.children.length) {
this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_01', 'reason' : 'max_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
return false;
}
if(tmp.valid_children !== undefined && tmp.valid_children !== -1 && $.inArray((obj.type || 'default'), tmp.valid_children) === -1) {
this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_02', 'reason' : 'valid_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
return false;
}
if(m && obj.children_d && obj.parents) {
d = 0;
for(i = 0, j = obj.children_d.length; i < j; i++) {
d = Math.max(d, m[obj.children_d[i]].parents.length);
}
d = d - obj.parents.length + 1;
}
if(d <= 0 || d === undefined) { d = 1; }
do {
if(tmp.max_depth !== undefined && tmp.max_depth !== -1 && tmp.max_depth < d) {
this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_03', 'reason' : 'max_depth prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
return false;
}
par = this.get_node(par.parent);
tmp = this.get_rules(par);
d++;
} while(par);
}
break;
}
return true;
};
/**
* used to retrieve the type settings object for a node
* @name get_rules(obj)
* @param {mixed} obj the node to find the rules for
* @return {Object}
* @plugin types
*/
this.get_rules = function (obj) {
obj = this.get_node(obj);
if(!obj) { return false; }
var tmp = this.get_type(obj, true);
if(tmp.max_depth === undefined) { tmp.max_depth = -1; }
if(tmp.max_children === undefined) { tmp.max_children = -1; }
if(tmp.valid_children === undefined) { tmp.valid_children = -1; }
return tmp;
};
/**
* used to retrieve the type string or settings object for a node
* @name get_type(obj [, rules])
* @param {mixed} obj the node to find the rules for
* @param {Boolean} rules if set to `true` instead of a string the settings object will be returned
* @return {String|Object}
* @plugin types
*/
this.get_type = function (obj, rules) {
obj = this.get_node(obj);
return (!obj) ? false : ( rules ? $.extend({ 'type' : obj.type }, this.settings.types[obj.type]) : obj.type);
};
/**
* used to change a node's type
* @name set_type(obj, type)
* @param {mixed} obj the node to change
* @param {String} type the new type
* @plugin types
*/
this.set_type = function (obj, type) {
var t, t1, t2, old_type, old_icon;
if($.isArray(obj)) {
obj = obj.slice();
for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
this.set_type(obj[t1], type);
}
return true;
}
t = this.settings.types;
obj = this.get_node(obj);
if(!t[type] || !obj) { return false; }
old_type = obj.type;
old_icon = this.get_icon(obj);
obj.type = type;
if(old_icon === true || (t[old_type] && t[old_type].icon !== undefined && old_icon === t[old_type].icon)) {
this.set_icon(obj, t[type].icon !== undefined ? t[type].icon : true);
}
return true;
};
};
// include the types plugin by default
// $.jstree.defaults.plugins.push("types");
}));

View File

@ -0,0 +1,121 @@
/**
* ### Unique plugin
*
* Enforces that no nodes with the same name can coexist as siblings.
*/
/*globals jQuery, define, exports, require */
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define('jstree.unique', ['jquery','jstree'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'), require('jstree'));
}
else {
factory(jQuery, jQuery.jstree);
}
}(function ($, jstree, undefined) {
"use strict";
if($.jstree.plugins.unique) { return; }
/**
* stores all defaults for the unique plugin
* @name $.jstree.defaults.unique
* @plugin unique
*/
$.jstree.defaults.unique = {
/**
* Indicates if the comparison should be case sensitive. Default is `false`.
* @name $.jstree.defaults.unique.case_sensitive
* @plugin unique
*/
case_sensitive : false,
/**
* A callback executed in the instance's scope when a new node is created and the name is already taken, the two arguments are the conflicting name and the counter. The default will produce results like `New node (2)`.
* @name $.jstree.defaults.unique.duplicate
* @plugin unique
*/
duplicate : function (name, counter) {
return name + ' (' + counter + ')';
}
};
$.jstree.plugins.unique = function (options, parent) {
this.check = function (chk, obj, par, pos, more) {
if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; }
obj = obj && obj.id ? obj : this.get_node(obj);
par = par && par.id ? par : this.get_node(par);
if(!par || !par.children) { return true; }
var n = chk === "rename_node" ? pos : obj.text,
c = [],
s = this.settings.unique.case_sensitive,
m = this._model.data, i, j;
for(i = 0, j = par.children.length; i < j; i++) {
c.push(s ? m[par.children[i]].text : m[par.children[i]].text.toLowerCase());
}
if(!s) { n = n.toLowerCase(); }
switch(chk) {
case "delete_node":
return true;
case "rename_node":
i = ($.inArray(n, c) === -1 || (obj.text && obj.text[ s ? 'toString' : 'toLowerCase']() === n));
if(!i) {
this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_01', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
}
return i;
case "create_node":
i = ($.inArray(n, c) === -1);
if(!i) {
this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_04', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
}
return i;
case "copy_node":
i = ($.inArray(n, c) === -1);
if(!i) {
this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_02', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
}
return i;
case "move_node":
i = ( (obj.parent === par.id && (!more || !more.is_multi)) || $.inArray(n, c) === -1);
if(!i) {
this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_03', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) };
}
return i;
}
return true;
};
this.create_node = function (par, node, pos, callback, is_loaded) {
if(!node || node.text === undefined) {
if(par === null) {
par = "#";
}
par = this.get_node(par);
if(!par) {
return parent.create_node.call(this, par, node, pos, callback, is_loaded);
}
pos = pos === undefined ? "last" : pos;
if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
return parent.create_node.call(this, par, node, pos, callback, is_loaded);
}
if(!node) { node = {}; }
var tmp, n, dpc, i, j, m = this._model.data, s = this.settings.unique.case_sensitive, cb = this.settings.unique.duplicate;
n = tmp = this.get_string('New node');
dpc = [];
for(i = 0, j = par.children.length; i < j; i++) {
dpc.push(s ? m[par.children[i]].text : m[par.children[i]].text.toLowerCase());
}
i = 1;
while($.inArray(s ? n : n.toLowerCase(), dpc) !== -1) {
n = cb.call(this, tmp, (++i)).toString();
}
node.text = n;
}
return parent.create_node.call(this, par, node, pos, callback, is_loaded);
};
};
// include the unique plugin by default
// $.jstree.defaults.plugins.push("unique");
}));

View File

@ -0,0 +1,115 @@
/**
* ### Wholerow plugin
*
* Makes each node appear block level. Making selection easier. May cause slow down for large trees in old browsers.
*/
/*globals jQuery, define, exports, require */
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define('jstree.wholerow', ['jquery','jstree'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'), require('jstree'));
}
else {
factory(jQuery, jQuery.jstree);
}
}(function ($, jstree, undefined) {
"use strict";
if($.jstree.plugins.wholerow) { return; }
var div = document.createElement('DIV');
div.setAttribute('unselectable','on');
div.setAttribute('role','presentation');
div.className = 'jstree-wholerow';
div.innerHTML = '&#160;';
$.jstree.plugins.wholerow = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
this.element
.on('ready.jstree set_state.jstree', $.proxy(function () {
this.hide_dots();
}, this))
.on("init.jstree loading.jstree ready.jstree", $.proxy(function () {
//div.style.height = this._data.core.li_height + 'px';
this.get_container_ul().addClass('jstree-wholerow-ul');
}, this))
.on("deselect_all.jstree", $.proxy(function (e, data) {
this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked');
}, this))
.on("changed.jstree", $.proxy(function (e, data) {
this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked');
var tmp = false, i, j;
for(i = 0, j = data.selected.length; i < j; i++) {
tmp = this.get_node(data.selected[i], true);
if(tmp && tmp.length) {
tmp.children('.jstree-wholerow').addClass('jstree-wholerow-clicked');
}
}
}, this))
.on("open_node.jstree", $.proxy(function (e, data) {
this.get_node(data.node, true).find('.jstree-clicked').parent().children('.jstree-wholerow').addClass('jstree-wholerow-clicked');
}, this))
.on("hover_node.jstree dehover_node.jstree", $.proxy(function (e, data) {
if(e.type === "hover_node" && this.is_disabled(data.node)) { return; }
this.get_node(data.node, true).children('.jstree-wholerow')[e.type === "hover_node"?"addClass":"removeClass"]('jstree-wholerow-hovered');
}, this))
.on("contextmenu.jstree", ".jstree-wholerow", $.proxy(function (e) {
e.preventDefault();
var tmp = $.Event('contextmenu', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey, pageX : e.pageX, pageY : e.pageY });
$(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp);
}, this))
/*!
.on("mousedown.jstree touchstart.jstree", ".jstree-wholerow", function (e) {
if(e.target === e.currentTarget) {
var a = $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor");
e.target = a[0];
a.trigger(e);
}
})
*/
.on("click.jstree", ".jstree-wholerow", function (e) {
e.stopImmediatePropagation();
var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });
$(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus();
})
.on("click.jstree", ".jstree-leaf > .jstree-ocl", $.proxy(function (e) {
e.stopImmediatePropagation();
var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey });
$(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).focus();
}, this))
.on("mouseover.jstree", ".jstree-wholerow, .jstree-icon", $.proxy(function (e) {
e.stopImmediatePropagation();
if(!this.is_disabled(e.currentTarget)) {
this.hover_node(e.currentTarget);
}
return false;
}, this))
.on("mouseleave.jstree", ".jstree-node", $.proxy(function (e) {
this.dehover_node(e.currentTarget);
}, this));
};
this.teardown = function () {
if(this.settings.wholerow) {
this.element.find(".jstree-wholerow").remove();
}
parent.teardown.call(this);
};
this.redraw_node = function(obj, deep, callback, force_render) {
obj = parent.redraw_node.apply(this, arguments);
if(obj) {
var tmp = div.cloneNode(true);
//tmp.style.height = this._data.core.li_height + 'px';
if($.inArray(obj.id, this._data.core.selected) !== -1) { tmp.className += ' jstree-wholerow-clicked'; }
if(this._data.core.focused && this._data.core.focused === obj.id) { tmp.className += ' jstree-wholerow-hovered'; }
obj.insertBefore(tmp, obj.childNodes[0]);
}
return obj;
};
};
// include the wholerow plugin by default
// $.jstree.defaults.plugins.push("wholerow");
}));

View File

@ -0,0 +1,394 @@
/* global jQuery */
// disable all events
(function ($, undefined) {
"use strict";
$.jstree.plugins.trigger = function (options, parent) {
this.init = function (el, options) {
// do not forget parent
parent.init.call(this, el, options);
this._data.trigger.disabled = false;
};
this.trigger = function (ev, data) {
if(!this._data.trigger.disabled) {
parent.trigger.call(this, ev, data);
}
};
this.disable_events = function () { this._data.trigger.disabled = true; };
this.enable_events = function () { this._data.trigger.disabled = false; };
};
})(jQuery);
// more detailed changed event
(function ($, undefined) {
"use strict";
$.jstree.plugins.changed = function (options, parent) {
var last = [], i, j;
this.trigger = function (ev, data) {
if(!data) {
data = {};
}
if(ev.replace('.jstree','') === 'changed') {
data.changed = { selected : [], deselected : [] };
var tmp = {};
for(i = 0, j = last.length; i < j; i++) {
tmp[last[i]] = 1;
}
for(i = 0, j = data.selected.length; i < j; i++) {
if(!tmp[data.selected[i]]) {
data.changed.selected.push(data.selected[i]);
}
else {
tmp[data.selected[i]] = 2;
}
}
for(i = 0, j = last.length; i < j; i++) {
if(tmp[last[i]] === 1) {
data.changed.deselected.push(last[i]);
}
}
last = data.selected.slice();
}
parent.trigger.call(this, ev, data);
};
};
})(jQuery);
// no hover
(function ($, undefined) {
"use strict";
$.jstree.plugins.nohover = function () {
this.hover_node = $.noop;
};
})(jQuery);
// conditional select
(function ($, undefined) {
"use strict";
$.jstree.defaults.conditionalselect = function () { return true; };
$.jstree.plugins.conditionalselect = function (options, parent) {
// own function
this.activate_node = function (obj, e) {
if(this.settings.conditionalselect.call(this, this.get_node(obj))) {
parent.activate_node.call(this, obj, e);
}
};
};
})(jQuery);
// real checkboxes
(function ($, undefined) {
"use strict";
var inp = document.createElement("INPUT");
inp.type = "checkbox";
inp.className = "jstree-checkbox jstree-realcheckbox";
$.jstree.defaults.realcheckboxes = {};
$.jstree.plugins.realcheckboxes = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
this._data.realcheckboxes.uto = false;
this.element
.on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree ready.jstree loaded.jstree', $.proxy(function () {
// only if undetermined is in setting
if(this._data.realcheckboxes.uto) { clearTimeout(this._data.realcheckboxes.uto); }
this._data.realcheckboxes.uto = setTimeout($.proxy(this._realcheckboxes, this), 50);
}, this));
};
this.redraw_node = function(obj, deep, callback, force_draw) {
obj = parent.redraw_node.call(this, obj, deep, callback, force_draw);
if(obj) {
var i, j, tmp = null, chk = inp.cloneNode(true);
for(i = 0, j = obj.childNodes.length; i < j; i++) {
if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
tmp = obj.childNodes[i];
break;
}
}
if(tmp) {
for(i = 0, j = tmp.childNodes.length; i < j; i++) {
if(tmp.childNodes[i] && tmp.childNodes[i].className && tmp.childNodes[i].className.indexOf("jstree-checkbox") !== -1) {
tmp = tmp.childNodes[i];
break;
}
}
}
if(tmp && tmp.tagName === "I") {
tmp.style.backgroundColor = "transparent";
tmp.style.backgroundImage = "none";
tmp.appendChild(chk);
}
}
return obj;
};
this._realcheckboxes = function () {
var ts = this.settings.checkbox.tie_selection;
console.log(ts);
$('.jstree-realcheckbox').each(function () {
this.checked = (!ts && this.parentNode.parentNode.className.indexOf("jstree-checked") !== -1) || (ts && this.parentNode.parentNode.className.indexOf('jstree-clicked') !== -1);
this.indeterminate = this.parentNode.className.indexOf("jstree-undetermined") !== -1;
this.disabled = this.parentNode.parentNode.className.indexOf("disabled") !== -1;
});
};
};
})(jQuery);
// no state
(function ($, undefined) {
"use strict";
$.jstree.plugins.nostate = function () {
this.set_state = function (state, callback) {
if(callback) { callback.call(this); }
this.trigger('set_state');
};
};
})(jQuery);
// no selected in state
(function ($, undefined) {
"use strict";
$.jstree.plugins.noselectedstate = function (options, parent) {
this.get_state = function () {
var state = parent.get_state.call(this);
delete state.core.selected;
return state;
};
};
})(jQuery);
// allow search results expanding
(function ($, undefined) {
"use strict";
$.jstree.plugins.show_matches_children = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
this.element
.on('search.jstree before_open.jstree', function (e, data) {
if(data.instance.settings.search && data.instance.settings.search.show_only_matches) {
data.instance._data.search.dom.find('.jstree-node')
.show().filter('.jstree-last').filter(function() { return this.nextSibling; }).removeClass('jstree-last')
.end().end().end().find(".jstree-children").each(function () { $(this).children(".jstree-node:visible").eq(-1).addClass("jstree-last"); });
}
});
};
};
})(jQuery);
// additional icon on node (outside of anchor)
(function ($, undefined) {
"use strict";
var img = document.createElement('IMG');
//img.src = "http://www.dpcd.vic.gov.au/__data/assets/image/0004/30667/help.gif";
img.className = "jstree-questionmark";
$.jstree.defaults.questionmark = $.noop;
$.jstree.plugins.questionmark = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
this.element
.on("click.jstree", ".jstree-questionmark", $.proxy(function (e) {
e.stopImmediatePropagation();
this.settings.questionmark.call(this, this.get_node(e.target));
}, this));
};
this.teardown = function () {
if(this.settings.questionmark) {
this.element.find(".jstree-questionmark").remove();
}
parent.teardown.call(this);
};
this.redraw_node = function(obj, deep, callback, force_draw) {
obj = parent.redraw_node.call(this, obj, deep, callback, force_draw);
if(obj) {
var tmp = img.cloneNode(true);
obj.insertBefore(tmp, obj.childNodes[2]);
}
return obj;
};
};
})(jQuery);
// auto numbering
(function ($, undefined) {
"use strict";
var span = document.createElement('SPAN');
span.className = "jstree-numbering";
$.jstree.defaults.numbering = {};
$.jstree.plugins.numbering = function (options, parent) {
this.teardown = function () {
if(this.settings.questionmark) {
this.element.find(".jstree-numbering").remove();
}
parent.teardown.call(this);
};
this.get_number = function (obj) {
obj = this.get_node(obj);
var ind = $.inArray(obj.id, this.get_node(obj.parent).children) + 1;
return obj.parent === '#' ? ind : this.get_number(obj.parent) + '.' + ind;
};
this.redraw_node = function(obj, deep, callback, force_draw) {
var i, j, tmp = null, elm = null, org = this.get_number(obj);
obj = parent.redraw_node.call(this, obj, deep, callback, force_draw);
if(obj) {
for(i = 0, j = obj.childNodes.length; i < j; i++) {
if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
tmp = obj.childNodes[i];
break;
}
}
if(tmp) {
elm = span.cloneNode(true);
elm.innerHTML = org + '. ';
tmp.insertBefore(elm, tmp.childNodes[tmp.childNodes.length - 1]);
}
}
return obj;
};
};
})(jQuery);
// selecting a node opens it
(function ($, undefined) {
"use strict";
$.jstree.plugins.selectopens = function (options, parent) {
this.bind = function () {
parent.bind.call(this);
this.element.on('select_node.jstree', function (e, data) { data.instance.open_node(data.node); });
};
};
})(jQuery);
// massloading
(function ($, undefined) {
"use strict";
$.jstree.defaults.massload = function (nodes, callback) {
callback(false);
};
$.jstree.plugins.massload = function (options, parent) {
this.init = function (el, options) {
parent.init.call(this, el, options);
this._data.massload = {};
};
this._load_nodes = function (nodes, callback, is_callback) {
if(is_callback && !$.isEmptyObject(this._data.massload)) {
return parent._load_nodes.call(this, nodes, callback, is_callback);
}
this.settings.massload.call(this, nodes, $.proxy(function (data) {
if(data) {
for(var i in data) {
if(data.hasOwnProperty(i)) {
this._data.massload[i] = data[i];
}
}
}
parent._load_nodes.call(this, nodes, callback, is_callback);
}, this));
};
this._load_node = function (obj, callback) {
var d = this._data.massload[obj.id];
if(d) {
return this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(function () { return this.nodeType !== 3; }) : d, function (status) {
callback.call(this, status);
delete this._data.massload[obj.id];
});
}
return parent._load_node.call(this, obj, callback);
};
};
})(jQuery);
// object as data
(function ($, undefined) {
"use strict";
$.jstree.defaults.datamodel = {};
$.jstree.plugins.datamodel = function (options, parent) {
this.init = function (el, options) {
this._data.datamodel = {};
parent.init.call(this, el, options);
};
this._datamodel = function (id, nodes, callback) {
var i = 0, j = nodes.length, tmp = [], obj = null;
for(; i < j; i++) {
this._data.datamodel[nodes[i].getID()] = nodes[i];
obj = {
id : nodes[i].getID(),
text : nodes[i].getText(),
children : nodes[i].hasChildren()
};
if(nodes[i].getExtra) {
obj = nodes[i].getExtra(obj); // icon, type
}
tmp.push(obj);
}
return this._append_json_data(id, tmp, $.proxy(function (status) {
callback.call(this, status);
}, this));
};
this._load_node = function (obj, callback) {
var id = obj.id;
var nd = obj.id === "#" ? this.settings.core.data : this._data.datamodel[obj.id].getChildren($.proxy(function (nodes) {
this._datamodel(id, nodes, callback);
}, this));
if($.isArray(nd)) {
this._datamodel(id, nd, callback);
}
};
};
})(jQuery);
/* demo of the above
function treeNode(val) {
var id = ++treeNode.counter;
this.getID = function () {
return id;
};
this.getText = function () {
return val.toString();
};
this.getExtra = function (obj) {
obj.icon = false;
return obj;
};
this.hasChildren = function () {
return true;
};
this.getChildren = function () {
return [
new treeNode(Math.pow(val, 2)),
new treeNode(Math.sqrt(val)),
];
};
}
treeNode.counter = 0;
$('#jstree').jstree({
'core': {
'data': [
new treeNode(2),
new treeNode(3),
new treeNode(4),
new treeNode(5)
]
},
plugins : ['datamodel']
});
*/
// paste override
(function ($, undefined) {
"use strict";
$.jstree.plugins.pastewithpos = function () {
this.paste = function (obj, pos) {
obj = this.get_node(obj);
if(!obj || !ccp_mode || !ccp_mode.match(/^(copy_node|move_node)$/) || !ccp_node) { return false; }
if(this[ccp_mode](ccp_node, obj, pos)) {
this.trigger('paste', { "parent" : obj.id, "node" : ccp_node, "mode" : ccp_mode });
}
ccp_node = false;
ccp_mode = false;
ccp_inst = false;
};
};
})(jQuery);

View File

@ -0,0 +1 @@
}));

View File

@ -0,0 +1,93 @@
/*global jQuery */
// wrap in IIFE and pass jQuery as $
(function ($, undefined) {
"use strict";
// some private plugin stuff if needed
var private_var = null;
// extending the defaults
$.jstree.defaults.sample = {
sample_option : 'sample_val'
};
// the actual plugin code
$.jstree.plugins.sample = function (options, parent) {
// own function
this.sample_function = function (arg) {
// you can chain this method if needed and available
if(parent.sample_function) { parent.sample_function.call(this, arg); }
};
// *SPECIAL* FUNCTIONS
this.init = function (el, options) {
// do not forget parent
parent.init.call(this, el, options);
};
// bind events if needed
this.bind = function () {
// call parent function first
parent.bind.call(this);
// do(stuff);
};
// unbind events if needed (all in jquery namespace are taken care of by the core)
this.unbind = function () {
// do(stuff);
// call parent function last
parent.unbind.call(this);
};
this.teardown = function () {
// do not forget parent
parent.teardown.call(this);
};
// state management - get and restore
this.get_state = function () {
// always get state from parent first
var state = parent.get_state.call(this);
// add own stuff to state
state.sample = { 'var' : 'val' };
return state;
};
this.set_state = function (state, callback) {
// only process your part if parent returns true
// there will be multiple times with false
if(parent.set_state.call(this, state, callback)) {
// check the key you set above
if(state.sample) {
// do(stuff); // like calling this.sample_function(state.sample.var);
// remove your part of the state, call again and RETURN FALSE, the next cycle will be TRUE
delete state.sample;
this.set_state(state, callback);
return false;
}
// return true if your state is gone (cleared in the previous step)
return true;
}
// parent was false - return false too
return false;
};
// node transportation
this.get_json = function (obj, options, flat) {
// get the node from the parent
var tmp = parent.get_json.call(this, obj, options, flat), i, j;
if($.isArray(tmp)) {
for(i = 0, j = tmp.length; i < j; i++) {
tmp[i].sample = 'value';
}
}
else {
tmp.sample = 'value';
}
// return the original / modified node
return tmp;
};
};
// attach to document ready if needed
$(function () {
// do(stuff);
});
// you can include the sample plugin in all instances by default
$.jstree.defaults.plugins.push("sample");
})(jQuery);

View File

@ -0,0 +1,87 @@
// base jstree
.jstree-node, .jstree-children, .jstree-container-ul { display:block; margin:0; padding:0; list-style-type:none; list-style-image:none; }
.jstree-node { white-space:nowrap; }
.jstree-anchor { display:inline-block; color:black; white-space:nowrap; padding:0 4px 0 1px; margin:0; vertical-align:top; }
.jstree-anchor:focus { outline:0; }
.jstree-anchor, .jstree-anchor:link, .jstree-anchor:visited, .jstree-anchor:hover, .jstree-anchor:active { text-decoration:none; color:inherit; }
.jstree-icon { display:inline-block; text-decoration:none; margin:0; padding:0; vertical-align:top; text-align:center; }
.jstree-icon:empty { display:inline-block; text-decoration:none; margin:0; padding:0; vertical-align:top; text-align:center; }
.jstree-ocl { cursor:pointer; }
.jstree-leaf > .jstree-ocl { cursor:default; }
.jstree .jstree-open > .jstree-children { display:block; }
.jstree .jstree-closed > .jstree-children,
.jstree .jstree-leaf > .jstree-children { display:none; }
.jstree-anchor > .jstree-themeicon { margin-right:2px; }
.jstree-no-icons .jstree-themeicon,
.jstree-anchor > .jstree-themeicon-hidden { display:none; }
// base jstree rtl
.jstree-rtl {
.jstree-anchor { padding:0 1px 0 4px; }
.jstree-anchor > .jstree-themeicon { margin-left:2px; margin-right:0; }
.jstree-node { margin-left:0; }
.jstree-container-ul > .jstree-node { margin-right:0; }
}
// base jstree wholerow
.jstree-wholerow-ul {
position:relative;
display:inline-block;
min-width:100%;
.jstree-leaf > .jstree-ocl { cursor:pointer; }
.jstree-anchor, .jstree-icon { position:relative; }
.jstree-wholerow { width:100%; cursor:pointer; position:absolute; left:0; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; }
}
// base contextmenu
.vakata-context {
display:none;
&, ul { margin:0; padding:2px; position:absolute; background:#f5f5f5; border:1px solid #979797; box-shadow:2px 2px 2px #999999; }
ul { list-style:none; left:100%; margin-top:-2.7em; margin-left:-4px; }
.vakata-context-right ul { left:auto; right:100%; margin-left:auto; margin-right:-4px; }
li {
list-style:none; display:inline;
> a {
display:block; padding:0 2em 0 2em; text-decoration:none; width:auto; color:black; white-space:nowrap; line-height:2.4em; text-shadow:1px 1px 0 white; border-radius:1px;
&:hover { position:relative; background-color:#e8eff7; box-shadow:0 0 2px #0a6aa1; }
&.vakata-context-parent { background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); background-position:right center; background-repeat:no-repeat; }
}
> a:focus { outline:0; }
}
.vakata-context-hover > a { position:relative; background-color:#e8eff7; box-shadow:0 0 2px #0a6aa1; }
.vakata-context-separator {
> a, > a:hover { background:white; border:0; border-top:1px solid #e2e3e3; height:1px; min-height:1px; max-height:1px; padding:0; margin:0 0 0 2.4em; border-left:1px solid #e0e0e0; text-shadow:0 0 0 transparent; box-shadow:0 0 0 transparent; border-radius:0; }
}
.vakata-contextmenu-disabled {
a, a:hover { color:silver; background-color:transparent; border:0; box-shadow:0 0 0; }
}
li > a {
> i { text-decoration:none; display:inline-block; width:2.4em; height:2.4em; background:transparent; margin:0 0 0 -2em; vertical-align:top; text-align:center; line-height:2.4em; }
> i:empty { width:2.4em; line-height:2.4em; }
.vakata-contextmenu-sep { display:inline-block; width:1px; height:2.4em; background:white; margin:0 0.5em 0 0; border-left:1px solid #e2e3e3; }
}
.vakata-contextmenu-shortcut { font-size:0.8em; color:silver; opacity:0.5; display:none; }
}
.vakata-context-rtl {
ul { left:auto; right:100%; margin-left:auto; margin-right:-4px; }
li > a.vakata-context-parent { background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); background-position:left center; background-repeat:no-repeat; }
.vakata-context-separator > a { margin:0 2.4em 0 0; border-left:0; border-right:1px solid #e2e3e3;}
.vakata-context-left ul { right:auto; left:100%; margin-left:-4px; margin-right:auto; }
li > a {
> i { margin:0 -2em 0 0; }
.vakata-contextmenu-sep { margin:0 0 0 0.5em; border-left-color:white; background:#e2e3e3; }
}
}
// base drag'n'drop
#jstree-marker { position: absolute; top:0; left:0; margin:-5px 0 0 0; padding:0; border-right:0; border-top:5px solid transparent; border-bottom:5px solid transparent; border-left:5px solid; width:0; height:0; font-size:0; line-height:0; }
#jstree-dnd {
line-height:16px;
margin:0;
padding:4px;
.jstree-icon,
.jstree-copy { display:inline-block; text-decoration:none; margin:0 2px 0 0; padding:0; width:16px; height:16px; }
.jstree-ok { background:green; }
.jstree-er { background:red; }
.jstree-copy { margin:0 2px 0 2px; }
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/* jsTree default dark theme */
@theme-name: default-dark;
@hovered-bg-color: #555;
@hovered-shadow-color: #555;
@disabled-color: #666666;
@disabled-bg-color: #333333;
@clicked-bg-color: #5fa2db;
@clicked-shadow-color: #666666;
@clicked-gradient-color-1: #5fa2db;
@clicked-gradient-color-2: #5fa2db;
@search-result-color: #ffffff;
@mobile-wholerow-bg-color: #333333;
@mobile-wholerow-shadow: #111111;
@mobile-wholerow-bordert: #666;
@mobile-wholerow-borderb: #000;
@responsive: true;
@image-path: "";
@base-height: 40px;
@import "../mixins.less";
@import "../base.less";
@import "../main.less";
.jstree-@{theme-name} {
background:#333;
.jstree-anchor { color:#999; text-shadow:1px 1px 0 rgba(0,0,0,0.5); }
.jstree-clicked, .jstree-checked { color:white; }
.jstree-hovered { color:white; }
#jstree-marker& {
border-left-color:#999;
background:transparent;
}
.jstree-anchor > .jstree-icon { opacity:0.75; }
.jstree-clicked > .jstree-icon,
.jstree-hovered > .jstree-icon,
.jstree-checked > .jstree-icon { opacity:1; }
}
// theme variants
.jstree-@{theme-name} {
&.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); }
&.jstree-rtl .jstree-last { background:transparent; }
}
.jstree-@{theme-name}-small {
&.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); }
&.jstree-rtl .jstree-last { background:transparent; }
}
.jstree-@{theme-name}-large {
&.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); }
&.jstree-rtl .jstree-last { background:transparent; }
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,22 @@
/* jsTree default theme */
@theme-name: default;
@hovered-bg-color: #e7f4f9;
@hovered-shadow-color: #cccccc;
@disabled-color: #666666;
@disabled-bg-color: #efefef;
@clicked-bg-color: #beebff;
@clicked-shadow-color: #999999;
@clicked-gradient-color-1: #beebff;
@clicked-gradient-color-2: #a8e4ff;
@search-result-color: #8b0000;
@mobile-wholerow-bg-color: #ebebeb;
@mobile-wholerow-shadow: #666666;
@mobile-wholerow-bordert: rgba(255,255,255,0.7);
@mobile-wholerow-borderb: rgba(64,64,64,0.2);
@responsive: true;
@image-path: "";
@base-height: 40px;
@import "../mixins.less";
@import "../base.less";
@import "../main.less";

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,75 @@
.jstree-@{theme-name} {
.jstree-node,
.jstree-icon { background-repeat:no-repeat; background-color:transparent; }
.jstree-anchor,
.jstree-wholerow { transition:background-color 0.15s, box-shadow 0.15s; }
.jstree-hovered { background:@hovered-bg-color; border-radius:2px; box-shadow:inset 0 0 1px @hovered-shadow-color; }
.jstree-clicked { background:@clicked-bg-color; border-radius:2px; box-shadow:inset 0 0 1px @clicked-shadow-color; }
.jstree-no-icons .jstree-anchor > .jstree-themeicon { display:none; }
.jstree-disabled {
background:transparent; color:@disabled-color;
&.jstree-hovered { background:transparent; box-shadow:none; }
&.jstree-clicked { background:@disabled-bg-color; }
> .jstree-icon { opacity:0.8; filter: url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\'><filter id=\'jstree-grayscale\'><feColorMatrix type=\'matrix\' values=\'0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0\'/></filter></svg>#jstree-grayscale"); /* Firefox 10+ */ filter: gray; /* IE6-9 */ -webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ }
}
// search
.jstree-search { font-style:italic; color:@search-result-color; font-weight:bold; }
// checkboxes
.jstree-no-checkboxes .jstree-checkbox { display:none !important; }
&.jstree-checkbox-no-clicked {
.jstree-clicked {
background:transparent;
box-shadow:none;
&.jstree-hovered { background:@hovered-bg-color; }
}
> .jstree-wholerow-ul .jstree-wholerow-clicked {
background:transparent;
&.jstree-wholerow-hovered { background:@hovered-bg-color; }
}
}
// stripes
> .jstree-striped { min-width:100%; display:inline-block; background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; }
// wholerow
> .jstree-wholerow-ul .jstree-hovered,
> .jstree-wholerow-ul .jstree-clicked { background:transparent; box-shadow:none; border-radius:0; }
.jstree-wholerow { -moz-box-sizing:border-box; -webkit-box-sizing:border-box; box-sizing:border-box; }
.jstree-wholerow-hovered { background:@hovered-bg-color; }
.jstree-wholerow-clicked { .gradient(@clicked-gradient-color-1, @clicked-gradient-color-2); }
}
// theme variants
.jstree-@{theme-name} {
.jstree-theme(24px, "@{image-path}32px.png", 32px);
&.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); }
&.jstree-rtl .jstree-last { background:transparent; }
}
.jstree-@{theme-name}-small {
.jstree-theme(18px, "@{image-path}32px.png", 32px);
&.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); }
&.jstree-rtl .jstree-last { background:transparent; }
}
.jstree-@{theme-name}-large {
.jstree-theme(32px, "@{image-path}32px.png", 32px);
&.jstree-rtl .jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); }
&.jstree-rtl .jstree-last { background:transparent; }
}
// mobile theme attempt
@media (max-width: 768px) {
#jstree-dnd.jstree-dnd-responsive when (@responsive = true) {
line-height:@base-height; font-weight:bold; font-size:1.1em; text-shadow:1px 1px white;
> i { background:transparent; width:@base-height; height:@base-height; }
> .jstree-ok { background-image:url("@{image-path}@{base-height}.png"); background-position:0 -(@base-height * 5); background-size:(@base-height * 3) (@base-height * 6); }
> .jstree-er { background-image:url("@{image-path}@{base-height}.png"); background-position:-(@base-height * 1) -(@base-height * 5); background-size:(@base-height * 3) (@base-height * 6); }
}
#jstree-marker.jstree-dnd-responsive when (@responsive = true) {
border-left-width:10px;
border-top-width:10px;
border-bottom-width:10px;
margin-top:-10px;
}
}
.jstree-@{theme-name}-responsive when (@responsive = true) {
@import "responsive.less";
}

View File

@ -0,0 +1,98 @@
.gradient (@color1; @color2) {
background:@color1;
background: -webkit-linear-gradient(top, @color1 0%,@color2 100%);
background: linear-gradient(to bottom, @color1 0%,@color2 100%);
}
.jstree-theme (@base-height, @image, @image-height) {
@correction: (@image-height - @base-height) / 2;
.jstree-node { min-height:@base-height; line-height:@base-height; margin-left:@base-height; min-width:@base-height; }
.jstree-anchor { line-height:@base-height; height:@base-height; }
.jstree-icon { width:@base-height; height:@base-height; line-height:@base-height; }
.jstree-icon:empty { width:@base-height; height:@base-height; line-height:@base-height; }
&.jstree-rtl .jstree-node { margin-right:@base-height; }
.jstree-wholerow { height:@base-height; }
.jstree-node,
.jstree-icon { background-image:url("@{image}"); }
.jstree-node { background-position:-(@image-height * 9 + @correction) -@correction; background-repeat:repeat-y; }
.jstree-last { background:transparent; }
.jstree-open > .jstree-ocl { background-position:-(@image-height * 4 + @correction) -@correction; }
.jstree-closed > .jstree-ocl { background-position:-(@image-height * 3 + @correction) -@correction; }
.jstree-leaf > .jstree-ocl { background-position:-(@image-height * 2 + @correction) -@correction; }
.jstree-themeicon { background-position:-(@image-height * 8 + @correction) -@correction; }
> .jstree-no-dots {
.jstree-node,
.jstree-leaf > .jstree-ocl { background:transparent; }
.jstree-open > .jstree-ocl { background-position:-(@image-height * 1 + @correction) -@correction; }
.jstree-closed > .jstree-ocl { background-position:-@correction -@correction; }
}
.jstree-disabled {
background:transparent;
&.jstree-hovered {
background:transparent;
}
&.jstree-clicked {
background:#efefef;
}
}
.jstree-checkbox {
background-position:-(@image-height * 5 + @correction) -@correction;
&:hover { background-position:-(@image-height * 5 + @correction) -(@image-height * 1 + @correction); }
}
&.jstree-checkbox-selection .jstree-clicked, .jstree-checked {
> .jstree-checkbox {
background-position:-(@image-height * 7 + @correction) -@correction;
&:hover { background-position:-(@image-height * 7 + @correction) -(@image-height * 1 + @correction); }
}
}
.jstree-anchor {
> .jstree-undetermined {
background-position:-(@image-height * 6 + @correction) -@correction;
&:hover {
background-position:-(@image-height * 6 + @correction) -(@image-height * 1 + @correction);
}
}
}
> .jstree-striped { background-size:auto (@base-height * 2); }
&.jstree-rtl {
.jstree-node { background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); background-position: 100% 1px; background-repeat:repeat-y; }
.jstree-last { background:transparent; }
.jstree-open > .jstree-ocl { background-position:-(@image-height * 4 + @correction) -(@image-height * 1 + @correction); }
.jstree-closed > .jstree-ocl { background-position:-(@image-height * 3 + @correction) -(@image-height * 1 + @correction); }
.jstree-leaf > .jstree-ocl { background-position:-(@image-height * 2 + @correction) -(@image-height * 1 + @correction); }
> .jstree-no-dots {
.jstree-node,
.jstree-leaf > .jstree-ocl { background:transparent; }
.jstree-open > .jstree-ocl { background-position:-(@image-height * 1 + @correction) -(@image-height * 1 + @correction); }
.jstree-closed > .jstree-ocl { background-position:-@correction -(@image-height * 1 + @correction); }
}
}
.jstree-themeicon-custom { background-color:transparent; background-image:none; background-position:0 0; }
> .jstree-container-ul .jstree-loading > .jstree-ocl { background:url("@{image-path}throbber.gif") center center no-repeat; }
.jstree-file { background:url("@{image}") -(@image-height * 3 + @correction) -(@image-height * 2 + @correction) no-repeat; }
.jstree-folder { background:url("@{image}") -(@image-height * 8 + @correction) -(@correction) no-repeat; }
> .jstree-container-ul > .jstree-node { margin-left:0; margin-right:0; }
// drag'n'drop
#jstree-dnd& {
line-height:@base-height; padding:0 4px;
.jstree-ok,
.jstree-er { background-image:url("@{image-path}32px.png"); background-repeat:no-repeat; background-color:transparent; }
i { background:transparent; width:@base-height; height:@base-height; line-height:@base-height; }
.jstree-ok { background-position: -(@correction) -(@image-height * 2 + @correction); }
.jstree-er { background-position: -(@image-height * 1 + @correction) -(@image-height * 2 + @correction); }
}
}

View File

@ -0,0 +1,66 @@
@media (max-width: 768px) {
// background image
.jstree-icon { background-image:url("@{image-path}@{base-height}.png"); }
.jstree-node,
.jstree-leaf > .jstree-ocl { background:transparent; }
.jstree-node { min-height:@base-height; line-height:@base-height; margin-left:@base-height; min-width:@base-height; white-space:nowrap; }
.jstree-anchor { line-height:@base-height; height:@base-height; }
.jstree-icon, .jstree-icon:empty { width:@base-height; height:@base-height; line-height:@base-height; }
> .jstree-container-ul > .jstree-node { margin-left:0; }
&.jstree-rtl .jstree-node { margin-left:0; margin-right:@base-height; }
&.jstree-rtl .jstree-container-ul > .jstree-node { margin-right:0; }
.jstree-ocl,
.jstree-themeicon,
.jstree-checkbox { background-size:(@base-height * 3) (@base-height * 6); }
.jstree-leaf > .jstree-ocl { background:transparent; }
.jstree-open > .jstree-ocl { background-position:0 0px !important; }
.jstree-closed > .jstree-ocl { background-position:0 -(@base-height * 1) !important; }
&.jstree-rtl .jstree-closed > .jstree-ocl { background-position:-(@base-height * 1) 0px !important; }
.jstree-themeicon { background-position:-(@base-height * 1) -(@base-height * 1); }
.jstree-checkbox, .jstree-checkbox:hover { background-position:-(@base-height * 1) -(@base-height * 2); }
&.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox,
&.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover,
.jstree-checked > .jstree-checkbox,
.jstree-checked > .jstree-checkbox:hover { background-position:0 -(@base-height * 2); }
.jstree-anchor > .jstree-undetermined, .jstree-anchor > .jstree-undetermined:hover { background-position:0 -(@base-height * 3); }
.jstree-anchor { font-weight:bold; font-size:1.1em; text-shadow:1px 1px white; }
> .jstree-striped { background:transparent; }
.jstree-wholerow { border-top:1px solid @mobile-wholerow-bordert; border-bottom:1px solid @mobile-wholerow-borderb; background:@mobile-wholerow-bg-color; height:@base-height; }
.jstree-wholerow-hovered { background:@hovered-bg-color; }
.jstree-wholerow-clicked { background:@clicked-bg-color; }
// thanks to PHOTONUI
.jstree-children .jstree-last > .jstree-wholerow { box-shadow: inset 0 -6px 3px -5px @mobile-wholerow-shadow; }
.jstree-children .jstree-open > .jstree-wholerow { box-shadow: inset 0 6px 3px -5px @mobile-wholerow-shadow; border-top:0; }
.jstree-children .jstree-open + .jstree-open { box-shadow:none; }
// experiment
.jstree-node,
.jstree-icon,
.jstree-node > .jstree-ocl,
.jstree-themeicon,
.jstree-checkbox { background-image:url("@{image-path}@{base-height}.png"); background-size:(@base-height * 3) (@base-height * 6); }
.jstree-node { background-position:-(@base-height * 2) 0; background-repeat:repeat-y; }
.jstree-last { background:transparent; }
.jstree-leaf > .jstree-ocl { background-position:-(@base-height * 1) -(@base-height * 3); }
.jstree-last > .jstree-ocl { background-position:-(@base-height * 1) -(@base-height * 4); }
/*
.jstree-open > .jstree-ocl,
.jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; }
*/
.jstree-themeicon-custom { background-color:transparent; background-image:none; background-position:0 0; }
.jstree-file { background:url("@{image-path}@{base-height}.png") 0 -(@base-height * 4) no-repeat; background-size:(@base-height * 3) (@base-height * 6); }
.jstree-folder { background:url("@{image-path}@{base-height}.png") -(@base-height * 1) -(@base-height * 1) no-repeat; background-size:(@base-height * 3) (@base-height * 6); }
> .jstree-container-ul > .jstree-node { margin-left:0; margin-right:0; }
}

View File

@ -0,0 +1,38 @@
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define('jstree.checkbox', ['jquery','jstree'], factory);
}
else if(typeof exports === 'object') {
factory(require('jquery'), require('jstree'));
}
else {
factory(jQuery);
}
}(function ($, undefined) {
"use strict";
if(document.registerElement && Object && Object.create) {
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function () {
var c = { core : {}, plugins : [] }, i;
for(i in $.jstree.plugins) {
if($.jstree.plugins.hasOwnProperty(i) && this.attributes[i]) {
c.plugins.push(i);
if(this.getAttribute(i) && JSON.parse(this.getAttribute(i))) {
c[i] = JSON.parse(this.getAttribute(i));
}
}
}
for(i in $.jstree.defaults.core) {
if($.jstree.defaults.core.hasOwnProperty(i) && this.attributes[i]) {
c.core[i] = JSON.parse(this.getAttribute(i)) || this.getAttribute(i);
}
}
$(this).jstree(c);
};
// proto.attributeChangedCallback = function (name, previous, value) { };
try {
document.registerElement("vakata-jstree", { prototype: proto });
} catch(ignore) { }
}
}));

View File

@ -1,6 +1,6 @@
{
"name": "paper-behaviors",
"version": "1.0.2",
"version": "1.0.3",
"description": "Common behaviors across the paper elements",
"authors": [
"The Polymer Authors"
@ -36,13 +36,13 @@
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.2",
"_release": "1.0.3",
"_resolution": {
"type": "version",
"tag": "v1.0.2",
"commit": "4dd226a2cc5b780a73d0058cd9998b6e0af1cb2c"
"tag": "v1.0.3",
"commit": "90b54de14264c19693601b9fc16af6b68a9d48e4"
},
"_source": "git://github.com/polymerelements/paper-behaviors.git",
"_source": "git://github.com/PolymerElements/paper-behaviors.git",
"_target": "^1.0.0",
"_originalSource": "polymerelements/paper-behaviors"
"_originalSource": "PolymerElements/paper-behaviors"
}

View File

@ -1,6 +1,6 @@
{
"name": "paper-behaviors",
"version": "1.0.2",
"version": "1.0.3",
"description": "Common behaviors across the paper elements",
"authors": [
"The Polymer Authors"

View File

@ -34,7 +34,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</style>
</head>
<body>
<body unresolved>
<h3>Normal</h3>

View File

@ -1,6 +1,6 @@
{
"name": "paper-button",
"version": "1.0.2",
"version": "1.0.3",
"description": "Material design button",
"authors": [
"The Polymer Authors"
@ -36,11 +36,11 @@
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.2",
"_release": "1.0.3",
"_resolution": {
"type": "version",
"tag": "v1.0.2",
"commit": "e804f62099c79f909ec9f94d78b790bff7b88682"
"tag": "v1.0.3",
"commit": "f50a40fa1bf3ab20aaad413769452ed69b14ef66"
},
"_source": "git://github.com/PolymerElements/paper-button.git",
"_target": "~1.0.1",

View File

@ -1,6 +1,6 @@
{
"name": "paper-button",
"version": "1.0.2",
"version": "1.0.3",
"description": "Material design button",
"authors": [
"The Polymer Authors"

View File

@ -19,7 +19,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<title>paper-button demo</title>
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../../paper-styles/paper-styles.html">
<link rel="import" href="../../paper-styles/color.html">
<link rel="import" href="../../paper-styles/demo-pages.html">
<link rel="import" href="../../iron-icons/iron-icons.html">
<link rel="import" href="../paper-button.html">
@ -103,8 +103,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</style>
</head>
<body>
<div class="horizontal center-justified layout">
<body unresolved>
<div class="horizontal-section-container">
<div>
<h4>Flat</h4>
<div class="horizontal-section">

View File

@ -26,6 +26,11 @@ Example:
<paper-button>flat button</paper-button>
<paper-button raised>raised button</paper-button>
<paper-button noink>No ripple effect</paper-button>
<paper-button toggles>toggle-able button</paper-button>
A button that has `toggles` true will remain `active` after being clicked (and
will have an `active` attribute set). For more information, see the `Polymer.IronButtonState`
behavior.
You may use custom DOM in the button body to create a variety of buttons. For example, to
create a button with an icon and some text:

View File

@ -1,7 +1,7 @@
{
"name": "paper-dialog",
"description": "A Material Design dialog",
"version": "1.0.0",
"version": "1.0.1",
"authors": "The Polymer Authors",
"keywords": [
"web-components",
@ -32,14 +32,13 @@
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.0",
"_release": "1.0.1",
"_resolution": {
"type": "version",
"tag": "v1.0.0",
"commit": "6d66cf1e022e56ec28353a2f718e93535c7cac20"
"tag": "v1.0.1",
"commit": "1339718c67ef50add5221dd63d35e03a54fb619f"
},
"_source": "git://github.com/PolymerElements/paper-dialog.git",
"_target": "~1.0.0",
"_originalSource": "PolymerElements/paper-dialog",
"_direct": true
"_originalSource": "PolymerElements/paper-dialog"
}

View File

@ -1,7 +1,7 @@
{
"name": "paper-dialog",
"description": "A Material Design dialog",
"version": "1.0.0",
"version": "1.0.1",
"authors": "The Polymer Authors",
"keywords": [
"web-components",

View File

@ -59,7 +59,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</style>
</head>
<body>
<body unresolved>
<section onclick="clickHandler(event)">
<h4>Dialog layouts</h4>
@ -128,7 +128,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<section onclick="clickHandler(event)">
<h4>Transitions</h4>
<paper-button data-dialog="animated">transitions</paper-button>
<paper-dialog id="animated" with-backdrop entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
<paper-dialog id="animated" entry-animation="scale-up-animation" exit-animation="fade-out-animation" with-backdrop>
<h2>Dialog Title</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</paper-dialog>
@ -140,7 +140,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
while (!button.hasAttribute('data-dialog') && button !== document.body) {
button = button.parentElement;
}
if (!button.hasAttribute('data-dialog')) {
return;
}

View File

@ -1,6 +1,6 @@
{
"name": "paper-fab",
"version": "1.0.2",
"version": "1.0.3",
"description": "A material design floating action button",
"authors": [
"The Polymer Authors"
@ -36,14 +36,13 @@
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.2",
"_release": "1.0.3",
"_resolution": {
"type": "version",
"tag": "v1.0.2",
"commit": "59d2f77f456271f1ae4059b92d83ba7655fb1580"
"tag": "v1.0.3",
"commit": "0371767ba859a842ffd07dfbdf574206c1d7294f"
},
"_source": "git://github.com/PolymerElements/paper-fab.git",
"_target": "~1.0.2",
"_originalSource": "PolymerElements/paper-fab",
"_direct": true
"_originalSource": "PolymerElements/paper-fab"
}

View File

@ -1,6 +1,6 @@
{
"name": "paper-fab",
"version": "1.0.2",
"version": "1.0.3",
"description": "A material design floating action button",
"authors": [
"The Polymer Authors"

View File

@ -18,7 +18,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<title>paper-fab demo</title>
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../../paper-styles/paper-styles.html">
<link rel="import" href="../../paper-styles/color.html">
<link rel="import" href="../../paper-styles/demo-pages.html">
<link rel="import" href="../../iron-icons/iron-icons.html">
<link rel="import" href="../paper-fab.html">
@ -58,8 +58,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</style>
</head>
<body>
<div class="horizontal center-justified layout">
<body unresolved>
<div class="horizontal-section-container">
<div>
<h4>Enabled</h4>
<div class="horizontal-section">

View File

@ -1,7 +1,7 @@
{
"name": "paper-icon-button",
"private": true,
"version": "1.0.2",
"version": "1.0.3",
"license": "http://polymer.github.io/LICENSE.txt",
"description": "A material design icon button",
"main": "paper-icon-button.html",
@ -15,6 +15,10 @@
"icon",
"control"
],
"repository": {
"type": "git",
"url": "git://github.com/PolymerElements/paper-icon-button.git"
},
"dependencies": {
"iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
"iron-icon": "polymerelements/iron-icon#^1.0.0",
@ -31,14 +35,13 @@
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"homepage": "https://github.com/PolymerElements/paper-icon-button",
"_release": "1.0.2",
"_release": "1.0.3",
"_resolution": {
"type": "version",
"tag": "v1.0.2",
"commit": "b22ade2080f2527760eae41e4700c52d4689a866"
"tag": "v1.0.3",
"commit": "9f183bdae3ff419aeae78a51a05fcc4d0100e5a3"
},
"_source": "git://github.com/PolymerElements/paper-icon-button.git",
"_target": "~1.0.2",
"_originalSource": "PolymerElements/paper-icon-button",
"_direct": true
"_originalSource": "PolymerElements/paper-icon-button"
}

View File

@ -1,7 +1,7 @@
{
"name": "paper-icon-button",
"private": true,
"version": "1.0.2",
"version": "1.0.3",
"license": "http://polymer.github.io/LICENSE.txt",
"description": "A material design icon button",
"main": "paper-icon-button.html",
@ -15,6 +15,10 @@
"icon",
"control"
],
"repository": {
"type": "git",
"url": "git://github.com/PolymerElements/paper-icon-button.git"
},
"dependencies": {
"iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
"iron-icon": "polymerelements/iron-icon#^1.0.0",

View File

@ -15,7 +15,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../../iron-icons/iron-icons.html">
<link rel="import" href="../../paper-styles/paper-styles.html">
<link rel="import" href="../../paper-styles/color.html">
<link rel="import" href="../../paper-styles/demo-pages.html">
<link rel="import" href="../paper-icon-button.html">
@ -86,9 +86,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</head>
<body onclick="clickAction(event);">
<body onclick="clickAction(event);" unresolved>
<div class="horizontal center-justified layout">
<div class="horizontal-section-container">
<div>
<h4>Enabled</h4>
<div class="horizontal-section">

View File

@ -77,6 +77,7 @@ Custom property | Description | Default
position: relative;
padding: 8px;
outline: none;
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;

View File

@ -1,6 +1,6 @@
{
"name": "paper-input",
"version": "1.0.5",
"version": "1.0.6",
"description": "Material design text fields",
"authors": [
"The Polymer Authors"
@ -42,11 +42,11 @@
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.5",
"_release": "1.0.6",
"_resolution": {
"type": "version",
"tag": "v1.0.5",
"commit": "72821a081710d9d5443e7b2311ff561def260807"
"tag": "v1.0.6",
"commit": "327605642c1bfa5366c0d3effc638b81f24c3adc"
},
"_source": "git://github.com/PolymerElements/paper-input.git",
"_target": "^1.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "paper-input",
"version": "1.0.5",
"version": "1.0.6",
"description": "Material design text fields",
"authors": [
"The Polymer Authors"

View File

@ -230,6 +230,24 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
type: Number
},
// Nonstandard attributes for binding if needed
/**
* Bind this to the `<input is="iron-input">`'s `autocapitalize` property.
*/
autocapitalize: {
type: String,
value: 'none'
},
/**
* Bind this to the `<input is="iron-input">`'s `autocorrect` property.
*/
autocorrect: {
type: String,
value: 'off'
},
_ariaDescribedBy: {
type: String,
value: ''
@ -241,6 +259,10 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
'addon-attached': '_onAddonAttached'
},
observers: [
'_focusedControlStateChanged(focused)'
],
/**
* Returns a reference to the input element.
*/
@ -305,6 +327,24 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
return placeholder || alwaysFloatLabel;
},
_focusedControlStateChanged: function(focused) {
// IronControlState stops the focus and blur events in order to redispatch them on the host
// element, but paper-input-container listens to those events. Since there are more
// pending work on focus/blur in IronControlState, I'm putting in this hack to get the
// input focus state working for now.
if (!this.$.container) {
this.$.container = Polymer.dom(this.root).querySelector('paper-input-container');
if (!this.$.container) {
return;
}
}
if (focused) {
this.$.container._onFocus();
} else {
this.$.container._onBlur();
}
},
_updateAriaLabelledBy: function() {
var label = Polymer.dom(this.root).querySelector('label');
if (!label) {
@ -323,6 +363,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
};
/** @polymerBehavior */
Polymer.PaperInputBehavior = [Polymer.IronControlState, Polymer.PaperInputBehaviorImpl];
</script>

View File

@ -65,7 +65,11 @@ Custom property | Description | Default
`--paper-input-container-input-color` | Input foreground color | `--primary-text-color`
`--paper-input-container` | Mixin applied to the container | `{}`
`--paper-input-container-label` | Mixin applied to the label | `{}`
`--paper-input-container-label-focus` | Mixin applied to the label when the input is focused | `{}`
`--paper-input-container-input` | Mixin applied to the input | `{}`
`--paper-input-container-underline` | Mixin applied to the underline | `{}`
`--paper-input-container-underline-focus` | Mixin applied to the underline when the input is focued | `{}`
`--paper-input-container-underline-disabled` | Mixin applied to the underline when the input is disabled | `{}`
This element is `display:block` by default, but you can set the `inline` attribute to make it
`display:inline-block`.
@ -107,6 +111,8 @@ This element is `display:block` by default, but you can set the `inline` attribu
transform: scale3d(0,1,1);
background: var(--paper-input-container-focus-color, --default-primary-color);
@apply(--paper-input-container-underline-focus);
}
.underline.is-highlighted .focused-line {
@ -132,12 +138,16 @@ This element is `display:block` by default, but you can set the `inline` attribu
.unfocused-line {
height: 1px;
background: var(--paper-input-container-color, --secondary-text-color);
@apply(--paper-input-container-underline);
}
:host([disabled]) .unfocused-line {
border-bottom: 1px dashed;
border-color: var(--paper-input-container-color, --secondary-text-color);
background: transparent;
@apply(--paper-input-container-underline-disabled);
}
.input-content {
@ -172,6 +182,8 @@ This element is `display:block` by default, but you can set the `inline` attribu
.input-content.label-is-highlighted ::content label,
.input-content.label-is-highlighted ::content .paper-input-label {
color: var(--paper-input-container-focus-color, --default-primary-color);
@apply(--paper-input-container-label-focus);
}
.input-content.is-invalid ::content label,

View File

@ -35,8 +35,8 @@ Custom property | Description | Default
<style>
:host {
/* need to use display: none for role="alert" */
display: none;
display: inline-block;
visibility: hidden;
float: left;
color: var(--paper-input-container-invalid-color, --google-red-500);
@ -46,7 +46,7 @@ Custom property | Description | Default
}
:host([invalid]) {
display: inline-block;
visibility: visible;
};
</style>
@ -71,10 +71,6 @@ Custom property | Description | Default
Polymer.PaperInputAddonBehavior
],
hostAttributes: {
'role': 'alert'
},
properties: {
/**

View File

@ -91,7 +91,9 @@ style this element.
placeholder$="[[placeholder]]"
readonly$="[[readonly]]"
list$="[[list]]"
size$="[[size]]">
size$="[[size]]"
autocapitalize$="[[autocapitalize]]"
autocorrect$="[[autocorrect]]">
<template is="dom-if" if="[[errorMessage]]">
<paper-input-error>[[errorMessage]]</paper-input-error>
@ -116,6 +118,7 @@ style this element.
is: 'paper-input',
behaviors: [
Polymer.IronFormElementBehavior,
Polymer.PaperInputBehavior,
Polymer.IronControlState
]

View File

@ -9,7 +9,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../iron-autogrow-textarea/iron-autogrow-textarea.html">
<link rel="import" href="../iron-form-element-behavior/iron-form-element-behavior.html">
<link rel="import" href="paper-input-behavior.html">
<link rel="import" href="paper-input-container.html">
<link rel="import" href="paper-input-error.html">
@ -48,7 +47,8 @@ style this element.
placeholder$="[[placeholder]]"
readonly$="[[readonly]]"
required$="[[required]]"
maxlength$="[[maxlength]]"></iron-autogrow-textarea>
maxlength$="[[maxlength]]"
autocapitalize$="[[autocapitalize]]"></iron-autogrow-textarea>
<template is="dom-if" if="[[errorMessage]]">
<paper-input-error>[[errorMessage]]</paper-input-error>
@ -73,8 +73,7 @@ style this element.
is: 'paper-textarea',
behaviors: [
Polymer.PaperInputBehavior,
Polymer.IronFormElementBehavior
Polymer.PaperInputBehavior
],
properties: {

View File

@ -21,6 +21,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<script src="../../web-component-tester/browser.js"></script>
<script src="../../test-fixture/test-fixture-mocha.js"></script>
<script src="../../iron-test-helpers/mock-interactions.js"></script>
<link rel="import" href="../../test-fixture/test-fixture.html">
<link rel="import" href="../../iron-input/iron-input.html">
<link rel="import" href="../paper-input-container.html">
@ -141,11 +143,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
var label = Polymer.dom(container).querySelector('#l');
var input = Polymer.dom(container).querySelector('#i');
var inputContent = Polymer.dom(container.root).querySelector('.input-content');
input.focus();
// 'focus' event isn't firing on windows ff for some reason when you call focus()
container._onFocus();
MockInteractions.focus(input);
requestAnimationFrame(function() {
assert.equal(document.activeElement, input, 'input is focused');
assert.isTrue(container.focused, 'focused is true');
assert.isTrue(inputContent.classList.contains('label-is-highlighted'), 'label is highlighted when input has focus');
done();
@ -157,8 +156,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
var label = Polymer.dom(container).querySelector('#l');
var input = Polymer.dom(container).querySelector('#i');
var inputContent = Polymer.dom(container.root).querySelector('.input-content');
input.focus();
container._onFocus();
MockInteractions.focus(input);
requestAnimationFrame(function() {
assert.isFalse(inputContent.classList.contains('label-is-highlighted'), 'label is not highlighted when input has focus and has null value');
done();
@ -170,10 +168,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
var input = Polymer.dom(container).querySelector('#i');
var line = Polymer.dom(container.root).querySelector('.underline');
assert.isFalse(line.classList.contains('is-highlighted'), 'line is not highlighted when input is not focused');
input.focus();
container._onFocus();
MockInteractions.focus(input);
requestAnimationFrame(function() {
assert.equal(document.activeElement, input, 'input is focused');
assert.isTrue(line.classList.contains('is-highlighted'), 'line is highlighted when input is focused');
done();
});

View File

@ -52,9 +52,9 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
var container = fixture('auto-validate-numbers');
var input = Polymer.dom(container).querySelector('#i');
var error = Polymer.dom(container).querySelector('#e');
assert.equal(getComputedStyle(error).display, 'none', 'error is display:none');
assert.equal(getComputedStyle(error).visibility, 'hidden', 'error is visibility:hidden');
input.bindValue = 'foobar';
assert.notEqual(getComputedStyle(error).display, 'none', 'error is not display:none');
assert.notEqual(getComputedStyle(error).visibility, 'hidden', 'error is not visibility:hidden');
});
test('error message add on is registered', function() {

View File

@ -22,6 +22,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<script src="../../test-fixture/test-fixture-mocha.js"></script>
<script src="../../iron-test-helpers/test-helpers.js"></script>
<script src="../../iron-test-helpers/mock-interactions.js"></script>
<link rel="import" href="../../test-fixture/test-fixture.html">
<link rel="import" href="../paper-input.html">
@ -42,6 +43,12 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</template>
</test-fixture>
<test-fixture id="label-has-value">
<template>
<paper-input label="foo" value="bar"></paper-input>
</template>
</test-fixture>
<test-fixture id="error">
<template>
<paper-input auto-validate pattern="[0-9]*" value="foobar" error-message="error"></paper-input>
@ -177,7 +184,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
// setTimeout to wait for potentially more, erroneous events
setTimeout(function() {
assert.equal(nFocusEvents, 1, 'one focus event fired');
input.inputElement.blur();
MockInteractions.blur(input.inputElement);
});
});
input.addEventListener('blur', function() {
@ -188,11 +195,28 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
done();
});
});
input.inputElement.focus();
MockInteractions.focus(input.inputElement);
});
});
suite('focused styling (integration test)', function() {
test('underline is colored when input is focused', function(done) {
var input = fixture('basic');
var container = Polymer.dom(input.root).querySelector('paper-input-container');
var line = Polymer.dom(container.root).querySelector('.underline');
assert.isFalse(line.classList.contains('is-highlighted'), 'line is not highlighted when input is not focused');
MockInteractions.focus(input.inputElement);
requestAnimationFrame(function() {
assert.isTrue(line.classList.contains('is-highlighted'), 'line is highlighted when input is focused');
done();
});
});
});
suite('validation', function() {
test('invalid attribute updated after calling validate()', function() {

View File

@ -22,6 +22,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<script src="../../test-fixture/test-fixture-mocha.js"></script>
<script src="../../iron-test-helpers/test-helpers.js"></script>
<script src="../../iron-test-helpers/mock-interactions.js"></script>
<link rel="import" href="../../test-fixture/test-fixture.html">
<link rel="import" href="../paper-textarea.html">
@ -140,23 +141,17 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
test('focus/blur events fired on host element', function(done) {
var nFocusEvents = 0;
var nBlurEvents = 0;
input.addEventListener('focus', function() {
input.addEventListener('focus', function(event) {
nFocusEvents += 1;
// setTimeout to wait for potentially more, erroneous events
setTimeout(function() {
assert.equal(nFocusEvents, 1, 'one focus event fired');
input.inputElement.textarea.blur();
});
MockInteractions.blur(input.inputElement.textarea);
});
input.addEventListener('blur', function() {
nBlurEvents += 1;
// setTimeout to wait for potentially more, erroneous events
setTimeout(function() {
assert.equal(nBlurEvents, 1, 'one blur event fired');
done();
});
assert.isTrue(nFocusEvents >= 1, 'focus event fired');
assert.isTrue(nBlurEvents >= 1, 'blur event fired');
done();
});
input.inputElement.textarea.focus();
MockInteractions.focus(input.inputElement.textarea);
});
});

View File

@ -1,6 +1,6 @@
{
"name": "paper-material",
"version": "1.0.0",
"version": "1.0.1",
"description": "A material design container that looks like a lifted sheet of paper",
"private": true,
"authors": [
@ -33,11 +33,11 @@
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.0",
"_release": "1.0.1",
"_resolution": {
"type": "version",
"tag": "v1.0.0",
"commit": "bd769d2b8c4f9ab000aee22582d76b5935793dc1"
"tag": "v1.0.1",
"commit": "1663016f2b9f1deb197cfa93ef16d45d3de815c8"
},
"_source": "git://github.com/polymerelements/paper-material.git",
"_target": "^1.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "paper-material",
"version": "1.0.0",
"version": "1.0.1",
"description": "A material design container that looks like a lifted sheet of paper",
"private": true,
"authors": [

View File

@ -24,7 +24,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<link rel="stylesheet" href="../../paper-styles/demo.css">
</head>
<body>
<body unresolved>
<template is="dom-bind" id="demo">
<style>
paper-material {

View File

@ -1,6 +1,6 @@
{
"name": "paper-menu",
"version": "1.0.0",
"version": "1.0.1",
"description": "Implements an accessible material design menu",
"authors": "The Polymer Authors",
"keywords": [
@ -29,14 +29,13 @@
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.0",
"_release": "1.0.1",
"_resolution": {
"type": "version",
"tag": "v1.0.0",
"commit": "0642450ec9df0fc0b1d909842f436c3dea79ed1e"
"tag": "v1.0.1",
"commit": "137caedb322ab2464730d7b1776e5c88989d2c3f"
},
"_source": "git://github.com/PolymerElements/paper-menu.git",
"_target": "~1.0.0",
"_originalSource": "PolymerElements/paper-menu",
"_direct": true
"_originalSource": "PolymerElements/paper-menu"
}

View File

@ -1,6 +1,6 @@
{
"name": "paper-menu",
"version": "1.0.0",
"version": "1.0.1",
"description": "Implements an accessible material design menu",
"authors": "The Polymer Authors",
"keywords": [

View File

@ -21,7 +21,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<link rel="import" href="../../paper-item/paper-item.html">
<link rel="import" href="../paper-menu.html">
<link rel="import" href="../../paper-styles/paper-styles.html">
<link rel="import" href="../../paper-styles/demo-pages.html">
<style>
@ -39,8 +38,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
}
</style>
</head>
<body>
<div class="horizontal center-justified layout">
<body unresolved>
<div class="horizontal-section-container">
<div>
<h4>Standard</h4>
<div class="horizontal-section">

View File

@ -21,6 +21,13 @@ is highlighted, and the selected item has bolded text.
<paper-item>Item 2</paper-item>
</paper-menu>
An initial selection can be specified with the `selected` attribute.
<paper-menu selected="0">
<paper-item>Item 1</paper-item>
<paper-item>Item 2</paper-item>
</paper-menu>
Make a multi-select menu with the `multi` attribute. Items in a multi-select menu can be deselected,
and multiple item can be selected.
@ -36,7 +43,7 @@ The following custom properties and mixins are available for styling:
Custom property | Description | Default
----------------|-------------|----------
`--paper-menu-background-color` | Menu background color | `--primary-background-color`
`-paper-menu-color` | Menu foreground color | `--primary-text-color`
`--paper-menu-color` | Menu foreground color | `--primary-text-color`
`--paper-menu-disabled-color` | Foreground color for a disabled item | `--disabled-text-color`
`--paper-menu` | Mixin applied to the menu | `{}`
`--paper-menu-selected-item` | Mixin applied to the selected item | `{}`
@ -85,7 +92,7 @@ of a menu item will also focus it.
position: relative;
outline: 0;
@apply(--paper-menu-colored-focused-item);
@apply(--paper-menu-focused-item);
}
.content > ::content > *:focus:after {
@ -95,7 +102,7 @@ of a menu item will also focus it.
opacity: 0.12;
content: '';
@apply(--paper-menu-colored-focused-item-after);
@apply(--paper-menu-focused-item-after);
}
.content > ::content > *[colored]:focus:after {

View File

@ -1,6 +1,6 @@
{
"name": "paper-progress",
"version": "1.0.0",
"version": "1.0.1",
"license": "http://polymer.github.io/LICENSE.txt",
"description": "A material design progress bar",
"authors": "The Polymer Authors",
@ -29,11 +29,11 @@
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"homepage": "https://github.com/PolymerElements/paper-progress",
"_release": "1.0.0",
"_release": "1.0.1",
"_resolution": {
"type": "version",
"tag": "v1.0.0",
"commit": "1bef80a0d4110654b85746e70c006796ce8cdc2c"
"tag": "v1.0.1",
"commit": "5171a785bd63e9687473d4b708f1b82137d4d9a5"
},
"_source": "git://github.com/PolymerElements/paper-progress.git",
"_target": "^1.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "paper-progress",
"version": "1.0.0",
"version": "1.0.1",
"license": "http://polymer.github.io/LICENSE.txt",
"description": "A material design progress bar",
"authors": "The Polymer Authors",

View File

@ -1,11 +1,11 @@
<!--
@license
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
The complete set of authors may be found at http://polymer.github.io/AUTHORS
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<!doctype html>
<html>
@ -17,7 +17,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<meta name="apple-mobile-web-app-capable" content="yes">
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../../paper-styles/paper-styles.html">
<link rel="import" href="../../paper-styles/color.html">
<link rel="import" href="../../paper-styles/demo-pages.html">
<link rel="import" href="../paper-progress.html">
<link rel="import" href="../../paper-button/paper-button.html">
@ -56,8 +56,8 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</style>
</head>
<body>
<div class="vertical layout">
<body unresolved>
<div class="vertical-section-container">
<h4>Progress bar</h4>
<div class="vertical-section">
<paper-progress></paper-progress>
@ -67,7 +67,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<h4>Indeterminate</h4>
<div class="vertical-section">
<paper-progress indeterminate></paper-progress><br>
<paper-progress class="blue" indeterminate alue="800" min="100" max="1000"></paper-progress><br>
<paper-progress class="blue" indeterminate value="800" min="100" max="1000"></paper-progress><br>
</div>
<h4>Color</h4>

View File

@ -1,13 +1,14 @@
<!--
@license
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
The complete set of authors may be found at http://polymer.github.io/AUTHORS
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../paper-styles/paper-styles.html">
<link rel="import" href="../iron-range-behavior/iron-range-behavior.html">
<link rel="import" href="../iron-flex-layout/classes/iron-flex-layout.html">

View File

@ -2,11 +2,11 @@
<!--
@license
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
The complete set of authors may be found at http://polymer.github.io/AUTHORS
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>

View File

@ -2,11 +2,11 @@
<!--
@license
Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE
The complete set of authors may be found at http://polymer.github.io/AUTHORS
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->
<html>
<head>

View File

@ -26,14 +26,14 @@
"web-component-tester": "*",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"homepage": "https://github.com/polymerelements/paper-ripple",
"homepage": "https://github.com/PolymerElements/paper-ripple",
"_release": "1.0.1",
"_resolution": {
"type": "version",
"tag": "v1.0.1",
"commit": "af19d904802437c305390bb03415c11661de3d0a"
},
"_source": "git://github.com/polymerelements/paper-ripple.git",
"_source": "git://github.com/PolymerElements/paper-ripple.git",
"_target": "^1.0.0",
"_originalSource": "polymerelements/paper-ripple"
"_originalSource": "PolymerElements/paper-ripple"
}

View File

@ -1,6 +1,6 @@
{
"name": "paper-spinner",
"version": "1.0.1",
"version": "1.0.2",
"description": "A material design spinner",
"authors": [
"The Polymer Authors"
@ -30,14 +30,13 @@
"test-fixture": "PolymerElements/test-fixture#^1.0.0",
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.1",
"_release": "1.0.2",
"_resolution": {
"type": "version",
"tag": "v1.0.1",
"commit": "5e2b7412922259c9eed1805d69abb18e433efaad"
"tag": "v1.0.2",
"commit": "18bda194750ace719102d54c17ae1c6ce4a6793e"
},
"_source": "git://github.com/PolymerElements/paper-spinner.git",
"_target": "~1.0.1",
"_originalSource": "PolymerElements/paper-spinner",
"_direct": true
"_originalSource": "PolymerElements/paper-spinner"
}

View File

@ -1,6 +1,6 @@
{
"name": "paper-spinner",
"version": "1.0.1",
"version": "1.0.2",
"description": "A material design spinner",
"authors": [
"The Polymer Authors"

View File

@ -14,7 +14,6 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
<meta charset="UTF-8">
<title>paper-spinner demo</title>
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../../paper-styles/paper-styles.html">
<link rel="import" href="../../paper-styles/demo-pages.html">
<link rel="import" href="../paper-spinner.html">
@ -60,14 +59,14 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
</style>
</head>
<body>
<div class="horizontal center-justified layout">
<body unresolved>
<div class="horizontal-section-container">
<div>
<h4>Default</h4>
<div class="horizontal-section">
<paper-spinner></paper-spinner>
<paper-spinner active></paper-spinner>
<paper-spinner active></paper-spinner>
<paper-spinner active></paper-spinner>
<paper-spinner></paper-spinner>
<paper-spinner active></paper-spinner>
<button onclick="toggle(event)">Toggle</button>
</div>

View File

@ -26,7 +26,7 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
* SHRINK_TIME = 400ms
*/
:host {
:host {
display: inline-block;
position: relative;
width: 28px; /* CONTAINERWIDTH */
@ -36,6 +36,11 @@ subject to an additional IP rights grant found at http://polymer.github.io/PATEN
#spinnerContainer {
width: 100%;
height: 100%;
/* The spinner does not have any contents that would have to be
* flipped if the direction changes. Always use ltr so that the
* style works out correctly in both cases. */
direction: ltr;
}
#spinnerContainer.active {

View File

@ -99,123 +99,101 @@ Custom property | Description | Default
<script>
(function() {
Polymer({
'use strict';
is: 'paper-spinner',
function classNames(obj) {
var classNames = [];
for (var key in obj) {
if (obj.hasOwnProperty(key) && obj[key]) {
classNames.push(key);
}
listeners: {
'animationend': 'reset',
'webkitAnimationEnd': 'reset'
},
properties: {
/**
* Displays the spinner.
*
* @attribute active
* @type boolean
* @default false
*/
active: {
type: Boolean,
value: false,
reflectToAttribute: true,
observer: '_activeChanged'
},
/**
* Alternative text content for accessibility support.
* If alt is present, it will add an aria-label whose content matches alt when active.
* If alt is not present, it will default to 'loading' as the alt value.
*
* @attribute alt
* @type string
* @default 'loading'
*/
alt: {
type: String,
value: 'loading',
observer: '_altChanged'
},
/**
* True when the spinner is going from active to inactive. This is represented by a fade
* to 0% opacity to the user.
*/
_coolingDown: {
type: Boolean,
value: false
},
_spinnerContainerClassName: {
type: String,
computed: '_computeSpinnerContainerClassName(active, _coolingDown)'
}
return classNames.join(' ');
},
_computeSpinnerContainerClassName: function(active, coolingDown) {
return [
active || coolingDown ? 'active' : '',
coolingDown ? 'cooldown' : ''
].join(' ');
},
_activeChanged: function(active, old) {
this._setAriaHidden(!active);
if (!active && old) {
this._coolingDown = true;
}
},
_altChanged: function(alt) {
// user-provided `aria-label` takes precedence over prototype default
if (alt === this.getPropertyInfo('alt').value) {
this.alt = this.getAttribute('aria-label') || alt;
} else {
this._setAriaHidden(alt==='');
this.setAttribute('aria-label', alt);
}
},
_setAriaHidden: function(hidden) {
var attr = 'aria-hidden';
if (hidden) {
this.setAttribute(attr, 'true');
} else {
this.removeAttribute(attr);
}
},
reset: function() {
this.active = false;
this._coolingDown = false;
}
Polymer({
is: 'paper-spinner',
listeners: {
'animationend': 'reset',
'webkitAnimationEnd': 'reset'
},
properties: {
/**
* Displays the spinner.
*
* @attribute active
* @type boolean
* @default false
*/
active: {
observer: '_activeChanged',
type: Boolean,
value: false
},
/**
* Alternative text content for accessibility support.
* If alt is present, it will add an aria-label whose content matches alt when active.
* If alt is not present, it will default to 'loading' as the alt value.
*
* @attribute alt
* @type string
* @default 'loading'
*/
alt: {
observer: '_altChanged',
type: String,
value: 'loading'
},
/**
* True when the spinner is going from active to inactive. This is represented by a fade
* to 0% opacity to the user.
*/
_coolingDown: {
type: Boolean,
value: false
},
_spinnerContainerClassName: {
type: String,
computed: '_computeSpinnerContainerClassName(active, _coolingDown)'
}
},
_computeSpinnerContainerClassName: function(active, _coolingDown) {
return classNames({
active: active || _coolingDown,
cooldown: _coolingDown
});
},
ready: function() {
// Allow user-provided `aria-label` take preference to any other text alternative.
if (this.hasAttribute('aria-label')) {
this.alt = this.getAttribute('aria-label');
} else {
this.setAttribute('aria-label', this.alt);
}
if (!this.active) {
this.setAttribute('aria-hidden', 'true');
}
},
_activeChanged: function() {
if (this.active) {
this.removeAttribute('aria-hidden');
} else {
this._coolingDown = true;
this.setAttribute('aria-hidden', 'true');
}
},
_altChanged: function() {
if (this.alt === '') {
this.setAttribute('aria-hidden', 'true');
} else {
this.removeAttribute('aria-hidden');
}
this.setAttribute('aria-label', this.alt);
},
reset: function() {
this.active = false;
this._coolingDown = false;
}
});
}());
});
</script>

View File

@ -1,6 +1,6 @@
{
"name": "paper-styles",
"version": "1.0.7",
"version": "1.0.8",
"description": "Common (global) styles for Material Design elements.",
"authors": [
"The Polymer Authors"
@ -28,11 +28,11 @@
"devDependencies": {
"webcomponentsjs": "webcomponents/webcomponentsjs#^0.7.0"
},
"_release": "1.0.7",
"_release": "1.0.8",
"_resolution": {
"type": "version",
"tag": "v1.0.7",
"commit": "c65f5ce6b898bb756fca35cedaa53c3e8011abeb"
"tag": "v1.0.8",
"commit": "741d688f260e29399dec1403acf2853001f94863"
},
"_source": "git://github.com/PolymerElements/paper-styles.git",
"_target": "^1.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "paper-styles",
"version": "1.0.7",
"version": "1.0.8",
"description": "Common (global) styles for Material Design elements.",
"authors": [
"The Polymer Authors"

View File

@ -37,7 +37,7 @@
</style>
</head>
<body>
<body unresolved>
<!-- FIXME remove when https://github.com/Polymer/polymer/issues/1415 is resolved -->
<dom-module id="x-demo">

View File

@ -1,6 +1,6 @@
{
"name": "paper-tabs",
"version": "1.0.0",
"version": "1.0.1",
"license": "http://polymer.github.io/LICENSE.txt",
"description": "Material design tabs",
"private": true,
@ -14,7 +14,10 @@
"tabs",
"control"
],
"repository": "https://github.com/PolymerElements/paper-tabs.git",
"repository": {
"type": "git",
"url": "git://github.com/PolymerElements/paper-tabs.git"
},
"dependencies": {
"iron-behaviors": "polymerelements/iron-behaviors#^1.0.0",
"iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",
@ -35,14 +38,13 @@
"web-component-tester": "*"
},
"homepage": "https://github.com/PolymerElements/paper-tabs",
"_release": "1.0.0",
"_release": "1.0.1",
"_resolution": {
"type": "version",
"tag": "v1.0.0",
"commit": "af6820e55f73fc5aa8c8e4d5294085e46374c7ca"
"tag": "v1.0.1",
"commit": "6403be53eeef5f9e7a7a7ccd9251f551d26c7548"
},
"_source": "git://github.com/PolymerElements/paper-tabs.git",
"_target": "~1.0.0",
"_originalSource": "PolymerElements/paper-tabs",
"_direct": true
"_originalSource": "PolymerElements/paper-tabs"
}

View File

@ -1,6 +1,6 @@
{
"name": "paper-tabs",
"version": "1.0.0",
"version": "1.0.1",
"license": "http://polymer.github.io/LICENSE.txt",
"description": "Material design tabs",
"private": true,
@ -14,7 +14,10 @@
"tabs",
"control"
],
"repository": "https://github.com/PolymerElements/paper-tabs.git",
"repository": {
"type": "git",
"url": "git://github.com/PolymerElements/paper-tabs.git"
},
"dependencies": {
"iron-behaviors": "polymerelements/iron-behaviors#^1.0.0",
"iron-flex-layout": "polymerelements/iron-flex-layout#^1.0.0",

Some files were not shown because too many files have changed in this diff Show More