From 12bbeeff0f42d75c5e6cfdb1251f5b1a1bda637d Mon Sep 17 00:00:00 2001 From: Donna Wu Date: Fri, 10 Aug 2012 16:29:24 +0800 Subject: [PATCH 1/4] [Serialize] Add 'find', 'add', 'remove' sandbox header functions --- src/js/serialize.js | 180 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 147 insertions(+), 33 deletions(-) diff --git a/src/js/serialize.js b/src/js/serialize.js index 5abbbc66..a709b407 100644 --- a/src/js/serialize.js +++ b/src/js/serialize.js @@ -36,6 +36,12 @@ var DEBUG = true, $(function () { + /* Variable definition */ + var headerPropertyMap = { + css: 'css', + js: 'libs' + }; + /** * Generate HTML from ADM tree. * @@ -747,7 +753,139 @@ $(function () { return $.rib.fsUtils.pathToUrl(fullPath); } - /***************** export functions out *********************/ + function indexOfArray(array, value) { + var i, index = -1; + if (typeof value !== 'object') { + return $.inArray(array, value); + } else { + for (i = 0; i < array.length; i++) { + if (JSON.stringify(array[i]) === JSON.stringify(value)) { + index = i; + } + } + return index; + } + } + + /** + * Check if the sandbox file is a design header, such as css, js file. + * + * @param {String} type Type of the specified header. + * @param {String} filePath Sandbox path of header file. + * + * @return {Boolean} Return true if find the file in header list, else false. + * Notes: filePath If the file is in project directory, relative path should + * be used. A path beginning with '/' will be considered as absolut + * path in sandbox. + */ + function isSandboxHeader(type, filePath) { + var property, array, design, index; + + if (!(type && filePath && (filePath.length > 0))) { + dumplog('Error: Invalid parameter(s) in isSandboxHeader.'); + return false; + } + property = headerPropertyMap[type]; + if (!property) { + dumplog('Error: No header:' + type + 'in design.'); + return false; + } + design = ADM.getDesignRoot(); + array = $.merge([], design.getProperty(property)); + index = indexOfArray(array, { + inSandbox: true, + value: filePath + }); + if (index > -1) { + return true; + } else { + return false; + } + } + + /** + * Add sandbox header file in current design, such as css, js file. + * + * @param {String} type Type of the specified header. + * @param {String} filePath Sandbox path of header file. + * + * @return {Boolean} Return true if added the header, else return false. + * + * Notes: filePath If the file is in project directory, relative path should + * be used. A path beginning with '/' will be considered as absolut + * path in sandbox. + */ + function addSandboxHeader(type, filePath) { + var property, array, design, index; + + if (!(type && filePath && (filePath.length > 0))) { + dumplog('Error: Invalid parameter(s) in addSandboxHeader.'); + return false; + } + property = headerPropertyMap[type]; + if (!property) { + dumplog('Error: No header:' + type + 'in design.'); + return false; + } + design = ADM.getDesignRoot(); + array = $.merge([], design.getProperty(property)); + index = indexOfArray(array, { + inSandbox: true, + value: filePath + }); + if (index === -1) { + array.push({ + inSandbox: true, + value: filePath + }); + // set the new array back + design.setProperty(property, array); + } else { + dumplog('warning:"' + filePath +'" is already in ' + type + ' list.'); + } + return true; + } + + /** + * Remove sandbox header file in current design, such as css, js file. + * + * @param {String} type Type of the specified header. + * @param {String} filePath Sandbox path of header file. + * + * @return {Boolean} Return true if deleted the header, else return false. + * + * Notes: filePath If the file is in project directory, relative path should + * be used. A path beginning with '/' will be considered as absolut + * path in sandbox. + */ + function removeSandboxHeader(type, filePath) { + var property, array, design, index; + + if (!(type && filePath && (filePath.length > 0))) { + dumplog('Error: Invalid parameter(s) in removeSandboxHeader.'); + return false; + } + property = headerPropertyMap[type]; + if (!property) { + dumplog('Error: No header:' + type + 'in design.'); + return false; + } + design = ADM.getDesignRoot(); + array = $.merge([], design.getProperty(property)); + index = indexOfArray(array, { + inSandbox: true, + value: filePath + }); + if (index > -1) { + array.splice(index, 1); + // set the new array back + design.setProperty(property, array); + } else { + dumplog('warning: not find:"' + filePath +'" in ' + type + ' list.'); + } + return true; + } + /** * Add custom file to current active project. * It will save the content in project folder. If the parent directy of @@ -761,7 +899,7 @@ $(function () { * * @return {None} */ - $.rib.addCustomFile = function (filePath, type, contents, success, error) { + function addCustomFile(filePath, type, contents, success, error) { var destPath, addToDesign, projectDir; projectDir = $.rib.pmUtils.getProjectDir(); // If it is relative path, then add the project folder path @@ -770,42 +908,14 @@ $(function () { } else { destPath = filePath; } - addToDesign = function (type, value) { - var design, array, property, propertyMap, i, temp; - propertyMap = { - css: 'css', - js: 'libs' - }; - design = ADM.getDesignRoot(); - property = propertyMap[type]; - temp = $.extend(true, {}, { - property: property, - value: design.getProperty(property) - }); - array = temp.value; - for (i = 0; i < array.length; i++) { - // If the value is in headers, then just return. - if (JSON.stringify(array[i]) === JSON.stringify(value)) { - return; - } - } - // If the value is not in array, then push the value in the list - array.push(value); - // set the new array back - design.setProperty(property, array); - return; - }; // Write contents to sandbox $.rib.fsUtils.write(destPath, contents, function (newFile) { - var headerValue = { - 'inSandbox': true, - 'value': filePath - }; - addToDesign(type, headerValue); + addSandboxHeader(type, filePath); success && success(newFile); }, error); - }; + } + /***************** export functions out *********************/ // Export serialization functions into $.rib namespace $.rib.generateHTML = generateHTML; $.rib.serializeADMSubtreeToDOM = serializeADMSubtreeToDOM; @@ -813,4 +923,8 @@ $(function () { $.rib.JSONToProj = JSONToProj; $.rib.getDesignHeaders = getDesignHeaders; $.rib.exportPackage = exportPackage; + $.rib.isSandboxHeader = isSandboxHeader; + $.rib.addSandboxHeader = addSandboxHeader; + $.rib.removeSandboxHeader = removeSandboxHeader; + $.rib.addCustomFile = addCustomFile; }); From d52311b6e82368384e3a138a12aa4ba4a5479bf8 Mon Sep 17 00:00:00 2001 From: Xuqing Kuang Date: Thu, 9 Aug 2012 16:44:45 +0800 Subject: [PATCH 2/4] [Widget] Fixed List Filter is not part of List. --- src/css/composer.css | 12 ++++++++++++ src/js/widgets.js | 18 +++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/css/composer.css b/src/css/composer.css index 2f3008d8..2b2489c6 100644 --- a/src/css/composer.css +++ b/src/css/composer.css @@ -282,3 +282,15 @@ label.adm-editable span.adm-text-content::before, body > li.ui-sortable-helper[class*="ui-block-"] { list-style: none; } + +/* List filter hacking */ +div.ui-listview-container { + padding: 0px; /* Override the settings in nrc-sortable-container for header label */ +} +div.ui-listview-container > form { + margin: 4px 2px 4px 2px; +} +div.ui-listview-container > ul.ui-listview, +div.ui-listview-container > ol.ui-listview { + margin: 1px 2px 1px 2px; +} diff --git a/src/js/widgets.js b/src/js/widgets.js index e8953786..02802d8f 100644 --- a/src/js/widgets.js +++ b/src/js/widgets.js @@ -1393,7 +1393,23 @@ var BWidgetRegistry = { cardinality: "N", allow: [ "ListItem", "ListDivider", "ListButton" ] } - ] + ], + delegate: function (domNode, admNode) { + var filterForm, headerLabel, newNode = $('
'); + if (!admNode.getProperty('filter')) + return domNode; + filterForm = domNode.prev('form'); + domNode.removeClass('ui-drag-header nrc-sortable-container'); + // Move header label attr to container + newNode.attr('header-label', domNode.attr('header-label')); + domNode.removeAttr('header-label'); + // Move specific classes to container + newNode.addClass( + 'ui-drag-header nrc-sortable-container ui-listview-container' + ); + // Reconstruct the domNode. + return filterForm.wrap(newNode).parent().append(domNode); + } }, /** From 789cfa35582a3e7e725b800fc5fb8c4ed5ee0b69 Mon Sep 17 00:00:00 2001 From: Donna Wu Date: Wed, 15 Aug 2012 14:39:43 +0800 Subject: [PATCH 3/4] [FixBug] Fix bug that delete key still work when dialog is showing --- src/js/keyHandler.js | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/js/keyHandler.js b/src/js/keyHandler.js index 8f6ff1b5..ec8da7f8 100644 --- a/src/js/keyHandler.js +++ b/src/js/keyHandler.js @@ -18,7 +18,6 @@ $(function() { enableKeys: function (element) { $(element).keyup(navUtils.shortCut); $(element).keydown(navUtils.tabHandler); - $(element).keyup(navUtils.deleteHandler); }, shortCut: function(e) { var charItem, shortKeys; @@ -34,7 +33,17 @@ $(function() { // "ctrl+v" for "past" 'v':'paste' }; - if (e.ctrlKey && !navUtils.ignoreText()) { + // If there is modal dialog or need to ignore text elements, do nothing. + if ($('.ui-widget-overlay:visible').length > 0 || navUtils.ignoreText()) { + return true; + } + // for "delete" + // fn + delete in Mac to delete element + if(e.which === 46) { + $('#deleteElement:visible').trigger("click"); + return false; + } + if (e.ctrlKey) { charItem = String.fromCharCode(e.which).toLowerCase(); if (shortKeys[charItem]) { $('#btn' + shortKeys[charItem] + ':visible').trigger("click"); @@ -45,6 +54,9 @@ $(function() { }, // for "tab" tabHandler: function (e) { + if ($('.ui-wiget-overlay:visible').length > 0) { + return true; + } var navItems = navUtils.enableFocus(); if (e.which !== 9) { return true; @@ -63,15 +75,6 @@ $(function() { } } }, - // for "delete" - deleteHandler: function (e) { - if (e.which !== 46 || navUtils.ignoreText()) { - return true; - } else { - $('#deleteElement:visible').trigger("click"); - return false; - } - }, /** * Enable items that wants to be focused by tab key. * From 69dee1080bd46f0f8466b91ef15b64375289edc7 Mon Sep 17 00:00:00 2001 From: "Xiaoyang Yu (Max)" Date: Fri, 3 Aug 2012 15:05:24 +0800 Subject: [PATCH 4/4] [Widgets] "previous page" becomes a target --- src/js/serialize.js | 24 ++++++++++++++++++++---- src/js/views/property.js | 17 +++++++++++++---- src/js/widgets.js | 19 +++++++------------ 3 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/js/serialize.js b/src/js/serialize.js index 672b18e3..3a00b9c2 100644 --- a/src/js/serialize.js +++ b/src/js/serialize.js @@ -61,13 +61,29 @@ var DEBUG = true, attrName = BWidget.getPropertyHTMLAttribute(node.getType(), propName); propValue = newValue || node.getProperty(propName); attrValue = propValue; + if (typeof attrName === "function") { + attrName = attrName(propValue); + } if (typeof attrName === "object") { attrMap = attrName; attrName = attrMap.name; - if (typeof attrMap.value === "function") - attrValue = attrMap.value(propValue); - else - attrValue = attrMap.value[propValue]; + attrValue = attrMap.value; + switch(typeof(attrValue)) { + case "function": + attrValue = attrValue(propValue); + break; + case "object": + attrValue = attrValue[propValue]; + break; + case "string": + break; + case "undefined": + break; + case "boolean": + break; + default: + throw "attrValue type can not be handled"; + } } return {"name": attrName, "value": attrValue}; diff --git a/src/js/views/property.js b/src/js/views/property.js index ebdf26af..bc7788f5 100644 --- a/src/js/views/property.js +++ b/src/js/views/property.js @@ -391,6 +391,7 @@ var o, items = "", pages, id, value = e.data.value, p = e.data.p; + items += '
  • previous page
  • '; pages = ADM.getDesignRoot().getChildren(); for (o = 0; o < pages.length; o++) { id = pages[o].getProperty('id'); @@ -423,10 +424,14 @@ default: // handle property has options if (options[p]) { - $('').attr('id', valueId) + .addClass('title') + .appendTo(value); + if(type === 'Button' && p === 'opentargetas' + && node.getProperty('target') === + 'previous page') { + value.find('#'+valueId).attr('disabled', 'disabled'); + } //add options to select list for (o in options[p]) { //TODO make it simple @@ -466,8 +471,12 @@ value = validValue($(this), BWidget.getPropertyType(node.getType(), updated)); ret = ADM.setProperty(node, updated, value); + type = node.getType(); if(ret.result === false) { $(this).val(node.getProperty(updated)); + } else if(type === "Button" && + value === "previous page") { + ADM.setProperty(node, "opentargetas", "default"); } event.stopPropagation(); return false; diff --git a/src/js/widgets.js b/src/js/widgets.js index 38c1e65b..b17695be 100644 --- a/src/js/widgets.js +++ b/src/js/widgets.js @@ -660,7 +660,13 @@ var BWidgetRegistry = { target: { type: "targetlist", defaultValue: "", - htmlAttribute: "href" + htmlAttribute: function(value) { + if (value === "previous page") { + return {"name": "data-rel", "value": "back"}; + } else { + return {"name": "href", "value": value}; + } + } }, opentargetas : { type: "string", @@ -702,17 +708,6 @@ var BWidgetRegistry = { defaultValue: "slide", htmlAttribute: "data-transition" }, - back: { - type: "boolean", - defaultValue: false, - htmlAttribute: { - name: "data-rel", - value: { - "true": "back", - "false": "" - } - } - }, corners: { type: "boolean", defaultValue: true,