Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(418)

Side by Side Diff: Source/devtools/front_end/elements/StylesSidebarPane.js

Issue 650123002: DevTools: [SSP] fix live edit of property values (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: update test description Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 * Copyright (C) 2009 Joseph Pecoraro 3 * Copyright (C) 2009 Joseph Pecoraro
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 2661 matching lines...) Expand 10 before | Expand all | Expand 10 after
2672 * @param {boolean} overloaded 2672 * @param {boolean} overloaded
2673 */ 2673 */
2674 WebInspector.StylePropertyTreeElement = function(stylesPane, styleRule, style, p roperty, isShorthand, inherited, overloaded) 2674 WebInspector.StylePropertyTreeElement = function(stylesPane, styleRule, style, p roperty, isShorthand, inherited, overloaded)
2675 { 2675 {
2676 WebInspector.StylePropertyTreeElementBase.call(this, styleRule, style, prope rty, inherited, overloaded, isShorthand); 2676 WebInspector.StylePropertyTreeElementBase.call(this, styleRule, style, prope rty, inherited, overloaded, isShorthand);
2677 this._parentPane = stylesPane; 2677 this._parentPane = stylesPane;
2678 this.isShorthand = isShorthand; 2678 this.isShorthand = isShorthand;
2679 this._applyStyleThrottler = new WebInspector.Throttler(0); 2679 this._applyStyleThrottler = new WebInspector.Throttler(0);
2680 } 2680 }
2681 2681
2682 /** @typedef {{expanded: boolean, hasChildren: boolean, isEditingName: boolean, previousContent: string}} */
2683 WebInspector.StylePropertyTreeElement.Context;
2684
2682 WebInspector.StylePropertyTreeElement.prototype = { 2685 WebInspector.StylePropertyTreeElement.prototype = {
2683 /** 2686 /**
2684 * @return {?WebInspector.DOMNode} 2687 * @return {?WebInspector.DOMNode}
2685 */ 2688 */
2686 node: function() 2689 node: function()
2687 { 2690 {
2688 return this._parentPane._node; 2691 return this._parentPane._node;
2689 }, 2692 },
2690 2693
2691 /** 2694 /**
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
2937 return fieldValue; 2940 return fieldValue;
2938 var modelUrlRegex = new RegExp(urlRegex); 2941 var modelUrlRegex = new RegExp(urlRegex);
2939 for (var i = 1; i < splitFieldValue.length; i += 2) { 2942 for (var i = 1; i < splitFieldValue.length; i += 2) {
2940 var match = modelUrlRegex.exec(modelValue); 2943 var match = modelUrlRegex.exec(modelValue);
2941 if (match) 2944 if (match)
2942 splitFieldValue[i] = match[0]; 2945 splitFieldValue[i] = match[0];
2943 } 2946 }
2944 return splitFieldValue.join(""); 2947 return splitFieldValue.join("");
2945 } 2948 }
2946 2949
2950 /** @type {!WebInspector.StylePropertyTreeElement.Context} */
2947 var context = { 2951 var context = {
2948 expanded: this.expanded, 2952 expanded: this.expanded,
2949 hasChildren: this.hasChildren, 2953 hasChildren: this.hasChildren,
2950 isEditingName: isEditingName, 2954 isEditingName: isEditingName,
2951 previousContent: selectElement.textContent 2955 previousContent: selectElement.textContent
2952 }; 2956 };
2953 2957
2954 // Lie about our children to prevent expanding on double click and to co llapse shorthands. 2958 // Lie about our children to prevent expanding on double click and to co llapse shorthands.
2955 this.hasChildren = false; 2959 this.hasChildren = false;
2956 2960
2957 if (selectElement.parentElement) 2961 if (selectElement.parentElement)
2958 selectElement.parentElement.classList.add("child-editing"); 2962 selectElement.parentElement.classList.add("child-editing");
2959 selectElement.textContent = selectElement.textContent; // remove color s watch and the like 2963 selectElement.textContent = selectElement.textContent; // remove color s watch and the like
2960 2964
2961 /** 2965 /**
2966 * @param {!WebInspector.StylePropertyTreeElement.Context} context
2967 * @param {!Event} event
2962 * @this {WebInspector.StylePropertyTreeElement} 2968 * @this {WebInspector.StylePropertyTreeElement}
2963 */ 2969 */
2964 function pasteHandler(context, event) 2970 function pasteHandler(context, event)
2965 { 2971 {
2966 var data = event.clipboardData.getData("Text"); 2972 var data = event.clipboardData.getData("Text");
2967 if (!data) 2973 if (!data)
2968 return; 2974 return;
2969 var colonIdx = data.indexOf(":"); 2975 var colonIdx = data.indexOf(":");
2970 if (colonIdx < 0) 2976 if (colonIdx < 0)
2971 return; 2977 return;
(...skipping 10 matching lines...) Expand all
2982 this.property.value = value; 2988 this.property.value = value;
2983 this.nameElement.textContent = name; 2989 this.nameElement.textContent = name;
2984 this.valueElement.textContent = value; 2990 this.valueElement.textContent = value;
2985 this.nameElement.normalize(); 2991 this.nameElement.normalize();
2986 this.valueElement.normalize(); 2992 this.valueElement.normalize();
2987 2993
2988 this.editingCommitted(event.target.textContent, context, "forward"); 2994 this.editingCommitted(event.target.textContent, context, "forward");
2989 } 2995 }
2990 2996
2991 /** 2997 /**
2998 * @param {!WebInspector.StylePropertyTreeElement.Context} context
2999 * @param {!Event} event
2992 * @this {WebInspector.StylePropertyTreeElement} 3000 * @this {WebInspector.StylePropertyTreeElement}
2993 */ 3001 */
2994 function blurListener(context, event) 3002 function blurListener(context, event)
2995 { 3003 {
2996 var treeElement = this._parentPane._mouseDownTreeElement; 3004 var treeElement = this._parentPane._mouseDownTreeElement;
2997 var moveDirection = ""; 3005 var moveDirection = "";
2998 if (treeElement === this) { 3006 if (treeElement === this) {
2999 if (isEditingName && this._parentPane._mouseDownTreeElementIsVal ue) 3007 if (isEditingName && this._parentPane._mouseDownTreeElementIsVal ue)
3000 moveDirection = "forward"; 3008 moveDirection = "forward";
3001 if (!isEditingName && this._parentPane._mouseDownTreeElementIsNa me) 3009 if (!isEditingName && this._parentPane._mouseDownTreeElementIsNa me)
(...skipping 10 matching lines...) Expand all
3012 3020
3013 var applyItemCallback = !isEditingName ? this._applyFreeFlowStyleTextEdi t.bind(this) : undefined; 3021 var applyItemCallback = !isEditingName ? this._applyFreeFlowStyleTextEdi t.bind(this) : undefined;
3014 this._prompt = new WebInspector.StylesSidebarPane.CSSPropertyPrompt(isEd itingName ? WebInspector.CSSMetadata.cssPropertiesMetainfo : WebInspector.CSSMet adata.keywordsForProperty(this.nameElement.textContent), this, isEditingName); 3022 this._prompt = new WebInspector.StylesSidebarPane.CSSPropertyPrompt(isEd itingName ? WebInspector.CSSMetadata.cssPropertiesMetainfo : WebInspector.CSSMet adata.keywordsForProperty(this.nameElement.textContent), this, isEditingName);
3015 this._prompt.setAutocompletionTimeout(0); 3023 this._prompt.setAutocompletionTimeout(0);
3016 if (applyItemCallback) { 3024 if (applyItemCallback) {
3017 this._prompt.addEventListener(WebInspector.TextPrompt.Events.ItemApp lied, applyItemCallback, this); 3025 this._prompt.addEventListener(WebInspector.TextPrompt.Events.ItemApp lied, applyItemCallback, this);
3018 this._prompt.addEventListener(WebInspector.TextPrompt.Events.ItemAcc epted, applyItemCallback, this); 3026 this._prompt.addEventListener(WebInspector.TextPrompt.Events.ItemAcc epted, applyItemCallback, this);
3019 } 3027 }
3020 var proxyElement = this._prompt.attachAndStartEditing(selectElement, blu rListener.bind(this, context)); 3028 var proxyElement = this._prompt.attachAndStartEditing(selectElement, blu rListener.bind(this, context));
3021 3029
3022 proxyElement.addEventListener("keydown", this.editingNameValueKeyDown.bi nd(this, context), false); 3030 proxyElement.addEventListener("keydown", this._editingNameValueKeyDown.b ind(this, context), false);
3023 proxyElement.addEventListener("keypress", this.editingNameValueKeyPress. bind(this, context), false); 3031 proxyElement.addEventListener("keypress", this._editingNameValueKeyPress .bind(this, context), false);
3032 proxyElement.addEventListener("input", this._editingNameValueInput.bind( this, context), false);
3024 if (isEditingName) 3033 if (isEditingName)
3025 proxyElement.addEventListener("paste", pasteHandler.bind(this, conte xt), false); 3034 proxyElement.addEventListener("paste", pasteHandler.bind(this, conte xt), false);
3026 3035
3027 window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1); 3036 window.getSelection().setBaseAndExtent(selectElement, 0, selectElement, 1);
3028 }, 3037 },
3029 3038
3030 editingNameValueKeyDown: function(context, event) 3039 /**
3040 * @param {!WebInspector.StylePropertyTreeElement.Context} context
3041 * @param {!Event} event
3042 */
3043 _editingNameValueKeyDown: function(context, event)
3031 { 3044 {
3032 if (event.handled) 3045 if (event.handled)
3033 return; 3046 return;
3034 3047
3035 var isEditingName = context.isEditingName;
3036 var result; 3048 var result;
3037 3049
3038 if (isEnterKey(event)) { 3050 if (isEnterKey(event)) {
3039 event.preventDefault(); 3051 event.preventDefault();
3040 result = "forward"; 3052 result = "forward";
3041 } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B") 3053 } else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
3042 result = "cancel"; 3054 result = "cancel";
3043 else if (!isEditingName && this._newProperty && event.keyCode === WebIns pector.KeyboardShortcut.Keys.Backspace.code) { 3055 else if (!context.isEditingName && this._newProperty && event.keyCode == = WebInspector.KeyboardShortcut.Keys.Backspace.code) {
3044 // For a new property, when Backspace is pressed at the beginning of new property value, move back to the property name. 3056 // For a new property, when Backspace is pressed at the beginning of new property value, move back to the property name.
3045 var selection = window.getSelection(); 3057 var selection = window.getSelection();
3046 if (selection.isCollapsed && !selection.focusOffset) { 3058 if (selection.isCollapsed && !selection.focusOffset) {
3047 event.preventDefault(); 3059 event.preventDefault();
3048 result = "backward"; 3060 result = "backward";
3049 } 3061 }
3050 } else if (event.keyIdentifier === "U+0009") { // Tab key. 3062 } else if (event.keyIdentifier === "U+0009") { // Tab key.
3051 result = event.shiftKey ? "backward" : "forward"; 3063 result = event.shiftKey ? "backward" : "forward";
3052 event.preventDefault(); 3064 event.preventDefault();
3053 } 3065 }
3054 3066
3055 if (result) { 3067 if (result) {
3056 switch (result) { 3068 switch (result) {
3057 case "cancel": 3069 case "cancel":
3058 this.editingCancelled(null, context); 3070 this.editingCancelled(null, context);
3059 break; 3071 break;
3060 case "forward": 3072 case "forward":
3061 case "backward": 3073 case "backward":
3062 this.editingCommitted(event.target.textContent, context, result) ; 3074 this.editingCommitted(event.target.textContent, context, result) ;
3063 break; 3075 break;
3064 } 3076 }
3065 3077
3066 event.consume(); 3078 event.consume();
3067 return; 3079 return;
3068 } 3080 }
3069
3070 if (!isEditingName)
3071 this._applyFreeFlowStyleTextEdit();
3072 }, 3081 },
3073 3082
3074 editingNameValueKeyPress: function(context, event) 3083 /**
3084 * @param {!WebInspector.StylePropertyTreeElement.Context} context
3085 * @param {!Event} event
3086 */
3087 _editingNameValueKeyPress: function(context, event)
3075 { 3088 {
3076 function shouldCommitValueSemicolon(text, cursorPosition) 3089 function shouldCommitValueSemicolon(text, cursorPosition)
3077 { 3090 {
3078 // FIXME: should this account for semicolons inside comments? 3091 // FIXME: should this account for semicolons inside comments?
3079 var openQuote = ""; 3092 var openQuote = "";
3080 for (var i = 0; i < cursorPosition; ++i) { 3093 for (var i = 0; i < cursorPosition; ++i) {
3081 var ch = text[i]; 3094 var ch = text[i];
3082 if (ch === "\\" && openQuote !== "") 3095 if (ch === "\\" && openQuote !== "")
3083 ++i; // skip next character inside string 3096 ++i; // skip next character inside string
3084 else if (!openQuote && (ch === "\"" || ch === "'")) 3097 else if (!openQuote && (ch === "\"" || ch === "'"))
3085 openQuote = ch; 3098 openQuote = ch;
3086 else if (openQuote === ch) 3099 else if (openQuote === ch)
3087 openQuote = ""; 3100 openQuote = "";
3088 } 3101 }
3089 return !openQuote; 3102 return !openQuote;
3090 } 3103 }
3091 3104
3092 var keyChar = String.fromCharCode(event.charCode); 3105 var keyChar = String.fromCharCode(event.charCode);
3093 var isFieldInputTerminated = (context.isEditingName ? keyChar === ":" : keyChar === ";" && shouldCommitValueSemicolon(event.target.textContent, event.ta rget.selectionLeftOffset())); 3106 var isFieldInputTerminated = (context.isEditingName ? keyChar === ":" : keyChar === ";" && shouldCommitValueSemicolon(event.target.textContent, event.ta rget.selectionLeftOffset()));
3094 if (isFieldInputTerminated) { 3107 if (isFieldInputTerminated) {
3095 // Enter or colon (for name)/semicolon outside of string (for value) . 3108 // Enter or colon (for name)/semicolon outside of string (for value) .
3096 event.consume(true); 3109 event.consume(true);
3097 this.editingCommitted(event.target.textContent, context, "forward"); 3110 this.editingCommitted(event.target.textContent, context, "forward");
3098 return; 3111 return;
3099 } 3112 }
3100 }, 3113 },
3101 3114
3115 /**
3116 * @param {!WebInspector.StylePropertyTreeElement.Context} context
3117 * @param {!Event} event
3118 */
3119 _editingNameValueInput: function(context, event)
3120 {
3121 if (!context.isEditingName)
apavlov 2014/10/13 13:39:48 You may want to check that the value has actually
lushnikov 2014/10/13 14:38:23 The check is performed in the innerApplyStyleText
3122 this._applyFreeFlowStyleTextEdit();
3123 },
3124
3102 _applyFreeFlowStyleTextEdit: function() 3125 _applyFreeFlowStyleTextEdit: function()
3103 { 3126 {
3104 var valueText = this.valueElement.textContent; 3127 var valueText = this.valueElement.textContent;
3105 if (valueText.indexOf(";") === -1) 3128 if (valueText.indexOf(";") === -1)
3106 this.applyStyleText(this.nameElement.textContent + ": " + valueText, false, false, false); 3129 this.applyStyleText(this.nameElement.textContent + ": " + valueText, false, false, false);
3107 }, 3130 },
3108 3131
3109 kickFreeFlowStyleEditForTest: function() 3132 kickFreeFlowStyleEditForTest: function()
3110 { 3133 {
3111 this._applyFreeFlowStyleTextEdit(); 3134 this._applyFreeFlowStyleTextEdit();
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
3559 if (userEnteredText && (userEnteredText === userEnteredText.toUpperCase( ))) { 3582 if (userEnteredText && (userEnteredText === userEnteredText.toUpperCase( ))) {
3560 for (var i = 0; i < results.length; ++i) 3583 for (var i = 0; i < results.length; ++i)
3561 results[i] = results[i].toUpperCase(); 3584 results[i] = results[i].toUpperCase();
3562 } 3585 }
3563 var selectedIndex = this._cssCompletions.mostUsedOf(results); 3586 var selectedIndex = this._cssCompletions.mostUsedOf(results);
3564 completionsReadyCallback(results, selectedIndex); 3587 completionsReadyCallback(results, selectedIndex);
3565 }, 3588 },
3566 3589
3567 __proto__: WebInspector.TextPrompt.prototype 3590 __proto__: WebInspector.TextPrompt.prototype
3568 } 3591 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698