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/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. * diff --git a/src/js/serialize.js b/src/js/serialize.js index 58b64b7a..87772ccf 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. * @@ -71,13 +77,29 @@ $(function () { 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}; @@ -768,7 +790,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 @@ -782,7 +936,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 @@ -791,42 +945,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; @@ -834,4 +960,8 @@ $(function () { $.rib.JSONToProj = JSONToProj; $.rib.getDesignHeaders = getDesignHeaders; $.rib.exportPackage = exportPackage; + $.rib.isSandboxHeader = isSandboxHeader; + $.rib.addSandboxHeader = addSandboxHeader; + $.rib.removeSandboxHeader = removeSandboxHeader; + $.rib.addCustomFile = addCustomFile; }); diff --git a/src/js/views/property.js b/src/js/views/property.js index 13916b81..41f319ec 100644 --- a/src/js/views/property.js +++ b/src/js/views/property.js @@ -396,6 +396,7 @@ var o, items = "", pages, id, value = e.data.value, p = e.data.p; + items += '