mirror of
https://github.com/Febbweiss/filebrowser-durandal-widget.git
synced 2026-03-05 06:35:49 +00:00
196 lines
7.4 KiB
JavaScript
196 lines
7.4 KiB
JavaScript
/**
|
|
* Durandal 2.1.0 Copyright (c) 2012 Blue Spire Consulting, Inc. All Rights Reserved.
|
|
* Available via the MIT license.
|
|
* see: http://durandaljs.com or https://github.com/BlueSpire/Durandal for details.
|
|
*/
|
|
/**
|
|
* Layers the widget sugar on top of the composition system.
|
|
* @module widget
|
|
* @requires system
|
|
* @requires composition
|
|
* @requires jquery
|
|
* @requires knockout
|
|
*/
|
|
define(['durandal/system', 'durandal/composition', 'jquery', 'knockout'], function(system, composition, $, ko) {
|
|
var kindModuleMaps = {},
|
|
kindViewMaps = {},
|
|
bindableSettings = ['model', 'view', 'kind'],
|
|
widgetDataKey = 'durandal-widget-data';
|
|
|
|
function extractParts(element, settings){
|
|
var data = ko.utils.domData.get(element, widgetDataKey);
|
|
|
|
if(!data){
|
|
data = {
|
|
parts:composition.cloneNodes(ko.virtualElements.childNodes(element))
|
|
};
|
|
|
|
ko.virtualElements.emptyNode(element);
|
|
ko.utils.domData.set(element, widgetDataKey, data);
|
|
}
|
|
|
|
settings.parts = data.parts;
|
|
}
|
|
|
|
/**
|
|
* @class WidgetModule
|
|
* @static
|
|
*/
|
|
var widget = {
|
|
getSettings: function(valueAccessor) {
|
|
var settings = ko.utils.unwrapObservable(valueAccessor()) || {};
|
|
|
|
if (system.isString(settings)) {
|
|
return { kind: settings };
|
|
}
|
|
|
|
for (var attrName in settings) {
|
|
if (ko.utils.arrayIndexOf(bindableSettings, attrName) != -1) {
|
|
settings[attrName] = ko.utils.unwrapObservable(settings[attrName]);
|
|
} else {
|
|
settings[attrName] = settings[attrName];
|
|
}
|
|
}
|
|
|
|
return settings;
|
|
},
|
|
/**
|
|
* Creates a ko binding handler for the specified kind.
|
|
* @method registerKind
|
|
* @param {string} kind The kind to create a custom binding handler for.
|
|
*/
|
|
registerKind: function(kind) {
|
|
ko.bindingHandlers[kind] = {
|
|
init: function() {
|
|
return { controlsDescendantBindings: true };
|
|
},
|
|
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
|
|
var settings = widget.getSettings(valueAccessor);
|
|
settings.kind = kind;
|
|
extractParts(element, settings);
|
|
widget.create(element, settings, bindingContext, true);
|
|
}
|
|
};
|
|
|
|
ko.virtualElements.allowedBindings[kind] = true;
|
|
composition.composeBindings.push(kind + ':');
|
|
},
|
|
/**
|
|
* Maps views and module to the kind identifier if a non-standard pattern is desired.
|
|
* @method mapKind
|
|
* @param {string} kind The kind name.
|
|
* @param {string} [viewId] The unconventional view id to map the kind to.
|
|
* @param {string} [moduleId] The unconventional module id to map the kind to.
|
|
*/
|
|
mapKind: function(kind, viewId, moduleId) {
|
|
if (viewId) {
|
|
kindViewMaps[kind] = viewId;
|
|
}
|
|
|
|
if (moduleId) {
|
|
kindModuleMaps[kind] = moduleId;
|
|
}
|
|
},
|
|
/**
|
|
* Maps a kind name to it's module id. First it looks up a custom mapped kind, then falls back to `convertKindToModulePath`.
|
|
* @method mapKindToModuleId
|
|
* @param {string} kind The kind name.
|
|
* @return {string} The module id.
|
|
*/
|
|
mapKindToModuleId: function(kind) {
|
|
return kindModuleMaps[kind] || widget.convertKindToModulePath(kind);
|
|
},
|
|
/**
|
|
* Converts a kind name to it's module path. Used to conventionally map kinds who aren't explicitly mapped through `mapKind`.
|
|
* @method convertKindToModulePath
|
|
* @param {string} kind The kind name.
|
|
* @return {string} The module path.
|
|
*/
|
|
convertKindToModulePath: function(kind) {
|
|
return 'widgets/' + kind + '/viewmodel';
|
|
},
|
|
/**
|
|
* Maps a kind name to it's view id. First it looks up a custom mapped kind, then falls back to `convertKindToViewPath`.
|
|
* @method mapKindToViewId
|
|
* @param {string} kind The kind name.
|
|
* @return {string} The view id.
|
|
*/
|
|
mapKindToViewId: function(kind) {
|
|
return kindViewMaps[kind] || widget.convertKindToViewPath(kind);
|
|
},
|
|
/**
|
|
* Converts a kind name to it's view id. Used to conventionally map kinds who aren't explicitly mapped through `mapKind`.
|
|
* @method convertKindToViewPath
|
|
* @param {string} kind The kind name.
|
|
* @return {string} The view id.
|
|
*/
|
|
convertKindToViewPath: function(kind) {
|
|
return 'widgets/' + kind + '/view';
|
|
},
|
|
createCompositionSettings: function(element, settings) {
|
|
if (!settings.model) {
|
|
settings.model = this.mapKindToModuleId(settings.kind);
|
|
}
|
|
|
|
if (!settings.view) {
|
|
settings.view = this.mapKindToViewId(settings.kind);
|
|
}
|
|
|
|
settings.preserveContext = true;
|
|
settings.activate = true;
|
|
settings.activationData = settings;
|
|
settings.mode = 'templated';
|
|
|
|
return settings;
|
|
},
|
|
/**
|
|
* Creates a widget.
|
|
* @method create
|
|
* @param {DOMElement} element The DOMElement or knockout virtual element that serves as the target element for the widget.
|
|
* @param {object} settings The widget settings.
|
|
* @param {object} [bindingContext] The current binding context.
|
|
*/
|
|
create: function(element, settings, bindingContext, fromBinding) {
|
|
if(!fromBinding){
|
|
settings = widget.getSettings(function() { return settings; }, element);
|
|
}
|
|
|
|
var compositionSettings = widget.createCompositionSettings(element, settings);
|
|
|
|
composition.compose(element, compositionSettings, bindingContext);
|
|
},
|
|
/**
|
|
* Installs the widget module by adding the widget binding handler and optionally registering kinds.
|
|
* @method install
|
|
* @param {object} config The module config. Add a `kinds` array with the names of widgets to automatically register. You can also specify a `bindingName` if you wish to use another name for the widget binding, such as "control" for example.
|
|
*/
|
|
install:function(config){
|
|
config.bindingName = config.bindingName || 'widget';
|
|
|
|
if(config.kinds){
|
|
var toRegister = config.kinds;
|
|
|
|
for(var i = 0; i < toRegister.length; i++){
|
|
widget.registerKind(toRegister[i]);
|
|
}
|
|
}
|
|
|
|
ko.bindingHandlers[config.bindingName] = {
|
|
init: function() {
|
|
return { controlsDescendantBindings: true };
|
|
},
|
|
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
|
|
var settings = widget.getSettings(valueAccessor);
|
|
extractParts(element, settings);
|
|
widget.create(element, settings, bindingContext, true);
|
|
}
|
|
};
|
|
|
|
composition.composeBindings.push(config.bindingName + ':');
|
|
ko.virtualElements.allowedBindings[config.bindingName] = true;
|
|
}
|
|
};
|
|
|
|
return widget;
|
|
});
|