From 258ca5f16581f0e8befa493644225a02ae2fc002 Mon Sep 17 00:00:00 2001
From: Misko Hevery
Date: Fri, 26 Mar 2010 16:27:18 -0700
Subject: moved all uneeded files out, widgets.html works, tests horribly
broken
---
src/delete/Widgets.js | 806 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 806 insertions(+)
create mode 100644 src/delete/Widgets.js
(limited to 'src/delete/Widgets.js')
diff --git a/src/delete/Widgets.js b/src/delete/Widgets.js
new file mode 100644
index 00000000..74f70f21
--- /dev/null
+++ b/src/delete/Widgets.js
@@ -0,0 +1,806 @@
+function WidgetFactory(serverUrl, database) {
+ this.nextUploadId = 0;
+ this.serverUrl = serverUrl;
+ this.database = database;
+ if (window['swfobject']) {
+ this.createSWF = window['swfobject']['createSWF'];
+ } else {
+ this.createSWF = function(){
+ alert("ERROR: swfobject not loaded!");
+ };
+ }
+};
+
+WidgetFactory.prototype = {
+ createController: function(input, scope) {
+ var controller;
+ var type = input.attr('type').toLowerCase();
+ var exp = input.attr('name');
+ if (exp) exp = exp.split(':').pop();
+ var event = "change";
+ var bubbleEvent = true;
+ var formatter = angularFormatter[input.attr('ng-format')] || angularFormatter['noop'];
+ if (type == 'button' || type == 'submit' || type == 'reset' || type == 'image') {
+ controller = new ButtonController(input[0], exp, formatter);
+ event = "click";
+ bubbleEvent = false;
+ } else if (type == 'text' || type == 'textarea' || type == 'hidden' || type == 'password') {
+ controller = new TextController(input[0], exp, formatter);
+ event = "keyup change";
+ } else if (type == 'checkbox') {
+ controller = new CheckboxController(input[0], exp, formatter);
+ event = "click";
+ } else if (type == 'radio') {
+ controller = new RadioController(input[0], exp, formatter);
+ event="click";
+ } else if (type == 'select-one') {
+ controller = new SelectController(input[0], exp, formatter);
+ } else if (type == 'select-multiple') {
+ controller = new MultiSelectController(input[0], exp, formatter);
+ } else if (type == 'file') {
+ controller = this.createFileController(input, exp, formatter);
+ } else {
+ throw 'Unknown type: ' + type;
+ }
+ input.data('controller', controller);
+ var updateView = scope.get('$updateView');
+ var action = function() {
+ if (controller.updateModel(scope)) {
+ var action = jQuery(controller.view).attr('ng-action') || "";
+ if (scope.evalWidget(controller, action)) {
+ updateView(scope);
+ }
+ }
+ return bubbleEvent;
+ };
+ jQuery(controller.view, ":input").
+ bind(event, action);
+ return controller;
+ },
+
+ createFileController: function(fileInput) {
+ var uploadId = '__uploadWidget_' + (this.nextUploadId++);
+ var view = FileController.template(uploadId);
+ fileInput.after(view);
+ var att = {
+ 'data':this.serverUrl + "/admin/ServerAPI.swf",
+ 'width':"95", 'height':"20", 'align':"top",
+ 'wmode':"transparent"};
+ var par = {
+ 'flashvars':"uploadWidgetId=" + uploadId,
+ 'allowScriptAccess':"always"};
+ var swfNode = this.createSWF(att, par, uploadId);
+ fileInput.remove();
+ var cntl = new FileController(view, fileInput[0].name, swfNode, this.serverUrl + "/data/" + this.database);
+ jQuery(swfNode).parent().data('controller', cntl);
+ return cntl;
+ }
+};
+/////////////////////
+// FileController
+///////////////////////
+
+function FileController(view, scopeName, uploader, databaseUrl) {
+ this.view = view;
+ this.uploader = uploader;
+ this.scopeName = scopeName;
+ this.attachmentsPath = databaseUrl + '/_attachments';
+ this.value = null;
+ this.lastValue = undefined;
+};
+
+angularCallbacks['flashEvent'] = function(id, event, args) {
+ var object = document.getElementById(id);
+ var jobject = jQuery(object);
+ var controller = jobject.parent().data("controller");
+ FileController.prototype[event].apply(controller, args);
+ _.defer(jobject.scope().get('$updateView'));
+};
+
+FileController.template = function(id) {
+ return jQuery('' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '');
+};
+
+extend(FileController.prototype, {
+ 'cancel': noop,
+ 'complete': noop,
+ 'httpStatus': function(status) {
+ alert("httpStatus:" + this.scopeName + " status:" + status);
+ },
+ 'ioError': function() {
+ alert("ioError:" + this.scopeName);
+ },
+ 'open': function() {
+ alert("open:" + this.scopeName);
+ },
+ 'progress':noop,
+ 'securityError': function() {
+ alert("securityError:" + this.scopeName);
+ },
+ 'uploadCompleteData': function(data) {
+ var value = fromJson(data);
+ value.url = this.attachmentsPath + '/' + value.id + '/' + value.text;
+ this.view.find("input").attr('checked', true);
+ var scope = this.view.scope();
+ this.value = value;
+ this.updateModel(scope);
+ this.value = null;
+ },
+ 'select': function(name, size, type) {
+ this.name = name;
+ this.view.find("a").text(name).attr('href', name);
+ this.view.find("span").text(angular['filter']['bytes'](size));
+ this.upload();
+ },
+
+ updateModel: function(scope) {
+ var isChecked = this.view.find("input").attr('checked');
+ var value = isChecked ? this.value : null;
+ if (this.lastValue === value) {
+ return false;
+ } else {
+ scope.set(this.scopeName, value);
+ return true;
+ }
+ },
+
+ updateView: function(scope) {
+ var modelValue = scope.get(this.scopeName);
+ if (modelValue && this.value !== modelValue) {
+ this.value = modelValue;
+ this.view.find("a").
+ attr("href", this.value.url).
+ text(this.value.text);
+ this.view.find("span").text(angular['filter']['bytes'](this.value.size));
+ }
+ this.view.find("input").attr('checked', !!modelValue);
+ },
+
+ upload: function() {
+ if (this.name) {
+ this.uploader['uploadFile'](this.attachmentsPath);
+ }
+ }
+});
+
+///////////////////////
+// NullController
+///////////////////////
+function NullController(view) {this.view = view;};
+NullController.prototype = {
+ updateModel: function() { return true; },
+ updateView: noop
+};
+NullController.instance = new NullController();
+
+
+///////////////////////
+// ButtonController
+///////////////////////
+var ButtonController = NullController;
+
+///////////////////////
+// TextController
+///////////////////////
+function TextController(view, exp, formatter) {
+ this.view = view;
+ this.formatter = formatter;
+ this.exp = exp;
+ this.validator = view.getAttribute('ng-validate');
+ this.required = typeof view.attributes['ng-required'] != "undefined";
+ this.lastErrorText = null;
+ this.lastValue = undefined;
+ this.initialValue = this.formatter['parse'](view.value);
+ var widget = view.getAttribute('ng-widget');
+ if (widget === 'datepicker') {
+ jQuery(view).datepicker();
+ }
+};
+
+TextController.prototype = {
+ updateModel: function(scope) {
+ var value = this.formatter['parse'](this.view.value);
+ if (this.lastValue === value) {
+ return false;
+ } else {
+ scope.setEval(this.exp, value);
+ this.lastValue = value;
+ return true;
+ }
+ },
+
+ updateView: function(scope) {
+ var view = this.view;
+ var value = scope.get(this.exp);
+ if (typeof value === "undefined") {
+ value = this.initialValue;
+ scope.setEval(this.exp, value);
+ }
+ value = value ? value : '';
+ if (!_(this.lastValue).isEqual(value)) {
+ view.value = this.formatter['format'](value);
+ this.lastValue = value;
+ }
+
+ var isValidationError = false;
+ view.removeAttribute('ng-error');
+ if (this.required) {
+ isValidationError = !(value && $.trim("" + value).length > 0);
+ }
+ var errorText = isValidationError ? "Required Value" : null;
+ if (!isValidationError && this.validator && value) {
+ errorText = scope.validate(this.validator, value, view);
+ isValidationError = !!errorText;
+ }
+ if (this.lastErrorText !== errorText) {
+ this.lastErrorText = isValidationError;
+ if (errorText && isVisible(view)) {
+ view.setAttribute('ng-error', errorText);
+ scope.markInvalid(this);
+ }
+ jQuery(view).toggleClass('ng-validation-error', isValidationError);
+ }
+ }
+};
+
+///////////////////////
+// CheckboxController
+///////////////////////
+function CheckboxController(view, exp, formatter) {
+ this.view = view;
+ this.exp = exp;
+ this.lastValue = undefined;
+ this.formatter = formatter;
+ this.initialValue = this.formatter['parse'](view.checked ? view.value : "");
+};
+
+CheckboxController.prototype = {
+ updateModel: function(scope) {
+ var input = this.view;
+ var value = input.checked ? input.value : '';
+ value = this.formatter['parse'](value);
+ value = this.formatter['format'](value);
+ if (this.lastValue === value) {
+ return false;
+ } else {
+ scope.setEval(this.exp, this.formatter['parse'](value));
+ this.lastValue = value;
+ return true;
+ }
+ },
+
+ updateView: function(scope) {
+ var input = this.view;
+ var value = scope.eval(this.exp);
+ if (typeof value === "undefined") {
+ value = this.initialValue;
+ scope.setEval(this.exp, value);
+ }
+ input.checked = this.formatter['parse'](input.value) == value;
+ }
+};
+
+///////////////////////
+// SelectController
+///////////////////////
+function SelectController(view, exp) {
+ this.view = view;
+ this.exp = exp;
+ this.lastValue = undefined;
+ this.initialValue = view.value;
+};
+
+SelectController.prototype = {
+ updateModel: function(scope) {
+ var input = this.view;
+ if (input.selectedIndex < 0) {
+ scope.setEval(this.exp, null);
+ } else {
+ var value = this.view.value;
+ if (this.lastValue === value) {
+ return false;
+ } else {
+ scope.setEval(this.exp, value);
+ this.lastValue = value;
+ return true;
+ }
+ }
+ },
+
+ updateView: function(scope) {
+ var input = this.view;
+ var value = scope.get(this.exp);
+ if (typeof value === 'undefined') {
+ value = this.initialValue;
+ scope.setEval(this.exp, value);
+ }
+ if (value !== this.lastValue) {
+ input.value = value ? value : "";
+ this.lastValue = value;
+ }
+ }
+};
+
+///////////////////////
+// MultiSelectController
+///////////////////////
+function MultiSelectController(view, exp) {
+ this.view = view;
+ this.exp = exp;
+ this.lastValue = undefined;
+ this.initialValue = this.selected();
+};
+
+MultiSelectController.prototype = {
+ selected: function () {
+ var value = [];
+ var options = this.view.options;
+ for ( var i = 0; i < options.length; i++) {
+ var option = options[i];
+ if (option.selected) {
+ value.push(option.value);
+ }
+ }
+ return value;
+ },
+
+ updateModel: function(scope) {
+ var value = this.selected();
+ // TODO: This is wrong! no caching going on here as we are always comparing arrays
+ if (this.lastValue === value) {
+ return false;
+ } else {
+ scope.setEval(this.exp, value);
+ this.lastValue = value;
+ return true;
+ }
+ },
+
+ updateView: function(scope) {
+ var input = this.view;
+ var selected = scope.get(this.exp);
+ if (typeof selected === "undefined") {
+ selected = this.initialValue;
+ scope.setEval(this.exp, selected);
+ }
+ if (selected !== this.lastValue) {
+ var options = input.options;
+ for ( var i = 0; i < options.length; i++) {
+ var option = options[i];
+ option.selected = _.include(selected, option.value);
+ }
+ this.lastValue = selected;
+ }
+ }
+};
+
+///////////////////////
+// RadioController
+///////////////////////
+function RadioController(view, exp) {
+ this.view = view;
+ this.exp = exp;
+ this.lastChecked = undefined;
+ this.lastValue = undefined;
+ this.inputValue = view.value;
+ this.initialValue = view.checked ? view.value : null;
+};
+
+RadioController.prototype = {
+ updateModel: function(scope) {
+ var input = this.view;
+ if (this.lastChecked) {
+ return false;
+ } else {
+ input.checked = true;
+ this.lastValue = scope.setEval(this.exp, this.inputValue);
+ this.lastChecked = true;
+ return true;
+ }
+ },
+
+ updateView: function(scope) {
+ var input = this.view;
+ var value = scope.get(this.exp);
+ if (this.initialValue && typeof value === "undefined") {
+ value = this.initialValue;
+ scope.setEval(this.exp, value);
+ }
+ if (this.lastValue != value) {
+ this.lastChecked = input.checked = this.inputValue == (''+value);
+ this.lastValue = value;
+ }
+ }
+};
+
+///////////////////////
+//ElementController
+///////////////////////
+function BindUpdater(view, exp) {
+ this.view = view;
+ this.exp = Binder.parseBindings(exp);
+ this.hasError = false;
+};
+
+BindUpdater.toText = function(obj) {
+ var e = escapeHtml;
+ switch(typeof obj) {
+ case "string":
+ case "boolean":
+ case "number":
+ return e(obj);
+ case "function":
+ return BindUpdater.toText(obj());
+ case "object":
+ if (isNode(obj)) {
+ return outerHTML(obj);
+ } else if (obj instanceof angular.filter.Meta) {
+ switch(typeof obj.html) {
+ case "string":
+ case "number":
+ return obj.html;
+ case "function":
+ return obj.html();
+ case "object":
+ if (isNode(obj.html))
+ return outerHTML(obj.html);
+ default:
+ break;
+ }
+ switch(typeof obj.text) {
+ case "string":
+ case "number":
+ return e(obj.text);
+ case "function":
+ return e(obj.text());
+ default:
+ break;
+ }
+ }
+ if (obj === null)
+ return "";
+ return e(toJson(obj, true));
+ default:
+ return "";
+ }
+};
+
+BindUpdater.prototype = {
+ updateModel: noop,
+ updateView: function(scope) {
+ var html = [];
+ var parts = this.exp;
+ var length = parts.length;
+ for(var i=0; i iteratorCounter; --r) {
+ this.children.pop().element.remove();
+ }
+ // Special case for option in select
+ if (child && child.element[0].nodeName === "OPTION") {
+ var select = jQuery(child.element[0].parentNode);
+ var cntl = select.data('controller');
+ if (cntl) {
+ cntl.lastValue = undefined;
+ cntl.updateView(scope);
+ }
+ }
+ });
+ }
+};
+
+//////////////////////////////////
+// PopUp
+//////////////////////////////////
+
+function PopUp(doc) {
+ this.doc = doc;
+};
+
+PopUp.OUT_EVENT = "mouseleave mouseout click dblclick keypress keyup";
+
+PopUp.onOver = function(e) {
+ PopUp.onOut();
+ var jNode = jQuery(this);
+ jNode.bind(PopUp.OUT_EVENT, PopUp.onOut);
+ var position = jNode.position();
+ var de = document.documentElement;
+ var w = self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
+ var hasArea = w - position.left;
+ var width = 300;
+ var title = jNode.hasClass("ng-exception") ? "EXCEPTION:" : "Validation error...";
+ var msg = jNode.attr("ng-error");
+
+ var x;
+ var arrowPos = hasArea>(width+75) ? "left" : "right";
+ var tip = jQuery(
+ "" +
+ "
" +
+ "
"+title+"
" +
+ "
"+msg+"
" +
+ "
");
+ jQuery("body").append(tip);
+ if(arrowPos === 'left'){
+ x = position.left + this.offsetWidth + 11;
+ }else{
+ x = position.left - (width + 15);
+ tip.find('.ng-arrow-right').css({left:width+1});
+ }
+
+ tip.css({left: x+"px", top: (position.top - 3)+"px"});
+ return true;
+};
+
+PopUp.onOut = function() {
+ jQuery('#ng-callout').
+ unbind(PopUp.OUT_EVENT, PopUp.onOut).
+ remove();
+ return true;
+};
+
+PopUp.prototype = {
+ bind: function () {
+ var self = this;
+ this.doc.find('.ng-validation-error,.ng-exception').
+ live("mouseover", PopUp.onOver);
+ }
+};
+
+//////////////////////////////////
+// Status
+//////////////////////////////////
+
+function NullStatus(body) {
+};
+
+NullStatus.prototype = {
+ beginRequest:function(){},
+ endRequest:function(){}
+};
+
+function Status(body) {
+ this.requestCount = 0;
+ this.body = body;
+};
+
+Status.DOM ='loading....
';
+
+Status.prototype = {
+ beginRequest: function () {
+ if (this.requestCount === 0) {
+ (this.loader = this.loader || this.body.append(Status.DOM).find("#ng-loading")).show();
+ }
+ this.requestCount++;
+ },
+
+ endRequest: function () {
+ this.requestCount--;
+ if (this.requestCount === 0) {
+ this.loader.hide("fold");
+ }
+ }
+};
--
cgit v1.2.3