diff --git a/src/LiveDevelopment/Agents/RemoteFunctions.js b/src/LiveDevelopment/Agents/RemoteFunctions.js index 1340a5d186d..685f986ce3e 100644 --- a/src/LiveDevelopment/Agents/RemoteFunctions.js +++ b/src/LiveDevelopment/Agents/RemoteFunctions.js @@ -310,6 +310,7 @@ function RemoteFunctions(config, remoteWSPort) { parseInt(realElBorder.left), outerHeight = innerHeight + parseInt(realElBorder.bottom) + parseInt(realElBorder.top); } + var visualisations = { horizontal: "left, right", @@ -321,7 +322,6 @@ function RemoteFunctions(config, remoteWSPort) { if (visualisations.horizontal.indexOf(side) >= 0) { elStyling['width'] = elementStyling.getPropertyValue('padding-' + side); - // get rid of px and remove borders elStyling['height'] = innerHeight + "px"; elStyling['top'] = 0; @@ -355,6 +355,7 @@ function RemoteFunctions(config, remoteWSPort) { margin['left'] = parseInt(elementStyling.getPropertyValue('margin-left')); if(visualisations['horizontal'].indexOf(side) >= 0) { + elStyling['width'] = elementStyling.getPropertyValue('margin-' + side); elStyling['height'] = outerHeight + margin['top'] + margin['bottom'] + "px"; elStyling['top'] = "-" + (margin['top'] + parseInt(realElBorder.top)) + "px"; @@ -430,37 +431,19 @@ function RemoteFunctions(config, remoteWSPort) { highlight.className = HIGHLIGHT_CLASSNAME; var offset = _screenOffset(element); - - var el = element, - offsetLeft = 0, - offsetTop = 0; - - // Probably the easiest way to get elements position without including transform - do { - offsetLeft += el.offsetLeft; - offsetTop += el.offsetTop; - el = el.offsetParent; - } while(el); var stylesToSet = { - "left": offsetLeft + "px", - "top": offsetTop + "px", - "width": innerWidth + "px", - "height": innerHeight + "px", + "left": offset.left + "px", + "top": offset.top + "px", + "width": elementBounds.width + "px", + "height": elementBounds.height + "px", "z-index": 2000000, "margin": 0, "padding": 0, "position": "absolute", "pointer-events": "none", "box-shadow": "0 0 1px #fff", - "box-sizing": elementStyling.getPropertyValue('box-sizing'), - "border-right": elementStyling.getPropertyValue('border-right'), - "border-left": elementStyling.getPropertyValue('border-left'), - "border-top": elementStyling.getPropertyValue('border-top'), - "border-bottom": elementStyling.getPropertyValue('border-bottom'), - "transform": elementStyling.getPropertyValue('transform'), - "transform-origin": elementStyling.getPropertyValue('transform-origin'), - "border-color": config.remoteHighlight.borderColor + "box-sizing": "border-box" }; var mergedStyles = Object.assign({}, stylesToSet, config.remoteHighlight.stylesToSet); diff --git a/src/editor/Editor.js b/src/editor/Editor.js index 0596833d3dc..c37f563317a 100644 --- a/src/editor/Editor.js +++ b/src/editor/Editor.js @@ -96,7 +96,8 @@ define(function (require, exports, module) { UPPERCASE_COLORS = "uppercaseColors", USE_TAB_CHAR = "useTabChar", WORD_WRAP = "wordWrap", - INDENT_LINE_COMMENT = "indentLineComment"; + INDENT_LINE_COMMENT = "indentLineComment", + INPUT_STYLE = "inputStyle"; /** * A list of gutter name and priorities currently registered for editors. @@ -137,6 +138,7 @@ define(function (require, exports, module) { cmOptions[TAB_SIZE] = "tabSize"; cmOptions[USE_TAB_CHAR] = "indentWithTabs"; cmOptions[WORD_WRAP] = "lineWrapping"; + cmOptions[INPUT_STYLE] = "inputStyle"; PreferencesManager.definePreference(CLOSE_BRACKETS, "boolean", true, { description: Strings.DESCRIPTION_CLOSE_BRACKETS @@ -228,6 +230,10 @@ define(function (require, exports, module) { description: Strings.DESCRIPTION_INDENT_LINE_COMMENT }); + PreferencesManager.definePreference(INPUT_STYLE, "string", "textarea", { + description: Strings.DESCRIPTION_INPUT_STYLE + }); + var editorOptions = Object.keys(cmOptions); /** Editor preferences */ @@ -413,7 +419,7 @@ define(function (require, exports, module) { highlightSelectionMatches : currentOptions[HIGHLIGHT_MATCHES], indentUnit : currentOptions[USE_TAB_CHAR] ? currentOptions[TAB_SIZE] : currentOptions[SPACE_UNITS], indentWithTabs : currentOptions[USE_TAB_CHAR], - inputStyle : "textarea", // the "contenteditable" mode used on mobiles could cause issues + inputStyle : currentOptions[INPUT_STYLE], lineNumbers : currentOptions[SHOW_LINE_NUMBERS], lineWiseCopyCut : currentOptions[LINEWISE_COPY_CUT], lineWrapping : currentOptions[WORD_WRAP], diff --git a/src/extensions/default/MDNDocs/unittest-files/test1.html b/src/extensions/default/MDNDocs/unittest-files/test1.html index 0c942431b3d..276b4ddf087 100644 --- a/src/extensions/default/MDNDocs/unittest-files/test1.html +++ b/src/extensions/default/MDNDocs/unittest-files/test1.html @@ -8,5 +8,10 @@ + <{{2}}nonexistent> +
{{3}}some text
+ +
+ \ No newline at end of file diff --git a/src/extensions/default/MDNDocs/unittests.js b/src/extensions/default/MDNDocs/unittests.js index 8a97926f59c..dadcf3bcff3 100644 --- a/src/extensions/default/MDNDocs/unittests.js +++ b/src/extensions/default/MDNDocs/unittests.js @@ -101,6 +101,22 @@ define(function (require, exports, module) { expect(Object.keys(json).length).toBeGreaterThan(0); }); }); + + it("should retrieve the HTML docs database", function () { + var json; + + runs(function () { + main._getDocs("html.json").done(function (result) { + json = result; + }); + }); + + waitsFor(function () { return json !== undefined; }, "read html.json database", 5000); + + runs(function () { + expect(Object.keys(json).length).toBeGreaterThan(0); + }); + }); }); @@ -165,9 +181,37 @@ define(function (require, exports, module) { queryInlineAtPos(testHTMLInfo, 0, true, "border"); }); - it("should open docs for HTML", function () { + it("should open docs when the selection is on an HTML tag", function () { queryInlineAtPos(testHTMLInfo, 1, true, ""); }); + + it("should not open docs when the selection is on an invalid HTML tag", function () { + queryInlineAtPos(testHTMLInfo, 2, false); + }); + + it("should not open docs when the selection is not an HTML tag", function () { + /* Text */ + queryInlineAtPos(testHTMLInfo, 3, false); + + /* Commented tag */ + queryInlineAtPos(testHTMLInfo, 4, false); + }); + + it("should open docs when the selection is on an HTML attribute", function () { + queryInlineAtPos(testHTMLInfo, 5, true, "
"); + }); + + it("should open docs for tag (fallback) when the selection is on an HTML attribute's value", function () { + queryInlineAtPos(testHTMLInfo, 6, true, "
"); + }); + + it("should open docs for tag (fallback) when the selection is on an invalid HTML attribute", function () { + queryInlineAtPos(testHTMLInfo, 7, true, "
"); + }); + + it("should not open docs when the selection is on an invalid HTML attribute on an invalid HTML tag", function () { + queryInlineAtPos(testHTMLInfo, 8, false); + }); }); diff --git a/src/nls/root/strings.js b/src/nls/root/strings.js index 4675f34cdba..afd9ea21dff 100644 --- a/src/nls/root/strings.js +++ b/src/nls/root/strings.js @@ -753,6 +753,7 @@ define({ "DESCRIPTION_LANGUAGE_FILE_EXTENSIONS" : "Additional mappings from file extension to language name", "DESCRIPTION_LANGUAGE_FILE_NAMES" : "Additional mappings from file name to language name", "DESCRIPTION_LINEWISE_COPY_CUT" : "Doing copy and cut when there's no selection will copy or cut the whole lines that have cursors in them", + "DESCRIPTION_INPUT_STYLE" : "Selects the way CodeMirror handles input and focus. It cans be textarea, which is the default, or contenteditable which is better for screen readers (unstable)", "DESCRIPTION_LINTING_ENABLED" : "true to enable Code Inspection", "DESCRIPTION_ASYNC_TIMEOUT" : "The time in milliseconds after which asynchronous linters time out", "DESCRIPTION_LINTING_PREFER" : "Array of linters to run first",