зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 4 changesets (bug 988313) because the gods of mochitest-bc are not appeased
Backed out changeset bb8e0a572620 (bug 988313) Backed out changeset ebcad2bf9017 (bug 988313) Backed out changeset 13c7239294aa (bug 988313) Backed out changeset 070988f93458 (bug 988313) --HG-- rename : browser/devtools/styleinspector/test/browser_computedview_keybindings_01.js => browser/devtools/styleinspector/test/browser_bug589375_keybindings.js rename : browser/devtools/styleinspector/test/doc_matched_selectors.html => browser/devtools/styleinspector/test/browser_bug683672.html rename : browser/devtools/styleinspector/test/browser_computedview_matched-selectors_01.js => browser/devtools/styleinspector/test/browser_bug683672.js rename : browser/devtools/styleinspector/test/browser_styleinspector_tooltip-longhand-fontfamily.js => browser/devtools/styleinspector/test/browser_bug702577_fontfamily_tooltip_longhand.js rename : browser/devtools/styleinspector/test/browser_styleinspector_tooltip-shorthand-fontfamily.js => browser/devtools/styleinspector/test/browser_bug702577_fontfamily_tooltip_shorthand.js rename : browser/devtools/styleinspector/test/doc_content_stylesheet.html => browser/devtools/styleinspector/test/browser_bug705707_is_content_stylesheet.html rename : browser/devtools/styleinspector/test/browser_styleinspector_csslogic-content-stylesheets.js => browser/devtools/styleinspector/test/browser_bug705707_is_content_stylesheet.js rename : browser/devtools/styleinspector/test/doc_content_stylesheet.xul => browser/devtools/styleinspector/test/browser_bug705707_is_content_stylesheet.xul rename : browser/devtools/styleinspector/test/doc_content_stylesheet_imported.css => browser/devtools/styleinspector/test/browser_bug705707_is_content_stylesheet_imported.css rename : browser/devtools/styleinspector/test/doc_content_stylesheet_imported2.css => browser/devtools/styleinspector/test/browser_bug705707_is_content_stylesheet_imported2.css rename : browser/devtools/styleinspector/test/doc_content_stylesheet_linked.css => browser/devtools/styleinspector/test/browser_bug705707_is_content_stylesheet_linked.css rename : browser/devtools/styleinspector/test/doc_content_stylesheet_script.css => browser/devtools/styleinspector/test/browser_bug705707_is_content_stylesheet_script.css rename : browser/devtools/styleinspector/test/doc_content_stylesheet_xul.css => browser/devtools/styleinspector/test/browser_bug705707_is_content_stylesheet_xul.css rename : browser/devtools/styleinspector/test/doc_media_queries.html => browser/devtools/styleinspector/test/browser_bug722196_identify_media_queries.html rename : browser/devtools/styleinspector/test/browser_computedview_media-queries.js => browser/devtools/styleinspector/test/browser_bug722196_property_view_media_queries.js rename : browser/devtools/styleinspector/test/browser_ruleview_media-queries.js => browser/devtools/styleinspector/test/browser_bug722196_rule_view_media_queries.js rename : browser/devtools/styleinspector/test/browser_ruleview_edit-property-increments.js => browser/devtools/styleinspector/test/browser_bug722691_rule_view_increment.js rename : browser/devtools/styleinspector/test/browser_styleinspector_tooltip-transform.js => browser/devtools/styleinspector/test/browser_bug726427_csstransform_tooltip.js rename : browser/devtools/styleinspector/test/browser_styleinspector_tooltip-background-image.js => browser/devtools/styleinspector/test/browser_bug765105_background_image_tooltip.js rename : browser/devtools/styleinspector/test/browser_ruleview_completion-existing-property_01.js => browser/devtools/styleinspector/test/browser_bug893965_css_property_completion_existing_property.js rename : browser/devtools/styleinspector/test/browser_ruleview_completion-new-property_01.js => browser/devtools/styleinspector/test/browser_bug893965_css_property_completion_new_property.js rename : browser/devtools/styleinspector/test/browser_ruleview_completion-existing-property_02.js => browser/devtools/styleinspector/test/browser_bug894376_css_value_completion_existing_property_value_pair.js rename : browser/devtools/styleinspector/test/browser_ruleview_completion-new-property_02.js => browser/devtools/styleinspector/test/browser_bug894376_css_value_completion_new_property_value_pair.js rename : browser/devtools/styleinspector/test/browser_computedview_matched-selectors-toggle.js => browser/devtools/styleinspector/test/browser_bug913014_matched_expand.js rename : browser/devtools/styleinspector/test/browser_ruleview_colorpicker-edit-gradient.js => browser/devtools/styleinspector/test/browser_bug940500_rule_view_pick_gradient_color.js rename : browser/devtools/styleinspector/test/browser_ruleview_user-property-reset.js => browser/devtools/styleinspector/test/browser_bug942297_user_property_reset.js rename : browser/devtools/styleinspector/test/browser_styleinspector_tooltip-closes-on-new-selection.js => browser/devtools/styleinspector/test/browser_bug946331_close_tooltip_on_new_selection.js rename : browser/devtools/styleinspector/test/browser_ruleview_mathml-element.js => browser/devtools/styleinspector/test/browser_bug970532_mathml_element.js rename : browser/devtools/styleinspector/test/browser_styleinspector_csslogic-specificity.js => browser/devtools/styleinspector/test/browser_bug_592743_specificity.js rename : browser/devtools/styleinspector/test/browser_computedview_matched-selectors_02.js => browser/devtools/styleinspector/test/browser_bug_692400_element_style.js rename : browser/devtools/styleinspector/test/browser_computedview_style-editor-link.js => browser/devtools/styleinspector/test/browser_computedview_734259_style_editor_link.js rename : browser/devtools/styleinspector/test/browser_computedview_keybindings_02.js => browser/devtools/styleinspector/test/browser_computedview_bug835808_keyboard_nav.js rename : browser/devtools/styleinspector/test/browser_computedview_select-and-copy-styles.js => browser/devtools/styleinspector/test/browser_computedview_copy.js rename : browser/devtools/styleinspector/test/browser_computedview_original-source-link.js => browser/devtools/styleinspector/test/browser_computedview_original_source_link.js rename : browser/devtools/styleinspector/test/browser_styleinspector_csslogic-inherited-properties.js => browser/devtools/styleinspector/test/browser_csslogic_inherited.js rename : browser/devtools/styleinspector/test/doc_style_editor_link.css => browser/devtools/styleinspector/test/browser_ruleview_734259_style_editor_link.css rename : browser/devtools/styleinspector/test/browser_ruleview_style-editor-link.js => browser/devtools/styleinspector/test/browser_ruleview_734259_style_editor_link.js rename : browser/devtools/styleinspector/test/browser_ruleview_edit-property-commit.js => browser/devtools/styleinspector/test/browser_ruleview_bug_902966_revert_value_on_ESC.js rename : browser/devtools/styleinspector/test/browser_ruleview_select-and-copy-styles.js => browser/devtools/styleinspector/test/browser_ruleview_copy.js rename : browser/devtools/styleinspector/test/browser_styleinspector_inplace-editor.js => browser/devtools/styleinspector/test/browser_ruleview_editor.js rename : browser/devtools/styleinspector/test/browser_ruleview_keybindings.js => browser/devtools/styleinspector/test/browser_ruleview_focus.js rename : browser/devtools/styleinspector/test/browser_ruleview_edit-property-order.js => browser/devtools/styleinspector/test/browser_ruleview_manipulation.js rename : browser/devtools/styleinspector/test/browser_ruleview_original-source-link.js => browser/devtools/styleinspector/test/browser_ruleview_original_source_link.js rename : browser/devtools/styleinspector/test/doc_pseudoelement.html => browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.html rename : browser/devtools/styleinspector/test/browser_ruleview_pseudo-element.js => browser/devtools/styleinspector/test/browser_ruleview_pseudoelement.js rename : browser/devtools/styleinspector/test/browser_ruleview_edit-property_02.js => browser/devtools/styleinspector/test/browser_ruleview_ui.js rename : browser/devtools/styleinspector/test/browser_computedview_search-filter.js => browser/devtools/styleinspector/test/browser_styleinspector_bug_672744_search_filter.js rename : browser/devtools/styleinspector/test/browser_computedview_browser-styles.js => browser/devtools/styleinspector/test/browser_styleinspector_bug_672746_default_styles.js rename : browser/devtools/styleinspector/test/doc_urls_clickable.html => browser/devtools/styleinspector/test/browser_styleinspector_bug_677930_urls_clickable.html rename : browser/devtools/styleinspector/test/browser_ruleview_urls-clickable.js => browser/devtools/styleinspector/test/browser_styleinspector_bug_677930_urls_clickable.js rename : browser/devtools/styleinspector/test/doc_urls_clickable.css => browser/devtools/styleinspector/test/browser_styleinspector_bug_677930_urls_clickable/browser_styleinspector_bug_677930_urls_clickable.css rename : browser/devtools/styleinspector/test/browser_computedview_no-results-placeholder.js => browser/devtools/styleinspector/test/browser_styleinspector_bug_689759_no_results_placeholder.js rename : browser/devtools/styleinspector/test/browser_styleinspector_output-parser.js => browser/devtools/styleinspector/test/browser_styleinspector_outputparser.js rename : browser/devtools/styleinspector/test/doc_sourcemaps.css => browser/devtools/styleinspector/test/sourcemaps.css rename : browser/devtools/styleinspector/test/doc_sourcemaps.css.map => browser/devtools/styleinspector/test/sourcemaps.css.map rename : browser/devtools/styleinspector/test/doc_sourcemaps.html => browser/devtools/styleinspector/test/sourcemaps.html rename : browser/devtools/styleinspector/test/doc_sourcemaps.scss => browser/devtools/styleinspector/test/sourcemaps.scss rename : browser/devtools/styleinspector/test/doc_test_image.png => browser/devtools/styleinspector/test/test-image.png
This commit is contained in:
Родитель
5f44632bc3
Коммит
4409a18fbe
|
@ -124,7 +124,6 @@ skip-if = os == 'linux'&&debug # bug 989083
|
||||||
[browser_tabview_bug650573.js]
|
[browser_tabview_bug650573.js]
|
||||||
[browser_tabview_bug651311.js]
|
[browser_tabview_bug651311.js]
|
||||||
[browser_tabview_bug654295.js]
|
[browser_tabview_bug654295.js]
|
||||||
skip-if = os == 'linux' && debug
|
|
||||||
[browser_tabview_bug654721.js]
|
[browser_tabview_bug654721.js]
|
||||||
[browser_tabview_bug654941.js]
|
[browser_tabview_bug654941.js]
|
||||||
skip-if = true # Bug 754222
|
skip-if = true # Bug 754222
|
||||||
|
|
|
@ -1,90 +1,82 @@
|
||||||
[DEFAULT]
|
[DEFAULT]
|
||||||
skip-if = e10s # Bug ?????? - devtools tests disabled with e10s
|
skip-if = e10s # Bug ?????? - devtools tests disabled with e10s
|
||||||
support-files =
|
support-files =
|
||||||
doc_content_stylesheet.html
|
|
||||||
doc_content_stylesheet.xul
|
|
||||||
doc_content_stylesheet_imported.css
|
|
||||||
doc_content_stylesheet_imported2.css
|
|
||||||
doc_content_stylesheet_linked.css
|
|
||||||
doc_content_stylesheet_script.css
|
|
||||||
doc_content_stylesheet_xul.css
|
|
||||||
doc_matched_selectors.html
|
|
||||||
doc_media_queries.html
|
|
||||||
doc_pseudoelement.html
|
|
||||||
doc_sourcemaps.css
|
|
||||||
doc_sourcemaps.css.map
|
|
||||||
doc_sourcemaps.html
|
|
||||||
doc_sourcemaps.scss
|
|
||||||
doc_style_editor_link.css
|
|
||||||
doc_test_image.png
|
|
||||||
doc_urls_clickable.css
|
|
||||||
doc_urls_clickable.html
|
|
||||||
head.js
|
head.js
|
||||||
|
browser_bug722196_identify_media_queries.html
|
||||||
|
browser_styleinspector_bug_677930_urls_clickable/browser_styleinspector_bug_677930_urls_clickable.css
|
||||||
|
|
||||||
[browser_computedview_browser-styles.js]
|
[browser_bug683672.js]
|
||||||
[browser_computedview_keybindings_01.js]
|
support-files = browser_bug683672.html
|
||||||
[browser_computedview_keybindings_02.js]
|
[browser_styleinspector_bug_672746_default_styles.js]
|
||||||
[browser_computedview_matched-selectors-toggle.js]
|
[browser_styleinspector_bug_672744_search_filter.js]
|
||||||
[browser_computedview_matched-selectors_01.js]
|
[browser_bug589375_keybindings.js]
|
||||||
[browser_computedview_matched-selectors_02.js]
|
skip-if = true # awaiting promise-based init
|
||||||
[browser_computedview_media-queries.js]
|
[browser_styleinspector_bug_689759_no_results_placeholder.js]
|
||||||
[browser_computedview_no-results-placeholder.js]
|
[browser_bug_692400_element_style.js]
|
||||||
[browser_computedview_original-source-link.js]
|
[browser_csslogic_inherited.js]
|
||||||
[browser_computedview_search-filter.js]
|
[browser_ruleview_734259_style_editor_link.js]
|
||||||
[browser_computedview_select-and-copy-styles.js]
|
support-files =
|
||||||
[browser_computedview_style-editor-link.js]
|
browser_ruleview_734259_style_editor_link.css
|
||||||
[browser_ruleview_add-property-and-reselect.js]
|
[browser_ruleview_editor.js]
|
||||||
[browser_ruleview_add-property-cancel_01.js]
|
[browser_ruleview_editor_changedvalues.js]
|
||||||
[browser_ruleview_add-property-cancel_02.js]
|
[browser_ruleview_copy.js]
|
||||||
[browser_ruleview_add-property-cancel_03.js]
|
[browser_ruleview_focus.js]
|
||||||
[browser_ruleview_add-property_01.js]
|
[browser_ruleview_inherit.js]
|
||||||
[browser_ruleview_add-property_02.js]
|
[browser_ruleview_manipulation.js]
|
||||||
|
[browser_ruleview_multiple_properties.js]
|
||||||
|
[browser_ruleview_override.js]
|
||||||
|
[browser_ruleview_ui.js]
|
||||||
|
[browser_ruleview_update.js]
|
||||||
|
[browser_ruleview_livepreview.js]
|
||||||
|
[browser_bug705707_is_content_stylesheet.js]
|
||||||
|
support-files =
|
||||||
|
browser_bug705707_is_content_stylesheet.html
|
||||||
|
browser_bug705707_is_content_stylesheet_imported.css
|
||||||
|
browser_bug705707_is_content_stylesheet_imported2.css
|
||||||
|
browser_bug705707_is_content_stylesheet_linked.css
|
||||||
|
browser_bug705707_is_content_stylesheet_script.css
|
||||||
|
browser_bug705707_is_content_stylesheet.xul
|
||||||
|
browser_bug705707_is_content_stylesheet_xul.css
|
||||||
|
[browser_bug722196_property_view_media_queries.js]
|
||||||
|
[browser_bug722196_rule_view_media_queries.js]
|
||||||
|
[browser_bug_592743_specificity.js]
|
||||||
|
[browser_bug722691_rule_view_increment.js]
|
||||||
|
[browser_computedview_734259_style_editor_link.js]
|
||||||
|
[browser_computedview_copy.js]
|
||||||
|
[browser_styleinspector_bug_677930_urls_clickable.js]
|
||||||
|
support-files =
|
||||||
|
test-image.png
|
||||||
|
browser_styleinspector_bug_677930_urls_clickable.html
|
||||||
|
[browser_bug893965_css_property_completion_new_property.js]
|
||||||
|
[browser_bug893965_css_property_completion_existing_property.js]
|
||||||
|
[browser_bug894376_css_value_completion_new_property_value_pair.js]
|
||||||
|
[browser_bug894376_css_value_completion_existing_property_value_pair.js]
|
||||||
|
[browser_ruleview_bug_902966_revert_value_on_ESC.js]
|
||||||
|
[browser_ruleview_pseudoelement.js]
|
||||||
|
support-files = browser_ruleview_pseudoelement.html
|
||||||
|
[browser_computedview_bug835808_keyboard_nav.js]
|
||||||
|
[browser_bug913014_matched_expand.js]
|
||||||
|
[browser_bug765105_background_image_tooltip.js]
|
||||||
|
[browser_bug726427_csstransform_tooltip.js]
|
||||||
|
[browser_bug702577_fontfamily_tooltip_shorthand.js]
|
||||||
|
[browser_bug702577_fontfamily_tooltip_longhand.js]
|
||||||
|
[browser_bug940500_rule_view_pick_gradient_color.js]
|
||||||
|
[browser_ruleview_original_source_link.js]
|
||||||
|
support-files =
|
||||||
|
sourcemaps.html
|
||||||
|
sourcemaps.css
|
||||||
|
sourcemaps.css.map
|
||||||
|
sourcemaps.scss
|
||||||
|
[browser_computedview_original_source_link.js]
|
||||||
|
[browser_bug946331_close_tooltip_on_new_selection.js]
|
||||||
|
[browser_bug942297_user_property_reset.js]
|
||||||
|
[browser_styleinspector_outputparser.js]
|
||||||
|
[browser_bug970532_mathml_element.js]
|
||||||
|
[browser_ruleview_colorpicker-swatch-displayed.js]
|
||||||
|
[browser_ruleview_colorpicker-appears-on-swatch-click.js]
|
||||||
|
[browser_ruleview_colorpicker-hides-on-tooltip.js]
|
||||||
|
[browser_ruleview_colorpicker-revert-on-ESC.js]
|
||||||
|
[browser_ruleview_colorpicker-commit-on-ENTER.js]
|
||||||
[browser_ruleview_colorpicker-and-image-tooltip_01.js]
|
[browser_ruleview_colorpicker-and-image-tooltip_01.js]
|
||||||
[browser_ruleview_colorpicker-and-image-tooltip_02.js]
|
[browser_ruleview_colorpicker-and-image-tooltip_02.js]
|
||||||
[browser_ruleview_colorpicker-appears-on-swatch-click.js]
|
|
||||||
[browser_ruleview_colorpicker-commit-on-ENTER.js]
|
|
||||||
[browser_ruleview_colorpicker-edit-gradient.js]
|
|
||||||
[browser_ruleview_colorpicker-hides-on-tooltip.js]
|
|
||||||
[browser_ruleview_colorpicker-multiple-changes.js]
|
[browser_ruleview_colorpicker-multiple-changes.js]
|
||||||
[browser_ruleview_colorpicker-revert-on-ESC.js]
|
|
||||||
[browser_ruleview_colorpicker-swatch-displayed.js]
|
|
||||||
[browser_ruleview_completion-existing-property_01.js]
|
|
||||||
[browser_ruleview_completion-existing-property_02.js]
|
|
||||||
[browser_ruleview_completion-new-property_01.js]
|
|
||||||
[browser_ruleview_completion-new-property_02.js]
|
|
||||||
[browser_ruleview_content.js]
|
|
||||||
[browser_ruleview_edit-property-commit.js]
|
|
||||||
[browser_ruleview_edit-property-increments.js]
|
|
||||||
[browser_ruleview_edit-property-order.js]
|
|
||||||
[browser_ruleview_edit-property_01.js]
|
|
||||||
[browser_ruleview_edit-property_02.js]
|
|
||||||
[browser_ruleview_inherit.js]
|
|
||||||
[browser_ruleview_keybindings.js]
|
|
||||||
[browser_ruleview_livepreview.js]
|
|
||||||
[browser_ruleview_mathml-element.js]
|
|
||||||
[browser_ruleview_media-queries.js]
|
|
||||||
[browser_ruleview_multiple-properties-duplicates.js]
|
|
||||||
[browser_ruleview_multiple-properties-priority.js]
|
|
||||||
[browser_ruleview_multiple-properties-unfinished_01.js]
|
|
||||||
[browser_ruleview_multiple-properties-unfinished_02.js]
|
|
||||||
[browser_ruleview_multiple_properties_01.js]
|
|
||||||
[browser_ruleview_multiple_properties_02.js]
|
|
||||||
[browser_ruleview_original-source-link.js]
|
|
||||||
[browser_ruleview_override.js]
|
|
||||||
[browser_ruleview_pseudo-element.js]
|
|
||||||
[browser_ruleview_refresh-on-attribute-change_01.js]
|
|
||||||
[browser_ruleview_refresh-on-attribute-change_02.js]
|
|
||||||
[browser_ruleview_select-and-copy-styles.js]
|
|
||||||
[browser_ruleview_style-editor-link.js]
|
|
||||||
[browser_ruleview_urls-clickable.js]
|
|
||||||
[browser_ruleview_user-property-reset.js]
|
|
||||||
[browser_styleinspector_csslogic-content-stylesheets.js]
|
|
||||||
[browser_styleinspector_csslogic-inherited-properties.js]
|
|
||||||
[browser_styleinspector_csslogic-specificity.js]
|
|
||||||
[browser_styleinspector_inplace-editor.js]
|
|
||||||
[browser_styleinspector_output-parser.js]
|
|
||||||
[browser_styleinspector_tooltip-background-image.js]
|
|
||||||
[browser_styleinspector_tooltip-closes-on-new-selection.js]
|
|
||||||
[browser_styleinspector_tooltip-longhand-fontfamily.js]
|
|
||||||
[browser_styleinspector_tooltip-shorthand-fontfamily.js]
|
|
||||||
[browser_styleinspector_tooltip-transform.js]
|
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Tests that the key bindings work properly.
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let computedView;
|
||||||
|
let iframe;
|
||||||
|
|
||||||
|
function createDocument()
|
||||||
|
{
|
||||||
|
doc.body.innerHTML = '<style type="text/css"> ' +
|
||||||
|
'.matches {color: #F00;}</style>' +
|
||||||
|
'<span class="matches">Some styled text</span>' +
|
||||||
|
'</div>';
|
||||||
|
doc.title = "Style Inspector key binding test";
|
||||||
|
|
||||||
|
openInspector(openComputedView);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openComputedView(aInspector)
|
||||||
|
{
|
||||||
|
inspector = aInspector;
|
||||||
|
iframe = inspector._toolbox.frame;
|
||||||
|
|
||||||
|
Services.obs.addObserver(runTests, "StyleInspector-populated", false);
|
||||||
|
|
||||||
|
inspector.sidebar.select("computedview");
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests()
|
||||||
|
{
|
||||||
|
Services.obs.removeObserver(runTests, "StyleInspector-populated");
|
||||||
|
computedView = getComputedView();
|
||||||
|
|
||||||
|
var span = doc.querySelector(".matches");
|
||||||
|
ok(span, "captain, we have the matches span");
|
||||||
|
|
||||||
|
inspector.selection.setNode(span);
|
||||||
|
|
||||||
|
is(span, computedView.viewedElement,
|
||||||
|
"style inspector node matches the selected node");
|
||||||
|
is(computedView.viewedElement, computedView.cssLogic.viewedElement,
|
||||||
|
"cssLogic node matches the cssHtmlTree node");
|
||||||
|
|
||||||
|
info("checking keybindings");
|
||||||
|
|
||||||
|
let searchbar = computedView.searchField;
|
||||||
|
let propView = getFirstVisiblePropertyView();
|
||||||
|
let rulesTable = propView.matchedSelectorsContainer;
|
||||||
|
let matchedExpander = propView.matchedExpander;
|
||||||
|
|
||||||
|
info("Adding focus event handler to search filter");
|
||||||
|
searchbar.addEventListener("focus", function searchbarFocused() {
|
||||||
|
searchbar.removeEventListener("focus", searchbarFocused);
|
||||||
|
info("search filter is focused");
|
||||||
|
info("tabbing to property expander node");
|
||||||
|
EventUtils.synthesizeKey("VK_TAB", {}, iframe.contentWindow);
|
||||||
|
});
|
||||||
|
|
||||||
|
info("Adding focus event handler to property expander");
|
||||||
|
matchedExpander.addEventListener("focus", function expanderFocused() {
|
||||||
|
matchedExpander.removeEventListener("focus", expanderFocused);
|
||||||
|
info("property expander is focused");
|
||||||
|
info("checking expand / collapse");
|
||||||
|
testKey(iframe.contentWindow, "VK_SPACE", rulesTable);
|
||||||
|
testKey(iframe.contentWindow, "VK_RETURN", rulesTable);
|
||||||
|
|
||||||
|
checkHelpLinkKeybinding();
|
||||||
|
computedView.destroy();
|
||||||
|
finishUp();
|
||||||
|
});
|
||||||
|
|
||||||
|
info("Making sure that the style inspector panel is focused");
|
||||||
|
SimpleTest.waitForFocus(function windowFocused() {
|
||||||
|
info("window is focused");
|
||||||
|
info("focusing search filter");
|
||||||
|
searchbar.focus();
|
||||||
|
}, iframe.contentWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFirstVisiblePropertyView()
|
||||||
|
{
|
||||||
|
let propView = null;
|
||||||
|
computedView.propertyViews.some(function(aPropView) {
|
||||||
|
if (aPropView.visible) {
|
||||||
|
propView = aPropView;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return propView;
|
||||||
|
}
|
||||||
|
|
||||||
|
function testKey(aContext, aVirtKey, aRulesTable)
|
||||||
|
{
|
||||||
|
info("testing " + aVirtKey + " key");
|
||||||
|
info("expanding rules table");
|
||||||
|
EventUtils.synthesizeKey(aVirtKey, {}, aContext);
|
||||||
|
isnot(aRulesTable.innerHTML, "", "rules Table is populated");
|
||||||
|
info("collapsing rules table");
|
||||||
|
EventUtils.synthesizeKey(aVirtKey, {}, aContext);
|
||||||
|
is(aRulesTable.innerHTML, "", "rules Table is not populated");
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkHelpLinkKeybinding()
|
||||||
|
{
|
||||||
|
info("checking help link keybinding");
|
||||||
|
let propView = getFirstVisiblePropertyView();
|
||||||
|
|
||||||
|
info("check that MDN link is opened on \"F1\"");
|
||||||
|
let linkClicked = false;
|
||||||
|
propView.mdnLinkClick = function(aEvent) {
|
||||||
|
linkClicked = true;
|
||||||
|
};
|
||||||
|
EventUtils.synthesizeKey("VK_F1", {}, iframe.contentWindow);
|
||||||
|
is(linkClicked, true, "MDN link will be shown");
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
doc = inspector = iframe = computedView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,default styles test";
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Tests that the style inspector works properly
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let div;
|
||||||
|
let computedView;
|
||||||
|
|
||||||
|
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/test/browser_bug683672.html";
|
||||||
|
|
||||||
|
let tempScope = {};
|
||||||
|
let {CssHtmlTree, PropertyView} = devtools.require("devtools/styleinspector/computed-view");
|
||||||
|
let {console} = Cu.import("resource://gre/modules/devtools/Console.jsm", {});
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
addTab(TEST_URI);
|
||||||
|
browser.addEventListener("load", tabLoaded, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tabLoaded()
|
||||||
|
{
|
||||||
|
browser.removeEventListener("load", tabLoaded, true);
|
||||||
|
doc = content.document;
|
||||||
|
openComputedView(selectNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectNode(aInspector, aComputedView)
|
||||||
|
{
|
||||||
|
inspector = aInspector;
|
||||||
|
computedView = aComputedView;
|
||||||
|
|
||||||
|
div = content.document.getElementById("test");
|
||||||
|
ok(div, "captain, we have the div");
|
||||||
|
|
||||||
|
inspector.selection.setNode(div);
|
||||||
|
inspector.once("inspector-updated", runTests);
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests()
|
||||||
|
{
|
||||||
|
testMatchedSelectors().then(() => {
|
||||||
|
info("finishing up");
|
||||||
|
finishUp();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testMatchedSelectors()
|
||||||
|
{
|
||||||
|
info("checking selector counts, matched rules and titles");
|
||||||
|
|
||||||
|
is(div, computedView.viewedElement.rawNode(),
|
||||||
|
"style inspector node matches the selected node");
|
||||||
|
|
||||||
|
let propertyView = new PropertyView(computedView, "color");
|
||||||
|
propertyView.buildMain();
|
||||||
|
propertyView.buildSelectorContainer();
|
||||||
|
propertyView.matchedExpanded = true;
|
||||||
|
return propertyView.refreshMatchedSelectors().then(() => {
|
||||||
|
let numMatchedSelectors = propertyView.matchedSelectors.length;
|
||||||
|
|
||||||
|
is(numMatchedSelectors, 6,
|
||||||
|
"CssLogic returns the correct number of matched selectors for div");
|
||||||
|
|
||||||
|
is(propertyView.hasMatchedSelectors, true,
|
||||||
|
"hasMatchedSelectors returns true");
|
||||||
|
}).then(null, (err) => console.error(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
doc = inspector = div = computedView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -0,0 +1,118 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let contentDoc;
|
||||||
|
let inspector;
|
||||||
|
let ruleView;
|
||||||
|
let computedView;
|
||||||
|
|
||||||
|
const PAGE_CONTENT = [
|
||||||
|
'<style type="text/css">',
|
||||||
|
' #testElement {',
|
||||||
|
' font-family: cursive;',
|
||||||
|
' color: #333;',
|
||||||
|
' padding-left: 70px;',
|
||||||
|
' }',
|
||||||
|
'</style>',
|
||||||
|
'<div id="testElement">test element</div>'
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
contentDoc = content.document;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html;charset=utf-8,font family longhand tooltip test";
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDocument() {
|
||||||
|
contentDoc.body.innerHTML = PAGE_CONTENT;
|
||||||
|
|
||||||
|
openRuleView((aInspector, aRuleView) => {
|
||||||
|
inspector = aInspector;
|
||||||
|
ruleView = aRuleView;
|
||||||
|
startTests();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startTests() {
|
||||||
|
inspector.selection.setNode(contentDoc.querySelector("#testElement"));
|
||||||
|
inspector.once("inspector-updated", testRuleView);
|
||||||
|
}
|
||||||
|
|
||||||
|
function endTests() {
|
||||||
|
contentDoc = inspector = ruleView = computedView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRuleView() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
info("Testing font-family tooltips in the rule view");
|
||||||
|
|
||||||
|
let panel = ruleView.previewTooltip.panel;
|
||||||
|
|
||||||
|
// Check that the rule view has a tooltip and that a XUL panel has been created
|
||||||
|
ok(ruleView.previewTooltip, "Tooltip instance exists");
|
||||||
|
ok(panel, "XUL panel exists");
|
||||||
|
|
||||||
|
// Get the font family property inside the rule view
|
||||||
|
let {valueSpan} = getRuleViewProperty("font-family");
|
||||||
|
|
||||||
|
// And verify that the tooltip gets shown on this property
|
||||||
|
assertTooltipShownOn(ruleView.previewTooltip, valueSpan);
|
||||||
|
|
||||||
|
let description = panel.getElementsByTagName("description")[0];
|
||||||
|
is(description.style.fontFamily, "cursive", "Tooltips contains correct font-family style");
|
||||||
|
}).then(testComputedView);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testComputedView() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
info("Testing font-family tooltips in the computed view");
|
||||||
|
|
||||||
|
inspector.sidebar.select("computedview");
|
||||||
|
computedView = inspector.sidebar.getWindowForTab("computedview").computedview.view;
|
||||||
|
let doc = computedView.styleDocument;
|
||||||
|
|
||||||
|
let panel = computedView.tooltip.panel;
|
||||||
|
let {valueSpan} = getComputedViewProperty("font-family");
|
||||||
|
|
||||||
|
assertTooltipShownOn(computedView.tooltip, valueSpan);
|
||||||
|
|
||||||
|
let description = panel.getElementsByTagName("description")[0];
|
||||||
|
is(description.style.fontFamily, "cursive", "Tooltips contains correct font-family style");
|
||||||
|
}).then(endTests);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRuleViewProperty(name) {
|
||||||
|
let prop = null;
|
||||||
|
[].forEach.call(ruleView.doc.querySelectorAll(".ruleview-property"), property => {
|
||||||
|
let nameSpan = property.querySelector(".ruleview-propertyname");
|
||||||
|
let valueSpan = property.querySelector(".ruleview-propertyvalue");
|
||||||
|
|
||||||
|
if (nameSpan.textContent === name) {
|
||||||
|
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getComputedViewProperty(name) {
|
||||||
|
let prop = null;
|
||||||
|
[].forEach.call(computedView.styleDocument.querySelectorAll(".property-view"), property => {
|
||||||
|
let nameSpan = property.querySelector(".property-name");
|
||||||
|
let valueSpan = property.querySelector(".property-value");
|
||||||
|
|
||||||
|
if (nameSpan.textContent === name) {
|
||||||
|
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return prop;
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let contentDoc;
|
||||||
|
let inspector;
|
||||||
|
let ruleView;
|
||||||
|
let computedView;
|
||||||
|
|
||||||
|
const PAGE_CONTENT = [
|
||||||
|
'<style type="text/css">',
|
||||||
|
' #testElement {',
|
||||||
|
' font: italic bold .8em/1.2 Arial;',
|
||||||
|
' }',
|
||||||
|
'</style>',
|
||||||
|
'<div id="testElement">test element</div>'
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
contentDoc = content.document;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html;charset=utf-8,font family shorthand tooltip test";
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDocument() {
|
||||||
|
contentDoc.body.innerHTML = PAGE_CONTENT;
|
||||||
|
|
||||||
|
openRuleView((aInspector, aRuleView) => {
|
||||||
|
inspector = aInspector;
|
||||||
|
ruleView = aRuleView;
|
||||||
|
startTests();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startTests() {
|
||||||
|
inspector.selection.setNode(contentDoc.querySelector("#testElement"));
|
||||||
|
inspector.once("inspector-updated", testRuleView);
|
||||||
|
}
|
||||||
|
|
||||||
|
function endTests() {
|
||||||
|
contentDoc = inspector = ruleView = computedView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRuleView() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
info("Testing font-family tooltips in the rule view");
|
||||||
|
|
||||||
|
let panel = ruleView.previewTooltip.panel;
|
||||||
|
|
||||||
|
// Check that the rule view has a tooltip and that a XUL panel has been created
|
||||||
|
ok(ruleView.previewTooltip, "Tooltip instance exists");
|
||||||
|
ok(panel, "XUL panel exists");
|
||||||
|
|
||||||
|
// Get the computed font family property inside the font rule view
|
||||||
|
let propertyList = ruleView.element.querySelectorAll(".ruleview-propertylist");
|
||||||
|
let fontExpander = propertyList[1].querySelectorAll(".ruleview-expander")[0];
|
||||||
|
fontExpander.click();
|
||||||
|
|
||||||
|
let {valueSpan} = getRuleViewProperty("font-family");
|
||||||
|
|
||||||
|
// And verify that the tooltip gets shown on this property
|
||||||
|
yield assertTooltipShownOn(ruleView.previewTooltip, valueSpan);
|
||||||
|
|
||||||
|
// And that it has the right content
|
||||||
|
let description = panel.getElementsByTagName("description")[0];
|
||||||
|
is(description.style.fontFamily, "Arial", "Tooltips contains correct font-family style");
|
||||||
|
}).then(testComputedView);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testComputedView() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
info("Testing font-family tooltips in the computed view");
|
||||||
|
|
||||||
|
inspector.sidebar.select("computedview");
|
||||||
|
computedView = inspector.sidebar.getWindowForTab("computedview").computedview.view;
|
||||||
|
let doc = computedView.styleDocument;
|
||||||
|
|
||||||
|
let panel = computedView.tooltip.panel;
|
||||||
|
let {valueSpan} = getComputedViewProperty("font-family");
|
||||||
|
|
||||||
|
yield assertTooltipShownOn(computedView.tooltip, valueSpan);
|
||||||
|
|
||||||
|
let description = panel.getElementsByTagName("description")[0];
|
||||||
|
is(description.style.fontFamily, "Arial", "Tooltips contains correct font-family style");
|
||||||
|
}).then(endTests);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRuleViewProperty(name) {
|
||||||
|
let prop = null;
|
||||||
|
[].forEach.call(ruleView.doc.querySelectorAll(".ruleview-computedlist"), property => {
|
||||||
|
let nameSpan = property.querySelector(".ruleview-propertyname");
|
||||||
|
let valueSpan = property.querySelector(".ruleview-propertyvalue");
|
||||||
|
|
||||||
|
if (nameSpan.textContent === name) {
|
||||||
|
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getComputedViewProperty(name) {
|
||||||
|
let prop = null;
|
||||||
|
[].forEach.call(computedView.styleDocument.querySelectorAll(".property-view"), property => {
|
||||||
|
let nameSpan = property.querySelector(".property-name");
|
||||||
|
let valueSpan = property.querySelector(".property-value");
|
||||||
|
|
||||||
|
if (nameSpan.textContent === name) {
|
||||||
|
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return prop;
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
<head>
|
<head>
|
||||||
<title>test</title>
|
<title>test</title>
|
||||||
|
|
||||||
<link href="./doc_content_stylesheet_linked.css" rel="stylesheet" type="text/css">
|
<link href="./browser_bug705707_is_content_stylesheet_linked.css" rel="stylesheet" type="text/css">
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Load script.css
|
// Load script.css
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
var link = document.createElement('link');
|
var link = document.createElement('link');
|
||||||
link.rel = 'stylesheet';
|
link.rel = 'stylesheet';
|
||||||
link.type = 'text/css';
|
link.type = 'text/css';
|
||||||
link.href = "./doc_content_stylesheet_script.css";
|
link.href = "./browser_bug705707_is_content_stylesheet_script.css";
|
||||||
document.getElementsByTagName('head')[0].appendChild(link);
|
document.getElementsByTagName('head')[0].appendChild(link);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
|
@ -0,0 +1,139 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Tests that the correct stylesheets origins are identified in HTML & XUL
|
||||||
|
// stylesheets
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
|
||||||
|
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" +
|
||||||
|
"test/browser_bug705707_is_content_stylesheet.html";
|
||||||
|
const TEST_URI2 = "http://example.com/browser/browser/devtools/styleinspector/" +
|
||||||
|
"test/browser_bug705707_is_content_stylesheet.xul";
|
||||||
|
const XUL_URI = Cc["@mozilla.org/network/io-service;1"]
|
||||||
|
.getService(Ci.nsIIOService)
|
||||||
|
.newURI(TEST_URI2, null, null);
|
||||||
|
const XUL_PRINCIPAL = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
|
||||||
|
.getService(Ci.nsIScriptSecurityManager)
|
||||||
|
.getNoAppCodebasePrincipal(XUL_URI);
|
||||||
|
|
||||||
|
let inspector, ruleView;
|
||||||
|
let {CssLogic} = devtools.require("devtools/styleinspector/css-logic");
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
addTab(TEST_URI);
|
||||||
|
browser.addEventListener("load", htmlLoaded, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function htmlLoaded()
|
||||||
|
{
|
||||||
|
browser.removeEventListener("load", htmlLoaded, true);
|
||||||
|
doc = content.document;
|
||||||
|
testFromHTML()
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFromHTML()
|
||||||
|
{
|
||||||
|
let target = doc.querySelector("#target");
|
||||||
|
|
||||||
|
executeSoon(function() {
|
||||||
|
checkSheets(target);
|
||||||
|
openRuleView((aInspector, aRuleView) => {
|
||||||
|
inspector = aInspector;
|
||||||
|
ruleView = aRuleView;
|
||||||
|
inspector.selection.setNode(target);
|
||||||
|
inspector.once("inspector-updated", testModifyRules);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function reselectElement(target, cb)
|
||||||
|
{
|
||||||
|
inspector.selection.setNode(target.parentNode);
|
||||||
|
inspector.once("inspector-updated", ()=> {
|
||||||
|
inspector.selection.setNode(target);
|
||||||
|
inspector.once("inspector-updated", cb);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testModifyRules()
|
||||||
|
{
|
||||||
|
// Set a property on all rules, then refresh and make sure they are still
|
||||||
|
// there (and there wasn't an error on the server side)
|
||||||
|
for (let rule of ruleView._elementStyle.rules) {
|
||||||
|
rule.editor.addProperty("font-weight", "bold", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
executeSoon(() => {
|
||||||
|
reselectElement(doc.querySelector("#target"), () => {
|
||||||
|
for (let rule of ruleView._elementStyle.rules) {
|
||||||
|
let lastRule = rule.textProps[rule.textProps.length - 1];
|
||||||
|
|
||||||
|
is (lastRule.name, "font-weight", "Last rule name is font-weight");
|
||||||
|
is (lastRule.value, "bold", "Last rule value is bold");
|
||||||
|
}
|
||||||
|
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
openXUL();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function openXUL()
|
||||||
|
{
|
||||||
|
Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager)
|
||||||
|
.addFromPrincipal(XUL_PRINCIPAL, 'allowXULXBL', Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||||
|
addTab(TEST_URI2);
|
||||||
|
browser.addEventListener("load", xulLoaded, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function xulLoaded()
|
||||||
|
{
|
||||||
|
browser.removeEventListener("load", xulLoaded, true);
|
||||||
|
doc = content.document;
|
||||||
|
testFromXUL()
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFromXUL()
|
||||||
|
{
|
||||||
|
let target = doc.querySelector("#target");
|
||||||
|
|
||||||
|
executeSoon(function() {
|
||||||
|
checkSheets(target);
|
||||||
|
finishUp();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkSheets(aTarget)
|
||||||
|
{
|
||||||
|
let domUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
|
||||||
|
.getService(Ci.inIDOMUtils);
|
||||||
|
let domRules = domUtils.getCSSStyleRules(aTarget);
|
||||||
|
|
||||||
|
for (let i = 0, n = domRules.Count(); i < n; i++) {
|
||||||
|
let domRule = domRules.GetElementAt(i);
|
||||||
|
let sheet = domRule.parentStyleSheet;
|
||||||
|
let isContentSheet = CssLogic.isContentStylesheet(sheet);
|
||||||
|
|
||||||
|
if (!sheet.href ||
|
||||||
|
/browser_bug705707_is_content_stylesheet_/.test(sheet.href)) {
|
||||||
|
ok(isContentSheet, sheet.href + " identified as content stylesheet");
|
||||||
|
} else {
|
||||||
|
ok(!isContentSheet, sheet.href + " identified as non-content stylesheet");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
info("finishing up");
|
||||||
|
Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager)
|
||||||
|
.addFromPrincipal(XUL_PRINCIPAL, 'allowXULXBL', Ci.nsIPermissionManager.DENY_ACTION);
|
||||||
|
doc = inspector = ruleView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<?xml-stylesheet href="chrome://global/skin/xul.css" type="text/css"?>
|
<?xml-stylesheet href="chrome://global/skin/xul.css" type="text/css"?>
|
||||||
<?xml-stylesheet href="./doc_content_stylesheet_xul.css"
|
<?xml-stylesheet href="./browser_bug705707_is_content_stylesheet_xul.css"
|
||||||
type="text/css"?>
|
type="text/css"?>
|
||||||
<!DOCTYPE window>
|
<!DOCTYPE window>
|
||||||
<window id="testwindow" xmlns:html="http://www.w3.org/1999/xhtml"
|
<window id="testwindow" xmlns:html="http://www.w3.org/1999/xhtml"
|
|
@ -0,0 +1,5 @@
|
||||||
|
@import url("./browser_bug705707_is_content_stylesheet_imported2.css");
|
||||||
|
|
||||||
|
#target {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
@import url("./browser_bug705707_is_content_stylesheet_imported.css");
|
||||||
|
|
||||||
|
table {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
|
@ -1,34 +1,49 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Tests that we correctly display appropriate media query titles in the
|
// Tests that we correctly display appropriate media query titles in the
|
||||||
// property view.
|
// property view.
|
||||||
|
|
||||||
const TEST_URI = TEST_URL_ROOT + "doc_media_queries.html";
|
let doc;
|
||||||
|
let computedView;
|
||||||
|
|
||||||
|
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" +
|
||||||
|
"test/browser_bug722196_identify_media_queries.html";
|
||||||
|
|
||||||
let {PropertyView} = devtools.require("devtools/styleinspector/computed-view");
|
let {PropertyView} = devtools.require("devtools/styleinspector/computed-view");
|
||||||
let {CssLogic} = devtools.require("devtools/styleinspector/css-logic");
|
let {CssLogic} = devtools.require("devtools/styleinspector/css-logic");
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function test()
|
||||||
yield addTab(TEST_URI);
|
{
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
waitForExplicitFinish();
|
||||||
|
addTab(TEST_URI);
|
||||||
|
browser.addEventListener("load", docLoaded, true);
|
||||||
|
}
|
||||||
|
|
||||||
info("Selecting the test element");
|
function docLoaded()
|
||||||
yield selectNode("div", inspector);
|
{
|
||||||
|
browser.removeEventListener("load", docLoaded, true);
|
||||||
|
doc = content.document;
|
||||||
|
|
||||||
info("Checking CSSLogic");
|
openComputedView(selectNode);
|
||||||
checkCssLogic();
|
}
|
||||||
|
|
||||||
info("Checking property view");
|
function selectNode(aInspector, aComputedView)
|
||||||
yield checkPropertyView(view);
|
{
|
||||||
});
|
computedView = aComputedView;
|
||||||
|
|
||||||
function checkCssLogic() {
|
var div = doc.querySelector("div");
|
||||||
|
ok(div, "captain, we have the div");
|
||||||
|
|
||||||
|
aInspector.selection.setNode(div);
|
||||||
|
aInspector.once("inspector-updated", checkCssLogic);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkCssLogic()
|
||||||
|
{
|
||||||
let cssLogic = new CssLogic();
|
let cssLogic = new CssLogic();
|
||||||
cssLogic.highlight(getNode("div"));
|
cssLogic.highlight(doc.querySelector("div"));
|
||||||
cssLogic.processMatchedSelectors();
|
cssLogic.processMatchedSelectors();
|
||||||
|
|
||||||
let _strings = Services.strings
|
let _strings = Services.strings
|
||||||
|
@ -42,14 +57,16 @@ function checkCssLogic() {
|
||||||
"rule.source gives correct output for rule 1");
|
"rule.source gives correct output for rule 1");
|
||||||
is(cssLogic._matchedRules[1][0].source, source2,
|
is(cssLogic._matchedRules[1][0].source, source2,
|
||||||
"rule.source gives correct output for rule 2");
|
"rule.source gives correct output for rule 2");
|
||||||
|
|
||||||
|
checkPropertyView();
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkPropertyView(view) {
|
function checkPropertyView()
|
||||||
let propertyView = new PropertyView(view, "width");
|
{
|
||||||
|
let propertyView = new PropertyView(computedView, "width");
|
||||||
propertyView.buildMain();
|
propertyView.buildMain();
|
||||||
propertyView.buildSelectorContainer();
|
propertyView.buildSelectorContainer();
|
||||||
propertyView.matchedExpanded = true;
|
propertyView.matchedExpanded = true;
|
||||||
|
|
||||||
return propertyView.refreshMatchedSelectors().then(() => {
|
return propertyView.refreshMatchedSelectors().then(() => {
|
||||||
let numMatchedSelectors = propertyView.matchedSelectors.length;
|
let numMatchedSelectors = propertyView.matchedSelectors.length;
|
||||||
|
|
||||||
|
@ -58,5 +75,14 @@ function checkPropertyView(view) {
|
||||||
|
|
||||||
is(propertyView.hasMatchedSelectors, true,
|
is(propertyView.hasMatchedSelectors, true,
|
||||||
"hasMatchedSelectors returns true");
|
"hasMatchedSelectors returns true");
|
||||||
});
|
|
||||||
|
finishUp();
|
||||||
|
}).then(null, (err) => console.error(err));
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
doc = computedView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
}
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Tests that we correctly display appropriate media query titles in the
|
||||||
|
// rule view.
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
|
||||||
|
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" +
|
||||||
|
"test/browser_bug722196_identify_media_queries.html";
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
addTab(TEST_URI);
|
||||||
|
browser.addEventListener("load", docLoaded, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function docLoaded()
|
||||||
|
{
|
||||||
|
browser.removeEventListener("load", docLoaded, true);
|
||||||
|
doc = content.document;
|
||||||
|
openRuleView(selectNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectNode(aInspector, aRuleView)
|
||||||
|
{
|
||||||
|
inspector = aInspector;
|
||||||
|
|
||||||
|
inspector.selection.setNode(doc.querySelector("div"));
|
||||||
|
inspector.once("inspector-updated", checkSheets);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkSheets()
|
||||||
|
{
|
||||||
|
var div = doc.querySelector("div");
|
||||||
|
ok(div, "captain, we have the div");
|
||||||
|
|
||||||
|
let elementStyle = ruleView()._elementStyle;
|
||||||
|
|
||||||
|
let _strings = Services.strings
|
||||||
|
.createBundle("chrome://global/locale/devtools/styleinspector.properties");
|
||||||
|
|
||||||
|
let inline = _strings.GetStringFromName("rule.sourceInline");
|
||||||
|
|
||||||
|
is(elementStyle.rules.length, 3, "Should have 3 rules.");
|
||||||
|
is(elementStyle.rules[0].title, inline, "check rule 0 title");
|
||||||
|
is(elementStyle.rules[1].title, inline +
|
||||||
|
":15 @media screen and (min-width: 1px)", "check rule 1 title");
|
||||||
|
is(elementStyle.rules[2].title, inline + ":8", "check rule 2 title");
|
||||||
|
finishUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
doc = inspector = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -0,0 +1,192 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Test that increasing/decreasing values in rule view using
|
||||||
|
// arrow keys works correctly.
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let view;
|
||||||
|
let inspector;
|
||||||
|
|
||||||
|
function setUpTests()
|
||||||
|
{
|
||||||
|
doc.body.innerHTML = '<div id="test" style="' +
|
||||||
|
'margin-top:0px;' +
|
||||||
|
'padding-top: 0px;' +
|
||||||
|
'color:#000000;' +
|
||||||
|
'background-color: #000000;" >'+
|
||||||
|
'</div>';
|
||||||
|
|
||||||
|
openRuleView((aInspector, aRuleView) => {
|
||||||
|
inspector = aInspector;
|
||||||
|
view = aRuleView;
|
||||||
|
inspector.selection.setNode(doc.getElementById("test"));
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
runTests();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests()
|
||||||
|
{
|
||||||
|
let idRuleEditor = view.element.children[0]._ruleEditor;
|
||||||
|
let marginPropEditor = idRuleEditor.rule.textProps[0].editor;
|
||||||
|
let paddingPropEditor = idRuleEditor.rule.textProps[1].editor;
|
||||||
|
let hexColorPropEditor = idRuleEditor.rule.textProps[2].editor;
|
||||||
|
let rgbColorPropEditor = idRuleEditor.rule.textProps[3].editor;
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
info("INCREMENTS");
|
||||||
|
newTest( marginPropEditor, {
|
||||||
|
1: { alt: true, start: "0px", end: "0.1px", selectAll: true },
|
||||||
|
2: { start: "0px", end: "1px", selectAll: true },
|
||||||
|
3: { shift: true, start: "0px", end: "10px", selectAll: true },
|
||||||
|
4: { down: true, alt: true, start: "0.1px", end: "0px", selectAll: true },
|
||||||
|
5: { down: true, start: "0px", end: "-1px", selectAll: true },
|
||||||
|
6: { down: true, shift: true, start: "0px", end: "-10px", selectAll: true },
|
||||||
|
7: { pageUp: true, shift: true, start: "0px", end: "100px", selectAll: true },
|
||||||
|
8: { pageDown: true, shift: true, start: "0px", end: "-100px", selectAll: true,
|
||||||
|
nextTest: test2 }
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeMouse(marginPropEditor.valueSpan, 1, 1, {}, view.doc.defaultView);
|
||||||
|
})();
|
||||||
|
|
||||||
|
function test2() {
|
||||||
|
info("UNITS");
|
||||||
|
newTest( paddingPropEditor, {
|
||||||
|
1: { start: "0px", end: "1px", selectAll: true },
|
||||||
|
2: { start: "0pt", end: "1pt", selectAll: true },
|
||||||
|
3: { start: "0pc", end: "1pc", selectAll: true },
|
||||||
|
4: { start: "0em", end: "1em", selectAll: true },
|
||||||
|
5: { start: "0%", end: "1%", selectAll: true },
|
||||||
|
6: { start: "0in", end: "1in", selectAll: true },
|
||||||
|
7: { start: "0cm", end: "1cm", selectAll: true },
|
||||||
|
8: { start: "0mm", end: "1mm", selectAll: true },
|
||||||
|
9: { start: "0ex", end: "1ex", selectAll: true,
|
||||||
|
nextTest: test3 }
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeMouse(paddingPropEditor.valueSpan, 1, 1, {}, view.doc.defaultView);
|
||||||
|
};
|
||||||
|
|
||||||
|
function test3() {
|
||||||
|
info("HEX COLORS");
|
||||||
|
newTest( hexColorPropEditor, {
|
||||||
|
1: { start: "#CCCCCC", end: "#CDCDCD", selectAll: true},
|
||||||
|
2: { shift: true, start: "#CCCCCC", end: "#DCDCDC", selectAll: true },
|
||||||
|
3: { start: "#CCCCCC", end: "#CDCCCC", selection: [1,3] },
|
||||||
|
4: { shift: true, start: "#CCCCCC", end: "#DCCCCC", selection: [1,3] },
|
||||||
|
5: { start: "#FFFFFF", end: "#FFFFFF", selectAll: true },
|
||||||
|
6: { down: true, shift: true, start: "#000000", end: "#000000", selectAll: true,
|
||||||
|
nextTest: test4 }
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeMouse(hexColorPropEditor.valueSpan, 1, 1, {}, view.doc.defaultView);
|
||||||
|
};
|
||||||
|
|
||||||
|
function test4() {
|
||||||
|
info("RGB COLORS");
|
||||||
|
newTest( rgbColorPropEditor, {
|
||||||
|
1: { start: "rgb(0,0,0)", end: "rgb(0,1,0)", selection: [6,7] },
|
||||||
|
2: { shift: true, start: "rgb(0,0,0)", end: "rgb(0,10,0)", selection: [6,7] },
|
||||||
|
3: { start: "rgb(0,255,0)", end: "rgb(0,255,0)", selection: [6,9] },
|
||||||
|
4: { shift: true, start: "rgb(0,250,0)", end: "rgb(0,255,0)", selection: [6,9] },
|
||||||
|
5: { down: true, start: "rgb(0,0,0)", end: "rgb(0,0,0)", selection: [6,7] },
|
||||||
|
6: { down: true, shift: true, start: "rgb(0,5,0)", end: "rgb(0,0,0)", selection: [6,7],
|
||||||
|
nextTest: test5 }
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeMouse(rgbColorPropEditor.valueSpan, 1, 1, {}, view.doc.defaultView);
|
||||||
|
};
|
||||||
|
|
||||||
|
function test5() {
|
||||||
|
info("SHORTHAND");
|
||||||
|
newTest( paddingPropEditor, {
|
||||||
|
1: { start: "0px 0px 0px 0px", end: "0px 1px 0px 0px", selection: [4,7] },
|
||||||
|
2: { shift: true, start: "0px 0px 0px 0px", end: "0px 10px 0px 0px", selection: [4,7] },
|
||||||
|
3: { start: "0px 0px 0px 0px", end: "1px 0px 0px 0px", selectAll: true },
|
||||||
|
4: { shift: true, start: "0px 0px 0px 0px", end: "10px 0px 0px 0px", selectAll: true },
|
||||||
|
5: { down: true, start: "0px 0px 0px 0px", end: "0px 0px -1px 0px", selection: [8,11] },
|
||||||
|
6: { down: true, shift: true, start: "0px 0px 0px 0px", end: "-10px 0px 0px 0px", selectAll: true,
|
||||||
|
nextTest: test6 }
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeMouse(paddingPropEditor.valueSpan, 1, 1, {}, view.doc.defaultView);
|
||||||
|
};
|
||||||
|
|
||||||
|
function test6() {
|
||||||
|
info("ODD CASES");
|
||||||
|
newTest( marginPropEditor, {
|
||||||
|
1: { start: "98.7%", end: "99.7%", selection: [3,3] },
|
||||||
|
2: { alt: true, start: "98.7%", end: "98.8%", selection: [3,3] },
|
||||||
|
3: { start: "0", end: "1" },
|
||||||
|
4: { down: true, start: "0", end: "-1" },
|
||||||
|
5: { start: "'a=-1'", end: "'a=0'", selection: [4,4] },
|
||||||
|
6: { start: "0 -1px", end: "0 0px", selection: [2,2] },
|
||||||
|
7: { start: "url(-1)", end: "url(-1)", selection: [4,4] },
|
||||||
|
8: { start: "url('test1.1.png')", end: "url('test1.2.png')", selection: [11,11] },
|
||||||
|
9: { start: "url('test1.png')", end: "url('test2.png')", selection: [9,9] },
|
||||||
|
10: { shift: true, start: "url('test1.1.png')", end: "url('test11.1.png')", selection: [9,9] },
|
||||||
|
11: { down: true, start: "url('test-1.png')", end: "url('test-2.png')", selection: [9,11] },
|
||||||
|
12: { start: "url('test1.1.png')", end: "url('test1.2.png')", selection: [11,12] },
|
||||||
|
13: { down: true, alt: true, start: "url('test-0.png')", end: "url('test--0.1.png')", selection: [10,11] },
|
||||||
|
14: { alt: true, start: "url('test--0.1.png')", end: "url('test-0.png')", selection: [10,14],
|
||||||
|
endTest: true }
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeMouse(marginPropEditor.valueSpan, 1, 1, {}, view.doc.defaultView);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function newTest( propEditor, tests )
|
||||||
|
{
|
||||||
|
waitForEditorFocus(propEditor.element, function onElementFocus(aEditor) {
|
||||||
|
for( test in tests) {
|
||||||
|
testIncrement( aEditor, tests[test] );
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testIncrement( aEditor, aOptions )
|
||||||
|
{
|
||||||
|
aEditor.input.value = aOptions.start;
|
||||||
|
let input = aEditor.input;
|
||||||
|
if ( aOptions.selectAll ) {
|
||||||
|
input.select();
|
||||||
|
} else if ( aOptions.selection ) {
|
||||||
|
input.setSelectionRange(aOptions.selection[0], aOptions.selection[1]);
|
||||||
|
}
|
||||||
|
is(input.value, aOptions.start, "Value initialized at " + aOptions.start);
|
||||||
|
input.addEventListener("keyup", function onIncrementUp() {
|
||||||
|
input.removeEventListener("keyup", onIncrementUp, false);
|
||||||
|
input = aEditor.input;
|
||||||
|
is(input.value, aOptions.end, "Value changed to " + aOptions.end);
|
||||||
|
if( aOptions.nextTest) {
|
||||||
|
aOptions.nextTest();
|
||||||
|
}
|
||||||
|
else if( aOptions.endTest ) {
|
||||||
|
finishTest();
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
let key;
|
||||||
|
key = ( aOptions.down ) ? "VK_DOWN" : "VK_UP";
|
||||||
|
key = ( aOptions.pageDown ) ? "VK_PAGE_DOWN" : ( aOptions.pageUp ) ? "VK_PAGE_UP" : key;
|
||||||
|
EventUtils.synthesizeKey(key,
|
||||||
|
{altKey: aOptions.alt, shiftKey: aOptions.shift},
|
||||||
|
view.doc.defaultView);
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishTest()
|
||||||
|
{
|
||||||
|
doc = view = inspector = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function onload(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, onload, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(setUpTests, content);
|
||||||
|
}, true);
|
||||||
|
content.location = "data:text/html,sample document for bug 722691";
|
||||||
|
}
|
|
@ -0,0 +1,188 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let contentDoc;
|
||||||
|
let inspector;
|
||||||
|
let ruleView;
|
||||||
|
let computedView;
|
||||||
|
|
||||||
|
const PAGE_CONTENT = [
|
||||||
|
'<style type="text/css">',
|
||||||
|
' #testElement {',
|
||||||
|
' width: 500px;',
|
||||||
|
' height: 300px;',
|
||||||
|
' background: red;',
|
||||||
|
' transform: skew(16deg);',
|
||||||
|
' }',
|
||||||
|
' .test-element {',
|
||||||
|
' transform-origin: top left;',
|
||||||
|
' transform: rotate(45deg);',
|
||||||
|
' }',
|
||||||
|
' div {',
|
||||||
|
' transform: scaleX(1.5);',
|
||||||
|
' transform-origin: bottom right;',
|
||||||
|
' }',
|
||||||
|
' [attr] {',
|
||||||
|
' }',
|
||||||
|
'</style>',
|
||||||
|
'<div id="testElement" class="test-element" attr="value">transformed element</div>'
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
contentDoc = content.document;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,rule view css transform tooltip test";
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDocument() {
|
||||||
|
contentDoc.body.innerHTML = PAGE_CONTENT;
|
||||||
|
|
||||||
|
openRuleView((aInspector, aRuleView) => {
|
||||||
|
inspector = aInspector;
|
||||||
|
ruleView = aRuleView;
|
||||||
|
startTests();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startTests() {
|
||||||
|
inspector.selection.setNode(contentDoc.querySelector("#testElement"));
|
||||||
|
inspector.once("inspector-updated", testTransformTooltipOnIDSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
function endTests() {
|
||||||
|
contentDoc = inspector = ruleView = computedView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTransformTooltipOnIDSelector() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
info("Testing that a transform tooltip appears on the #ID rule");
|
||||||
|
|
||||||
|
let panel = ruleView.previewTooltip.panel;
|
||||||
|
ok(panel, "The XUL panel exists for the rule-view preview tooltips");
|
||||||
|
|
||||||
|
let {valueSpan} = getRuleViewProperty("#testElement", "transform");
|
||||||
|
yield assertTooltipShownOn(ruleView.previewTooltip, valueSpan);
|
||||||
|
|
||||||
|
// The transform preview is canvas, so there's not much we can test, so for
|
||||||
|
// now, let's just be happy with the fact that the tooltips is shown!
|
||||||
|
ok(true, "Tooltip shown on the transform property of the #ID rule");
|
||||||
|
}).then(testTransformTooltipOnClassSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTransformTooltipOnClassSelector() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
info("Testing that a transform tooltip appears on the .class rule");
|
||||||
|
|
||||||
|
let {valueSpan} = getRuleViewProperty(".test-element", "transform");
|
||||||
|
yield assertTooltipShownOn(ruleView.previewTooltip, valueSpan);
|
||||||
|
|
||||||
|
// The transform preview is canvas, so there's not much we can test, so for
|
||||||
|
// now, let's just be happy with the fact that the tooltips is shown!
|
||||||
|
ok(true, "Tooltip shown on the transform property of the .class rule");
|
||||||
|
}).then(testTransformTooltipOnTagSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTransformTooltipOnTagSelector() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
info("Testing that a transform tooltip appears on the tag rule");
|
||||||
|
|
||||||
|
let {valueSpan} = getRuleViewProperty("div", "transform");
|
||||||
|
yield assertTooltipShownOn(ruleView.previewTooltip, valueSpan);
|
||||||
|
|
||||||
|
// The transform preview is canvas, so there's not much we can test, so for
|
||||||
|
// now, let's just be happy with the fact that the tooltips is shown!
|
||||||
|
ok(true, "Tooltip shown on the transform property of the tag rule");
|
||||||
|
}).then(testTransformTooltipNotShownOnInvalidTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTransformTooltipNotShownOnInvalidTransform() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
info("Testing that a transform tooltip does not appear for invalid values");
|
||||||
|
|
||||||
|
let ruleEditor;
|
||||||
|
for (let rule of ruleView._elementStyle.rules) {
|
||||||
|
if (rule.matchedSelectors[0] === "[attr]") {
|
||||||
|
ruleEditor = rule.editor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ruleEditor.addProperty("transform", "muchTransform(suchAngle)", "");
|
||||||
|
|
||||||
|
let {valueSpan} = getRuleViewProperty("[attr]", "transform");
|
||||||
|
let isValid = yield isHoverTooltipTarget(ruleView.previewTooltip, valueSpan);
|
||||||
|
ok(!isValid, "The tooltip did not appear on hover of an invalid transform value");
|
||||||
|
}).then(testTransformTooltipOnComputedView);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTransformTooltipOnComputedView() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
info("Testing that a transform tooltip appears in the computed view too");
|
||||||
|
|
||||||
|
inspector.sidebar.select("computedview");
|
||||||
|
computedView = inspector.sidebar.getWindowForTab("computedview").computedview.view;
|
||||||
|
let doc = computedView.styleDocument;
|
||||||
|
|
||||||
|
let panel = computedView.tooltip.panel;
|
||||||
|
let {valueSpan} = getComputedViewProperty("transform");
|
||||||
|
|
||||||
|
yield assertTooltipShownOn(computedView.tooltip, valueSpan);
|
||||||
|
|
||||||
|
// The transform preview is canvas, so there's not much we can test, so for
|
||||||
|
// now, let's just be happy with the fact that the tooltips is shown!
|
||||||
|
ok(true, "Tooltip shown on the computed transform property");
|
||||||
|
}).then(endTests);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRule(selectorText) {
|
||||||
|
let rule;
|
||||||
|
|
||||||
|
[].forEach.call(ruleView.doc.querySelectorAll(".ruleview-rule"), aRule => {
|
||||||
|
let selector = aRule.querySelector(".ruleview-selector-matched");
|
||||||
|
if (selector && selector.textContent === selectorText) {
|
||||||
|
rule = aRule;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRuleViewProperty(selectorText, propertyName) {
|
||||||
|
let prop;
|
||||||
|
|
||||||
|
let rule = getRule(selectorText);
|
||||||
|
if (rule) {
|
||||||
|
// Look for the propertyName in that rule element
|
||||||
|
[].forEach.call(rule.querySelectorAll(".ruleview-property"), property => {
|
||||||
|
let nameSpan = property.querySelector(".ruleview-propertyname");
|
||||||
|
let valueSpan = property.querySelector(".ruleview-propertyvalue");
|
||||||
|
|
||||||
|
if (nameSpan.textContent === propertyName) {
|
||||||
|
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getComputedViewProperty(name) {
|
||||||
|
let prop;
|
||||||
|
[].forEach.call(computedView.styleDocument.querySelectorAll(".property-view"), property => {
|
||||||
|
let nameSpan = property.querySelector(".property-name");
|
||||||
|
let valueSpan = property.querySelector(".property-value");
|
||||||
|
|
||||||
|
if (nameSpan.textContent === name) {
|
||||||
|
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return prop;
|
||||||
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
"use strict";
|
let contentDoc;
|
||||||
|
let inspector;
|
||||||
// Test that background-image URLs have image preview tooltips in the rule-view
|
let ruleView;
|
||||||
// and computed-view
|
let computedView;
|
||||||
|
|
||||||
const PAGE_CONTENT = [
|
const PAGE_CONTENT = [
|
||||||
'<style type="text/css">',
|
'<style type="text/css">',
|
||||||
|
@ -25,97 +25,150 @@ const PAGE_CONTENT = [
|
||||||
'<div class="test-element">test element</div>'
|
'<div class="test-element">test element</div>'
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function test() {
|
||||||
yield addTab("data:text/html,rule view tooltip test");
|
waitForExplicitFinish();
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Testing the background-image property on the body rule");
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
yield testBodyRuleView(view);
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
contentDoc = content.document;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
info("Selecting the test div node");
|
content.location = "data:text/html,rule view tooltip test";
|
||||||
yield selectNode(".test-element", inspector);
|
|
||||||
info("Testing the the background property on the .test-element rule");
|
|
||||||
yield testDivRuleView(view);
|
|
||||||
|
|
||||||
info("Testing that image preview tooltips show even when there are fields being edited");
|
|
||||||
yield testTooltipAppearsEvenInEditMode(view);
|
|
||||||
|
|
||||||
info("Switching over to the computed-view");
|
|
||||||
let {view} = yield openComputedView();
|
|
||||||
|
|
||||||
info("Testing that the background-image computed style has a tooltip too");
|
|
||||||
yield testComputedView(view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testBodyRuleView(view) {
|
|
||||||
info("Testing tooltips in the rule view");
|
|
||||||
let panel = view.previewTooltip.panel;
|
|
||||||
|
|
||||||
// Check that the rule view has a tooltip and that a XUL panel has been created
|
|
||||||
ok(view.previewTooltip, "Tooltip instance exists");
|
|
||||||
ok(panel, "XUL panel exists");
|
|
||||||
|
|
||||||
// Get the background-image property inside the rule view
|
|
||||||
let {valueSpan} = getRuleViewProperty(view, "body", "background-image");
|
|
||||||
let uriSpan = valueSpan.querySelector(".theme-link");
|
|
||||||
|
|
||||||
yield assertHoverTooltipOn(view.previewTooltip, uriSpan);
|
|
||||||
|
|
||||||
let images = panel.getElementsByTagName("image");
|
|
||||||
is(images.length, 1, "Tooltip contains an image");
|
|
||||||
ok(images[0].getAttribute("src").indexOf("iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHe") !== -1,
|
|
||||||
"The image URL seems fine");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function* testDivRuleView(view) {
|
function createDocument() {
|
||||||
let panel = view.previewTooltip.panel;
|
contentDoc.body.innerHTML = PAGE_CONTENT;
|
||||||
|
|
||||||
// Get the background property inside the rule view
|
openRuleView((aInspector, aRuleView) => {
|
||||||
let {valueSpan} = getRuleViewProperty(view, ".test-element", "background");
|
inspector = aInspector;
|
||||||
let uriSpan = valueSpan.querySelector(".theme-link");
|
ruleView = aRuleView;
|
||||||
|
startTests();
|
||||||
yield assertHoverTooltipOn(view.previewTooltip, uriSpan);
|
});
|
||||||
|
|
||||||
let images = panel.getElementsByTagName("image");
|
|
||||||
is(images.length, 1, "Tooltip contains an image");
|
|
||||||
ok(images[0].getAttribute("src").startsWith("data:"), "Tooltip contains a data-uri image as expected");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function* testTooltipAppearsEvenInEditMode(view) {
|
function startTests() {
|
||||||
let panel = view.previewTooltip.panel;
|
inspector.selection.setNode(contentDoc.body);
|
||||||
|
inspector.once("inspector-updated", testBodyRuleView);
|
||||||
|
}
|
||||||
|
|
||||||
info("Switching to edit mode in the rule view");
|
function endTests() {
|
||||||
let editor = yield turnToEditMode(view);
|
contentDoc = inspector = ruleView = computedView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
info("Now trying to show the preview tooltip");
|
function testBodyRuleView() {
|
||||||
let {valueSpan} = getRuleViewProperty(view, ".test-element", "background");
|
Task.spawn(function*() {
|
||||||
let uriSpan = valueSpan.querySelector(".theme-link");
|
info("Testing tooltips in the rule view");
|
||||||
yield assertHoverTooltipOn(view.previewTooltip, uriSpan);
|
let panel = ruleView.previewTooltip.panel;
|
||||||
|
|
||||||
is(view.doc.activeElement, editor.input,
|
// Check that the rule view has a tooltip and that a XUL panel has been created
|
||||||
"Tooltip was shown in edit mode, and inplace-editor still focused");
|
ok(ruleView.previewTooltip, "Tooltip instance exists");
|
||||||
|
ok(panel, "XUL panel exists");
|
||||||
|
|
||||||
|
// Get the background-image property inside the rule view
|
||||||
|
let {valueSpan} = getRuleViewProperty("background-image");
|
||||||
|
let uriSpan = valueSpan.querySelector(".theme-link");
|
||||||
|
|
||||||
|
yield assertTooltipShownOn(ruleView.previewTooltip, uriSpan);
|
||||||
|
|
||||||
|
let images = panel.getElementsByTagName("image");
|
||||||
|
is(images.length, 1, "Tooltip contains an image");
|
||||||
|
ok(images[0].getAttribute("src").indexOf("iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHe") !== -1,
|
||||||
|
"The image URL seems fine");
|
||||||
|
|
||||||
|
let onUpdated = inspector.once("inspector-updated");
|
||||||
|
inspector.selection.setNode(contentDoc.querySelector(".test-element"));
|
||||||
|
yield onUpdated;
|
||||||
|
}).then(testDivRuleView);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testDivRuleView() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
let panel = ruleView.previewTooltip.panel;
|
||||||
|
|
||||||
|
// Get the background property inside the rule view
|
||||||
|
let {valueSpan} = getRuleViewProperty("background");
|
||||||
|
let uriSpan = valueSpan.querySelector(".theme-link");
|
||||||
|
|
||||||
|
yield assertTooltipShownOn(ruleView.previewTooltip, uriSpan);
|
||||||
|
|
||||||
|
let images = panel.getElementsByTagName("image");
|
||||||
|
is(images.length, 1, "Tooltip contains an image");
|
||||||
|
ok(images[0].getAttribute("src").startsWith("data:"), "Tooltip contains a data-uri image as expected");
|
||||||
|
}).then(testTooltipAppearsEvenInEditMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTooltipAppearsEvenInEditMode() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
let panel = ruleView.previewTooltip.panel;
|
||||||
|
|
||||||
|
info("Switching to edit mode in the rule view");
|
||||||
|
let editor = yield turnToEditMode(ruleView);
|
||||||
|
|
||||||
|
info("Now trying to show the preview tooltip");
|
||||||
|
let {valueSpan} = getRuleViewProperty("background");
|
||||||
|
let uriSpan = valueSpan.querySelector(".theme-link");
|
||||||
|
yield assertTooltipShownOn(ruleView.previewTooltip, uriSpan);
|
||||||
|
|
||||||
|
is(ruleView.doc.activeElement, editor.input,
|
||||||
|
"Tooltip was shown in edit mode, and inplace-editor still focused");
|
||||||
|
}).then(testComputedView);
|
||||||
}
|
}
|
||||||
|
|
||||||
function turnToEditMode(ruleView) {
|
function turnToEditMode(ruleView) {
|
||||||
|
let def = promise.defer();
|
||||||
let brace = ruleView.doc.querySelector(".ruleview-ruleclose");
|
let brace = ruleView.doc.querySelector(".ruleview-ruleclose");
|
||||||
return focusEditableField(brace);
|
waitForEditorFocus(brace.parentNode, def.resolve);
|
||||||
|
brace.click();
|
||||||
|
return def.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
function* testComputedView(view) {
|
function testComputedView() {
|
||||||
let tooltip = view.tooltip;
|
Task.spawn(function*() {
|
||||||
ok(tooltip, "The computed-view has a tooltip defined");
|
info("Testing tooltips in the computed view");
|
||||||
|
|
||||||
let panel = tooltip.panel;
|
inspector.sidebar.select("computedview");
|
||||||
ok(panel, "The computed-view tooltip has a XUL panel");
|
computedView = inspector.sidebar.getWindowForTab("computedview").computedview.view;
|
||||||
|
let doc = computedView.styleDocument;
|
||||||
|
|
||||||
let {valueSpan} = getComputedViewProperty(view, "background-image");
|
let panel = computedView.tooltip.panel;
|
||||||
let uriSpan = valueSpan.querySelector(".theme-link");
|
let {valueSpan} = getComputedViewProperty("background-image");
|
||||||
|
let uriSpan = valueSpan.querySelector(".theme-link");
|
||||||
|
|
||||||
yield assertHoverTooltipOn(view.tooltip, uriSpan);
|
yield assertTooltipShownOn(computedView.tooltip, uriSpan);
|
||||||
|
|
||||||
let images = panel.getElementsByTagName("image");
|
let images = panel.getElementsByTagName("image");
|
||||||
is(images.length, 1, "Tooltip contains an image");
|
is(images.length, 1, "Tooltip contains an image");
|
||||||
|
|
||||||
ok(images[0].getAttribute("src").startsWith("data:"), "Tooltip contains a data-uri in the computed-view too");
|
ok(images[0].getAttribute("src").startsWith("data:"), "Tooltip contains a data-uri in the computed-view too");
|
||||||
|
}).then(endTests);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRuleViewProperty(name) {
|
||||||
|
let prop = null;
|
||||||
|
[].forEach.call(ruleView.doc.querySelectorAll(".ruleview-property"), property => {
|
||||||
|
let nameSpan = property.querySelector(".ruleview-propertyname");
|
||||||
|
let valueSpan = property.querySelector(".ruleview-propertyvalue");
|
||||||
|
|
||||||
|
if (nameSpan.textContent === name) {
|
||||||
|
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getComputedViewProperty(name) {
|
||||||
|
let prop = null;
|
||||||
|
[].forEach.call(computedView.styleDocument.querySelectorAll(".property-view"), property => {
|
||||||
|
let nameSpan = property.querySelector(".property-name");
|
||||||
|
let valueSpan = property.querySelector(".property-value");
|
||||||
|
|
||||||
|
if (nameSpan.textContent === name) {
|
||||||
|
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return prop;
|
||||||
}
|
}
|
|
@ -0,0 +1,157 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Test that CSS property names are autocompleted and cycled correctly.
|
||||||
|
|
||||||
|
const MAX_ENTRIES = 10;
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let ruleViewWindow;
|
||||||
|
let editor;
|
||||||
|
let state;
|
||||||
|
// format :
|
||||||
|
// [
|
||||||
|
// what key to press,
|
||||||
|
// expected input box value after keypress,
|
||||||
|
// selectedIndex of the popup,
|
||||||
|
// total items in the popup
|
||||||
|
// ]
|
||||||
|
let testData = [
|
||||||
|
["VK_RIGHT", "border", -1, 0],
|
||||||
|
["-","border-bottom", 0, 10],
|
||||||
|
["b","border-bottom", 0, 6],
|
||||||
|
["VK_BACK_SPACE", "border-b", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "border-", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "border", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "borde", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "bord", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "bor", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "bo", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "b", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "", -1, 0],
|
||||||
|
["d", "direction", 0, 3],
|
||||||
|
["VK_DOWN", "display", 1, 3],
|
||||||
|
["VK_DOWN", "dominant-baseline", 2, 3],
|
||||||
|
["VK_DOWN", "direction", 0, 3],
|
||||||
|
["VK_DOWN", "display", 1, 3],
|
||||||
|
["VK_UP", "direction", 0, 3],
|
||||||
|
["VK_UP", "dominant-baseline", 2, 3],
|
||||||
|
["VK_UP", "display", 1, 3],
|
||||||
|
["VK_BACK_SPACE", "d", -1, 0],
|
||||||
|
["i", "direction", 0, 2],
|
||||||
|
["s", "display", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "dis", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "di", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "d", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "", -1, 0],
|
||||||
|
["f", "fill", 0, MAX_ENTRIES],
|
||||||
|
["i", "fill", 0, 4],
|
||||||
|
["VK_LEFT", "fill", -1, 0],
|
||||||
|
["VK_LEFT", "fill", -1, 0],
|
||||||
|
["i", "fiill", -1, 0],
|
||||||
|
["VK_ESCAPE", null, -1, 0],
|
||||||
|
];
|
||||||
|
|
||||||
|
function openRuleView()
|
||||||
|
{
|
||||||
|
var target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||||
|
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||||
|
inspector = toolbox.getCurrentPanel();
|
||||||
|
inspector.sidebar.select("ruleview");
|
||||||
|
|
||||||
|
// Highlight a node.
|
||||||
|
let node = content.document.getElementsByTagName("h1")[0];
|
||||||
|
inspector.selection.setNode(node);
|
||||||
|
|
||||||
|
inspector.once("inspector-updated", testCompletion);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCompletion()
|
||||||
|
{
|
||||||
|
ruleViewWindow = inspector.sidebar.getWindowForTab("ruleview");
|
||||||
|
let brace = ruleViewWindow.document.querySelector(".ruleview-propertyname");
|
||||||
|
|
||||||
|
waitForEditorFocus(brace.parentNode, function onNewElement(aEditor) {
|
||||||
|
editor = aEditor;
|
||||||
|
checkStateAndMoveOn(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
brace.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkStateAndMoveOn(index) {
|
||||||
|
if (index == testData.length) {
|
||||||
|
finishUp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let [key] = testData[index];
|
||||||
|
state = index;
|
||||||
|
|
||||||
|
info("pressing key " + key + " to get result: [" + testData[index].slice(1) +
|
||||||
|
"] for state " + state);
|
||||||
|
if (/(left|right|back_space|escape)/ig.test(key)) {
|
||||||
|
info("added event listener for right|back_space|escape keys");
|
||||||
|
editor.input.addEventListener("keypress", function onKeypress() {
|
||||||
|
if (editor.input) {
|
||||||
|
editor.input.removeEventListener("keypress", onKeypress);
|
||||||
|
}
|
||||||
|
info("inside event listener");
|
||||||
|
checkState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
editor.once("after-suggest", checkState);
|
||||||
|
}
|
||||||
|
EventUtils.synthesizeKey(key, {}, ruleViewWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkState() {
|
||||||
|
executeSoon(() => {
|
||||||
|
info("After keypress for state " + state);
|
||||||
|
let [key, completion, index, total] = testData[state];
|
||||||
|
if (completion != null) {
|
||||||
|
is(editor.input.value, completion,
|
||||||
|
"Correct value is autocompleted for state " + state);
|
||||||
|
}
|
||||||
|
if (total == 0) {
|
||||||
|
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed for state " +
|
||||||
|
state);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(editor.popup._panel.state == "open" ||
|
||||||
|
editor.popup._panel.state == "showing",
|
||||||
|
"Popup is open for state " + state);
|
||||||
|
is(editor.popup.getItems().length, total,
|
||||||
|
"Number of suggestions match for state " + state);
|
||||||
|
is(editor.popup.selectedIndex, index,
|
||||||
|
"Correct item is selected for state " + state);
|
||||||
|
}
|
||||||
|
checkStateAndMoveOn(state + 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
doc = inspector = editor = ruleViewWindow = state = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
doc = content.document;
|
||||||
|
doc.title = "Rule View Test";
|
||||||
|
waitForFocus(openRuleView, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,<h1 style='border: 1px solid red'>Filename" +
|
||||||
|
": browser_bug893965_css_property_completion_existing_property.js</h1>";
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Test that CSS property names are autocompleted and cycled correctly.
|
||||||
|
|
||||||
|
const MAX_ENTRIES = 10;
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let ruleViewWindow;
|
||||||
|
let editor;
|
||||||
|
let state;
|
||||||
|
// format :
|
||||||
|
// [
|
||||||
|
// what key to press,
|
||||||
|
// expected input box value after keypress,
|
||||||
|
// selectedIndex of the popup,
|
||||||
|
// total items in the popup
|
||||||
|
// ]
|
||||||
|
let testData = [
|
||||||
|
["d", "direction", 0, 3],
|
||||||
|
["VK_DOWN", "display", 1, 3],
|
||||||
|
["VK_DOWN", "dominant-baseline", 2, 3],
|
||||||
|
["VK_DOWN", "direction", 0, 3],
|
||||||
|
["VK_DOWN", "display", 1, 3],
|
||||||
|
["VK_UP", "direction", 0, 3],
|
||||||
|
["VK_UP", "dominant-baseline", 2, 3],
|
||||||
|
["VK_UP", "display", 1, 3],
|
||||||
|
["VK_BACK_SPACE", "d", -1, 0],
|
||||||
|
["i", "direction", 0, 2],
|
||||||
|
["s", "display", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "dis", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "di", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "d", -1, 0],
|
||||||
|
["VK_BACK_SPACE", "", -1, 0],
|
||||||
|
["f", "fill", 0, MAX_ENTRIES],
|
||||||
|
["i", "fill", 0, 4],
|
||||||
|
["VK_ESCAPE", null, -1, 0],
|
||||||
|
];
|
||||||
|
|
||||||
|
function openRuleView() {
|
||||||
|
var target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||||
|
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||||
|
inspector = toolbox.getCurrentPanel();
|
||||||
|
inspector.sidebar.select("ruleview");
|
||||||
|
|
||||||
|
// Highlight a node.
|
||||||
|
let node = content.document.getElementsByTagName("h1")[0];
|
||||||
|
inspector.selection.setNode(node);
|
||||||
|
|
||||||
|
inspector.once("inspector-updated", testCompletion);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCompletion() {
|
||||||
|
ruleViewWindow = inspector.sidebar.getWindowForTab("ruleview");
|
||||||
|
let brace = ruleViewWindow.document.querySelector(".ruleview-ruleclose");
|
||||||
|
|
||||||
|
waitForEditorFocus(brace.parentNode, function onNewElement(aEditor) {
|
||||||
|
editor = aEditor;
|
||||||
|
checkStateAndMoveOn(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
brace.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkStateAndMoveOn(index) {
|
||||||
|
if (index == testData.length) {
|
||||||
|
finishUp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let [key] = testData[index];
|
||||||
|
state = index;
|
||||||
|
|
||||||
|
info("pressing key " + key + " to get result: [" + testData[index].slice(1) +
|
||||||
|
"] for state " + state);
|
||||||
|
if (/(return|back_space|escape)/ig.test(key)) {
|
||||||
|
info("added event listener for return|back_space|escape keys");
|
||||||
|
editor.input.addEventListener("keypress", function onKeypress() {
|
||||||
|
if (editor.input) {
|
||||||
|
editor.input.removeEventListener("keypress", onKeypress);
|
||||||
|
}
|
||||||
|
info("inside event listener");
|
||||||
|
checkState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
editor.once("after-suggest", checkState);
|
||||||
|
}
|
||||||
|
EventUtils.synthesizeKey(key, {}, ruleViewWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkState(event) {
|
||||||
|
executeSoon(() => {
|
||||||
|
info("After keypress for state " + state);
|
||||||
|
let [key, completion, index, total] = testData[state];
|
||||||
|
if (completion != null) {
|
||||||
|
is(editor.input.value, completion,
|
||||||
|
"Correct value is autocompleted for state " + state);
|
||||||
|
}
|
||||||
|
if (total == 0) {
|
||||||
|
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed for state " +
|
||||||
|
state);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(editor.popup.isOpen, "Popup is open for state " + state);
|
||||||
|
is(editor.popup.getItems().length, total,
|
||||||
|
"Number of suggestions match for state " + state);
|
||||||
|
is(editor.popup.selectedIndex, index,
|
||||||
|
"Correct item is selected for state " + state);
|
||||||
|
}
|
||||||
|
checkStateAndMoveOn(state + 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp() {
|
||||||
|
doc = inspector = editor = ruleViewWindow = state = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
doc = content.document;
|
||||||
|
doc.title = "Rule View Test";
|
||||||
|
waitForFocus(openRuleView, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,<h1 style='border: 1px solid red'>Filename:" +
|
||||||
|
"browser_bug893965_css_property_completion_new_property.js</h1>";
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Test that CSS property names are autocompleted and cycled correctly.
|
||||||
|
|
||||||
|
const MAX_ENTRIES = 10;
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let ruleViewWindow;
|
||||||
|
let editor;
|
||||||
|
let state;
|
||||||
|
let brace;
|
||||||
|
// format :
|
||||||
|
// [
|
||||||
|
// what key to press,
|
||||||
|
// modifers,
|
||||||
|
// expected input box value after keypress,
|
||||||
|
// selectedIndex of the popup,
|
||||||
|
// total items in the popup
|
||||||
|
// ]
|
||||||
|
let testData = [
|
||||||
|
["b", {}, "beige", 0, 8],
|
||||||
|
["l", {}, "black", 0, 4],
|
||||||
|
["VK_DOWN", {}, "blanchedalmond", 1, 4],
|
||||||
|
["VK_DOWN", {}, "blue", 2, 4],
|
||||||
|
["VK_RIGHT", {}, "blue", -1, 0],
|
||||||
|
[" ", {}, "blue !important", 0, 10],
|
||||||
|
["!", {}, "blue !important", 0, 0],
|
||||||
|
["VK_BACK_SPACE", {}, "blue !", -1, 0],
|
||||||
|
["VK_BACK_SPACE", {}, "blue ", -1, 0],
|
||||||
|
["VK_BACK_SPACE", {}, "blue", -1, 0],
|
||||||
|
["VK_TAB", {shiftKey: true}, "color", -1, 0],
|
||||||
|
["VK_BACK_SPACE", {}, "", -1, 0],
|
||||||
|
["d", {}, "direction", 0, 3],
|
||||||
|
["i", {}, "direction", 0, 2],
|
||||||
|
["s", {}, "display", -1, 0],
|
||||||
|
["VK_TAB", {}, "blue", -1, 0],
|
||||||
|
["n", {}, "none", -1, 0],
|
||||||
|
["VK_RETURN", {}, null, -1, 0]
|
||||||
|
];
|
||||||
|
|
||||||
|
function openRuleView()
|
||||||
|
{
|
||||||
|
var target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||||
|
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||||
|
inspector = toolbox.getCurrentPanel();
|
||||||
|
inspector.sidebar.select("ruleview");
|
||||||
|
|
||||||
|
// Highlight a node.
|
||||||
|
let node = content.document.getElementsByTagName("h1")[0];
|
||||||
|
inspector.selection.setNode(node);
|
||||||
|
|
||||||
|
inspector.once("inspector-updated", testCompletion);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCompletion()
|
||||||
|
{
|
||||||
|
ruleViewWindow = inspector.sidebar.getWindowForTab("ruleview");
|
||||||
|
brace = ruleViewWindow.document.querySelector(".ruleview-ruleclose");
|
||||||
|
|
||||||
|
waitForEditorFocus(brace.parentNode, function onNewElement(aEditor) {
|
||||||
|
editor = aEditor;
|
||||||
|
checkStateAndMoveOn(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
ruleViewWindow.document.querySelector(".ruleview-propertyvalue").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkStateAndMoveOn(index) {
|
||||||
|
if (index == testData.length) {
|
||||||
|
finishUp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let [key, modifiers] = testData[index];
|
||||||
|
state = index;
|
||||||
|
|
||||||
|
info("pressing key " + key + " to get result: [" + testData[index].slice(2) +
|
||||||
|
"] for state " + state);
|
||||||
|
if (/tab/ig.test(key)) {
|
||||||
|
info("waiting for the editor to get focused");
|
||||||
|
waitForEditorFocus(brace.parentNode, function onNewElement(aEditor) {
|
||||||
|
info("editor focused : " + aEditor.input);
|
||||||
|
editor = aEditor;
|
||||||
|
checkState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (/(right|return|back_space)/ig.test(key)) {
|
||||||
|
info("added event listener for right|return|back_space keys");
|
||||||
|
editor.input.addEventListener("keypress", function onKeypress() {
|
||||||
|
if (editor.input) {
|
||||||
|
editor.input.removeEventListener("keypress", onKeypress);
|
||||||
|
}
|
||||||
|
info("inside event listener");
|
||||||
|
checkState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
editor.once("after-suggest", checkState);
|
||||||
|
}
|
||||||
|
EventUtils.synthesizeKey(key, modifiers, ruleViewWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkState(event) {
|
||||||
|
executeSoon(() => {
|
||||||
|
info("After keypress for state " + state);
|
||||||
|
let [key, modifier, completion, index, total] = testData[state];
|
||||||
|
if (completion != null) {
|
||||||
|
is(editor.input.value, completion,
|
||||||
|
"Correct value is autocompleted for state " + state);
|
||||||
|
}
|
||||||
|
if (total == 0) {
|
||||||
|
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed for state " +
|
||||||
|
state);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(editor.popup.isOpen, "Popup is open for state " + state);
|
||||||
|
is(editor.popup.getItems().length, total,
|
||||||
|
"Number of suggestions match for state " + state);
|
||||||
|
is(editor.popup.selectedIndex, index,
|
||||||
|
"Correct item is selected for state " + state);
|
||||||
|
}
|
||||||
|
checkStateAndMoveOn(state + 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
brace = doc = inspector = editor = ruleViewWindow = state = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
doc = content.document;
|
||||||
|
doc.title = "Rule View Test";
|
||||||
|
waitForFocus(openRuleView, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,<h1 style='color: red'>Filename: " +
|
||||||
|
"browser_bug894376_css_value_completion_existing_property_value_pair.js</h1>";
|
||||||
|
}
|
|
@ -0,0 +1,148 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Test that CSS property names are autocompleted and cycled correctly.
|
||||||
|
|
||||||
|
const MAX_ENTRIES = 10;
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let ruleViewWindow;
|
||||||
|
let editor;
|
||||||
|
let state;
|
||||||
|
let brace;
|
||||||
|
// format :
|
||||||
|
// [
|
||||||
|
// what key to press,
|
||||||
|
// modifers,
|
||||||
|
// expected input box value after keypress,
|
||||||
|
// selectedIndex of the popup,
|
||||||
|
// total items in the popup
|
||||||
|
// ]
|
||||||
|
let testData = [
|
||||||
|
["a", {accelKey: true, ctrlKey: true}, "", -1, 0],
|
||||||
|
["d", {}, "direction", 0, 3],
|
||||||
|
["VK_DOWN", {}, "display", 1, 3],
|
||||||
|
["VK_TAB", {}, "", -1, 10],
|
||||||
|
["VK_DOWN", {}, "-moz-box", 0, 10],
|
||||||
|
["n", {}, "none", -1, 0],
|
||||||
|
["VK_TAB", {shiftKey: true}, "display", -1, 0],
|
||||||
|
["VK_BACK_SPACE", {}, "", -1, 0],
|
||||||
|
["c", {}, "caption-side", 0, 10],
|
||||||
|
["o", {}, "color", 0, 6],
|
||||||
|
["VK_TAB", {}, "none", -1, 0],
|
||||||
|
["r", {}, "red", 0, 5],
|
||||||
|
["VK_DOWN", {}, "rgb", 1, 5],
|
||||||
|
["VK_DOWN", {}, "rgba", 2, 5],
|
||||||
|
["VK_DOWN", {}, "rosybrown", 3, 5],
|
||||||
|
["VK_DOWN", {}, "royalblue", 4, 5],
|
||||||
|
["VK_RIGHT", {}, "royalblue", -1, 0],
|
||||||
|
[" ", {}, "royalblue !important", 0, 10],
|
||||||
|
["!", {}, "royalblue !important", 0, 0],
|
||||||
|
["VK_ESCAPE", {}, null, -1, 0]
|
||||||
|
];
|
||||||
|
function openRuleView() {
|
||||||
|
var target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||||
|
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||||
|
inspector = toolbox.getCurrentPanel();
|
||||||
|
inspector.sidebar.select("ruleview");
|
||||||
|
|
||||||
|
// Highlight a node.
|
||||||
|
let node = content.document.getElementsByTagName("h1")[0];
|
||||||
|
inspector.selection.setNode(node);
|
||||||
|
|
||||||
|
inspector.once("inspector-updated", testCompletion);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCompletion() {
|
||||||
|
ruleViewWindow = inspector.sidebar.getWindowForTab("ruleview");
|
||||||
|
brace = ruleViewWindow.document.querySelector(".ruleview-ruleclose");
|
||||||
|
|
||||||
|
waitForEditorFocus(brace.parentNode, function onNewElement(aEditor) {
|
||||||
|
editor = aEditor;
|
||||||
|
checkStateAndMoveOn(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
brace.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkStateAndMoveOn(index) {
|
||||||
|
if (index == testData.length) {
|
||||||
|
finishUp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let [key, modifiers] = testData[index];
|
||||||
|
state = index;
|
||||||
|
|
||||||
|
info("pressing key " + key + " to get result: [" + testData[index].slice(2) +
|
||||||
|
"] for state " + state);
|
||||||
|
if (/tab/ig.test(key)) {
|
||||||
|
info("waiting for the editor to get focused");
|
||||||
|
waitForEditorFocus(brace.parentNode, function onNewElement(aEditor) {
|
||||||
|
info("editor focused : " + aEditor.input);
|
||||||
|
editor = aEditor;
|
||||||
|
checkState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (/(right|back_space|escape|return)/ig.test(key) ||
|
||||||
|
(modifiers.accelKey || modifiers.ctrlKey)) {
|
||||||
|
info("added event listener for right|escape|back_space|return keys");
|
||||||
|
editor.input.addEventListener("keypress", function onKeypress() {
|
||||||
|
if (editor.input) {
|
||||||
|
editor.input.removeEventListener("keypress", onKeypress);
|
||||||
|
}
|
||||||
|
info("inside event listener");
|
||||||
|
checkState();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
editor.once("after-suggest", checkState);
|
||||||
|
}
|
||||||
|
EventUtils.synthesizeKey(key, modifiers, ruleViewWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkState(event) {
|
||||||
|
executeSoon(() => {
|
||||||
|
info("After keypress for state " + state);
|
||||||
|
let [key, modifier, completion, index, total] = testData[state];
|
||||||
|
if (completion != null) {
|
||||||
|
is(editor.input.value, completion,
|
||||||
|
"Correct value is autocompleted for state " + state);
|
||||||
|
}
|
||||||
|
if (total == 0) {
|
||||||
|
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed for state " +
|
||||||
|
state);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ok(editor.popup.isOpen, "Popup is open for state " + state);
|
||||||
|
is(editor.popup.getItems().length, total,
|
||||||
|
"Number of suggestions match for state " + state);
|
||||||
|
is(editor.popup.selectedIndex, index,
|
||||||
|
"Correct item is selected for state " + state);
|
||||||
|
}
|
||||||
|
checkStateAndMoveOn(state + 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp() {
|
||||||
|
brace = doc = inspector = editor = ruleViewWindow = state = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
doc = content.document;
|
||||||
|
doc.title = "Rule View Test";
|
||||||
|
waitForFocus(openRuleView, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,<h1 style='border: 1px solid red'>Filename:"+
|
||||||
|
" browser_bug894376_css_value_completion_new_property_value_pair.js</h1>";
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let view;
|
||||||
|
let viewDoc;
|
||||||
|
|
||||||
|
const DOCUMENT_URL = "data:text/html," + encodeURIComponent([
|
||||||
|
'<html>' +
|
||||||
|
'<head>' +
|
||||||
|
' <title>Computed view toggling test</title>',
|
||||||
|
' <style type="text/css"> ',
|
||||||
|
' html { color: #000000; font-size: 15pt; } ',
|
||||||
|
' h1 { color: red; } ',
|
||||||
|
' </style>',
|
||||||
|
'</head>',
|
||||||
|
'<body>',
|
||||||
|
' <h1>Some header text</h1>',
|
||||||
|
'</body>',
|
||||||
|
'</html>'
|
||||||
|
].join("\n"));
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
|
||||||
|
true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(function () { openComputedView(startTests); }, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = DOCUMENT_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
function startTests(aInspector, aview)
|
||||||
|
{
|
||||||
|
inspector = aInspector;
|
||||||
|
view = aview;
|
||||||
|
viewDoc = view.styleDocument;
|
||||||
|
|
||||||
|
testExpandOnTwistyClick();
|
||||||
|
}
|
||||||
|
|
||||||
|
function endTests()
|
||||||
|
{
|
||||||
|
doc = inspector = view = viewDoc = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testExpandOnTwistyClick()
|
||||||
|
{
|
||||||
|
let h1 = doc.querySelector("h1");
|
||||||
|
ok(h1, "H1 exists");
|
||||||
|
|
||||||
|
inspector.selection.setNode(h1);
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
// Get the first twisty
|
||||||
|
let twisty = viewDoc.querySelector(".expandable");
|
||||||
|
ok(twisty, "Twisty found");
|
||||||
|
|
||||||
|
// Click and check whether it's been expanded
|
||||||
|
inspector.once("computed-view-property-expanded", () => {
|
||||||
|
// Expanded means the matchedselectors div is not empty
|
||||||
|
let div = viewDoc.querySelector(".property-content .matchedselectors");
|
||||||
|
ok(div.childNodes.length > 0, "Matched selectors are expanded on twisty click");
|
||||||
|
|
||||||
|
testCollapseOnTwistyClick();
|
||||||
|
});
|
||||||
|
twisty.click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCollapseOnTwistyClick() {
|
||||||
|
// Get the same first twisty again
|
||||||
|
let twisty = viewDoc.querySelector(".expandable");
|
||||||
|
ok(twisty, "Twisty found");
|
||||||
|
|
||||||
|
// Click and check whether matched selectors are collapsed now
|
||||||
|
inspector.once("computed-view-property-collapsed", () => {
|
||||||
|
// Collapsed means the matchedselectors div is empty
|
||||||
|
let div = viewDoc.querySelector(".property-content .matchedselectors");
|
||||||
|
ok(div.childNodes.length === 0, "Matched selectors are collapsed on twisty click");
|
||||||
|
|
||||||
|
testExpandOnDblClick();
|
||||||
|
});
|
||||||
|
twisty.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testExpandOnDblClick()
|
||||||
|
{
|
||||||
|
// Get the computed rule container, not the twisty this time
|
||||||
|
let container = viewDoc.querySelector(".property-view");
|
||||||
|
|
||||||
|
// Dblclick on it and check if it expands the matched selectors
|
||||||
|
inspector.once("computed-view-property-expanded", () => {
|
||||||
|
// Expanded means the matchedselectors div is not empty
|
||||||
|
let div = viewDoc.querySelector(".property-content .matchedselectors");
|
||||||
|
ok(div.childNodes.length > 0, "Matched selectors are expanded on dblclick");
|
||||||
|
|
||||||
|
testCollapseOnDblClick();
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeMouseAtCenter(container, {clickCount: 2}, view.styleWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCollapseOnDblClick()
|
||||||
|
{
|
||||||
|
// Get the computed rule container, not the twisty this time
|
||||||
|
let container = viewDoc.querySelector(".property-view");
|
||||||
|
|
||||||
|
// Dblclick on it and check if it expands the matched selectors
|
||||||
|
inspector.once("computed-view-property-collapsed", () => {
|
||||||
|
// Collapsed means the matchedselectors div is empty
|
||||||
|
let div = viewDoc.querySelector(".property-content .matchedselectors");
|
||||||
|
ok(div.childNodes.length === 0, "Matched selectors are collapsed on dblclick");
|
||||||
|
|
||||||
|
endTests();
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeMouseAtCenter(container, {clickCount: 2}, view.styleWindow);
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Test that changing a color in a gradient css declaration using the tooltip
|
||||||
|
// color picker works
|
||||||
|
|
||||||
|
let {gDevTools} = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
|
||||||
|
|
||||||
|
let contentDoc;
|
||||||
|
let contentWin;
|
||||||
|
let inspector;
|
||||||
|
let ruleView;
|
||||||
|
|
||||||
|
const PAGE_CONTENT = [
|
||||||
|
'<style type="text/css">',
|
||||||
|
' body {',
|
||||||
|
' background-image: linear-gradient(to left, #f06 25%, #333 95%, #000 100%);',
|
||||||
|
' }',
|
||||||
|
'</style>',
|
||||||
|
'Updating a gradient declaration with the color picker tooltip'
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
contentDoc = content.document;
|
||||||
|
contentWin = contentDoc.defaultView;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,rule view color picker tooltip test";
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDocument() {
|
||||||
|
contentDoc.body.innerHTML = PAGE_CONTENT;
|
||||||
|
|
||||||
|
openRuleView((aInspector, aRuleView) => {
|
||||||
|
inspector = aInspector;
|
||||||
|
ruleView = aRuleView;
|
||||||
|
startTests();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startTests() {
|
||||||
|
inspector.selection.setNode(contentDoc.body);
|
||||||
|
inspector.once("inspector-updated", testColorParsing);
|
||||||
|
}
|
||||||
|
|
||||||
|
function endTests() {
|
||||||
|
executeSoon(function() {
|
||||||
|
gDevTools.once("toolbox-destroyed", () => {
|
||||||
|
contentDoc = contentWin = inspector = ruleView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
inspector._toolbox.destroy();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testColorParsing() {
|
||||||
|
let ruleEl = getRuleViewProperty("background-image");
|
||||||
|
ok(ruleEl, "The background-image gradient declaration was found");
|
||||||
|
|
||||||
|
let swatchEls = ruleEl.valueSpan.querySelectorAll(".ruleview-colorswatch");
|
||||||
|
ok(swatchEls, "The color swatch elements were found");
|
||||||
|
is(swatchEls.length, 3, "There are 3 color swatches");
|
||||||
|
|
||||||
|
let colorEls = ruleEl.valueSpan.querySelectorAll(".ruleview-color");
|
||||||
|
ok(colorEls, "The color elements were found");
|
||||||
|
is(colorEls.length, 3, "There are 3 color values");
|
||||||
|
|
||||||
|
let colors = ["#F06", "#333", "#000"];
|
||||||
|
for (let i = 0; i < colors.length; i ++) {
|
||||||
|
is(colorEls[i].textContent, colors[i], "The right color value was found");
|
||||||
|
}
|
||||||
|
|
||||||
|
testPickingNewColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testPickingNewColor() {
|
||||||
|
// Grab the first color swatch and color in the gradient
|
||||||
|
let ruleEl = getRuleViewProperty("background-image");
|
||||||
|
let swatchEl = ruleEl.valueSpan.querySelector(".ruleview-colorswatch");
|
||||||
|
let colorEl = ruleEl.valueSpan.querySelector(".ruleview-color");
|
||||||
|
|
||||||
|
// Get the color picker tooltip
|
||||||
|
let cPicker = ruleView.colorPicker;
|
||||||
|
|
||||||
|
cPicker.tooltip.once("shown", () => {
|
||||||
|
simulateColorChange(cPicker, [1, 1, 1, 1]);
|
||||||
|
|
||||||
|
executeSoon(() => {
|
||||||
|
is(swatchEl.style.backgroundColor, "rgb(1, 1, 1)",
|
||||||
|
"The color swatch's background was updated");
|
||||||
|
is(colorEl.textContent, "rgba(1, 1, 1, 1)",
|
||||||
|
"The color text was updated");
|
||||||
|
is(content.getComputedStyle(content.document.body).backgroundImage,
|
||||||
|
"linear-gradient(to left, rgb(255, 0, 102) 25%, rgb(51, 51, 51) 95%, rgb(0, 0, 0) 100%)",
|
||||||
|
"The gradient has been updated correctly");
|
||||||
|
|
||||||
|
cPicker.hide();
|
||||||
|
endTests();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
swatchEl.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function simulateColorChange(colorPicker, newRgba) {
|
||||||
|
// Note that this test isn't concerned with simulating events to test how the
|
||||||
|
// spectrum color picker reacts, see browser_spectrum.js for this.
|
||||||
|
// This test only cares about the color swatch <-> color picker <-> rule view
|
||||||
|
// interactions. That's why there's no event simulations here
|
||||||
|
colorPicker.spectrum.then(spectrum => {
|
||||||
|
spectrum.rgb = newRgba;
|
||||||
|
spectrum.updateUI();
|
||||||
|
spectrum.onChange();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRuleViewProperty(name) {
|
||||||
|
let prop = null;
|
||||||
|
[].forEach.call(ruleView.doc.querySelectorAll(".ruleview-property"), property => {
|
||||||
|
let nameSpan = property.querySelector(".ruleview-propertyname");
|
||||||
|
let valueSpan = property.querySelector(".ruleview-propertyvalue");
|
||||||
|
|
||||||
|
if (nameSpan.textContent === name) {
|
||||||
|
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return prop;
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Test that user set style properties can be changed from the markup-view and
|
||||||
|
// don't survive page reload
|
||||||
|
|
||||||
|
let {devtools} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
|
||||||
|
let promise = devtools.require("sdk/core/promise");
|
||||||
|
let {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
|
||||||
|
|
||||||
|
let TEST_PAGE = [
|
||||||
|
"data:text/html,",
|
||||||
|
"<p id='id1' style='width:200px;'>element 1</p>",
|
||||||
|
"<p id='id2' style='width:100px;'>element 2</p>"
|
||||||
|
].join("");
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let ruleView;
|
||||||
|
let markupView;
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function onload(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(() => {
|
||||||
|
openRuleView((aInspector, aView) => {
|
||||||
|
inspector = aInspector;
|
||||||
|
ruleView = aView;
|
||||||
|
markupView = inspector.markup;
|
||||||
|
|
||||||
|
Task.spawn(function() {
|
||||||
|
yield selectElement("id1");
|
||||||
|
yield modifyRuleViewWidth("300px");
|
||||||
|
assertRuleAndMarkupViewWidth("id1", "300px");
|
||||||
|
yield selectElement("id2");
|
||||||
|
assertRuleAndMarkupViewWidth("id2", "100px");
|
||||||
|
yield modifyRuleViewWidth("50px");
|
||||||
|
assertRuleAndMarkupViewWidth("id2", "50px");
|
||||||
|
|
||||||
|
yield reloadPage();
|
||||||
|
yield selectElement("id1");
|
||||||
|
assertRuleAndMarkupViewWidth("id1", "200px");
|
||||||
|
yield selectElement("id2");
|
||||||
|
assertRuleAndMarkupViewWidth("id2", "100px");
|
||||||
|
|
||||||
|
finishTest();
|
||||||
|
}).then(null, Cu.reportError);
|
||||||
|
});
|
||||||
|
}, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = TEST_PAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishTest() {
|
||||||
|
doc = inspector = ruleView = markupView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectElement(id) {
|
||||||
|
let deferred = promise.defer();
|
||||||
|
inspector.selection.setNode(doc.getElementById(id));
|
||||||
|
inspector.once("inspector-updated", deferred.resolve);
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStyleRule() {
|
||||||
|
return ruleView.doc.querySelector(".ruleview-rule");
|
||||||
|
}
|
||||||
|
|
||||||
|
function modifyRuleViewWidth(value) {
|
||||||
|
let deferred = promise.defer();
|
||||||
|
|
||||||
|
let valueSpan = getStyleRule().querySelector(".ruleview-propertyvalue");
|
||||||
|
waitForEditorFocus(valueSpan.parentNode, () => {
|
||||||
|
let editor = inplaceEditor(valueSpan);
|
||||||
|
editor.input.value = value;
|
||||||
|
waitForEditorBlur(editor, () => {
|
||||||
|
// Changing the style will refresh the markup view, let's wait for that
|
||||||
|
inspector.once("markupmutation", () => {
|
||||||
|
waitForEditorBlur({input: ruleView.doc.activeElement}, deferred.resolve);
|
||||||
|
EventUtils.sendKey("escape");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
EventUtils.sendKey("return");
|
||||||
|
});
|
||||||
|
valueSpan.click();
|
||||||
|
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContainerStyleAttrValue(id) {
|
||||||
|
let front = markupView.walker.frontForRawNode(doc.getElementById(id));
|
||||||
|
let container = markupView.getContainer(front);
|
||||||
|
|
||||||
|
let attrIndex = 0;
|
||||||
|
for (let attrName of container.elt.querySelectorAll(".attr-name")) {
|
||||||
|
if (attrName.textContent === "style") {
|
||||||
|
return container.elt.querySelectorAll(".attr-value")[attrIndex];
|
||||||
|
}
|
||||||
|
attrIndex ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function assertRuleAndMarkupViewWidth(id, value) {
|
||||||
|
let valueSpan = getStyleRule().querySelector(".ruleview-propertyvalue");
|
||||||
|
is(valueSpan.textContent, value, "Rule-view style width is " + value + " as expected");
|
||||||
|
|
||||||
|
let attr = getContainerStyleAttrValue(id);
|
||||||
|
is(attr.textContent.replace(/\s/g, ""), "width:" + value + ";", "Markup-view style attribute width is " + value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function reloadPage() {
|
||||||
|
let deferred = promise.defer();
|
||||||
|
inspector.once("new-root", () => {
|
||||||
|
doc = content.document;
|
||||||
|
markupView = inspector.markup;
|
||||||
|
markupView._waitForChildren().then(deferred.resolve);
|
||||||
|
});
|
||||||
|
content.location.reload();
|
||||||
|
return deferred.promise;
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let contentDoc;
|
||||||
|
let inspector;
|
||||||
|
let ruleView;
|
||||||
|
let computedView;
|
||||||
|
|
||||||
|
const PAGE_CONTENT = '<div class="one">el 1</div><div class="two">el 2</div>';
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
contentDoc = content.document;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,rule/computed views tooltip hiding test";
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDocument() {
|
||||||
|
contentDoc.body.innerHTML = PAGE_CONTENT;
|
||||||
|
|
||||||
|
openView("ruleview", (aInspector, aRuleView) => {
|
||||||
|
inspector = aInspector;
|
||||||
|
ruleView = aRuleView;
|
||||||
|
openView("computedview", (_, aComputedView) => {
|
||||||
|
computedView = aComputedView;
|
||||||
|
startTests();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startTests() {
|
||||||
|
inspector.selection.setNode(contentDoc.querySelector(".one"));
|
||||||
|
inspector.once("inspector-updated", testRuleView);
|
||||||
|
}
|
||||||
|
|
||||||
|
function endTests() {
|
||||||
|
contentDoc = inspector = ruleView = computedView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRuleView() {
|
||||||
|
info("Testing rule view tooltip closes on new selection");
|
||||||
|
|
||||||
|
// Show the rule view tooltip
|
||||||
|
let tooltip = ruleView.previewTooltip;
|
||||||
|
tooltip.show();
|
||||||
|
tooltip.once("shown", () => {
|
||||||
|
// Select a new node and assert that the tooltip closes
|
||||||
|
tooltip.once("hidden", () => {
|
||||||
|
ok(true, "Rule view tooltip closed after a new node got selected");
|
||||||
|
inspector.once("inspector-updated", testComputedView);
|
||||||
|
});
|
||||||
|
inspector.selection.setNode(contentDoc.querySelector(".two"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testComputedView() {
|
||||||
|
info("Testing computed view tooltip closes on new selection");
|
||||||
|
|
||||||
|
inspector.sidebar.select("computedview");
|
||||||
|
|
||||||
|
// Show the computed view tooltip
|
||||||
|
let tooltip = computedView.tooltip;
|
||||||
|
tooltip.show();
|
||||||
|
tooltip.once("shown", () => {
|
||||||
|
// Select a new node and assert that the tooltip closes
|
||||||
|
tooltip.once("hidden", () => {
|
||||||
|
ok(true, "Computed view tooltip closed after a new node got selected");
|
||||||
|
inspector.once("inspector-updated", endTests);
|
||||||
|
});
|
||||||
|
inspector.selection.setNode(contentDoc.querySelector(".one"));
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* Any copyright", " is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Tests that the rule-view displays correctly on MathML elements
|
||||||
|
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
const TEST_URL = [
|
||||||
|
"data:text/html,",
|
||||||
|
"<div>",
|
||||||
|
" <math xmlns=\"http://www.w3.org/1998/Math/MathML\">",
|
||||||
|
" <mfrac>",
|
||||||
|
" <msubsup>",
|
||||||
|
" <mi>a</mi>",
|
||||||
|
" <mi>i</mi>",
|
||||||
|
" <mi>j</mi>",
|
||||||
|
" </msubsup>",
|
||||||
|
" <msub>",
|
||||||
|
" <mi>x</mi>",
|
||||||
|
" <mn>0</mn>",
|
||||||
|
" </msub>",
|
||||||
|
" </mfrac>",
|
||||||
|
" </math>",
|
||||||
|
"</div>"
|
||||||
|
].join("");
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function onload(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
|
||||||
|
waitForFocus(runTests, content);
|
||||||
|
}, true);
|
||||||
|
content.location = TEST_URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
openRuleView((inspector, ruleView) => {
|
||||||
|
Task.spawn(function() {
|
||||||
|
info("Select the DIV node and verify the rule-view shows rules");
|
||||||
|
yield selectNode("div", inspector);
|
||||||
|
ok(ruleView.element.querySelectorAll(".ruleview-rule").length,
|
||||||
|
"The rule-view shows rules for the div element");
|
||||||
|
|
||||||
|
info("Select various MathML nodes and verify the rule-view is empty");
|
||||||
|
yield selectNode("math", inspector);
|
||||||
|
ok(!ruleView.element.querySelectorAll(".ruleview-rule").length,
|
||||||
|
"The rule-view is empty for the math element");
|
||||||
|
|
||||||
|
yield selectNode("msubsup", inspector);
|
||||||
|
ok(!ruleView.element.querySelectorAll(".ruleview-rule").length,
|
||||||
|
"The rule-view is empty for the msubsup element");
|
||||||
|
|
||||||
|
yield selectNode("mn", inspector);
|
||||||
|
ok(!ruleView.element.querySelectorAll(".ruleview-rule").length,
|
||||||
|
"The rule-view is empty for the mn element");
|
||||||
|
|
||||||
|
info("Select again the DIV node and verify the rule-view shows rules");
|
||||||
|
yield selectNode("div", inspector);
|
||||||
|
ok(ruleView.element.querySelectorAll(".ruleview-rule").length,
|
||||||
|
"The rule-view shows rules for the div element");
|
||||||
|
}).then(null, ok.bind(null, false)).then(finishUp);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp() {
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Tests that CSS specificity is properly calculated.
|
||||||
|
|
||||||
|
const DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
|
||||||
|
.getService(Ci.inIDOMUtils);
|
||||||
|
|
||||||
|
function createDocument()
|
||||||
|
{
|
||||||
|
let doc = content.document;
|
||||||
|
doc.body.innerHTML = getStylesheetText();
|
||||||
|
doc.title = "Computed view specificity test";
|
||||||
|
runTests(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests(doc) {
|
||||||
|
let cssLogic = new CssLogic();
|
||||||
|
cssLogic.highlight(doc.body);
|
||||||
|
|
||||||
|
let tests = getTests();
|
||||||
|
let cssSheet = cssLogic.sheets[0];
|
||||||
|
let cssRule = cssSheet.domSheet.cssRules[0];
|
||||||
|
let selectors = CssLogic.getSelectors(cssRule);
|
||||||
|
|
||||||
|
for (let i = 0; i < selectors.length; i++) {
|
||||||
|
let selectorText = selectors[i];
|
||||||
|
let selector = new CssSelector(cssRule, selectorText, i);
|
||||||
|
let expected = getExpectedSpecificity(selectorText);
|
||||||
|
let specificity = DOMUtils.getSpecificity(selector.cssRule,
|
||||||
|
selector.selectorIndex)
|
||||||
|
is(specificity, expected,
|
||||||
|
'selector "' + selectorText + '" has a specificity of ' + expected);
|
||||||
|
}
|
||||||
|
finishUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExpectedSpecificity(selectorText) {
|
||||||
|
let tests = getTests();
|
||||||
|
|
||||||
|
for (let test of tests) {
|
||||||
|
if (test.text == selectorText) {
|
||||||
|
return test.expected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTests() {
|
||||||
|
return [
|
||||||
|
{text: "*", expected: 0},
|
||||||
|
{text: "LI", expected: 1},
|
||||||
|
{text: "UL LI", expected: 2},
|
||||||
|
{text: "UL OL + LI", expected: 3},
|
||||||
|
{text: "H1 + [REL=\"up\"]", expected: 257},
|
||||||
|
{text: "UL OL LI.red", expected: 259},
|
||||||
|
{text: "LI.red.level", expected: 513},
|
||||||
|
{text: ".red .level", expected: 512},
|
||||||
|
{text: "#x34y", expected: 65536},
|
||||||
|
{text: "#s12:not(FOO)", expected: 65537},
|
||||||
|
{text: "body#home div#warning p.message", expected: 131331},
|
||||||
|
{text: "* body#home div#warning p.message", expected: 131331},
|
||||||
|
{text: "#footer :not(nav) li", expected: 65538},
|
||||||
|
{text: "bar:nth-child(n)", expected: 257},
|
||||||
|
{text: "li::-moz-list-number", expected: 1},
|
||||||
|
{text: "a:hover", expected: 257},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStylesheetText() {
|
||||||
|
let tests = getTests();
|
||||||
|
let text = "";
|
||||||
|
|
||||||
|
tests.forEach(function(test) {
|
||||||
|
if (text.length > 0) {
|
||||||
|
text += ",";
|
||||||
|
}
|
||||||
|
text += test.text;
|
||||||
|
});
|
||||||
|
return '<style type="text/css">' + text + " {color:red;}</style>";
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
CssLogic = CssSelector = tempScope = null;
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,Computed view specificity test";
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Tests for selector text errors.
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let computedView;
|
||||||
|
|
||||||
|
function createDocument()
|
||||||
|
{
|
||||||
|
doc.body.innerHTML = "<div style='color:blue;'></div>";
|
||||||
|
|
||||||
|
doc.title = "Style Inspector Selector Text Test";
|
||||||
|
|
||||||
|
openComputedView(startTests);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function startTests(aInspector, aComputedView)
|
||||||
|
{
|
||||||
|
computedView = aComputedView;
|
||||||
|
|
||||||
|
let div = doc.querySelector("div");
|
||||||
|
ok(div, "captain, we have the test div");
|
||||||
|
|
||||||
|
aInspector.selection.setNode(div);
|
||||||
|
aInspector.once("inspector-updated", SI_checkText);
|
||||||
|
}
|
||||||
|
|
||||||
|
function SI_checkText()
|
||||||
|
{
|
||||||
|
let propertyView = null;
|
||||||
|
computedView.propertyViews.some(function(aView) {
|
||||||
|
if (aView.name == "color") {
|
||||||
|
propertyView = aView;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
ok(propertyView, "found PropertyView for color");
|
||||||
|
|
||||||
|
is(propertyView.hasMatchedSelectors, true, "hasMatchedSelectors is true");
|
||||||
|
|
||||||
|
propertyView.matchedExpanded = true;
|
||||||
|
propertyView.refreshMatchedSelectors().then(() => {
|
||||||
|
|
||||||
|
let span = propertyView.matchedSelectorsContainer.querySelector("span.rule-text");
|
||||||
|
ok(span, "found the first table row");
|
||||||
|
|
||||||
|
let selector = propertyView.matchedSelectorViews[0];
|
||||||
|
ok(selector, "found the first matched selector view");
|
||||||
|
|
||||||
|
finishUp();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
doc = computedView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,selector text test, bug 692400";
|
||||||
|
}
|
|
@ -0,0 +1,167 @@
|
||||||
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let computedView;
|
||||||
|
|
||||||
|
const STYLESHEET_URL = "data:text/css,"+encodeURIComponent(
|
||||||
|
[".highlight {",
|
||||||
|
"color: blue",
|
||||||
|
"}"].join("\n"));
|
||||||
|
|
||||||
|
const DOCUMENT_URL = "data:text/html,"+encodeURIComponent(
|
||||||
|
['<html>' +
|
||||||
|
'<head>' +
|
||||||
|
'<title>Computed view style editor link test</title>',
|
||||||
|
'<style type="text/css"> ',
|
||||||
|
'html { color: #000000; } ',
|
||||||
|
'span { font-variant: small-caps; color: #000000; } ',
|
||||||
|
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ',
|
||||||
|
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">',
|
||||||
|
'</style>',
|
||||||
|
'<link rel="stylesheet" type="text/css" href="'+STYLESHEET_URL+'">',
|
||||||
|
'</head>',
|
||||||
|
'<body>',
|
||||||
|
'<h1>Some header text</h1>',
|
||||||
|
'<p id="salutation" style="font-size: 12pt">hi.</p>',
|
||||||
|
'<p id="body" style="font-size: 12pt">I am a test-case. This text exists ',
|
||||||
|
'solely to provide some things to ',
|
||||||
|
'<span style="color: yellow" class="highlight">',
|
||||||
|
'highlight</span> and <span style="font-weight: bold">count</span> ',
|
||||||
|
'style list-items in the box at right. If you are reading this, ',
|
||||||
|
'you should go do something else instead. Maybe read a book. Or better ',
|
||||||
|
'yet, write some test-cases for another bit of code. ',
|
||||||
|
'<span style="font-style: italic">some text</span></p>',
|
||||||
|
'<p id="closing">more text</p>',
|
||||||
|
'<p>even more text</p>',
|
||||||
|
'</div>',
|
||||||
|
'</body>',
|
||||||
|
'</html>'].join("\n"));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function selectNode(aInspector, aComputedView)
|
||||||
|
{
|
||||||
|
inspector = aInspector;
|
||||||
|
computedView = aComputedView;
|
||||||
|
|
||||||
|
let span = doc.querySelector("span");
|
||||||
|
ok(span, "captain, we have the span");
|
||||||
|
|
||||||
|
inspector.selection.setNode(span);
|
||||||
|
inspector.once("inspector-updated", testInlineStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInlineStyle()
|
||||||
|
{
|
||||||
|
expandProperty(0, function propertyExpanded() {
|
||||||
|
Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
|
||||||
|
if (aTopic != "domwindowopened") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
info("window opened");
|
||||||
|
let win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||||
|
win.addEventListener("load", function windowLoad() {
|
||||||
|
win.removeEventListener("load", windowLoad);
|
||||||
|
info("window load completed");
|
||||||
|
let windowType = win.document.documentElement.getAttribute("windowtype");
|
||||||
|
is(windowType, "navigator:view-source", "view source window is open");
|
||||||
|
info("closing window");
|
||||||
|
win.close();
|
||||||
|
Services.ww.unregisterNotification(onWindow);
|
||||||
|
executeSoon(() => {
|
||||||
|
testInlineStyleSheet();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
let link = getLinkByIndex(0);
|
||||||
|
link.click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInlineStyleSheet()
|
||||||
|
{
|
||||||
|
info("clicking an inline stylesheet");
|
||||||
|
|
||||||
|
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||||
|
let toolbox = gDevTools.getToolbox(target);
|
||||||
|
toolbox.once("styleeditor-selected", () => {
|
||||||
|
let panel = toolbox.getCurrentPanel();
|
||||||
|
|
||||||
|
panel.UI.once("editor-selected", (event, editor) => {
|
||||||
|
validateStyleEditorSheet(editor, 0);
|
||||||
|
executeSoon(() => {
|
||||||
|
testExternalStyleSheet(toolbox);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let link = getLinkByIndex(2);
|
||||||
|
link.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testExternalStyleSheet(toolbox) {
|
||||||
|
info ("clicking an external stylesheet");
|
||||||
|
|
||||||
|
let panel = toolbox.getCurrentPanel();
|
||||||
|
panel.UI.once("editor-selected", (event, editor) => {
|
||||||
|
is(toolbox.currentToolId, "styleeditor", "style editor selected");
|
||||||
|
validateStyleEditorSheet(editor, 1);
|
||||||
|
finishUp();
|
||||||
|
});
|
||||||
|
|
||||||
|
toolbox.selectTool("inspector").then(function () {
|
||||||
|
info("inspector selected");
|
||||||
|
let link = getLinkByIndex(1);
|
||||||
|
link.click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateStyleEditorSheet(aEditor, aExpectedSheetIndex)
|
||||||
|
{
|
||||||
|
info("validating style editor stylesheet");
|
||||||
|
let sheet = doc.styleSheets[aExpectedSheetIndex];
|
||||||
|
is(aEditor.styleSheet.href, sheet.href, "loaded stylesheet matches document stylesheet");
|
||||||
|
}
|
||||||
|
|
||||||
|
function expandProperty(aIndex, aCallback)
|
||||||
|
{
|
||||||
|
info("expanding property " + aIndex);
|
||||||
|
let contentDoc = computedView.styleDocument;
|
||||||
|
let expando = contentDoc.querySelectorAll(".expandable")[aIndex];
|
||||||
|
|
||||||
|
expando.click();
|
||||||
|
|
||||||
|
inspector.once("computed-view-property-expanded", aCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLinkByIndex(aIndex)
|
||||||
|
{
|
||||||
|
let contentDoc = computedView.styleDocument;
|
||||||
|
let links = contentDoc.querySelectorAll(".rule-link .link");
|
||||||
|
return links[aIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
doc = inspector = computedView = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
|
||||||
|
true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(function () { openComputedView(selectNode); }, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = DOCUMENT_URL;
|
||||||
|
}
|
|
@ -1,54 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Tests that the checkbox to include browser styles works properly.
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,default styles test");
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
|
||||||
'.matches {color: #F00;}</style>' +
|
|
||||||
'<span id="matches" class="matches">Some styled text</span>' +
|
|
||||||
'</div>';
|
|
||||||
content.document.title = "Style Inspector Default Styles Test";
|
|
||||||
|
|
||||||
info("Opening the computed view");
|
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("#matches", inspector);
|
|
||||||
|
|
||||||
info("Checking the default styles");
|
|
||||||
is(isPropertyVisible("color", view), true,
|
|
||||||
"span #matches color property is visible");
|
|
||||||
is(isPropertyVisible("background-color", view), false,
|
|
||||||
"span #matches background-color property is hidden");
|
|
||||||
|
|
||||||
info("Toggling the browser styles");
|
|
||||||
let doc = view.styleDocument;
|
|
||||||
let checkbox = doc.querySelector(".includebrowserstyles");
|
|
||||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
|
||||||
checkbox.click();
|
|
||||||
yield onRefreshed;
|
|
||||||
|
|
||||||
info("Checking the browser styles");
|
|
||||||
is(isPropertyVisible("color", view), true,
|
|
||||||
"span color property is visible");
|
|
||||||
is(isPropertyVisible("background-color", view), true,
|
|
||||||
"span background-color property is visible");
|
|
||||||
});
|
|
||||||
|
|
||||||
function isPropertyVisible(name, view) {
|
|
||||||
info("Checking property visibility for " + name);
|
|
||||||
let propertyViews = view.propertyViews;
|
|
||||||
for each (let propView in propertyViews) {
|
|
||||||
if (propView.name == name) {
|
|
||||||
return propView.visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Tests that the style inspector works properly
|
||||||
|
|
||||||
|
let doc, computedView, inspector;
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function onBrowserLoad(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", onBrowserLoad, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,computed view context menu test";
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDocument()
|
||||||
|
{
|
||||||
|
doc.body.innerHTML = '<style type="text/css"> ' +
|
||||||
|
'span { font-variant: small-caps; color: #000000; } ' +
|
||||||
|
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
|
||||||
|
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
|
||||||
|
'<h1>Some header text</h1>\n' +
|
||||||
|
'<p id="salutation" style="font-size: 12pt">hi.</p>\n' +
|
||||||
|
'<p id="body" style="font-size: 12pt">I am a test-case. This text exists ' +
|
||||||
|
'solely to provide some things to <span style="color: yellow">' +
|
||||||
|
'highlight</span> and <span style="font-weight: bold">count</span> ' +
|
||||||
|
'style list-items in the box at right. If you are reading this, ' +
|
||||||
|
'you should go do something else instead. Maybe read a book. Or better ' +
|
||||||
|
'yet, write some test-cases for another bit of code. ' +
|
||||||
|
'<span style="font-style: italic">some text</span></p>\n' +
|
||||||
|
'<p id="closing">more text</p>\n' +
|
||||||
|
'<p>even more text</p>' +
|
||||||
|
'</div>';
|
||||||
|
doc.title = "Computed view keyboard navigation test";
|
||||||
|
|
||||||
|
openComputedView(startTests);
|
||||||
|
}
|
||||||
|
|
||||||
|
function startTests(aInspector, aComputedView)
|
||||||
|
{
|
||||||
|
computedView = aComputedView;
|
||||||
|
inspector = aInspector;
|
||||||
|
testTabThrougStyles();
|
||||||
|
}
|
||||||
|
|
||||||
|
function endTests()
|
||||||
|
{
|
||||||
|
computedView = inspector = doc = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTabThrougStyles()
|
||||||
|
{
|
||||||
|
let span = doc.querySelector("span");
|
||||||
|
|
||||||
|
inspector.once("computed-view-refreshed", () => {
|
||||||
|
// Selecting the first computed style in the list
|
||||||
|
let firstStyle = computedView.styleDocument.querySelector(".property-view");
|
||||||
|
ok(firstStyle, "First computed style found in panel");
|
||||||
|
firstStyle.focus();
|
||||||
|
|
||||||
|
// Tab to select the 2nd style, press return
|
||||||
|
EventUtils.synthesizeKey("VK_TAB", {});
|
||||||
|
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||||
|
inspector.once("computed-view-property-expanded", () => {
|
||||||
|
// Verify the 2nd style has been expanded
|
||||||
|
let secondStyleSelectors = computedView.styleDocument.querySelectorAll(
|
||||||
|
".property-content .matchedselectors")[1];
|
||||||
|
ok(secondStyleSelectors.childNodes.length > 0, "Matched selectors expanded");
|
||||||
|
|
||||||
|
// Tab back up and test the same thing, with space
|
||||||
|
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true});
|
||||||
|
EventUtils.synthesizeKey("VK_SPACE", {});
|
||||||
|
inspector.once("computed-view-property-expanded", () => {
|
||||||
|
// Verify the 1st style has been expanded too
|
||||||
|
let firstStyleSelectors = computedView.styleDocument.querySelectorAll(
|
||||||
|
".property-content .matchedselectors")[0];
|
||||||
|
ok(firstStyleSelectors.childNodes.length > 0, "Matched selectors expanded");
|
||||||
|
|
||||||
|
endTests();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
inspector.selection.setNode(span);
|
||||||
|
}
|
|
@ -1,20 +1,20 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
"use strict";
|
// Tests that the style inspector works properly
|
||||||
|
|
||||||
// Tests that properties can be selected and copied from the computed view
|
let doc;
|
||||||
|
let win;
|
||||||
|
let computedView;
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "osString", function() {
|
XPCOMUtils.defineLazyGetter(this, "osString", function() {
|
||||||
return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
|
return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
|
||||||
});
|
});
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function createDocument()
|
||||||
yield addTab("data:text/html,computed view copy test");
|
{
|
||||||
|
doc.body.innerHTML = '<style type="text/css"> ' +
|
||||||
info("Creating the test document");
|
|
||||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
|
||||||
'span { font-variant: small-caps; color: #000000; } ' +
|
'span { font-variant: small-caps; color: #000000; } ' +
|
||||||
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
|
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
|
||||||
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
|
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
|
||||||
|
@ -30,89 +30,132 @@ let test = asyncTest(function*() {
|
||||||
'<p id="closing">more text</p>\n' +
|
'<p id="closing">more text</p>\n' +
|
||||||
'<p>even more text</p>' +
|
'<p>even more text</p>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
content.document.title = "Computed view context menu test";
|
doc.title = "Computed view context menu test";
|
||||||
|
|
||||||
info("Opening the computed view");
|
openComputedView(selectNode);
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
}
|
||||||
|
|
||||||
info("Selecting the test node");
|
function selectNode(aInspector, aComputedView)
|
||||||
yield selectNode("span", inspector);
|
{
|
||||||
|
computedView = aComputedView;
|
||||||
|
win = aInspector.sidebar.getWindowForTab("computedview");
|
||||||
|
|
||||||
yield checkCopySelection(view);
|
let span = doc.querySelector("span");
|
||||||
yield checkSelectAll(view);
|
ok(span, "captain, we have the span");
|
||||||
});
|
|
||||||
|
|
||||||
function checkCopySelection(view) {
|
aInspector.selection.setNode(span);
|
||||||
info("Testing selection copy");
|
aInspector.once("inspector-updated", runStyleInspectorTests);
|
||||||
|
}
|
||||||
|
|
||||||
let contentDocument = view.styleDocument;
|
|
||||||
|
function runStyleInspectorTests()
|
||||||
|
{
|
||||||
|
let contentDocument = computedView.styleDocument;
|
||||||
|
let prop = contentDocument.querySelector(".property-view");
|
||||||
|
ok(prop, "captain, we have the property-view node");
|
||||||
|
|
||||||
|
checkCopySelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkCopySelection()
|
||||||
|
{
|
||||||
|
let contentDocument = computedView.styleDocument;
|
||||||
let props = contentDocument.querySelectorAll(".property-view");
|
let props = contentDocument.querySelectorAll(".property-view");
|
||||||
ok(props, "captain, we have the property-view nodes");
|
ok(props, "captain, we have the property-view nodes");
|
||||||
|
|
||||||
let range = contentDocument.createRange();
|
let range = document.createRange();
|
||||||
range.setStart(props[1], 0);
|
range.setStart(props[1], 0);
|
||||||
range.setEnd(props[3], 3);
|
range.setEnd(props[3], 3);
|
||||||
contentDocument.defaultView.getSelection().addRange(range);
|
win.getSelection().addRange(range);
|
||||||
|
|
||||||
info("Checking that cssHtmlTree.siBoundCopy() returns the correct clipboard value");
|
info("Checking that cssHtmlTree.siBoundCopy() " +
|
||||||
|
" returns the correct clipboard value");
|
||||||
|
|
||||||
let expectedPattern = "font-family: helvetica,sans-serif;[\\r\\n]+" +
|
let expectedPattern = "font-family: helvetica,sans-serif;[\\r\\n]+" +
|
||||||
"font-size: 16px;[\\r\\n]+" +
|
"font-size: 16px;[\\r\\n]+" +
|
||||||
"font-variant: small-caps;[\\r\\n]*";
|
"font-variant: small-caps;[\\r\\n]*";
|
||||||
|
|
||||||
return waitForClipboard(() => {
|
SimpleTest.waitForClipboard(function CS_boundCopyCheck() {
|
||||||
fireCopyEvent(props[0]);
|
|
||||||
}, () => {
|
|
||||||
return checkClipboardData(expectedPattern);
|
return checkClipboardData(expectedPattern);
|
||||||
}).then(() => {}, () => {
|
},
|
||||||
failedClipboard(expectedPattern);
|
function() {
|
||||||
|
fireCopyEvent(props[0]);
|
||||||
|
},
|
||||||
|
checkSelectAll,
|
||||||
|
function() {
|
||||||
|
failedClipboard(expectedPattern, checkSelectAll);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSelectAll(view) {
|
function checkSelectAll()
|
||||||
info("Testing select-all copy");
|
{
|
||||||
|
let contentDoc = computedView.styleDocument;
|
||||||
let contentDoc = view.styleDocument;
|
|
||||||
let prop = contentDoc.querySelector(".property-view");
|
let prop = contentDoc.querySelector(".property-view");
|
||||||
|
|
||||||
info("Checking that _SelectAll() then copy returns the correct clipboard value");
|
info("Checking that _SelectAll() then copy returns the correct clipboard value");
|
||||||
view._onSelectAll();
|
computedView._onSelectAll();
|
||||||
let expectedPattern = "color: #FF0;[\\r\\n]+" +
|
let expectedPattern = "color: #FF0;[\\r\\n]+" +
|
||||||
"font-family: helvetica,sans-serif;[\\r\\n]+" +
|
"font-family: helvetica,sans-serif;[\\r\\n]+" +
|
||||||
"font-size: 16px;[\\r\\n]+" +
|
"font-size: 16px;[\\r\\n]+" +
|
||||||
"font-variant: small-caps;[\\r\\n]*";
|
"font-variant: small-caps;[\\r\\n]*";
|
||||||
|
|
||||||
return waitForClipboard(() => {
|
SimpleTest.waitForClipboard(function() {
|
||||||
fireCopyEvent(prop);
|
|
||||||
}, () => {
|
|
||||||
return checkClipboardData(expectedPattern);
|
return checkClipboardData(expectedPattern);
|
||||||
}).then(() => {}, () => {
|
},
|
||||||
failedClipboard(expectedPattern);
|
function() {
|
||||||
|
fireCopyEvent(prop);
|
||||||
|
},
|
||||||
|
finishUp,
|
||||||
|
function() {
|
||||||
|
failedClipboard(expectedPattern, finishUp);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkClipboardData(expectedPattern) {
|
function checkClipboardData(aExpectedPattern)
|
||||||
|
{
|
||||||
let actual = SpecialPowers.getClipboardData("text/unicode");
|
let actual = SpecialPowers.getClipboardData("text/unicode");
|
||||||
let expectedRegExp = new RegExp(expectedPattern, "g");
|
let expectedRegExp = new RegExp(aExpectedPattern, "g");
|
||||||
return expectedRegExp.test(actual);
|
return expectedRegExp.test(actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
function failedClipboard(expectedPattern) {
|
function failedClipboard(aExpectedPattern, aCallback)
|
||||||
|
{
|
||||||
// Format expected text for comparison
|
// Format expected text for comparison
|
||||||
let terminator = osString == "WINNT" ? "\r\n" : "\n";
|
let terminator = osString == "WINNT" ? "\r\n" : "\n";
|
||||||
expectedPattern = expectedPattern.replace(/\[\\r\\n\][+*]/g, terminator);
|
aExpectedPattern = aExpectedPattern.replace(/\[\\r\\n\][+*]/g, terminator);
|
||||||
expectedPattern = expectedPattern.replace(/\\\(/g, "(");
|
aExpectedPattern = aExpectedPattern.replace(/\\\(/g, "(");
|
||||||
expectedPattern = expectedPattern.replace(/\\\)/g, ")");
|
aExpectedPattern = aExpectedPattern.replace(/\\\)/g, ")");
|
||||||
|
|
||||||
let actual = SpecialPowers.getClipboardData("text/unicode");
|
let actual = SpecialPowers.getClipboardData("text/unicode");
|
||||||
|
|
||||||
// Trim the right hand side of our strings. This is because expectedPattern
|
// Trim the right hand side of our strings. This is because expectedPattern
|
||||||
// accounts for windows sometimes adding a newline to our copied data.
|
// accounts for windows sometimes adding a newline to our copied data.
|
||||||
expectedPattern = expectedPattern.trimRight();
|
aExpectedPattern = aExpectedPattern.trimRight();
|
||||||
actual = actual.trimRight();
|
actual = actual.trimRight();
|
||||||
|
|
||||||
dump("TEST-UNEXPECTED-FAIL | Clipboard text does not match expected ... " +
|
dump("TEST-UNEXPECTED-FAIL | Clipboard text does not match expected ... " +
|
||||||
"results (escaped for accurate comparison):\n");
|
"results (escaped for accurate comparison):\n");
|
||||||
info("Actual: " + escape(actual));
|
info("Actual: " + escape(actual));
|
||||||
info("Expected: " + escape(expectedPattern));
|
info("Expected: " + escape(aExpectedPattern));
|
||||||
|
aCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
computedView = doc = win = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,computed view context menu test";
|
||||||
}
|
}
|
|
@ -1,79 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test computed view key bindings
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,default styles test");
|
|
||||||
|
|
||||||
info("Adding content to the test page");
|
|
||||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
|
||||||
'.matches {color: #F00;}</style>' +
|
|
||||||
'<span class="matches">Some styled text</span>' +
|
|
||||||
'</div>';
|
|
||||||
|
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode(".matches", inspector);
|
|
||||||
|
|
||||||
let propView = getFirstVisiblePropertyView(view);
|
|
||||||
let rulesTable = propView.matchedSelectorsContainer;
|
|
||||||
let matchedExpander = propView.element;
|
|
||||||
|
|
||||||
info("Focusing the property");
|
|
||||||
let onMatchedExpanderFocus = once(matchedExpander, "focus", true);
|
|
||||||
EventUtils.synthesizeMouseAtCenter(matchedExpander, {}, view.styleWindow);
|
|
||||||
yield onMatchedExpanderFocus;
|
|
||||||
|
|
||||||
yield checkToggleKeyBinding(view.styleWindow, "VK_SPACE", rulesTable, inspector);
|
|
||||||
yield checkToggleKeyBinding(view.styleWindow, "VK_RETURN", rulesTable, inspector);
|
|
||||||
yield checkHelpLinkKeybinding(view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function getFirstVisiblePropertyView(view) {
|
|
||||||
let propView = null;
|
|
||||||
view.propertyViews.some(p => {
|
|
||||||
if (p.visible) {
|
|
||||||
propView = p;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
return propView;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* checkToggleKeyBinding(win, key, rulesTable, inspector) {
|
|
||||||
info("Pressing " + key + " key a couple of times to check that the property gets expanded/collapsed");
|
|
||||||
|
|
||||||
let onExpand = inspector.once("computed-view-property-expanded");
|
|
||||||
let onCollapse = inspector.once("computed-view-property-collapsed");
|
|
||||||
|
|
||||||
info("Expanding the property");
|
|
||||||
EventUtils.synthesizeKey(key, {}, win);
|
|
||||||
yield onExpand;
|
|
||||||
isnot(rulesTable.innerHTML, "", "The property has been expanded");
|
|
||||||
|
|
||||||
info("Collapsing the property");
|
|
||||||
EventUtils.synthesizeKey(key, {}, win);
|
|
||||||
yield onCollapse;
|
|
||||||
is(rulesTable.innerHTML, "", "The property has been collapsed");
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkHelpLinkKeybinding(view) {
|
|
||||||
info("Check that MDN link is opened on \"F1\"");
|
|
||||||
let def = promise.defer();
|
|
||||||
|
|
||||||
let propView = getFirstVisiblePropertyView(view);
|
|
||||||
propView.mdnLinkClick = function(aEvent) {
|
|
||||||
ok(true, "Pressing F1 opened the MDN link");
|
|
||||||
def.resolve();
|
|
||||||
};
|
|
||||||
|
|
||||||
EventUtils.synthesizeKey("VK_F1", {}, view.styleWindow);
|
|
||||||
return def.promise;
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Tests the computed-view keyboard navigation
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,computed view keyboard nav test");
|
|
||||||
|
|
||||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
|
||||||
'span { font-variant: small-caps; color: #000000; } ' +
|
|
||||||
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
|
|
||||||
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
|
|
||||||
'<h1>Some header text</h1>\n' +
|
|
||||||
'<p id="salutation" style="font-size: 12pt">hi.</p>\n' +
|
|
||||||
'<p id="body" style="font-size: 12pt">I am a test-case. This text exists ' +
|
|
||||||
'solely to provide some things to <span style="color: yellow">' +
|
|
||||||
'highlight</span> and <span style="font-weight: bold">count</span> ' +
|
|
||||||
'style list-items in the box at right. If you are reading this, ' +
|
|
||||||
'you should go do something else instead. Maybe read a book. Or better ' +
|
|
||||||
'yet, write some test-cases for another bit of code. ' +
|
|
||||||
'<span style="font-style: italic">some text</span></p>\n' +
|
|
||||||
'<p id="closing">more text</p>\n' +
|
|
||||||
'<p>even more text</p>' +
|
|
||||||
'</div>';
|
|
||||||
content.document.title = "Computed view keyboard navigation test";
|
|
||||||
|
|
||||||
info("Opening the computed-view");
|
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("span", inspector);
|
|
||||||
|
|
||||||
info("Selecting the first computed style in the list");
|
|
||||||
let firstStyle = view.styleDocument.querySelector(".property-view");
|
|
||||||
ok(firstStyle, "First computed style found in panel");
|
|
||||||
firstStyle.focus();
|
|
||||||
|
|
||||||
info("Tab to select the 2nd style and press return");
|
|
||||||
let onExpanded = inspector.once("computed-view-property-expanded");
|
|
||||||
EventUtils.synthesizeKey("VK_TAB", {});
|
|
||||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
|
||||||
yield onExpanded;
|
|
||||||
|
|
||||||
info("Verify the 2nd style has been expanded");
|
|
||||||
let secondStyleSelectors = view.styleDocument.querySelectorAll(
|
|
||||||
".property-content .matchedselectors")[1];
|
|
||||||
ok(secondStyleSelectors.childNodes.length > 0, "Matched selectors expanded");
|
|
||||||
|
|
||||||
info("Tab back up and test the same thing, with space");
|
|
||||||
let onExpanded = inspector.once("computed-view-property-expanded");
|
|
||||||
EventUtils.synthesizeKey("VK_TAB", {shiftKey: true});
|
|
||||||
EventUtils.synthesizeKey("VK_SPACE", {});
|
|
||||||
yield onExpanded;
|
|
||||||
|
|
||||||
info("Verify the 1st style has been expanded too");
|
|
||||||
let firstStyleSelectors = view.styleDocument.querySelectorAll(
|
|
||||||
".property-content .matchedselectors")[0];
|
|
||||||
ok(firstStyleSelectors.childNodes.length > 0, "Matched selectors expanded");
|
|
||||||
});
|
|
|
@ -1,108 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that the computed view properties can be expanded and collapsed with
|
|
||||||
// either the twisty or by dbl-clicking on the container
|
|
||||||
|
|
||||||
const TEST_URL = "data:text/html," + encodeURIComponent([
|
|
||||||
'<html>' +
|
|
||||||
'<head>' +
|
|
||||||
' <title>Computed view toggling test</title>',
|
|
||||||
' <style type="text/css"> ',
|
|
||||||
' html { color: #000000; font-size: 15pt; } ',
|
|
||||||
' h1 { color: red; } ',
|
|
||||||
' </style>',
|
|
||||||
'</head>',
|
|
||||||
'<body>',
|
|
||||||
' <h1>Some header text</h1>',
|
|
||||||
'</body>',
|
|
||||||
'</html>'
|
|
||||||
].join("\n"));
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab(TEST_URL);
|
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("h1", inspector);
|
|
||||||
|
|
||||||
yield testExpandOnTwistyClick(view, inspector);
|
|
||||||
yield testCollapseOnTwistyClick(view, inspector);
|
|
||||||
yield testExpandOnDblClick(view, inspector);
|
|
||||||
yield testCollapseOnDblClick(view, inspector);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testExpandOnTwistyClick({styleDocument, styleWindow}, inspector) {
|
|
||||||
info("Testing that a property expands on twisty click");
|
|
||||||
|
|
||||||
info("Getting twisty element");
|
|
||||||
let twisty = styleDocument.querySelector(".expandable");
|
|
||||||
ok(twisty, "Twisty found");
|
|
||||||
|
|
||||||
let onExpand = inspector.once("computed-view-property-expanded");
|
|
||||||
info("Clicking on the twisty element");
|
|
||||||
twisty.click();
|
|
||||||
|
|
||||||
yield onExpand;
|
|
||||||
|
|
||||||
// Expanded means the matchedselectors div is not empty
|
|
||||||
let div = styleDocument.querySelector(".property-content .matchedselectors");
|
|
||||||
ok(div.childNodes.length > 0, "Matched selectors are expanded on twisty click");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testCollapseOnTwistyClick({styleDocument, styleWindow}, inspector) {
|
|
||||||
info("Testing that a property collapses on twisty click");
|
|
||||||
|
|
||||||
info("Getting twisty element");
|
|
||||||
let twisty = styleDocument.querySelector(".expandable");
|
|
||||||
ok(twisty, "Twisty found");
|
|
||||||
|
|
||||||
let onCollapse = inspector.once("computed-view-property-collapsed");
|
|
||||||
info("Clicking on the twisty element");
|
|
||||||
twisty.click();
|
|
||||||
|
|
||||||
yield onCollapse;
|
|
||||||
|
|
||||||
// Collapsed means the matchedselectors div is empty
|
|
||||||
let div = styleDocument.querySelector(".property-content .matchedselectors");
|
|
||||||
ok(div.childNodes.length === 0, "Matched selectors are collapsed on twisty click");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testExpandOnDblClick({styleDocument, styleWindow}, inspector) {
|
|
||||||
info("Testing that a property expands on container dbl-click");
|
|
||||||
|
|
||||||
info("Getting computed property container");
|
|
||||||
let container = styleDocument.querySelector(".property-view");
|
|
||||||
ok(container, "Container found");
|
|
||||||
|
|
||||||
let onExpand = inspector.once("computed-view-property-expanded");
|
|
||||||
info("Dbl-clicking on the container");
|
|
||||||
EventUtils.synthesizeMouseAtCenter(container, {clickCount: 2}, styleWindow);
|
|
||||||
|
|
||||||
yield onExpand;
|
|
||||||
|
|
||||||
// Expanded means the matchedselectors div is not empty
|
|
||||||
let div = styleDocument.querySelector(".property-content .matchedselectors");
|
|
||||||
ok(div.childNodes.length > 0, "Matched selectors are expanded on dblclick");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testCollapseOnDblClick({styleDocument, styleWindow}, inspector) {
|
|
||||||
info("Testing that a property collapses on container dbl-click");
|
|
||||||
|
|
||||||
info("Getting computed property container");
|
|
||||||
let container = styleDocument.querySelector(".property-view");
|
|
||||||
ok(container, "Container found");
|
|
||||||
|
|
||||||
let onCollapse = inspector.once("computed-view-property-collapsed");
|
|
||||||
info("Dbl-clicking on the container");
|
|
||||||
EventUtils.synthesizeMouseAtCenter(container, {clickCount: 2}, styleWindow);
|
|
||||||
|
|
||||||
yield onCollapse;
|
|
||||||
|
|
||||||
// Collapsed means the matchedselectors div is empty
|
|
||||||
let div = styleDocument.querySelector(".property-content .matchedselectors");
|
|
||||||
ok(div.childNodes.length === 0, "Matched selectors are collapsed on dblclick");
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Checking selector counts, matched rules and titles in the computed-view
|
|
||||||
|
|
||||||
const {PropertyView} = devtools.require("devtools/styleinspector/computed-view");
|
|
||||||
const TEST_URI = TEST_URL_ROOT + "doc_matched_selectors.html";
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab(TEST_URI);
|
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
|
||||||
|
|
||||||
yield selectNode("#test", inspector);
|
|
||||||
yield testMatchedSelectors(view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testMatchedSelectors(view) {
|
|
||||||
info("checking selector counts, matched rules and titles");
|
|
||||||
|
|
||||||
is(getNode("#test"), view.viewedElement.rawNode(),
|
|
||||||
"style inspector node matches the selected node");
|
|
||||||
|
|
||||||
let propertyView = new PropertyView(view, "color");
|
|
||||||
propertyView.buildMain();
|
|
||||||
propertyView.buildSelectorContainer();
|
|
||||||
propertyView.matchedExpanded = true;
|
|
||||||
|
|
||||||
yield propertyView.refreshMatchedSelectors();
|
|
||||||
|
|
||||||
let numMatchedSelectors = propertyView.matchedSelectors.length;
|
|
||||||
is(numMatchedSelectors, 6, "CssLogic returns the correct number of matched selectors for div");
|
|
||||||
is(propertyView.hasMatchedSelectors, true, "hasMatchedSelectors returns true");
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Tests for matched selector texts in the computed view
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,<div style='color:blue;'></div>");
|
|
||||||
|
|
||||||
info("Opening the computed view");
|
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("div", inspector);
|
|
||||||
|
|
||||||
info("Checking the color property view");
|
|
||||||
let propertyView = getPropertyView(view, "color");
|
|
||||||
ok(propertyView, "found PropertyView for color");
|
|
||||||
is(propertyView.hasMatchedSelectors, true, "hasMatchedSelectors is true");
|
|
||||||
|
|
||||||
info("Expanding the matched selectors");
|
|
||||||
propertyView.matchedExpanded = true;
|
|
||||||
yield propertyView.refreshMatchedSelectors();
|
|
||||||
|
|
||||||
let span = propertyView.matchedSelectorsContainer.querySelector("span.rule-text");
|
|
||||||
ok(span, "Found the first table row");
|
|
||||||
|
|
||||||
let selector = propertyView.matchedSelectorViews[0];
|
|
||||||
ok(selector, "Found the first matched selector view");
|
|
||||||
});
|
|
||||||
|
|
||||||
function getPropertyView(computedView, name) {
|
|
||||||
let propertyView = null;
|
|
||||||
computedView.propertyViews.some(function(view) {
|
|
||||||
if (view.name == name) {
|
|
||||||
propertyView = view;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
return propertyView;
|
|
||||||
}
|
|
|
@ -1,73 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Tests that the no results placeholder works properly.
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,no results placeholder test");
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
|
||||||
'.matches {color: #F00;}</style>' +
|
|
||||||
'<span id="matches" class="matches">Some styled text</span>';
|
|
||||||
content.document.title = "Tests that the no results placeholder works properly";
|
|
||||||
|
|
||||||
info("Opening the computed view");
|
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("#matches", inspector);
|
|
||||||
|
|
||||||
yield enterInvalidFilter(inspector, view);
|
|
||||||
checkNoResultsPlaceholderShown(view);
|
|
||||||
|
|
||||||
yield clearFilterText(inspector, view);
|
|
||||||
checkNoResultsPlaceholderHidden(view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* enterInvalidFilter(inspector, computedView) {
|
|
||||||
let searchbar = computedView.searchField;
|
|
||||||
let searchTerm = "xxxxx";
|
|
||||||
|
|
||||||
info("setting filter text to \"" + searchTerm + "\"");
|
|
||||||
|
|
||||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
|
||||||
searchbar.focus();
|
|
||||||
for each (let c in searchTerm) {
|
|
||||||
EventUtils.synthesizeKey(c, {}, computedView.styleWindow);
|
|
||||||
}
|
|
||||||
yield onRefreshed;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkNoResultsPlaceholderShown(computedView) {
|
|
||||||
info("Checking that the no results placeholder is shown");
|
|
||||||
|
|
||||||
let placeholder = computedView.noResults;
|
|
||||||
let win = computedView.styleWindow;
|
|
||||||
let display = win.getComputedStyle(placeholder).display;
|
|
||||||
is(display, "block", "placeholder is visible");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* clearFilterText(inspector, computedView) {
|
|
||||||
info("Clearing the filter text");
|
|
||||||
|
|
||||||
let searchbar = computedView.searchField;
|
|
||||||
|
|
||||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
|
||||||
searchbar.focus();
|
|
||||||
searchbar.value = "";
|
|
||||||
EventUtils.synthesizeKey("c", {}, computedView.styleWindow);
|
|
||||||
yield onRefreshed;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkNoResultsPlaceholderHidden(computedView) {
|
|
||||||
info("Checking that the no results placeholder is hidden");
|
|
||||||
|
|
||||||
let placeholder = computedView.noResults;
|
|
||||||
let win = computedView.styleWindow;
|
|
||||||
let display = win.getComputedStyle(placeholder).display;
|
|
||||||
is(display, "none", "placeholder is hidden");
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that the computed view shows the original source link when source maps
|
|
||||||
// are enabled
|
|
||||||
|
|
||||||
const TESTCASE_URI = TEST_URL_ROOT_SSL + "doc_sourcemaps.html";
|
|
||||||
const PREF = "devtools.styleeditor.source-maps-enabled";
|
|
||||||
const SCSS_LOC = "doc_sourcemaps.scss:4";
|
|
||||||
const CSS_LOC = "doc_sourcemaps.css:1";
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
info("Turning the pref " + PREF + " on");
|
|
||||||
Services.prefs.setBoolPref(PREF, true);
|
|
||||||
|
|
||||||
yield addTab(TESTCASE_URI);
|
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
|
||||||
|
|
||||||
info("Select the test node");
|
|
||||||
yield selectNode("div", inspector);
|
|
||||||
|
|
||||||
info("Expanding the first property");
|
|
||||||
yield expandComputedViewPropertyByIndex(view, inspector, 0);
|
|
||||||
|
|
||||||
info("Verifying the link text");
|
|
||||||
yield verifyLinkText(view, SCSS_LOC);
|
|
||||||
|
|
||||||
info("Toggling the pref");
|
|
||||||
Services.prefs.setBoolPref(PREF, false);
|
|
||||||
|
|
||||||
info("Verifying that the link text has changed after the pref change");
|
|
||||||
yield verifyLinkText(view, CSS_LOC);
|
|
||||||
|
|
||||||
info("Toggling the pref again");
|
|
||||||
Services.prefs.setBoolPref(PREF, true);
|
|
||||||
|
|
||||||
info("Testing that clicking on the link works");
|
|
||||||
yield testClickingLink(toolbox, view);
|
|
||||||
|
|
||||||
info("Turning the pref " + PREF + " off");
|
|
||||||
Services.prefs.clearUserPref(PREF);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testClickingLink(toolbox, view) {
|
|
||||||
let onEditor = waitForStyleEditor(toolbox, "doc_sourcemaps.scss");
|
|
||||||
|
|
||||||
info("Clicking the computedview stylesheet link");
|
|
||||||
let link = getComputedViewLinkByIndex(view, 0);
|
|
||||||
link.scrollIntoView();
|
|
||||||
link.click();
|
|
||||||
|
|
||||||
let editor = yield onEditor;
|
|
||||||
|
|
||||||
let {line, col} = editor.sourceEditor.getCursor();
|
|
||||||
is(line, 3, "cursor is at correct line number in original source");
|
|
||||||
}
|
|
||||||
|
|
||||||
function verifyLinkText(view, text) {
|
|
||||||
let link = getComputedViewLinkByIndex(view, 0);
|
|
||||||
|
|
||||||
return waitForSuccess(
|
|
||||||
() => link.textContent == text,
|
|
||||||
"link text changed to display correct location: " + text
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let win;
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let computedView;
|
||||||
|
let toolbox;
|
||||||
|
|
||||||
|
const TESTCASE_URI = TEST_BASE_HTTPS + "sourcemaps.html";
|
||||||
|
const PREF = "devtools.styleeditor.source-maps-enabled";
|
||||||
|
|
||||||
|
const SCSS_LOC = "sourcemaps.scss:4";
|
||||||
|
const CSS_LOC = "sourcemaps.css:1";
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
Services.prefs.setBoolPref(PREF, true);
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
|
||||||
|
true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(function () { openComputedView(highlightNode); }, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = TESTCASE_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlightNode(aInspector, aComputedView)
|
||||||
|
{
|
||||||
|
inspector = aInspector;
|
||||||
|
computedView = aComputedView;
|
||||||
|
|
||||||
|
// Highlight a node.
|
||||||
|
let div = content.document.getElementsByTagName("div")[0];
|
||||||
|
ok(div, "div to select exists")
|
||||||
|
|
||||||
|
inspector.selection.setNode(div);
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
is(inspector.selection.node, div, "selection matches the div element");
|
||||||
|
|
||||||
|
expandProperty(0, testComputedViewLink);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testComputedViewLink() {
|
||||||
|
verifyLinkText(SCSS_LOC, testTogglePref);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTogglePref() {
|
||||||
|
Services.prefs.setBoolPref(PREF, false);
|
||||||
|
|
||||||
|
verifyLinkText(CSS_LOC, () => {
|
||||||
|
Services.prefs.setBoolPref(PREF, true);
|
||||||
|
|
||||||
|
testClickingLink();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function testClickingLink() {
|
||||||
|
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||||
|
let toolbox = gDevTools.getToolbox(target);
|
||||||
|
|
||||||
|
toolbox.once("styleeditor-ready", function(id, aToolbox) {
|
||||||
|
let panel = toolbox.getCurrentPanel();
|
||||||
|
panel.UI.on("editor-selected", (event, editor) => {
|
||||||
|
// The style editor selects the first sheet at first load before
|
||||||
|
// selecting the desired sheet.
|
||||||
|
if (editor.styleSheet.href.endsWith("scss")) {
|
||||||
|
info("original source editor selected");
|
||||||
|
editor.getSourceEditor().then(editorSelected);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let link = getLinkByIndex(0);
|
||||||
|
|
||||||
|
info("clicking rule view link");
|
||||||
|
link.scrollIntoView();
|
||||||
|
link.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function editorSelected(editor) {
|
||||||
|
let href = editor.styleSheet.href;
|
||||||
|
ok(href.endsWith("sourcemaps.scss"), "selected stylesheet is correct one");
|
||||||
|
|
||||||
|
let {line, col} = editor.sourceEditor.getCursor();
|
||||||
|
is(line, 3, "cursor is at correct line number in original source");
|
||||||
|
|
||||||
|
finishUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helpers */
|
||||||
|
function expandProperty(aIndex, aCallback)
|
||||||
|
{
|
||||||
|
info("expanding property " + aIndex);
|
||||||
|
let contentDoc = computedView.styleDocument;
|
||||||
|
let expando = contentDoc.querySelectorAll(".expandable")[aIndex];
|
||||||
|
|
||||||
|
expando.click();
|
||||||
|
|
||||||
|
inspector.once("computed-view-property-expanded", aCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLinkByIndex(aIndex)
|
||||||
|
{
|
||||||
|
let contentDoc = computedView.styleDocument;
|
||||||
|
let links = contentDoc.querySelectorAll(".rule-link .link");
|
||||||
|
return links[aIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyLinkText(text, callback) {
|
||||||
|
let link = getLinkByIndex(0);
|
||||||
|
|
||||||
|
waitForSuccess({
|
||||||
|
name: "link text changed to display correct location: " + text,
|
||||||
|
validatorFn: function()
|
||||||
|
{
|
||||||
|
return link.textContent == text;
|
||||||
|
},
|
||||||
|
successFn: callback,
|
||||||
|
failureFn: callback,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
doc = inspector = computedView = toolbox = win = null;
|
||||||
|
Services.prefs.clearUserPref(PREF);
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -1,65 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Tests that the search filter works properly.
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,default styles test");
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
|
||||||
'.matches {color: #F00;}</style>' +
|
|
||||||
'<span id="matches" class="matches">Some styled text</span>' +
|
|
||||||
'</div>';
|
|
||||||
content.document.title = "Style Inspector Search Filter Test";
|
|
||||||
|
|
||||||
info("Opening the computed-view");
|
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("#matches", inspector);
|
|
||||||
|
|
||||||
yield testToggleDefaultStyles(inspector, view);
|
|
||||||
yield testAddTextInFilter(inspector, view);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function* testToggleDefaultStyles(inspector, computedView) {
|
|
||||||
info("checking \"Browser styles\" checkbox");
|
|
||||||
|
|
||||||
let doc = computedView.styleDocument;
|
|
||||||
let checkbox = doc.querySelector(".includebrowserstyles");
|
|
||||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
|
||||||
checkbox.click();
|
|
||||||
yield onRefreshed;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testAddTextInFilter(inspector, computedView) {
|
|
||||||
info("setting filter text to \"color\"");
|
|
||||||
|
|
||||||
let doc = computedView.styleDocument;
|
|
||||||
let searchbar = doc.querySelector(".devtools-searchinput");
|
|
||||||
let onRefreshed = inspector.once("computed-view-refreshed");
|
|
||||||
searchbar.focus();
|
|
||||||
|
|
||||||
let win = computedView.styleWindow;
|
|
||||||
EventUtils.synthesizeKey("c", {}, win);
|
|
||||||
EventUtils.synthesizeKey("o", {}, win);
|
|
||||||
EventUtils.synthesizeKey("l", {}, win);
|
|
||||||
EventUtils.synthesizeKey("o", {}, win);
|
|
||||||
EventUtils.synthesizeKey("r", {}, win);
|
|
||||||
|
|
||||||
yield onRefreshed;
|
|
||||||
|
|
||||||
info("check that the correct properties are visible");
|
|
||||||
|
|
||||||
let propertyViews = computedView.propertyViews;
|
|
||||||
propertyViews.forEach(function(propView) {
|
|
||||||
let name = propView.name;
|
|
||||||
is(propView.visible, name.indexOf("color") > -1,
|
|
||||||
"span " + name + " property visibility check");
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,114 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test the links from the computed view to the style editor
|
|
||||||
|
|
||||||
const STYLESHEET_URL = "data:text/css,"+encodeURIComponent(
|
|
||||||
[".highlight {",
|
|
||||||
"color: blue",
|
|
||||||
"}"].join("\n"));
|
|
||||||
|
|
||||||
const DOCUMENT_URL = "data:text/html,"+encodeURIComponent(
|
|
||||||
['<html>' +
|
|
||||||
'<head>' +
|
|
||||||
'<title>Computed view style editor link test</title>',
|
|
||||||
'<style type="text/css"> ',
|
|
||||||
'html { color: #000000; } ',
|
|
||||||
'span { font-variant: small-caps; color: #000000; } ',
|
|
||||||
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ',
|
|
||||||
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">',
|
|
||||||
'</style>',
|
|
||||||
'<link rel="stylesheet" type="text/css" href="'+STYLESHEET_URL+'">',
|
|
||||||
'</head>',
|
|
||||||
'<body>',
|
|
||||||
'<h1>Some header text</h1>',
|
|
||||||
'<p id="salutation" style="font-size: 12pt">hi.</p>',
|
|
||||||
'<p id="body" style="font-size: 12pt">I am a test-case. This text exists ',
|
|
||||||
'solely to provide some things to ',
|
|
||||||
'<span style="color: yellow" class="highlight">',
|
|
||||||
'highlight</span> and <span style="font-weight: bold">count</span> ',
|
|
||||||
'style list-items in the box at right. If you are reading this, ',
|
|
||||||
'you should go do something else instead. Maybe read a book. Or better ',
|
|
||||||
'yet, write some test-cases for another bit of code. ',
|
|
||||||
'<span style="font-style: italic">some text</span></p>',
|
|
||||||
'<p id="closing">more text</p>',
|
|
||||||
'<p>even more text</p>',
|
|
||||||
'</div>',
|
|
||||||
'</body>',
|
|
||||||
'</html>'].join("\n"));
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab(DOCUMENT_URL);
|
|
||||||
|
|
||||||
info("Opening the computed-view");
|
|
||||||
let {toolbox, inspector, view} = yield openComputedView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("span", inspector);
|
|
||||||
|
|
||||||
yield testInlineStyle(view, inspector);
|
|
||||||
yield testInlineStyleSheet(view, toolbox);
|
|
||||||
yield testExternalStyleSheet(view, toolbox);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testInlineStyle(view, inspector) {
|
|
||||||
info("Testing inline style");
|
|
||||||
|
|
||||||
yield expandComputedViewPropertyByIndex(view, inspector, 0);
|
|
||||||
|
|
||||||
let onWindow = waitForWindow();
|
|
||||||
info("Clicking on the first rule-link in the computed-view");
|
|
||||||
let link = getComputedViewLinkByIndex(view, 0);
|
|
||||||
link.click();
|
|
||||||
|
|
||||||
let win = yield onWindow;
|
|
||||||
|
|
||||||
let windowType = win.document.documentElement.getAttribute("windowtype");
|
|
||||||
is(windowType, "navigator:view-source", "View source window is open");
|
|
||||||
info("Closing window");
|
|
||||||
win.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testInlineStyleSheet(view, toolbox) {
|
|
||||||
info("Testing inline stylesheet");
|
|
||||||
|
|
||||||
info("Listening for toolbox switch to the styleeditor");
|
|
||||||
let onSwitch = waitForStyleEditor(toolbox);
|
|
||||||
|
|
||||||
info("Clicking an inline stylesheet");
|
|
||||||
let link = getComputedViewLinkByIndex(view, 2);
|
|
||||||
link.click();
|
|
||||||
let editor = yield onSwitch;
|
|
||||||
|
|
||||||
ok(true, "Switched to the style-editor panel in the toolbox");
|
|
||||||
|
|
||||||
validateStyleEditorSheet(editor, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testExternalStyleSheet(view, toolbox) {
|
|
||||||
info("Testing external stylesheet");
|
|
||||||
|
|
||||||
info("Waiting for the stylesheet editor to be selected");
|
|
||||||
let panel = toolbox.getCurrentPanel();
|
|
||||||
let onSelected = panel.UI.once("editor-selected");
|
|
||||||
|
|
||||||
info("Switching back to the inspector panel in the toolbox");
|
|
||||||
yield toolbox.selectTool("inspector");
|
|
||||||
|
|
||||||
info("Clicking on an external stylesheet link");
|
|
||||||
let link = getComputedViewLinkByIndex(view, 1);
|
|
||||||
link.click();
|
|
||||||
let editor = yield onSelected;
|
|
||||||
|
|
||||||
is(toolbox.currentToolId, "styleeditor", "The style editor is selected again");
|
|
||||||
validateStyleEditorSheet(editor, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateStyleEditorSheet(editor, expectedSheetIndex) {
|
|
||||||
info("Validating style editor stylesheet");
|
|
||||||
let sheet = content.document.styleSheets[expectedSheetIndex];
|
|
||||||
is(editor.styleSheet.href, sheet.href, "loaded stylesheet matches document stylesheet");
|
|
||||||
}
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Test that inherited properties are treated correctly.
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
|
||||||
|
function createDocument()
|
||||||
|
{
|
||||||
|
doc.body.innerHTML = '<div style="margin-left:10px; font-size: 5px"><div id="innerdiv">Inner div</div></div>';
|
||||||
|
doc.title = "Style Inspector Inheritance Test";
|
||||||
|
|
||||||
|
let cssLogic = new CssLogic();
|
||||||
|
cssLogic.highlight(doc.getElementById("innerdiv"));
|
||||||
|
|
||||||
|
let marginProp = cssLogic.getPropertyInfo("margin-left");
|
||||||
|
is(marginProp.matchedRuleCount, 0, "margin-left should not be included in matched selectors.");
|
||||||
|
|
||||||
|
let fontSizeProp = cssLogic.getPropertyInfo("font-size");
|
||||||
|
is(fontSizeProp.matchedRuleCount, 1, "font-size should be included in matched selectors.");
|
||||||
|
|
||||||
|
finishUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
doc = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,selector text test, bug 692400";
|
||||||
|
}
|
|
@ -0,0 +1,189 @@
|
||||||
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let win;
|
||||||
|
let doc;
|
||||||
|
let contentWindow;
|
||||||
|
let inspector;
|
||||||
|
let toolbox;
|
||||||
|
|
||||||
|
let tempScope = {};
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm", tempScope);
|
||||||
|
let Services = tempScope.Services;
|
||||||
|
|
||||||
|
const STYLESHEET_URL = "data:text/css,"+encodeURIComponent(
|
||||||
|
["#first {",
|
||||||
|
"color: blue",
|
||||||
|
"}"].join("\n"));
|
||||||
|
|
||||||
|
const EXTERNAL_STYLESHEET_FILE_NAME = "browser_ruleview_734259_style_editor_link.css"
|
||||||
|
const EXTERNAL_STYLESHEET_URL = TEST_BASE_HTTP + EXTERNAL_STYLESHEET_FILE_NAME;
|
||||||
|
|
||||||
|
const DOCUMENT_URL = "data:text/html,"+encodeURIComponent(
|
||||||
|
['<html>' +
|
||||||
|
'<head>' +
|
||||||
|
'<title>Rule view style editor link test</title>',
|
||||||
|
'<style type="text/css"> ',
|
||||||
|
'html { color: #000000; } ',
|
||||||
|
'div { font-variant: small-caps; color: #000000; } ',
|
||||||
|
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ',
|
||||||
|
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">',
|
||||||
|
'</style>',
|
||||||
|
'<link rel="stylesheet" type="text/css" href="'+STYLESHEET_URL+'">',
|
||||||
|
'<link rel="stylesheet" type="text/css" href="'+EXTERNAL_STYLESHEET_URL+'">',
|
||||||
|
'</head>',
|
||||||
|
'<body>',
|
||||||
|
'<h1>Some header text</h1>',
|
||||||
|
'<p id="salutation" style="font-size: 12pt">hi.</p>',
|
||||||
|
'<p id="body" style="font-size: 12pt">I am a test-case. This text exists ',
|
||||||
|
'solely to provide some things to ',
|
||||||
|
'<span style="color: yellow" class="highlight">',
|
||||||
|
'highlight</span> and <span style="font-weight: bold">count</span> ',
|
||||||
|
'style list-items in the box at right. If you are reading this, ',
|
||||||
|
'you should go do something else instead. Maybe read a book. Or better ',
|
||||||
|
'yet, write some test-cases for another bit of code. ',
|
||||||
|
'<span style="font-style: italic">some text</span></p>',
|
||||||
|
'<p id="closing">more text</p>',
|
||||||
|
'<p>even more text</p>',
|
||||||
|
'</div>',
|
||||||
|
'</body>',
|
||||||
|
'</html>'].join("\n"));
|
||||||
|
|
||||||
|
function openToolbox() {
|
||||||
|
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||||
|
|
||||||
|
gDevTools.showToolbox(target, "inspector").then(function(aToolbox) {
|
||||||
|
toolbox = aToolbox;
|
||||||
|
inspector = toolbox.getCurrentPanel();
|
||||||
|
inspector.sidebar.select("ruleview");
|
||||||
|
highlightNode();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlightNode()
|
||||||
|
{
|
||||||
|
// Highlight a node.
|
||||||
|
let div = content.document.getElementsByTagName("div")[0];
|
||||||
|
|
||||||
|
inspector.selection.setNode(div);
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
is(inspector.selection.node, div, "selection matches the div element");
|
||||||
|
testInlineStyle();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInlineStyle()
|
||||||
|
{
|
||||||
|
info("clicking an inline style");
|
||||||
|
|
||||||
|
Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
|
||||||
|
if (aTopic != "domwindowopened") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
win = aSubject.QueryInterface(Ci.nsIDOMWindow);
|
||||||
|
win.addEventListener("load", function windowLoad() {
|
||||||
|
win.removeEventListener("load", windowLoad);
|
||||||
|
let windowType = win.document.documentElement.getAttribute("windowtype");
|
||||||
|
is(windowType, "navigator:view-source", "view source window is open");
|
||||||
|
win.close();
|
||||||
|
Services.ww.unregisterNotification(onWindow);
|
||||||
|
executeSoon(() => {
|
||||||
|
testInlineStyleSheet();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let link = getLinkByIndex(0);
|
||||||
|
link.scrollIntoView();
|
||||||
|
link.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testInlineStyleSheet()
|
||||||
|
{
|
||||||
|
info("clicking an inline stylesheet");
|
||||||
|
|
||||||
|
toolbox.once("styleeditor-ready", function(id, aToolbox) {
|
||||||
|
let panel = toolbox.getCurrentPanel();
|
||||||
|
|
||||||
|
panel.UI.once("editor-selected", (event, editor) => {
|
||||||
|
validateStyleEditorSheet(editor, 0);
|
||||||
|
executeSoon(() => {
|
||||||
|
testExternalStyleSheet(toolbox);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let link = getLinkByIndex(4);
|
||||||
|
link.scrollIntoView();
|
||||||
|
link.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testExternalStyleSheet(toolbox) {
|
||||||
|
info ("clicking an external stylesheet");
|
||||||
|
|
||||||
|
let panel = toolbox.getCurrentPanel();
|
||||||
|
panel.UI.once("editor-selected", (event, editor) => {
|
||||||
|
is(toolbox.currentToolId, "styleeditor", "style editor tool selected");
|
||||||
|
validateStyleEditorSheet(editor, 1);
|
||||||
|
finishUp();
|
||||||
|
});
|
||||||
|
|
||||||
|
toolbox.selectTool("inspector").then(function () {
|
||||||
|
testRuleViewLinkLabel();
|
||||||
|
let link = getLinkByIndex(1);
|
||||||
|
link.scrollIntoView();
|
||||||
|
link.click();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRuleViewLinkLabel()
|
||||||
|
{
|
||||||
|
let link = getLinkByIndex(2);
|
||||||
|
let labelElem = link.querySelector(".source-link-label");
|
||||||
|
let value = labelElem.getAttribute("value");
|
||||||
|
let tooltipText = labelElem.getAttribute("tooltiptext");
|
||||||
|
|
||||||
|
is(value, EXTERNAL_STYLESHEET_FILE_NAME + ":1",
|
||||||
|
"rule view stylesheet display value matches filename and line number");
|
||||||
|
is(tooltipText, EXTERNAL_STYLESHEET_URL,
|
||||||
|
"rule view stylesheet tooltip text matches the full URI path");
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateStyleEditorSheet(aEditor, aExpectedSheetIndex)
|
||||||
|
{
|
||||||
|
info("validating style editor stylesheet");
|
||||||
|
let sheet = doc.styleSheets[aExpectedSheetIndex];
|
||||||
|
is(aEditor.styleSheet.href, sheet.href, "loaded stylesheet matches document stylesheet");
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLinkByIndex(aIndex)
|
||||||
|
{
|
||||||
|
let contentDoc = ruleView().doc;
|
||||||
|
contentWindow = contentDoc.defaultView;
|
||||||
|
let links = contentDoc.querySelectorAll(".ruleview-rule-source");
|
||||||
|
return links[aIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
contentWindow = doc = inspector = toolbox = win = null;
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
|
||||||
|
true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(openToolbox, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = DOCUMENT_URL;
|
||||||
|
}
|
|
@ -1,47 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Tests that adding properties to rules work and reselecting the element still
|
|
||||||
// show them
|
|
||||||
|
|
||||||
const TEST_URI = TEST_URL_ROOT + "doc_content_stylesheet.html";
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab(TEST_URI);
|
|
||||||
|
|
||||||
let target = getNode("#target");
|
|
||||||
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
yield selectNode(target, inspector);
|
|
||||||
|
|
||||||
info("Setting a font-weight property on all rules");
|
|
||||||
setPropertyOnAllRules(view);
|
|
||||||
|
|
||||||
info("Reselecting the element");
|
|
||||||
yield reselectElement(target, inspector);
|
|
||||||
|
|
||||||
checkPropertyOnAllRules(view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* reselectElement(node, inspector) {
|
|
||||||
yield selectNode(node.parentNode, inspector);
|
|
||||||
yield selectNode(node, inspector);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPropertyOnAllRules(view) {
|
|
||||||
for (let rule of view._elementStyle.rules) {
|
|
||||||
rule.editor.addProperty("font-weight", "bold", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkPropertyOnAllRules(view) {
|
|
||||||
for (let rule of view._elementStyle.rules) {
|
|
||||||
let lastRule = rule.textProps[rule.textProps.length - 1];
|
|
||||||
|
|
||||||
is(lastRule.name, "font-weight", "Last rule name is font-weight");
|
|
||||||
is(lastRule.value, "bold", "Last rule value is bold");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Testing various inplace-editor behaviors in the rule-view
|
|
||||||
|
|
||||||
let TEST_URL = 'url("' + TEST_URL_ROOT + 'doc_test_image.png")';
|
|
||||||
let PAGE_CONTENT = [
|
|
||||||
'<style type="text/css">',
|
|
||||||
' #testid {',
|
|
||||||
' background-color: blue;',
|
|
||||||
' }',
|
|
||||||
' .testclass {',
|
|
||||||
' background-color: green;',
|
|
||||||
' }',
|
|
||||||
'</style>',
|
|
||||||
'<div id="testid" class="testclass">Styled Node</div>'
|
|
||||||
].join("\n");
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,test rule view user changes");
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
|
||||||
|
|
||||||
info("Opening the rule-view");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Selecting the test element");
|
|
||||||
yield selectNode("#testid", inspector);
|
|
||||||
|
|
||||||
yield testCancelNew(view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCancelNew(view) {
|
|
||||||
info("Test adding a new rule to the element's style declaration and leaving it empty.");
|
|
||||||
|
|
||||||
let elementRuleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
|
|
||||||
info("Focusing a new property name in the rule-view");
|
|
||||||
let editor = yield focusEditableField(elementRuleEditor.closeBrace);
|
|
||||||
is(inplaceEditor(elementRuleEditor.newPropSpan), editor, "The new property editor got focused");
|
|
||||||
|
|
||||||
info("Bluring the editor input");
|
|
||||||
let onBlur = once(editor.input, "blur");
|
|
||||||
editor.input.blur();
|
|
||||||
yield onBlur;
|
|
||||||
|
|
||||||
info("Checking the state of canceling a new property name editor");
|
|
||||||
ok(!elementRuleEditor.rule._applyingModifications, "Shouldn't have an outstanding request after a cancel.");
|
|
||||||
is(elementRuleEditor.rule.textProps.length, 0, "Should have canceled creating a new text property.");
|
|
||||||
ok(!elementRuleEditor.propertyList.hasChildNodes(), "Should not have any properties.");
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Testing various inplace-editor behaviors in the rule-view
|
|
||||||
// FIXME: To be split in several test files, and some of the inplace-editor
|
|
||||||
// focus/blur/commit/revert stuff should be factored out in head.js
|
|
||||||
|
|
||||||
let TEST_URL = 'url("' + TEST_URL_ROOT + 'doc_test_image.png")';
|
|
||||||
let PAGE_CONTENT = [
|
|
||||||
'<style type="text/css">',
|
|
||||||
' #testid {',
|
|
||||||
' background-color: blue;',
|
|
||||||
' }',
|
|
||||||
' .testclass {',
|
|
||||||
' background-color: green;',
|
|
||||||
' }',
|
|
||||||
'</style>',
|
|
||||||
'<div id="testid" class="testclass" style="background-color:red;">Styled Node</div>'
|
|
||||||
].join("\n");
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,test rule view user changes");
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
|
||||||
|
|
||||||
info("Opening the rule-view");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Selecting the test element");
|
|
||||||
yield selectNode("#testid", inspector);
|
|
||||||
|
|
||||||
yield testCreateNewEscape(view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCreateNewEscape(view) {
|
|
||||||
info("Test creating a new property and escaping");
|
|
||||||
|
|
||||||
let elementRuleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
|
|
||||||
info("Focusing a new property name in the rule-view");
|
|
||||||
let editor = yield focusEditableField(elementRuleEditor.closeBrace);
|
|
||||||
|
|
||||||
is(inplaceEditor(elementRuleEditor.newPropSpan), editor, "The new property editor got focused.");
|
|
||||||
let input = editor.input;
|
|
||||||
|
|
||||||
info("Entering a value in the property name editor");
|
|
||||||
input.value = "color";
|
|
||||||
|
|
||||||
info("Pressing return to commit and focus the new value field");
|
|
||||||
let onValueFocus = once(elementRuleEditor.element, "focus", true);
|
|
||||||
let onModifications = elementRuleEditor.rule._applyingModifications;
|
|
||||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
|
||||||
yield onValueFocus;
|
|
||||||
yield onModifications;
|
|
||||||
|
|
||||||
// Getting the new value editor after focus
|
|
||||||
editor = inplaceEditor(view.doc.activeElement);
|
|
||||||
let textProp = elementRuleEditor.rule.textProps[1];
|
|
||||||
|
|
||||||
is(elementRuleEditor.rule.textProps.length, 2, "Created a new text property.");
|
|
||||||
is(elementRuleEditor.propertyList.children.length, 2, "Created a property editor.");
|
|
||||||
is(editor, inplaceEditor(textProp.editor.valueSpan), "Editing the value span now.");
|
|
||||||
|
|
||||||
info("Entering a property value");
|
|
||||||
editor.input.value = "red";
|
|
||||||
|
|
||||||
info("Escaping out of the field");
|
|
||||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
|
||||||
|
|
||||||
info("Checking that the previous field is focused");
|
|
||||||
let focusedElement = inplaceEditor(elementRuleEditor.rule.textProps[0].editor.valueSpan).input;
|
|
||||||
is(focusedElement, focusedElement.ownerDocument.activeElement, "Correct element has focus");
|
|
||||||
|
|
||||||
let onModifications = elementRuleEditor.rule._applyingModifications;
|
|
||||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
|
||||||
yield onModifications;
|
|
||||||
|
|
||||||
is(elementRuleEditor.rule.textProps.length, 1, "Removed the new text property.");
|
|
||||||
is(elementRuleEditor.propertyList.children.length, 1, "Removed the property editor.");
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test cancelling the addition of a new property in the rule-view
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html;charset=utf-8,browser_ruleview_ui.js");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
let style = "" +
|
|
||||||
"#testid {" +
|
|
||||||
" background-color: blue;" +
|
|
||||||
"}" +
|
|
||||||
".testclass, .unmatched {" +
|
|
||||||
" background-color: green;" +
|
|
||||||
"}";
|
|
||||||
let styleNode = addStyle(content.document, style);
|
|
||||||
content.document.body.innerHTML = "<div id='testid' class='testclass'>Styled Node</div>" +
|
|
||||||
"<div id='testid2'>Styled Node</div>";
|
|
||||||
|
|
||||||
yield testCancelNew(inspector, view);
|
|
||||||
yield testCancelNewOnEscape(inspector, view);
|
|
||||||
yield inspector.once("inspector-updated");
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCancelNew(inspector, ruleView) {
|
|
||||||
// Start at the beginning: start to add a rule to the element's style
|
|
||||||
// declaration, but leave it empty.
|
|
||||||
|
|
||||||
let elementRuleEditor = ruleView.element.children[0]._ruleEditor;
|
|
||||||
let editor = yield focusEditableField(elementRuleEditor.closeBrace);
|
|
||||||
|
|
||||||
is(inplaceEditor(elementRuleEditor.newPropSpan), editor,
|
|
||||||
"Property editor is focused");
|
|
||||||
|
|
||||||
let onBlur = once(editor.input, "blur");
|
|
||||||
editor.input.blur();
|
|
||||||
yield onBlur;
|
|
||||||
|
|
||||||
ok(!elementRuleEditor.rule._applyingModifications, "Shouldn't have an outstanding modification request after a cancel.");
|
|
||||||
is(elementRuleEditor.rule.textProps.length, 0, "Should have canceled creating a new text property.");
|
|
||||||
ok(!elementRuleEditor.propertyList.hasChildNodes(), "Should not have any properties.");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testCancelNewOnEscape(inspector, ruleView) {
|
|
||||||
// Start at the beginning: start to add a rule to the element's style
|
|
||||||
// declaration, add some text, then press escape.
|
|
||||||
|
|
||||||
let elementRuleEditor = ruleView.element.children[0]._ruleEditor;
|
|
||||||
let editor = yield focusEditableField(elementRuleEditor.closeBrace);
|
|
||||||
|
|
||||||
is(inplaceEditor(elementRuleEditor.newPropSpan), editor, "Next focused editor should be the new property editor.");
|
|
||||||
for (let ch of "background") {
|
|
||||||
EventUtils.sendChar(ch, ruleView.doc.defaultView);
|
|
||||||
}
|
|
||||||
|
|
||||||
let onBlur = once(editor.input, "blur");
|
|
||||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
|
||||||
yield onBlur;
|
|
||||||
|
|
||||||
ok(!elementRuleEditor.rule._applyingModifications, "Shouldn't have an outstanding modification request after a cancel.");
|
|
||||||
is(elementRuleEditor.rule.textProps.length, 0, "Should have canceled creating a new text property.");
|
|
||||||
ok(!elementRuleEditor.propertyList.hasChildNodes(), "Should not have any properties.");
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Testing various inplace-editor behaviors in the rule-view
|
|
||||||
// FIXME: To be split in several test files, and some of the inplace-editor
|
|
||||||
// focus/blur/commit/revert stuff should be factored out in head.js
|
|
||||||
|
|
||||||
let TEST_URL = 'url("' + TEST_URL_ROOT + 'doc_test_image.png")';
|
|
||||||
let PAGE_CONTENT = [
|
|
||||||
'<style type="text/css">',
|
|
||||||
' #testid {',
|
|
||||||
' background-color: blue;',
|
|
||||||
' }',
|
|
||||||
' .testclass {',
|
|
||||||
' background-color: green;',
|
|
||||||
' }',
|
|
||||||
'</style>',
|
|
||||||
'<div id="testid" class="testclass">Styled Node</div>'
|
|
||||||
].join("\n");
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,test rule view user changes");
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
|
||||||
|
|
||||||
info("Opening the rule-view");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Selecting the test element");
|
|
||||||
yield selectNode("#testid", inspector);
|
|
||||||
|
|
||||||
yield testCreateNew(view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCreateNew(view) {
|
|
||||||
info("Test creating a new property");
|
|
||||||
|
|
||||||
let elementRuleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
|
|
||||||
info("Focusing a new property name in the rule-view");
|
|
||||||
let editor = yield focusEditableField(elementRuleEditor.closeBrace);
|
|
||||||
|
|
||||||
is(inplaceEditor(elementRuleEditor.newPropSpan), editor, "The new property editor got focused");
|
|
||||||
let input = editor.input;
|
|
||||||
|
|
||||||
info("Entering background-color in the property name editor");
|
|
||||||
input.value = "background-color";
|
|
||||||
|
|
||||||
info("Pressing return to commit and focus the new value field");
|
|
||||||
let onValueFocus = once(elementRuleEditor.element, "focus", true);
|
|
||||||
let onModifications = elementRuleEditor.rule._applyingModifications;
|
|
||||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
|
||||||
yield onValueFocus;
|
|
||||||
yield onModifications;
|
|
||||||
|
|
||||||
// Getting the new value editor after focus
|
|
||||||
editor = inplaceEditor(view.doc.activeElement);
|
|
||||||
let textProp = elementRuleEditor.rule.textProps[0];
|
|
||||||
|
|
||||||
is(elementRuleEditor.rule.textProps.length, 1, "Created a new text property.");
|
|
||||||
is(elementRuleEditor.propertyList.children.length, 1, "Created a property editor.");
|
|
||||||
is(editor, inplaceEditor(textProp.editor.valueSpan), "Editing the value span now.");
|
|
||||||
|
|
||||||
info("Entering a value and bluring the field to expect a rule change");
|
|
||||||
editor.input.value = "#XYZ";
|
|
||||||
let onBlur = once(editor.input, "blur");
|
|
||||||
let onModifications = elementRuleEditor.rule._applyingModifications;
|
|
||||||
editor.input.blur();
|
|
||||||
yield onBlur;
|
|
||||||
yield onModifications;
|
|
||||||
|
|
||||||
is(textProp.value, "#XYZ", "Text prop should have been changed.");
|
|
||||||
is(textProp.editor.isValid(), false, "#XYZ should not be a valid entry");
|
|
||||||
}
|
|
|
@ -1,70 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test all sorts of additions and updates of properties in the rule-view
|
|
||||||
// FIXME: TO BE SPLIT IN *MANY* SMALLER TESTS
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html;charset=utf-8,browser_ruleview_ui.js");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
let style = "" +
|
|
||||||
"#testid {" +
|
|
||||||
" background-color: blue;" +
|
|
||||||
"}" +
|
|
||||||
".testclass, .unmatched {" +
|
|
||||||
" background-color: green;" +
|
|
||||||
"}";
|
|
||||||
let styleNode = addStyle(content.document, style);
|
|
||||||
content.document.body.innerHTML = "<div id='testid' class='testclass'>Styled Node</div>" +
|
|
||||||
"<div id='testid2'>Styled Node</div>";
|
|
||||||
|
|
||||||
yield testCreateNew(inspector, view);
|
|
||||||
yield inspector.once("inspector-updated");
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCreateNew(inspector, ruleView) {
|
|
||||||
// Create a new property.
|
|
||||||
let elementRuleEditor = ruleView.element.children[0]._ruleEditor;
|
|
||||||
let editor = yield focusEditableField(elementRuleEditor.closeBrace);
|
|
||||||
|
|
||||||
is(inplaceEditor(elementRuleEditor.newPropSpan), editor,
|
|
||||||
"Next focused editor should be the new property editor.");
|
|
||||||
|
|
||||||
let input = editor.input;
|
|
||||||
|
|
||||||
ok(input.selectionStart === 0 && input.selectionEnd === input.value.length,
|
|
||||||
"Editor contents are selected.");
|
|
||||||
|
|
||||||
// Try clicking on the editor's input again, shouldn't cause trouble (see bug 761665).
|
|
||||||
EventUtils.synthesizeMouse(input, 1, 1, {}, ruleView.doc.defaultView);
|
|
||||||
input.select();
|
|
||||||
|
|
||||||
info("Entering the property name");
|
|
||||||
input.value = "background-color";
|
|
||||||
|
|
||||||
info("Pressing RETURN and waiting for the value field focus");
|
|
||||||
let onFocus = once(elementRuleEditor.element, "focus", true);
|
|
||||||
EventUtils.sendKey("return", ruleView.doc.defaultView);
|
|
||||||
yield onFocus;
|
|
||||||
yield elementRuleEditor.rule._applyingModifications;
|
|
||||||
|
|
||||||
editor = inplaceEditor(ruleView.doc.activeElement);
|
|
||||||
|
|
||||||
is(elementRuleEditor.rule.textProps.length, 1, "Should have created a new text property.");
|
|
||||||
is(elementRuleEditor.propertyList.children.length, 1, "Should have created a property editor.");
|
|
||||||
let textProp = elementRuleEditor.rule.textProps[0];
|
|
||||||
is(editor, inplaceEditor(textProp.editor.valueSpan), "Should be editing the value span now.");
|
|
||||||
|
|
||||||
editor.input.value = "purple";
|
|
||||||
let onBlur = once(editor.input, "blur");
|
|
||||||
editor.input.blur();
|
|
||||||
yield onBlur;
|
|
||||||
yield elementRuleEditor.rule._applyingModifications;
|
|
||||||
|
|
||||||
is(textProp.value, "purple", "Text prop should have been changed.");
|
|
||||||
}
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Test original value is correctly displayed when ESCaping out of the
|
||||||
|
// inplace editor in the style inspector.
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let ruleWindow;
|
||||||
|
let ruleView;
|
||||||
|
let inspector;
|
||||||
|
let originalValue = "#00F";
|
||||||
|
|
||||||
|
// Test data format
|
||||||
|
// {
|
||||||
|
// value: what char sequence to type,
|
||||||
|
// commitKey: what key to type to "commit" the change,
|
||||||
|
// modifiers: commitKey modifiers,
|
||||||
|
// expected: what value is expected as a result
|
||||||
|
// }
|
||||||
|
let testData = [
|
||||||
|
{value: "red", commitKey: "VK_ESCAPE", modifiers: {}, expected: originalValue},
|
||||||
|
{value: "red", commitKey: "VK_RETURN", modifiers: {}, expected: "#F00"},
|
||||||
|
{value: "invalid", commitKey: "VK_RETURN", modifiers: {}, expected: "invalid"},
|
||||||
|
{value: "blue", commitKey: "VK_TAB", modifiers: {shiftKey: true}, expected: "blue"}
|
||||||
|
];
|
||||||
|
|
||||||
|
function startTests()
|
||||||
|
{
|
||||||
|
let style = '' +
|
||||||
|
'#testid {' +
|
||||||
|
' color: ' + originalValue + ';' +
|
||||||
|
'}';
|
||||||
|
|
||||||
|
let styleNode = addStyle(doc, style);
|
||||||
|
doc.body.innerHTML = '<div id="testid">Styled Node</div>';
|
||||||
|
let testElement = doc.getElementById("testid");
|
||||||
|
|
||||||
|
openRuleView((aInspector, aRuleView) => {
|
||||||
|
inspector = aInspector;
|
||||||
|
ruleView = aRuleView;
|
||||||
|
ruleWindow = aRuleView.doc.defaultView;
|
||||||
|
inspector.selection.setNode(testElement);
|
||||||
|
inspector.once("inspector-updated", () => runTestData(0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTestData(index)
|
||||||
|
{
|
||||||
|
if (index === testData.length) {
|
||||||
|
finishTest();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let idRuleEditor = ruleView.element.children[1]._ruleEditor;
|
||||||
|
let propEditor = idRuleEditor.rule.textProps[0].editor;
|
||||||
|
waitForEditorFocus(propEditor.element, function(aEditor) {
|
||||||
|
is(inplaceEditor(propEditor.valueSpan), aEditor, "Focused editor should be the value span.");
|
||||||
|
|
||||||
|
for (let ch of testData[index].value) {
|
||||||
|
EventUtils.sendChar(ch, ruleWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to wait for the change to be finished before the next test starts
|
||||||
|
// if not cancelling the change (the previous modification can change which
|
||||||
|
// color format is shown).
|
||||||
|
if (testData[index].commitKey === "VK_ESCAPE") {
|
||||||
|
EventUtils.synthesizeKey(testData[index].commitKey, testData[index].modifiers);
|
||||||
|
is(propEditor.valueSpan.textContent, testData[index].expected, "Value is same as expected: " + testData[index].expected);
|
||||||
|
runTestData(index + 1);
|
||||||
|
} else {
|
||||||
|
ruleView.element.addEventListener("CssRuleViewChanged", function nextTest() {
|
||||||
|
ruleView.element.removeEventListener("CssRuleViewChanged", nextTest);
|
||||||
|
is(propEditor.valueSpan.textContent, testData[index].expected, "Value is same as expected: " + testData[index].expected);
|
||||||
|
runTestData(index + 1);
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeKey(testData[index].commitKey, testData[index].modifiers);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
EventUtils.synthesizeMouse(propEditor.valueSpan, 1, 1, {}, ruleWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishTest()
|
||||||
|
{
|
||||||
|
inspector = ruleWindow = ruleView = null;
|
||||||
|
doc = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function escapePropertyChange_load(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, escapePropertyChange_load, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(startTests, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,test escaping property change reverts back to original value";
|
||||||
|
}
|
|
@ -17,44 +17,58 @@ const PAGE_CONTENT = [
|
||||||
'Testing the color picker tooltip!'
|
'Testing the color picker tooltip!'
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function test() {
|
||||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
let value = getRuleViewProperty(view, "body", "background").valueSpan;
|
content.location = "data:text/html,rule view color picker tooltip test";
|
||||||
let swatch = value.querySelector(".ruleview-colorswatch");
|
}
|
||||||
let url = value.querySelector(".theme-link");
|
|
||||||
yield testImageTooltipAfterColorChange(swatch, url, view);
|
function createDocument() {
|
||||||
});
|
content.document.body.innerHTML = PAGE_CONTENT;
|
||||||
|
|
||||||
function* testImageTooltipAfterColorChange(swatch, url, ruleView) {
|
openRuleView((inspector, ruleView) => {
|
||||||
info("First, verify that the image preview tooltip works");
|
inspector.once("inspector-updated", () => {
|
||||||
let anchor = yield isHoverTooltipTarget(ruleView.previewTooltip, url);
|
let value = getRuleViewProperty("background", ruleView).valueSpan;
|
||||||
ok(anchor, "The image preview tooltip is shown on the url span");
|
let swatch = value.querySelector(".ruleview-colorswatch");
|
||||||
is(anchor, url, "The anchor returned by the showOnHover callback is correct");
|
let url = value.querySelector(".theme-link");
|
||||||
|
testImageTooltipAfterColorChange(swatch, url, ruleView);
|
||||||
info("Open the color picker tooltip and change the color");
|
});
|
||||||
let picker = ruleView.colorPicker;
|
});
|
||||||
let onShown = picker.tooltip.once("shown");
|
}
|
||||||
swatch.click();
|
|
||||||
yield onShown;
|
function testImageTooltipAfterColorChange(swatch, url, ruleView) {
|
||||||
yield simulateColorPickerChange(picker, [0, 0, 0, 1], {
|
Task.spawn(function*() {
|
||||||
element: content.document.body,
|
info("First, verify that the image preview tooltip works");
|
||||||
name: "backgroundImage",
|
let anchor = yield isHoverTooltipTarget(ruleView.previewTooltip, url);
|
||||||
value: 'url("chrome://global/skin/icons/warning-64.png"), linear-gradient(rgb(0, 0, 0), rgb(255, 0, 102) 400px)'
|
ok(anchor, "The image preview tooltip is shown on the url span");
|
||||||
});
|
is(anchor, url, "The anchor returned by the showOnHover callback is correct");
|
||||||
|
|
||||||
let spectrum = yield picker.spectrum;
|
info("Open the color picker tooltip and change the color");
|
||||||
let onHidden = picker.tooltip.once("hidden");
|
let picker = ruleView.colorPicker;
|
||||||
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
|
let onShown = picker.tooltip.once("shown");
|
||||||
yield onHidden;
|
swatch.click();
|
||||||
|
yield onShown;
|
||||||
info("Verify again that the image preview tooltip works");
|
yield simulateColorChange(picker, [0, 0, 0, 1], {
|
||||||
// After a color change, the property is re-populated, we need to get the new
|
element: content.document.body,
|
||||||
// dom node
|
name: "backgroundImage",
|
||||||
url = getRuleViewProperty(ruleView, "body", "background").valueSpan.querySelector(".theme-link");
|
value: 'url("chrome://global/skin/icons/warning-64.png"), linear-gradient(rgb(0, 0, 0), rgb(255, 0, 102) 400px)'
|
||||||
let anchor = yield isHoverTooltipTarget(ruleView.previewTooltip, url);
|
});
|
||||||
ok(anchor, "The image preview tooltip is shown on the url span");
|
|
||||||
is(anchor, url, "The anchor returned by the showOnHover callback is correct");
|
let spectrum = yield picker.spectrum;
|
||||||
|
let onHidden = picker.tooltip.once("hidden");
|
||||||
|
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
|
||||||
|
yield onHidden;
|
||||||
|
|
||||||
|
info("Verify again that the image preview tooltip works");
|
||||||
|
// After a color change, the property is re-populated, we need to get the new
|
||||||
|
// dom node
|
||||||
|
url = getRuleViewProperty("background", ruleView).valueSpan.querySelector(".theme-link");
|
||||||
|
let anchor = yield isHoverTooltipTarget(ruleView.previewTooltip, url);
|
||||||
|
ok(anchor, "The image preview tooltip is shown on the url span");
|
||||||
|
is(anchor, url, "The anchor returned by the showOnHover callback is correct");
|
||||||
|
}).then(finish);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,43 +19,58 @@ const PAGE_CONTENT = [
|
||||||
'Testing the color picker tooltip!'
|
'Testing the color picker tooltip!'
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function test() {
|
||||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||||
yield testColorChangeIsntRevertedWhenOtherTooltipIsShown(view);
|
waitForFocus(createDocument, content);
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
function* testColorChangeIsntRevertedWhenOtherTooltipIsShown(ruleView) {
|
content.location = "data:text/html,rule view color picker tooltip test";
|
||||||
let swatch = getRuleViewProperty(ruleView, "body", "background").valueSpan
|
}
|
||||||
.querySelector(".ruleview-colorswatch");
|
|
||||||
|
function createDocument() {
|
||||||
info("Open the color picker tooltip and change the color");
|
content.document.body.innerHTML = PAGE_CONTENT;
|
||||||
let picker = ruleView.colorPicker;
|
|
||||||
let onShown = picker.tooltip.once("shown");
|
openRuleView((inspector, ruleView) => {
|
||||||
swatch.click();
|
inspector.once("inspector-updated", () => {
|
||||||
yield onShown;
|
testColorChangeIsntRevertedWhenOtherTooltipIsShown(ruleView);
|
||||||
|
});
|
||||||
yield simulateColorPickerChange(picker, [0, 0, 0, 1], {
|
});
|
||||||
element: content.document.body,
|
}
|
||||||
name: "backgroundColor",
|
|
||||||
value: "rgb(0, 0, 0)"
|
function testColorChangeIsntRevertedWhenOtherTooltipIsShown(ruleView) {
|
||||||
});
|
Task.spawn(function*() {
|
||||||
let spectrum = yield picker.spectrum;
|
let swatch = getRuleViewProperty("background", ruleView).valueSpan
|
||||||
let onHidden = picker.tooltip.once("hidden");
|
.querySelector(".ruleview-colorswatch");
|
||||||
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
|
|
||||||
yield onHidden;
|
info("Open the color picker tooltip and change the color");
|
||||||
|
let picker = ruleView.colorPicker;
|
||||||
info("Open the image preview tooltip");
|
let onShown = picker.tooltip.once("shown");
|
||||||
let value = getRuleViewProperty(ruleView, "body", "background").valueSpan;
|
swatch.click();
|
||||||
let url = value.querySelector(".theme-link");
|
yield onShown;
|
||||||
let onShown = ruleView.previewTooltip.once("shown");
|
|
||||||
let anchor = yield isHoverTooltipTarget(ruleView.previewTooltip, url);
|
yield simulateColorChange(picker, [0, 0, 0, 1], {
|
||||||
ruleView.previewTooltip.show(anchor);
|
element: content.document.body,
|
||||||
yield onShown;
|
name: "backgroundColor",
|
||||||
|
value: "rgb(0, 0, 0)"
|
||||||
info("Image tooltip is shown, verify that the swatch is still correct");
|
});
|
||||||
let swatch = value.querySelector(".ruleview-colorswatch");
|
let spectrum = yield picker.spectrum;
|
||||||
is(swatch.style.backgroundColor, "rgb(0, 0, 0)", "The swatch's color is correct");
|
let onHidden = picker.tooltip.once("hidden");
|
||||||
is(swatch.nextSibling.textContent, "#000", "The color name is correct");
|
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
|
||||||
|
yield onHidden;
|
||||||
|
|
||||||
|
info("Open the image preview tooltip");
|
||||||
|
let value = getRuleViewProperty("background", ruleView).valueSpan;
|
||||||
|
let url = value.querySelector(".theme-link");
|
||||||
|
let onShown = ruleView.previewTooltip.once("shown");
|
||||||
|
let anchor = yield isHoverTooltipTarget(ruleView.previewTooltip, url);
|
||||||
|
ruleView.previewTooltip.show(anchor);
|
||||||
|
yield onShown;
|
||||||
|
|
||||||
|
info("Image tooltip is shown, verify that the swatch is still correct");
|
||||||
|
let swatch = value.querySelector(".ruleview-colorswatch");
|
||||||
|
is(swatch.style.backgroundColor, "rgb(0, 0, 0)", "The swatch's color is correct");
|
||||||
|
is(swatch.nextSibling.textContent, "#000", "The color name is correct");
|
||||||
|
}).then(finish);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
// Test that color pickers appear when clicking on color swatches
|
// Test that color pickers appear when clicking on color swatches
|
||||||
|
|
||||||
|
let ruleView, swatches;
|
||||||
|
|
||||||
const PAGE_CONTENT = [
|
const PAGE_CONTENT = [
|
||||||
'<style type="text/css">',
|
'<style type="text/css">',
|
||||||
' body {',
|
' body {',
|
||||||
|
@ -18,37 +20,58 @@ const PAGE_CONTENT = [
|
||||||
'Testing the color picker tooltip!'
|
'Testing the color picker tooltip!'
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function test() {
|
||||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,rule view color picker tooltip test";
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDocument() {
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
content.document.body.innerHTML = PAGE_CONTENT;
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
let cSwatch = getRuleViewProperty(view, "body", "color").valueSpan
|
openRuleView((inspector, view) => {
|
||||||
.querySelector(".ruleview-colorswatch");
|
ruleView = view;
|
||||||
let bgSwatch = getRuleViewProperty(view, "body", "background-color").valueSpan
|
inspector.once("inspector-updated", () => {
|
||||||
.querySelector(".ruleview-colorswatch");
|
let cSwatch = getRuleViewProperty("color", ruleView).valueSpan
|
||||||
let bSwatch = getRuleViewProperty(view, "body", "border").valueSpan
|
.querySelector(".ruleview-colorswatch");
|
||||||
.querySelector(".ruleview-colorswatch");
|
let bgSwatch = getRuleViewProperty("background-color", ruleView).valueSpan
|
||||||
|
.querySelector(".ruleview-colorswatch");
|
||||||
|
let bSwatch = getRuleViewProperty("border", ruleView).valueSpan
|
||||||
|
.querySelector(".ruleview-colorswatch");
|
||||||
|
swatches = [cSwatch, bgSwatch, bSwatch];
|
||||||
|
|
||||||
for (let swatch of [cSwatch, bgSwatch, bSwatch]) {
|
testColorPickerAppearsOnColorSwatchClick();
|
||||||
info("Testing that the colorpicker appears colorswatch click");
|
});
|
||||||
yield testColorPickerAppearsOnColorSwatchClick(view, swatch);
|
});
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
function* testColorPickerAppearsOnColorSwatchClick(view, swatch) {
|
|
||||||
let cPicker = view.colorPicker;
|
|
||||||
ok(cPicker, "The rule-view has the expected colorPicker property");
|
|
||||||
|
|
||||||
|
function testColorPickerAppearsOnColorSwatchClick() {
|
||||||
|
let cPicker = ruleView.colorPicker;
|
||||||
let cPickerPanel = cPicker.tooltip.panel;
|
let cPickerPanel = cPicker.tooltip.panel;
|
||||||
ok(cPickerPanel, "The XUL panel for the color picker exists");
|
ok(cPickerPanel, "The XUL panel for the color picker exists");
|
||||||
|
|
||||||
let onShown = cPicker.tooltip.once("shown");
|
function clickOnSwatch(index, cb) {
|
||||||
swatch.click();
|
if (index === swatches.length) {
|
||||||
yield onShown;
|
return cb();
|
||||||
|
}
|
||||||
|
|
||||||
ok(true, "The color picker was shown on click of the color swatch");
|
let swatch = swatches[index];
|
||||||
ok(!inplaceEditor(swatch.parentNode),
|
cPicker.tooltip.once("shown", () => {
|
||||||
"The inplace editor wasn't shown as a result of the color swatch click");
|
ok(true, "The color picker was shown on click of the color swatch");
|
||||||
cPicker.hide();
|
ok(!inplaceEditor(swatch.parentNode),
|
||||||
|
"The inplace editor wasn't shown as a result of the color swatch click");
|
||||||
|
cPicker.hide();
|
||||||
|
clickOnSwatch(index + 1, cb);
|
||||||
|
});
|
||||||
|
swatch.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
clickOnSwatch(0, () => {
|
||||||
|
ruleView = swatches = null;
|
||||||
|
finish();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,45 +15,59 @@ const PAGE_CONTENT = [
|
||||||
'Testing the color picker tooltip!'
|
'Testing the color picker tooltip!'
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function test() {
|
||||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
let swatch = getRuleViewProperty(view, "body" , "border").valueSpan
|
content.location = "data:text/html,rule view color picker tooltip test";
|
||||||
.querySelector(".ruleview-colorswatch");
|
}
|
||||||
yield testPressingEnterCommitsChanges(swatch, view);
|
|
||||||
});
|
function createDocument() {
|
||||||
|
content.document.body.innerHTML = PAGE_CONTENT;
|
||||||
function* testPressingEnterCommitsChanges(swatch, ruleView) {
|
|
||||||
let cPicker = ruleView.colorPicker;
|
openRuleView((inspector, ruleView) => {
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
let onShown = cPicker.tooltip.once("shown");
|
let swatch = getRuleViewProperty("border", ruleView).valueSpan
|
||||||
swatch.click();
|
.querySelector(".ruleview-colorswatch");
|
||||||
yield onShown;
|
testPressingEnterCommitsChanges(swatch, ruleView);
|
||||||
|
});
|
||||||
yield simulateColorPickerChange(cPicker, [0, 255, 0, .5], {
|
});
|
||||||
element: content.document.body,
|
}
|
||||||
name: "borderLeftColor",
|
|
||||||
value: "rgba(0, 255, 0, 0.5)"
|
function testPressingEnterCommitsChanges(swatch, ruleView) {
|
||||||
});
|
Task.spawn(function*() {
|
||||||
|
let cPicker = ruleView.colorPicker;
|
||||||
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
|
|
||||||
"The color swatch's background was updated");
|
let onShown = cPicker.tooltip.once("shown");
|
||||||
is(getRuleViewProperty(ruleView, "body", "border").valueSpan.textContent,
|
swatch.click();
|
||||||
"2em solid rgba(0, 255, 0, 0.5)",
|
yield onShown;
|
||||||
"The text of the border css property was updated");;
|
|
||||||
|
yield simulateColorChange(cPicker, [0, 255, 0, .5], {
|
||||||
let spectrum = yield cPicker.spectrum;
|
element: content.document.body,
|
||||||
let onHidden = cPicker.tooltip.once("hidden");
|
name: "borderLeftColor",
|
||||||
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
|
value: "rgba(0, 255, 0, 0.5)"
|
||||||
yield onHidden;
|
});
|
||||||
|
|
||||||
is(content.getComputedStyle(content.document.body).borderLeftColor,
|
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
|
||||||
"rgba(0, 255, 0, 0.5)", "The element's border was kept after RETURN");
|
"The color swatch's background was updated");
|
||||||
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
|
is(getRuleViewProperty("border", ruleView).valueSpan.textContent,
|
||||||
"The color swatch's background was kept after RETURN");
|
"2em solid rgba(0, 255, 0, 0.5)",
|
||||||
is(getRuleViewProperty(ruleView, "body", "border").valueSpan.textContent,
|
"The text of the border css property was updated");;
|
||||||
"2em solid rgba(0, 255, 0, 0.5)",
|
|
||||||
"The text of the border css property was kept after RETURN");
|
let spectrum = yield cPicker.spectrum;
|
||||||
|
let onHidden = cPicker.tooltip.once("hidden");
|
||||||
|
EventUtils.sendKey("RETURN", spectrum.element.ownerDocument.defaultView);
|
||||||
|
yield onHidden;
|
||||||
|
|
||||||
|
is(content.getComputedStyle(content.document.body).borderLeftColor,
|
||||||
|
"rgba(0, 255, 0, 0.5)", "The element's border was kept after RETURN");
|
||||||
|
is(swatch.style.backgroundColor, "rgba(0, 255, 0, 0.5)",
|
||||||
|
"The color swatch's background was kept after RETURN");
|
||||||
|
is(getRuleViewProperty("border", ruleView).valueSpan.textContent,
|
||||||
|
"2em solid rgba(0, 255, 0, 0.5)",
|
||||||
|
"The text of the border css property was kept after RETURN");
|
||||||
|
}).then(finish);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that changing a color in a gradient css declaration using the tooltip
|
|
||||||
// color picker works
|
|
||||||
|
|
||||||
const PAGE_CONTENT = [
|
|
||||||
'<style type="text/css">',
|
|
||||||
' body {',
|
|
||||||
' background-image: linear-gradient(to left, #f06 25%, #333 95%, #000 100%);',
|
|
||||||
' }',
|
|
||||||
'</style>',
|
|
||||||
'Updating a gradient declaration with the color picker tooltip'
|
|
||||||
].join("\n");
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
|
||||||
|
|
||||||
info("Opening the rule-view")
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Testing that the colors in gradient properties are parsed correctly");
|
|
||||||
testColorParsing(view);
|
|
||||||
|
|
||||||
info("Testing that changing one of the colors of a gradient property works");
|
|
||||||
yield testPickingNewColor(view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function testColorParsing(view) {
|
|
||||||
let ruleEl = getRuleViewProperty(view, "body", "background-image");
|
|
||||||
ok(ruleEl, "The background-image gradient declaration was found");
|
|
||||||
|
|
||||||
let swatchEls = ruleEl.valueSpan.querySelectorAll(".ruleview-colorswatch");
|
|
||||||
ok(swatchEls, "The color swatch elements were found");
|
|
||||||
is(swatchEls.length, 3, "There are 3 color swatches");
|
|
||||||
|
|
||||||
let colorEls = ruleEl.valueSpan.querySelectorAll(".ruleview-color");
|
|
||||||
ok(colorEls, "The color elements were found");
|
|
||||||
is(colorEls.length, 3, "There are 3 color values");
|
|
||||||
|
|
||||||
let colors = ["#F06", "#333", "#000"];
|
|
||||||
for (let i = 0; i < colors.length; i ++) {
|
|
||||||
is(colorEls[i].textContent, colors[i], "The right color value was found");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testPickingNewColor(view) {
|
|
||||||
// Grab the first color swatch and color in the gradient
|
|
||||||
let ruleEl = getRuleViewProperty(view, "body", "background-image");
|
|
||||||
let swatchEl = ruleEl.valueSpan.querySelector(".ruleview-colorswatch");
|
|
||||||
let colorEl = ruleEl.valueSpan.querySelector(".ruleview-color");
|
|
||||||
|
|
||||||
info("Getting the color picker tooltip and clicking on the swatch to show it");
|
|
||||||
let cPicker = view.colorPicker;
|
|
||||||
let onShown = cPicker.tooltip.once("shown");
|
|
||||||
swatchEl.click();
|
|
||||||
yield onShown;
|
|
||||||
|
|
||||||
yield simulateColorPickerChange(cPicker, [1, 1, 1, 1]);
|
|
||||||
|
|
||||||
is(swatchEl.style.backgroundColor, "rgb(1, 1, 1)",
|
|
||||||
"The color swatch's background was updated");
|
|
||||||
is(colorEl.textContent, "rgba(1, 1, 1, 1)",
|
|
||||||
"The color text was updated");
|
|
||||||
is(content.getComputedStyle(content.document.body).backgroundImage,
|
|
||||||
"linear-gradient(to left, rgb(255, 0, 102) 25%, rgb(51, 51, 51) 95%, rgb(0, 0, 0) 100%)",
|
|
||||||
"The gradient has been updated correctly");
|
|
||||||
|
|
||||||
cPicker.hide();
|
|
||||||
}
|
|
|
@ -7,6 +7,8 @@
|
||||||
// Test that the color picker tooltip hides when an image or transform
|
// Test that the color picker tooltip hides when an image or transform
|
||||||
// tooltip appears
|
// tooltip appears
|
||||||
|
|
||||||
|
let ruleView, swatches;
|
||||||
|
|
||||||
const PAGE_CONTENT = [
|
const PAGE_CONTENT = [
|
||||||
'<style type="text/css">',
|
'<style type="text/css">',
|
||||||
' body {',
|
' body {',
|
||||||
|
@ -20,49 +22,75 @@ const PAGE_CONTENT = [
|
||||||
'Testing the color picker tooltip!'
|
'Testing the color picker tooltip!'
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function test() {
|
||||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,rule view color picker tooltip test";
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDocument() {
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
content.document.body.innerHTML = PAGE_CONTENT;
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
let swatch = getRuleViewProperty(view, "body", "color").valueSpan
|
openRuleView((inspector, view) => {
|
||||||
.querySelector(".ruleview-colorswatch");
|
ruleView = view;
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
let cSwatch = getRuleViewProperty("color", ruleView).valueSpan
|
||||||
|
.querySelector(".ruleview-colorswatch");
|
||||||
|
let bgSwatch = getRuleViewProperty("background-color", ruleView).valueSpan
|
||||||
|
.querySelector(".ruleview-colorswatch");
|
||||||
|
let bSwatch = getRuleViewProperty("border", ruleView).valueSpan
|
||||||
|
.querySelector(".ruleview-colorswatch");
|
||||||
|
swatches = [cSwatch, bgSwatch, bSwatch];
|
||||||
|
|
||||||
yield testColorPickerHidesWhenImageTooltipAppears(view, swatch);
|
testColorPickerHidesWhenImageTooltipAppears();
|
||||||
yield testColorPickerHidesWhenTransformTooltipAppears(view, swatch);
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function* testColorPickerHidesWhenImageTooltipAppears(view, swatch) {
|
|
||||||
let bgImageSpan = getRuleViewProperty(view, "body", "background-image").valueSpan;
|
|
||||||
let uriSpan = bgImageSpan.querySelector(".theme-link");
|
|
||||||
let tooltip = view.colorPicker.tooltip;
|
|
||||||
|
|
||||||
info("Showing the color picker tooltip by clicking on the color swatch");
|
|
||||||
let onShown = tooltip.once("shown");
|
|
||||||
swatch.click();
|
|
||||||
yield onShown;
|
|
||||||
|
|
||||||
info("Now showing the image preview tooltip to hide the color picker");
|
|
||||||
let onHidden = tooltip.once("hidden");
|
|
||||||
yield assertHoverTooltipOn(view.previewTooltip, uriSpan);
|
|
||||||
yield onHidden;
|
|
||||||
|
|
||||||
ok(true, "The color picker closed when the image preview tooltip appeared");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function* testColorPickerHidesWhenTransformTooltipAppears(view, swatch) {
|
function testColorPickerHidesWhenImageTooltipAppears() {
|
||||||
let transformSpan = getRuleViewProperty(view, "body", "transform").valueSpan;
|
Task.spawn(function*() {
|
||||||
let tooltip = view.colorPicker.tooltip;
|
let swatch = swatches[0];
|
||||||
|
let bgImageSpan = getRuleViewProperty("background-image", ruleView).valueSpan;
|
||||||
|
let uriSpan = bgImageSpan.querySelector(".theme-link");
|
||||||
|
let tooltip = ruleView.colorPicker.tooltip;
|
||||||
|
|
||||||
info("Showing the color picker tooltip by clicking on the color swatch");
|
info("Showing the color picker tooltip by clicking on the color swatch");
|
||||||
let onShown = tooltip.once("shown");
|
let onShown = tooltip.once("shown");
|
||||||
swatch.click();
|
swatch.click();
|
||||||
yield onShown;
|
yield onShown;
|
||||||
|
|
||||||
info("Now showing the transform preview tooltip to hide the color picker");
|
info("Now showing the image preview tooltip to hide the color picker");
|
||||||
let onHidden = tooltip.once("hidden");
|
let onHidden = tooltip.once("hidden");
|
||||||
yield assertHoverTooltipOn(view.previewTooltip, transformSpan);
|
yield assertTooltipShownOn(ruleView.previewTooltip, uriSpan);
|
||||||
yield onHidden;
|
yield onHidden;
|
||||||
|
|
||||||
ok(true, "The color picker closed when the transform preview tooltip appeared");
|
ok(true, "The color picker closed when the image preview tooltip appeared");
|
||||||
|
}).then(testColorPickerHidesWhenTransformTooltipAppears);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testColorPickerHidesWhenTransformTooltipAppears() {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
let swatch = swatches[0];
|
||||||
|
let transformSpan = getRuleViewProperty("transform", ruleView).valueSpan;
|
||||||
|
let tooltip = ruleView.colorPicker.tooltip;
|
||||||
|
|
||||||
|
info("Showing the color picker tooltip by clicking on the color swatch");
|
||||||
|
let onShown = tooltip.once("shown");
|
||||||
|
swatch.click();
|
||||||
|
yield onShown;
|
||||||
|
|
||||||
|
info("Now showing the transform preview tooltip to hide the color picker");
|
||||||
|
let onHidden = tooltip.once("hidden");
|
||||||
|
yield assertTooltipShownOn(ruleView.previewTooltip, transformSpan);
|
||||||
|
yield onHidden;
|
||||||
|
|
||||||
|
ok(true, "The color picker closed when the transform preview tooltip appeared");
|
||||||
|
}).then(() => {
|
||||||
|
swatches = ruleView = null;
|
||||||
|
finish();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,103 +24,123 @@ const PAGE_CONTENT = [
|
||||||
'<p>Testing the color picker tooltip!</p>'
|
'<p>Testing the color picker tooltip!</p>'
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function test() {
|
||||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,rule view color picker tooltip test";
|
||||||
|
}
|
||||||
|
|
||||||
|
function createDocument() {
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
content.document.body.innerHTML = PAGE_CONTENT;
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
yield testSimpleMultipleColorChanges(inspector, view);
|
openRuleView((inspector, ruleView) => {
|
||||||
yield testComplexMultipleColorChanges(inspector, view);
|
inspector.once("inspector-updated", () => {
|
||||||
yield testOverriddenMultipleColorChanges(inspector, view);
|
testSimpleMultipleColorChanges(inspector, ruleView);
|
||||||
});
|
|
||||||
|
|
||||||
function* testSimpleMultipleColorChanges(inspector, ruleView) {
|
|
||||||
yield selectNode("p", inspector);
|
|
||||||
|
|
||||||
info("Getting the <p> tag's color property");
|
|
||||||
let swatch = getRuleViewProperty(ruleView, "p", "color").valueSpan
|
|
||||||
.querySelector(".ruleview-colorswatch");
|
|
||||||
|
|
||||||
info("Opening the color picker");
|
|
||||||
let picker = ruleView.colorPicker;
|
|
||||||
let onShown = picker.tooltip.once("shown");
|
|
||||||
swatch.click();
|
|
||||||
yield onShown;
|
|
||||||
|
|
||||||
info("Changing the color several times");
|
|
||||||
let colors = [
|
|
||||||
{rgba: [0, 0, 0, 1], computed: "rgb(0, 0, 0)"},
|
|
||||||
{rgba: [100, 100, 100, 1], computed: "rgb(100, 100, 100)"},
|
|
||||||
{rgba: [200, 200, 200, 1], computed: "rgb(200, 200, 200)"}
|
|
||||||
];
|
|
||||||
for (let {rgba, computed} of colors) {
|
|
||||||
yield simulateColorPickerChange(picker, rgba, {
|
|
||||||
element: content.document.querySelector("p"),
|
|
||||||
name: "color",
|
|
||||||
value: computed
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function* testComplexMultipleColorChanges(inspector, ruleView) {
|
function testSimpleMultipleColorChanges(inspector, ruleView) {
|
||||||
yield selectNode("body", inspector);
|
Task.spawn(function*() {
|
||||||
|
yield selectNode("p", inspector);
|
||||||
|
|
||||||
info("Getting the <body> tag's color property");
|
info("Getting the <p> tag's color property");
|
||||||
let swatch = getRuleViewProperty(ruleView, "body", "background").valueSpan
|
let swatch = getRuleViewSelectorProperty("p", "color", ruleView).valueSpan
|
||||||
.querySelector(".ruleview-colorswatch");
|
.querySelector(".ruleview-colorswatch");
|
||||||
|
|
||||||
info("Opening the color picker");
|
info("Opening the color picker");
|
||||||
let picker = ruleView.colorPicker;
|
let picker = ruleView.colorPicker;
|
||||||
let onShown = picker.tooltip.once("shown");
|
let onShown = picker.tooltip.once("shown");
|
||||||
swatch.click();
|
swatch.click();
|
||||||
yield onShown;
|
yield onShown;
|
||||||
|
|
||||||
info("Changing the color several times");
|
info("Changing the color several times");
|
||||||
let colors = [
|
let colors = [
|
||||||
{rgba: [0, 0, 0, 1], computed: "rgb(0, 0, 0)"},
|
{rgba: [0, 0, 0, 1], computed: "rgb(0, 0, 0)"},
|
||||||
{rgba: [100, 100, 100, 1], computed: "rgb(100, 100, 100)"},
|
{rgba: [100, 100, 100, 1], computed: "rgb(100, 100, 100)"},
|
||||||
{rgba: [200, 200, 200, 1], computed: "rgb(200, 200, 200)"}
|
{rgba: [200, 200, 200, 1], computed: "rgb(200, 200, 200)"}
|
||||||
];
|
];
|
||||||
for (let {rgba, computed} of colors) {
|
for (let {rgba, computed} of colors) {
|
||||||
yield simulateColorPickerChange(picker, rgba, {
|
yield simulateColorChange(picker, rgba, {
|
||||||
element: content.document.body,
|
element: content.document.querySelector("p"),
|
||||||
name: "backgroundColor",
|
name: "color",
|
||||||
value: computed
|
value: computed
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}).then(() => {
|
||||||
info("Closing the color picker");
|
testComplexMultipleColorChanges(inspector, ruleView);
|
||||||
let onHidden = picker.tooltip.once("hidden");
|
});
|
||||||
picker.tooltip.hide();
|
|
||||||
yield onHidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function* testOverriddenMultipleColorChanges(inspector, ruleView) {
|
function testComplexMultipleColorChanges(inspector, ruleView) {
|
||||||
yield selectNode("p", inspector);
|
Task.spawn(function*() {
|
||||||
|
yield selectNode("body", inspector);
|
||||||
|
|
||||||
info("Getting the <body> tag's color property");
|
info("Getting the <body> tag's color property");
|
||||||
let swatch = getRuleViewProperty(ruleView, "body", "color").valueSpan
|
let swatch = getRuleViewSelectorProperty("body", "background", ruleView).valueSpan
|
||||||
.querySelector(".ruleview-colorswatch");
|
.querySelector(".ruleview-colorswatch");
|
||||||
|
|
||||||
info("Opening the color picker");
|
info("Opening the color picker");
|
||||||
let picker = ruleView.colorPicker;
|
let picker = ruleView.colorPicker;
|
||||||
let onShown = picker.tooltip.once("shown");
|
let onShown = picker.tooltip.once("shown");
|
||||||
swatch.click();
|
swatch.click();
|
||||||
yield onShown;
|
yield onShown;
|
||||||
|
|
||||||
info("Changing the color several times");
|
info("Changing the color several times");
|
||||||
let colors = [
|
let colors = [
|
||||||
{rgba: [0, 0, 0, 1], computed: "rgb(0, 0, 0)"},
|
{rgba: [0, 0, 0, 1], computed: "rgb(0, 0, 0)"},
|
||||||
{rgba: [100, 100, 100, 1], computed: "rgb(100, 100, 100)"},
|
{rgba: [100, 100, 100, 1], computed: "rgb(100, 100, 100)"},
|
||||||
{rgba: [200, 200, 200, 1], computed: "rgb(200, 200, 200)"}
|
{rgba: [200, 200, 200, 1], computed: "rgb(200, 200, 200)"}
|
||||||
];
|
];
|
||||||
for (let {rgba, computed} of colors) {
|
for (let {rgba, computed} of colors) {
|
||||||
yield simulateColorPickerChange(picker, rgba, {
|
yield simulateColorChange(picker, rgba, {
|
||||||
element: content.document.body,
|
element: content.document.body,
|
||||||
name: "color",
|
name: "backgroundColor",
|
||||||
value: computed
|
value: computed
|
||||||
});
|
});
|
||||||
is(content.getComputedStyle(content.document.querySelector("p")).color,
|
}
|
||||||
"rgb(200, 200, 200)", "The color of the P tag is still correct");
|
|
||||||
}
|
info("Closing the color picker");
|
||||||
|
let onHidden = picker.tooltip.once("hidden");
|
||||||
|
picker.tooltip.hide();
|
||||||
|
yield onHidden;
|
||||||
|
}).then(() => {
|
||||||
|
testOverriddenMultipleColorChanges(inspector, ruleView);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testOverriddenMultipleColorChanges(inspector, ruleView) {
|
||||||
|
Task.spawn(function*() {
|
||||||
|
yield selectNode("p", inspector);
|
||||||
|
|
||||||
|
info("Getting the <body> tag's color property");
|
||||||
|
let swatch = getRuleViewSelectorProperty("body", "color", ruleView).valueSpan
|
||||||
|
.querySelector(".ruleview-colorswatch");
|
||||||
|
|
||||||
|
info("Opening the color picker");
|
||||||
|
let picker = ruleView.colorPicker;
|
||||||
|
let onShown = picker.tooltip.once("shown");
|
||||||
|
swatch.click();
|
||||||
|
yield onShown;
|
||||||
|
|
||||||
|
info("Changing the color several times");
|
||||||
|
let colors = [
|
||||||
|
{rgba: [0, 0, 0, 1], computed: "rgb(0, 0, 0)"},
|
||||||
|
{rgba: [100, 100, 100, 1], computed: "rgb(100, 100, 100)"},
|
||||||
|
{rgba: [200, 200, 200, 1], computed: "rgb(200, 200, 200)"}
|
||||||
|
];
|
||||||
|
for (let {rgba, computed} of colors) {
|
||||||
|
yield simulateColorChange(picker, rgba, {
|
||||||
|
element: content.document.body,
|
||||||
|
name: "color",
|
||||||
|
value: computed
|
||||||
|
});
|
||||||
|
is(content.getComputedStyle(content.document.querySelector("p")).color,
|
||||||
|
"rgb(200, 200, 200)", "The color of the P tag is still correct");
|
||||||
|
}
|
||||||
|
}).then(finish);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,42 +15,59 @@ const PAGE_CONTENT = [
|
||||||
'Testing the color picker tooltip!'
|
'Testing the color picker tooltip!'
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function test() {
|
||||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
let swatch = getRuleViewProperty(view, "body", "background-color").valueSpan
|
content.location = "data:text/html,rule view color picker tooltip test";
|
||||||
.querySelector(".ruleview-colorswatch");
|
}
|
||||||
yield testPressingEscapeRevertsChanges(swatch, view);
|
|
||||||
});
|
function createDocument() {
|
||||||
|
content.document.body.innerHTML = PAGE_CONTENT;
|
||||||
function* testPressingEscapeRevertsChanges(swatch, ruleView) {
|
|
||||||
let cPicker = ruleView.colorPicker;
|
openRuleView((inspector, ruleView) => {
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
let onShown = cPicker.tooltip.once("shown");
|
let swatch = getRuleViewProperty("background-color", ruleView).valueSpan
|
||||||
swatch.click();
|
.querySelector(".ruleview-colorswatch");
|
||||||
yield onShown;
|
testPressingEscapeRevertsChanges(swatch, ruleView);
|
||||||
|
});
|
||||||
yield simulateColorPickerChange(cPicker, [0, 0, 0, 1], {
|
});
|
||||||
element: content.document.body,
|
}
|
||||||
name: "backgroundColor",
|
|
||||||
value: "rgb(0, 0, 0)"
|
function testPressingEscapeRevertsChanges(swatch, ruleView) {
|
||||||
});
|
Task.spawn(function*() {
|
||||||
|
let cPicker = ruleView.colorPicker;
|
||||||
is(swatch.style.backgroundColor, "rgb(0, 0, 0)",
|
|
||||||
"The color swatch's background was updated");
|
let onShown = cPicker.tooltip.once("shown");
|
||||||
is(getRuleViewProperty(ruleView, "body", "background-color").valueSpan.textContent,
|
swatch.click();
|
||||||
"rgba(0, 0, 0, 1)", "The text of the background-color css property was updated");
|
yield onShown;
|
||||||
|
|
||||||
let spectrum = yield cPicker.spectrum;
|
yield simulateColorChange(cPicker, [0, 0, 0, 1], {
|
||||||
|
element: content.document.body,
|
||||||
// ESC out of the color picker
|
name: "backgroundColor",
|
||||||
let onHidden = cPicker.tooltip.once("hidden");
|
value: "rgb(0, 0, 0)"
|
||||||
EventUtils.sendKey("ESCAPE", spectrum.element.ownerDocument.defaultView);
|
});
|
||||||
yield onHidden;
|
|
||||||
|
is(swatch.style.backgroundColor, "rgb(0, 0, 0)",
|
||||||
yield waitForSuccess(() => {
|
"The color swatch's background was updated");
|
||||||
return content.getComputedStyle(content.document.body).backgroundColor === "rgb(237, 237, 237)";
|
is(getRuleViewProperty("background-color", ruleView).valueSpan.textContent,
|
||||||
}, "The element's background-color was reverted");
|
"rgba(0, 0, 0, 1)", "The text of the background-color css property was updated");
|
||||||
|
|
||||||
|
let spectrum = yield cPicker.spectrum;
|
||||||
|
|
||||||
|
// ESC out of the color picker
|
||||||
|
let onHidden = cPicker.tooltip.once("hidden");
|
||||||
|
EventUtils.sendKey("ESCAPE", spectrum.element.ownerDocument.defaultView);
|
||||||
|
yield onHidden;
|
||||||
|
|
||||||
|
yield waitForSuccess({
|
||||||
|
validatorFn: () => {
|
||||||
|
return content.getComputedStyle(content.document.body).backgroundColor === "rgb(237, 237, 237)";
|
||||||
|
},
|
||||||
|
name: "The element's background-color was reverted"
|
||||||
|
});
|
||||||
|
}).then(finish);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
// Test that color swatches are displayed next to colors in the rule-view
|
// Test that color swatches are displayed next to colors in the rule-view
|
||||||
|
|
||||||
|
let ruleView;
|
||||||
|
|
||||||
const PAGE_CONTENT = [
|
const PAGE_CONTENT = [
|
||||||
'<style type="text/css">',
|
'<style type="text/css">',
|
||||||
' body {',
|
' body {',
|
||||||
|
@ -14,42 +16,42 @@ const PAGE_CONTENT = [
|
||||||
' background-image: url(chrome://global/skin/icons/warning-64.png);',
|
' background-image: url(chrome://global/skin/icons/warning-64.png);',
|
||||||
' border: 2em solid rgba(120, 120, 120, .5);',
|
' border: 2em solid rgba(120, 120, 120, .5);',
|
||||||
' }',
|
' }',
|
||||||
' * {',
|
|
||||||
' color: blue;',
|
|
||||||
' box-shadow: inset 0 0 2px 20px red, inset 0 0 2px 40px blue;',
|
|
||||||
' }',
|
|
||||||
'</style>',
|
'</style>',
|
||||||
'Testing the color picker tooltip!'
|
'Testing the color picker tooltip!'
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
|
||||||
// Tests that properties in the rule-view contain color swatches
|
function test() {
|
||||||
// Each entry in the test array should contain:
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
// {
|
gBrowser.selectedBrowser.addEventListener("load", function load(evt) {
|
||||||
// selector: the rule-view selector to look for the property in
|
gBrowser.selectedBrowser.removeEventListener("load", load, true);
|
||||||
// propertyName: the property to test
|
waitForFocus(createDocument, content);
|
||||||
// nb: the number of color swatches this property should have
|
}, true);
|
||||||
// }
|
|
||||||
const TESTS = [
|
|
||||||
{selector: "body", propertyName: "color", nb: 1},
|
|
||||||
{selector: "body", propertyName: "background-color", nb: 1},
|
|
||||||
{selector: "body", propertyName: "border", nb: 1},
|
|
||||||
{selector: "*", propertyName: "color", nb: 1},
|
|
||||||
{selector: "*", propertyName: "box-shadow", nb: 2},
|
|
||||||
];
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
content.location = "data:text/html,rule view color picker tooltip test";
|
||||||
yield addTab("data:text/html,rule view color picker tooltip test");
|
}
|
||||||
|
|
||||||
|
function createDocument() {
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
content.document.body.innerHTML = PAGE_CONTENT;
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
for (let {selector, propertyName, nb} of TESTS) {
|
openRuleView((inspector, view) => {
|
||||||
info("Looking for color swatches in property " + propertyName +
|
ruleView = view;
|
||||||
" in selector " + selector);
|
inspector.once("inspector-updated", testColorSwatchesAreDisplayed);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let prop = getRuleViewProperty(view, selector, propertyName).valueSpan;
|
function testColorSwatchesAreDisplayed() {
|
||||||
let swatches = prop.querySelectorAll(".ruleview-colorswatch");
|
let cSwatch = getRuleViewProperty("color", ruleView).valueSpan
|
||||||
|
.querySelector(".ruleview-colorswatch");
|
||||||
|
ok(cSwatch, "Color swatch is displayed for the color property");
|
||||||
|
|
||||||
ok(swatches.length, "Swatches found in the property");
|
let bgSwatch = getRuleViewProperty("background-color", ruleView).valueSpan
|
||||||
is(swatches.length, nb, "Correct number of swatches found in the property");
|
.querySelector(".ruleview-colorswatch");
|
||||||
}
|
ok(bgSwatch, "Color swatch is displayed for the bg-color property");
|
||||||
});
|
|
||||||
|
let bSwatch = getRuleViewProperty("border", ruleView).valueSpan
|
||||||
|
.querySelector(".ruleview-colorswatch");
|
||||||
|
ok(bSwatch, "Color swatch is displayed for the border property");
|
||||||
|
|
||||||
|
ruleView = null;
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that CSS property names are autocompleted and cycled correctly when
|
|
||||||
// editing an existing property in the rule view
|
|
||||||
|
|
||||||
const MAX_ENTRIES = 10;
|
|
||||||
|
|
||||||
// format :
|
|
||||||
// [
|
|
||||||
// what key to press,
|
|
||||||
// expected input box value after keypress,
|
|
||||||
// selectedIndex of the popup,
|
|
||||||
// total items in the popup
|
|
||||||
// ]
|
|
||||||
let testData = [
|
|
||||||
["VK_RIGHT", "border", -1, 0],
|
|
||||||
["-","border-bottom", 0, 10],
|
|
||||||
["b","border-bottom", 0, 6],
|
|
||||||
["VK_BACK_SPACE", "border-b", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "border-", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "border", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "borde", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "bord", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "bor", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "bo", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "b", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "", -1, 0],
|
|
||||||
["d", "direction", 0, 3],
|
|
||||||
["VK_DOWN", "display", 1, 3],
|
|
||||||
["VK_DOWN", "dominant-baseline", 2, 3],
|
|
||||||
["VK_DOWN", "direction", 0, 3],
|
|
||||||
["VK_DOWN", "display", 1, 3],
|
|
||||||
["VK_UP", "direction", 0, 3],
|
|
||||||
["VK_UP", "dominant-baseline", 2, 3],
|
|
||||||
["VK_UP", "display", 1, 3],
|
|
||||||
["VK_BACK_SPACE", "d", -1, 0],
|
|
||||||
["i", "direction", 0, 2],
|
|
||||||
["s", "display", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "dis", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "di", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "d", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "", -1, 0],
|
|
||||||
["f", "fill", 0, MAX_ENTRIES],
|
|
||||||
["i", "fill", 0, 4],
|
|
||||||
["VK_LEFT", "fill", -1, 0],
|
|
||||||
["VK_LEFT", "fill", -1, 0],
|
|
||||||
["i", "fiill", -1, 0],
|
|
||||||
["VK_ESCAPE", null, -1, 0],
|
|
||||||
];
|
|
||||||
|
|
||||||
let TEST_URL = "data:text/html,<h1 style='border: 1px solid red'>Filename" +
|
|
||||||
": browser_bug893965_css_property_completion_existing_property.js</h1>";
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab(TEST_URL);
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("h1", inspector);
|
|
||||||
|
|
||||||
info("Focusing the css property editable field");
|
|
||||||
let propertyName = view.doc.querySelectorAll(".ruleview-propertyname")[0];
|
|
||||||
let editor = yield focusEditableField(propertyName);
|
|
||||||
|
|
||||||
info("Starting to test for css property completion");
|
|
||||||
for (let i = 0; i < testData.length; i ++) {
|
|
||||||
yield testCompletion(testData[i], editor, view);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCompletion([key, completion, index, total], editor, view) {
|
|
||||||
info("Pressing key " + key);
|
|
||||||
info("Expecting " + completion + ", " + index + ", " + total);
|
|
||||||
|
|
||||||
let onSuggest;
|
|
||||||
|
|
||||||
if (/(left|right|back_space|escape)/ig.test(key)) {
|
|
||||||
info("Adding event listener for left|right|back_space|escape keys");
|
|
||||||
onSuggest = once(editor.input, "keypress");
|
|
||||||
} else {
|
|
||||||
info("Waiting for after-suggest event on the editor");
|
|
||||||
onSuggest = editor.once("after-suggest");
|
|
||||||
}
|
|
||||||
|
|
||||||
info("Synthesizing key " + key);
|
|
||||||
EventUtils.synthesizeKey(key, {}, view.doc.defaultView);
|
|
||||||
|
|
||||||
yield onSuggest;
|
|
||||||
yield wait(1); // Equivalent of executeSoon
|
|
||||||
|
|
||||||
info("Checking the state");
|
|
||||||
if (completion != null) {
|
|
||||||
is(editor.input.value, completion, "Correct value is autocompleted");
|
|
||||||
}
|
|
||||||
if (total == 0) {
|
|
||||||
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
|
|
||||||
} else {
|
|
||||||
ok(editor.popup._panel.state == "open" || editor.popup._panel.state == "showing", "Popup is open");
|
|
||||||
is(editor.popup.getItems().length, total, "Number of suggestions match");
|
|
||||||
is(editor.popup.selectedIndex, index, "Correct item is selected");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,101 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that CSS property names and values are autocompleted and cycled correctly
|
|
||||||
// when editing existing properties in the rule view
|
|
||||||
|
|
||||||
// format :
|
|
||||||
// [
|
|
||||||
// what key to press,
|
|
||||||
// modifers,
|
|
||||||
// expected input box value after keypress,
|
|
||||||
// selectedIndex of the popup,
|
|
||||||
// total items in the popup
|
|
||||||
// ]
|
|
||||||
let testData = [
|
|
||||||
["b", {}, "beige", 0, 8],
|
|
||||||
["l", {}, "black", 0, 4],
|
|
||||||
["VK_DOWN", {}, "blanchedalmond", 1, 4],
|
|
||||||
["VK_DOWN", {}, "blue", 2, 4],
|
|
||||||
["VK_RIGHT", {}, "blue", -1, 0],
|
|
||||||
[" ", {}, "blue !important", 0, 10],
|
|
||||||
["!", {}, "blue !important", 0, 0],
|
|
||||||
["VK_BACK_SPACE", {}, "blue !", -1, 0],
|
|
||||||
["VK_BACK_SPACE", {}, "blue ", -1, 0],
|
|
||||||
["VK_BACK_SPACE", {}, "blue", -1, 0],
|
|
||||||
["VK_TAB", {shiftKey: true}, "color", -1, 0],
|
|
||||||
["VK_BACK_SPACE", {}, "", -1, 0],
|
|
||||||
["d", {}, "direction", 0, 3],
|
|
||||||
["i", {}, "direction", 0, 2],
|
|
||||||
["s", {}, "display", -1, 0],
|
|
||||||
["VK_TAB", {}, "blue", -1, 0],
|
|
||||||
["n", {}, "none", -1, 0],
|
|
||||||
["VK_RETURN", {}, null, -1, 0]
|
|
||||||
];
|
|
||||||
|
|
||||||
let TEST_URL = "data:text/html,<h1 style='color: red'>Filename: " +
|
|
||||||
"browser_bug894376_css_value_completion_existing_property_value_pair.js</h1>";
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab(TEST_URL);
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("h1", inspector);
|
|
||||||
|
|
||||||
info("Focusing the css property editable value");
|
|
||||||
let value = view.doc.querySelectorAll(".ruleview-propertyvalue")[0];
|
|
||||||
let editor = yield focusEditableField(value);
|
|
||||||
|
|
||||||
info("Starting to test for css property completion");
|
|
||||||
for (let i = 0; i < testData.length; i ++) {
|
|
||||||
// Re-define the editor at each iteration, because the focus may have moved
|
|
||||||
// from property to value and back
|
|
||||||
editor = inplaceEditor(view.doc.activeElement);
|
|
||||||
yield testCompletion(testData[i], editor, view);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCompletion([key, modifiers, completion, index, total], editor, view) {
|
|
||||||
info("Pressing key " + key);
|
|
||||||
info("Expecting " + completion + ", " + index + ", " + total);
|
|
||||||
|
|
||||||
let onKeyPress;
|
|
||||||
|
|
||||||
if (/tab/ig.test(key)) {
|
|
||||||
info("Waiting for the new property or value editor to get focused");
|
|
||||||
let brace = view.doc.querySelector(".ruleview-ruleclose");
|
|
||||||
onKeyPress = once(brace.parentNode, "focus", true);
|
|
||||||
} else if (/(right|return|back_space)/ig.test(key)) {
|
|
||||||
info("Adding event listener for right|return|back_space keys");
|
|
||||||
onKeyPress = once(editor.input, "keypress");
|
|
||||||
} else {
|
|
||||||
info("Waiting for after-suggest event on the editor");
|
|
||||||
onKeyPress = editor.once("after-suggest");
|
|
||||||
}
|
|
||||||
|
|
||||||
info("Synthesizing key " + key + ", modifiers: " + Object.keys(modifiers));
|
|
||||||
EventUtils.synthesizeKey(key, modifiers, view.doc.defaultView);
|
|
||||||
|
|
||||||
yield onKeyPress;
|
|
||||||
yield wait(1); // Equivalent of executeSoon
|
|
||||||
|
|
||||||
// The key might have been a TAB or shift-TAB, in which case the editor will
|
|
||||||
// be a new one
|
|
||||||
editor = inplaceEditor(view.doc.activeElement);
|
|
||||||
|
|
||||||
info("Checking the state");
|
|
||||||
if (completion != null) {
|
|
||||||
is(editor.input.value, completion, "Correct value is autocompleted");
|
|
||||||
}
|
|
||||||
if (total == 0) {
|
|
||||||
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
|
|
||||||
} else {
|
|
||||||
ok(editor.popup._panel.state == "open" || editor.popup._panel.state == "showing", "Popup is open");
|
|
||||||
is(editor.popup.getItems().length, total, "Number of suggestions match");
|
|
||||||
is(editor.popup.selectedIndex, index, "Correct item is selected");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,91 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that CSS property names are autocompleted and cycled correctly when
|
|
||||||
// creating a new property in the ruleview
|
|
||||||
|
|
||||||
const MAX_ENTRIES = 10;
|
|
||||||
|
|
||||||
// format :
|
|
||||||
// [
|
|
||||||
// what key to press,
|
|
||||||
// expected input box value after keypress,
|
|
||||||
// selectedIndex of the popup,
|
|
||||||
// total items in the popup
|
|
||||||
// ]
|
|
||||||
let testData = [
|
|
||||||
["d", "direction", 0, 3],
|
|
||||||
["VK_DOWN", "display", 1, 3],
|
|
||||||
["VK_DOWN", "dominant-baseline", 2, 3],
|
|
||||||
["VK_DOWN", "direction", 0, 3],
|
|
||||||
["VK_DOWN", "display", 1, 3],
|
|
||||||
["VK_UP", "direction", 0, 3],
|
|
||||||
["VK_UP", "dominant-baseline", 2, 3],
|
|
||||||
["VK_UP", "display", 1, 3],
|
|
||||||
["VK_BACK_SPACE", "d", -1, 0],
|
|
||||||
["i", "direction", 0, 2],
|
|
||||||
["s", "display", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "dis", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "di", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "d", -1, 0],
|
|
||||||
["VK_BACK_SPACE", "", -1, 0],
|
|
||||||
["f", "fill", 0, MAX_ENTRIES],
|
|
||||||
["i", "fill", 0, 4],
|
|
||||||
["VK_ESCAPE", null, -1, 0],
|
|
||||||
];
|
|
||||||
|
|
||||||
let TEST_URL = "data:text/html,<h1 style='border: 1px solid red'>Filename:" +
|
|
||||||
"browser_bug893965_css_property_completion_new_property.js</h1>";
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab(TEST_URL);
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("h1", inspector);
|
|
||||||
|
|
||||||
info("Focusing the css property editable field");
|
|
||||||
let brace = view.doc.querySelector(".ruleview-ruleclose");
|
|
||||||
let editor = yield focusEditableField(brace);
|
|
||||||
|
|
||||||
info("Starting to test for css property completion");
|
|
||||||
for (let i = 0; i < testData.length; i ++) {
|
|
||||||
yield testCompletion(testData[i], editor, view);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCompletion([key, completion, index, total], editor, view) {
|
|
||||||
info("Pressing key " + key);
|
|
||||||
info("Expecting " + completion + ", " + index + ", " + total);
|
|
||||||
|
|
||||||
let onSuggest;
|
|
||||||
|
|
||||||
if (/(right|back_space|escape)/ig.test(key)) {
|
|
||||||
info("Adding event listener for right|back_space|escape keys");
|
|
||||||
onSuggest = once(editor.input, "keypress");
|
|
||||||
} else {
|
|
||||||
info("Waiting for after-suggest event on the editor");
|
|
||||||
onSuggest = editor.once("after-suggest");
|
|
||||||
}
|
|
||||||
|
|
||||||
info("Synthesizing key " + key);
|
|
||||||
EventUtils.synthesizeKey(key, {}, view.doc.defaultView);
|
|
||||||
|
|
||||||
yield onSuggest;
|
|
||||||
yield wait(1); // Equivalent of executeSoon
|
|
||||||
|
|
||||||
info("Checking the state");
|
|
||||||
if (completion != null) {
|
|
||||||
is(editor.input.value, completion, "Correct value is autocompleted");
|
|
||||||
}
|
|
||||||
if (total == 0) {
|
|
||||||
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
|
|
||||||
} else {
|
|
||||||
ok(editor.popup._panel.state == "open" || editor.popup._panel.state == "showing", "Popup is open");
|
|
||||||
is(editor.popup.getItems().length, total, "Number of suggestions match");
|
|
||||||
is(editor.popup.selectedIndex, index, "Correct item is selected");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,103 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that CSS property names and values are autocompleted and cycled correctly
|
|
||||||
// when editing new properties in the rule view
|
|
||||||
|
|
||||||
// format :
|
|
||||||
// [
|
|
||||||
// what key to press,
|
|
||||||
// modifers,
|
|
||||||
// expected input box value after keypress,
|
|
||||||
// selectedIndex of the popup,
|
|
||||||
// total items in the popup
|
|
||||||
// ]
|
|
||||||
let testData = [
|
|
||||||
["a", {accelKey: true, ctrlKey: true}, "", -1, 0],
|
|
||||||
["d", {}, "direction", 0, 3],
|
|
||||||
["VK_DOWN", {}, "display", 1, 3],
|
|
||||||
["VK_TAB", {}, "", -1, 10],
|
|
||||||
["VK_DOWN", {}, "-moz-box", 0, 10],
|
|
||||||
["n", {}, "none", -1, 0],
|
|
||||||
["VK_TAB", {shiftKey: true}, "display", -1, 0],
|
|
||||||
["VK_BACK_SPACE", {}, "", -1, 0],
|
|
||||||
["c", {}, "caption-side", 0, 10],
|
|
||||||
["o", {}, "color", 0, 6],
|
|
||||||
["VK_TAB", {}, "none", -1, 0],
|
|
||||||
["r", {}, "red", 0, 5],
|
|
||||||
["VK_DOWN", {}, "rgb", 1, 5],
|
|
||||||
["VK_DOWN", {}, "rgba", 2, 5],
|
|
||||||
["VK_DOWN", {}, "rosybrown", 3, 5],
|
|
||||||
["VK_DOWN", {}, "royalblue", 4, 5],
|
|
||||||
["VK_RIGHT", {}, "royalblue", -1, 0],
|
|
||||||
[" ", {}, "royalblue !important", 0, 10],
|
|
||||||
["!", {}, "royalblue !important", 0, 0],
|
|
||||||
["VK_ESCAPE", {}, null, -1, 0]
|
|
||||||
];
|
|
||||||
|
|
||||||
let TEST_URL = "data:text/html,<h1 style='border: 1px solid red'>Filename:"+
|
|
||||||
" browser_bug894376_css_value_completion_new_property_value_pair.js</h1>";
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab(TEST_URL);
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("h1", inspector);
|
|
||||||
|
|
||||||
info("Focusing a new css property editable property");
|
|
||||||
let brace = view.doc.querySelectorAll(".ruleview-ruleclose")[0];
|
|
||||||
let editor = yield focusEditableField(brace);
|
|
||||||
|
|
||||||
info("Starting to test for css property completion");
|
|
||||||
for (let i = 0; i < testData.length; i ++) {
|
|
||||||
// Re-define the editor at each iteration, because the focus may have moved
|
|
||||||
// from property to value and back
|
|
||||||
editor = inplaceEditor(view.doc.activeElement);
|
|
||||||
yield testCompletion(testData[i], editor, view);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCompletion([key, modifiers, completion, index, total], editor, view) {
|
|
||||||
info("Pressing key " + key);
|
|
||||||
info("Expecting " + completion + ", " + index + ", " + total);
|
|
||||||
|
|
||||||
let onKeyPress;
|
|
||||||
|
|
||||||
if (/tab/ig.test(key)) {
|
|
||||||
info("Waiting for the new property or value editor to get focused");
|
|
||||||
let brace = view.doc.querySelector(".ruleview-ruleclose");
|
|
||||||
onKeyPress = once(brace.parentNode, "focus", true);
|
|
||||||
} else if (/(right|back_space|escape|return)/ig.test(key) ||
|
|
||||||
(modifiers.accelKey || modifiers.ctrlKey)) {
|
|
||||||
info("Adding event listener for right|escape|back_space|return keys");
|
|
||||||
onKeyPress = once(editor.input, "keypress");
|
|
||||||
} else {
|
|
||||||
info("Waiting for after-suggest event on the editor");
|
|
||||||
onKeyPress = editor.once("after-suggest");
|
|
||||||
}
|
|
||||||
|
|
||||||
info("Synthesizing key " + key + ", modifiers: " + Object.keys(modifiers));
|
|
||||||
EventUtils.synthesizeKey(key, modifiers, view.doc.defaultView);
|
|
||||||
|
|
||||||
yield onKeyPress;
|
|
||||||
yield wait(1); // Equivalent of executeSoon
|
|
||||||
|
|
||||||
info("Checking the state");
|
|
||||||
if (completion != null) {
|
|
||||||
// The key might have been a TAB or shift-TAB, in which case the editor will
|
|
||||||
// be a new one
|
|
||||||
editor = inplaceEditor(view.doc.activeElement);
|
|
||||||
is(editor.input.value, completion, "Correct value is autocompleted");
|
|
||||||
}
|
|
||||||
if (total == 0) {
|
|
||||||
ok(!(editor.popup && editor.popup.isOpen), "Popup is closed");
|
|
||||||
} else {
|
|
||||||
ok(editor.popup._panel.state == "open" || editor.popup._panel.state == "showing", "Popup is open");
|
|
||||||
is(editor.popup.getItems().length, total, "Number of suggestions match");
|
|
||||||
is(editor.popup.selectedIndex, index, "Correct item is selected");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test the rule-view content
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html;charset=utf-8,browser_ruleview_ui.js");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
let style = "" +
|
|
||||||
"#testid {" +
|
|
||||||
" background-color: blue;" +
|
|
||||||
"}" +
|
|
||||||
".testclass, .unmatched {" +
|
|
||||||
" background-color: green;" +
|
|
||||||
"}";
|
|
||||||
let styleNode = addStyle(content.document, style);
|
|
||||||
content.document.body.innerHTML = "<div id='testid' class='testclass'>Styled Node</div>" +
|
|
||||||
"<div id='testid2'>Styled Node</div>";
|
|
||||||
|
|
||||||
yield testContentAfterNodeSelection(inspector, view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testContentAfterNodeSelection(inspector, ruleView) {
|
|
||||||
yield selectNode("#testid", inspector);
|
|
||||||
is(ruleView.element.querySelectorAll("#noResults").length, 0,
|
|
||||||
"After a highlight, no longer has a no-results element.");
|
|
||||||
|
|
||||||
yield clearCurrentNodeSelection(inspector)
|
|
||||||
is(ruleView.element.querySelectorAll("#noResults").length, 1,
|
|
||||||
"After highlighting null, has a no-results element again.");
|
|
||||||
|
|
||||||
yield selectNode("#testid", inspector);
|
|
||||||
let classEditor = ruleView.element.children[2]._ruleEditor;
|
|
||||||
is(classEditor.selectorText.querySelector(".ruleview-selector-matched").textContent,
|
|
||||||
".testclass", ".textclass should be matched.");
|
|
||||||
is(classEditor.selectorText.querySelector(".ruleview-selector-unmatched").textContent,
|
|
||||||
".unmatched", ".unmatched should not be matched.");
|
|
||||||
}
|
|
|
@ -2,19 +2,17 @@
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
"use strict";
|
let doc;
|
||||||
|
let inspector;
|
||||||
// Tests that properties can be selected and copied from the rule view
|
let win;
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "osString", function() {
|
XPCOMUtils.defineLazyGetter(this, "osString", function() {
|
||||||
return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
|
return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
|
||||||
});
|
});
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function createDocument()
|
||||||
yield addTab("data:text/html,<p>rule view context menu test</p>");
|
{
|
||||||
|
doc.body.innerHTML = '<style type="text/css"> ' +
|
||||||
info("Creating the test document");
|
|
||||||
content.document.body.innerHTML = '<style type="text/css"> ' +
|
|
||||||
'html { color: #000000; } ' +
|
'html { color: #000000; } ' +
|
||||||
'span { font-variant: small-caps; color: #000000; } ' +
|
'span { font-variant: small-caps; color: #000000; } ' +
|
||||||
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
|
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
|
||||||
|
@ -31,32 +29,44 @@ let test = asyncTest(function*() {
|
||||||
'<p id="closing">more text</p>\n' +
|
'<p id="closing">more text</p>\n' +
|
||||||
'<p>even more text</p>' +
|
'<p>even more text</p>' +
|
||||||
'</div>';
|
'</div>';
|
||||||
content.document.title = "Rule view context menu test";
|
doc.title = "Rule view context menu test";
|
||||||
|
|
||||||
info("Opening the computed view");
|
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||||
|
inspector = toolbox.getCurrentPanel();
|
||||||
|
inspector.sidebar.select("ruleview");
|
||||||
|
win = inspector.sidebar.getWindowForTab("ruleview");
|
||||||
|
highlightNode();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
info("Selecting the test node");
|
function highlightNode()
|
||||||
yield selectNode("div", inspector);
|
{
|
||||||
|
// Highlight a node.
|
||||||
|
let div = content.document.getElementsByTagName("div")[0];
|
||||||
|
|
||||||
yield checkCopySelection(view);
|
inspector.once("inspector-updated", function() {
|
||||||
yield checkSelectAll(view);
|
is(inspector.selection.node, div, "selection matches the div element");
|
||||||
});
|
executeSoon(checkCopySelection);
|
||||||
|
});
|
||||||
|
|
||||||
function checkCopySelection(view) {
|
inspector.selection.setNode(div);
|
||||||
info("Testing selection copy");
|
}
|
||||||
|
|
||||||
let contentDoc = view.doc;
|
function checkCopySelection()
|
||||||
|
{
|
||||||
|
let contentDoc = win.document;
|
||||||
let prop = contentDoc.querySelector(".ruleview-property");
|
let prop = contentDoc.querySelector(".ruleview-property");
|
||||||
let values = contentDoc.querySelectorAll(".ruleview-propertycontainer");
|
let values = contentDoc.querySelectorAll(".ruleview-propertycontainer");
|
||||||
|
|
||||||
let range = contentDoc.createRange();
|
let range = contentDoc.createRange();
|
||||||
range.setStart(prop, 0);
|
range.setStart(prop, 0);
|
||||||
range.setEnd(values[4], 2);
|
range.setEnd(values[4], 2);
|
||||||
let selection = view.doc.defaultView.getSelection().addRange(range);
|
|
||||||
|
let selection = win.getSelection();
|
||||||
|
selection.addRange(range);
|
||||||
|
|
||||||
info("Checking that _Copy() returns the correct clipboard value");
|
info("Checking that _Copy() returns the correct clipboard value");
|
||||||
|
|
||||||
let expectedPattern = " margin: 10em;[\\r\\n]+" +
|
let expectedPattern = " margin: 10em;[\\r\\n]+" +
|
||||||
" font-size: 14pt;[\\r\\n]+" +
|
" font-size: 14pt;[\\r\\n]+" +
|
||||||
" font-family: helvetica,sans-serif;[\\r\\n]+" +
|
" font-family: helvetica,sans-serif;[\\r\\n]+" +
|
||||||
|
@ -65,23 +75,26 @@ function checkCopySelection(view) {
|
||||||
"html {[\\r\\n]+" +
|
"html {[\\r\\n]+" +
|
||||||
" color: #000;[\\r\\n]*";
|
" color: #000;[\\r\\n]*";
|
||||||
|
|
||||||
return waitForClipboard(() => {
|
SimpleTest.waitForClipboard(function() {
|
||||||
fireCopyEvent(prop);
|
|
||||||
}, () => {
|
|
||||||
return checkClipboardData(expectedPattern);
|
return checkClipboardData(expectedPattern);
|
||||||
}).then(() => {}, () => {
|
},
|
||||||
failedClipboard(expectedPattern);
|
function() {
|
||||||
|
fireCopyEvent(prop);
|
||||||
|
},
|
||||||
|
checkSelectAll,
|
||||||
|
function() {
|
||||||
|
failedClipboard(expectedPattern, checkSelectAll);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSelectAll(view) {
|
function checkSelectAll()
|
||||||
info("Testing select-all copy");
|
{
|
||||||
|
let contentDoc = win.document;
|
||||||
let contentDoc = view.doc;
|
let _ruleView = ruleView();
|
||||||
let prop = contentDoc.querySelector(".ruleview-property");
|
let prop = contentDoc.querySelector(".ruleview-property");
|
||||||
|
|
||||||
info("Checking that _SelectAll() then copy returns the correct clipboard value");
|
info("Checking that _SelectAll() then copy returns the correct clipboard value");
|
||||||
view._onSelectAll();
|
_ruleView._onSelectAll();
|
||||||
let expectedPattern = "[\\r\\n]+" +
|
let expectedPattern = "[\\r\\n]+" +
|
||||||
"element {[\\r\\n]+" +
|
"element {[\\r\\n]+" +
|
||||||
" margin: 10em;[\\r\\n]+" +
|
" margin: 10em;[\\r\\n]+" +
|
||||||
|
@ -93,37 +106,65 @@ function checkSelectAll(view) {
|
||||||
" color: #000;[\\r\\n]+" +
|
" color: #000;[\\r\\n]+" +
|
||||||
"}[\\r\\n]*";
|
"}[\\r\\n]*";
|
||||||
|
|
||||||
return waitForClipboard(() => {
|
SimpleTest.waitForClipboard(function() {
|
||||||
fireCopyEvent(prop);
|
|
||||||
}, () => {
|
|
||||||
return checkClipboardData(expectedPattern);
|
return checkClipboardData(expectedPattern);
|
||||||
}).then(() => {}, () => {
|
},
|
||||||
failedClipboard(expectedPattern);
|
function() {
|
||||||
|
fireCopyEvent(prop);
|
||||||
|
},
|
||||||
|
finishup,
|
||||||
|
function() {
|
||||||
|
failedClipboard(expectedPattern, finishup);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkClipboardData(expectedPattern) {
|
function checkClipboardData(aExpectedPattern)
|
||||||
|
{
|
||||||
let actual = SpecialPowers.getClipboardData("text/unicode");
|
let actual = SpecialPowers.getClipboardData("text/unicode");
|
||||||
let expectedRegExp = new RegExp(expectedPattern, "g");
|
let expectedRegExp = new RegExp(aExpectedPattern, "g");
|
||||||
return expectedRegExp.test(actual);
|
return expectedRegExp.test(actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
function failedClipboard(expectedPattern) {
|
function failedClipboard(aExpectedPattern, aCallback)
|
||||||
|
{
|
||||||
// Format expected text for comparison
|
// Format expected text for comparison
|
||||||
let terminator = osString == "WINNT" ? "\r\n" : "\n";
|
let terminator = osString == "WINNT" ? "\r\n" : "\n";
|
||||||
expectedPattern = expectedPattern.replace(/\[\\r\\n\][+*]/g, terminator);
|
aExpectedPattern = aExpectedPattern.replace(/\[\\r\\n\][+*]/g, terminator);
|
||||||
expectedPattern = expectedPattern.replace(/\\\(/g, "(");
|
aExpectedPattern = aExpectedPattern.replace(/\\\(/g, "(");
|
||||||
expectedPattern = expectedPattern.replace(/\\\)/g, ")");
|
aExpectedPattern = aExpectedPattern.replace(/\\\)/g, ")");
|
||||||
|
|
||||||
let actual = SpecialPowers.getClipboardData("text/unicode");
|
let actual = SpecialPowers.getClipboardData("text/unicode");
|
||||||
|
|
||||||
// Trim the right hand side of our strings. This is because expectedPattern
|
// Trim the right hand side of our strings. This is because expectedPattern
|
||||||
// accounts for windows sometimes adding a newline to our copied data.
|
// accounts for windows sometimes adding a newline to our copied data.
|
||||||
expectedPattern = expectedPattern.trimRight();
|
aExpectedPattern = aExpectedPattern.trimRight();
|
||||||
actual = actual.trimRight();
|
actual = actual.trimRight();
|
||||||
|
|
||||||
dump("TEST-UNEXPECTED-FAIL | Clipboard text does not match expected ... " +
|
dump("TEST-UNEXPECTED-FAIL | Clipboard text does not match expected ... " +
|
||||||
"results (escaped for accurate comparison):\n");
|
"results (escaped for accurate comparison):\n");
|
||||||
info("Actual: " + escape(actual));
|
info("Actual: " + escape(actual));
|
||||||
info("Expected: " + escape(expectedPattern));
|
info("Expected: " + escape(aExpectedPattern));
|
||||||
|
aCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishup()
|
||||||
|
{
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
doc = inspector = win = null;
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
|
||||||
|
true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(createDocument, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,<p>rule view context menu test</p>";
|
||||||
}
|
}
|
|
@ -1,84 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test original value is correctly displayed when ESCaping out of the
|
|
||||||
// inplace editor in the style inspector.
|
|
||||||
|
|
||||||
const originalValue = "#00F";
|
|
||||||
|
|
||||||
// Test data format
|
|
||||||
// {
|
|
||||||
// value: what char sequence to type,
|
|
||||||
// commitKey: what key to type to "commit" the change,
|
|
||||||
// modifiers: commitKey modifiers,
|
|
||||||
// expected: what value is expected as a result
|
|
||||||
// }
|
|
||||||
const testData = [
|
|
||||||
{value: "red", commitKey: "VK_ESCAPE", modifiers: {}, expected: originalValue},
|
|
||||||
{value: "red", commitKey: "VK_RETURN", modifiers: {}, expected: "#F00"},
|
|
||||||
{value: "invalid", commitKey: "VK_RETURN", modifiers: {}, expected: "invalid"},
|
|
||||||
{value: "blue", commitKey: "VK_TAB", modifiers: {shiftKey: true}, expected: "blue"}
|
|
||||||
];
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,test escaping property change reverts back to original value");
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
createDocument();
|
|
||||||
|
|
||||||
info("Opening the rule view");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("#testid", inspector);
|
|
||||||
|
|
||||||
info("Iterating over the test data");
|
|
||||||
for (let data of testData) {
|
|
||||||
yield runTestData(view, data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function createDocument() {
|
|
||||||
let style = '' +
|
|
||||||
'#testid {' +
|
|
||||||
' color: ' + originalValue + ';' +
|
|
||||||
'}';
|
|
||||||
|
|
||||||
let node = content.document.createElement('style');
|
|
||||||
node.setAttribute("type", "text/css");
|
|
||||||
node.textContent = style;
|
|
||||||
content.document.getElementsByTagName("head")[0].appendChild(node);
|
|
||||||
|
|
||||||
content.document.body.innerHTML = '<div id="testid">Styled Node</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
function* runTestData(view, {value, commitKey, modifiers, expected}) {
|
|
||||||
let idRuleEditor = view.element.children[1]._ruleEditor;
|
|
||||||
let propEditor = idRuleEditor.rule.textProps[0].editor;
|
|
||||||
|
|
||||||
info("Focusing the inplace editor field");
|
|
||||||
let editor = yield focusEditableField(propEditor.valueSpan);
|
|
||||||
is(inplaceEditor(propEditor.valueSpan), editor, "Focused editor should be the value span.");
|
|
||||||
|
|
||||||
info("Entering test data " + value)
|
|
||||||
for (let ch of value) {
|
|
||||||
EventUtils.sendChar(ch, view.doc.defaultView);
|
|
||||||
}
|
|
||||||
|
|
||||||
info("Waiting for focus on the field");
|
|
||||||
let onBlur = once(editor.input, "blur");
|
|
||||||
|
|
||||||
info("Entering the commit key " + commitKey + " " + modifiers);
|
|
||||||
EventUtils.synthesizeKey(commitKey, modifiers);
|
|
||||||
yield onBlur;
|
|
||||||
|
|
||||||
if (commitKey === "VK_ESCAPE") {
|
|
||||||
is(propEditor.valueSpan.textContent, expected, "Value is as expected: " + expected);
|
|
||||||
} else {
|
|
||||||
yield once(view.element, "CssRuleViewChanged");
|
|
||||||
is(propEditor.valueSpan.textContent, expected, "Value is as expected: " + expected);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,176 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that increasing/decreasing values in rule view using
|
|
||||||
// arrow keys works correctly.
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,sample document for bug 722691");
|
|
||||||
createDocument();
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
yield selectNode("#test", inspector);
|
|
||||||
|
|
||||||
yield testMarginIncrements(view);
|
|
||||||
yield testVariousUnitIncrements(view);
|
|
||||||
yield testHexIncrements(view);
|
|
||||||
yield testRgbIncrements(view);
|
|
||||||
yield testShorthandIncrements(view);
|
|
||||||
yield testOddCases(view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function createDocument() {
|
|
||||||
content.document.body.innerHTML = '<div id="test" style="' +
|
|
||||||
'margin-top:0px;' +
|
|
||||||
'padding-top: 0px;' +
|
|
||||||
'color:#000000;' +
|
|
||||||
'background-color: #000000;" >'+
|
|
||||||
'</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testMarginIncrements(view) {
|
|
||||||
info("Testing keyboard increments on the margin property");
|
|
||||||
|
|
||||||
let idRuleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
let marginPropEditor = idRuleEditor.rule.textProps[0].editor;
|
|
||||||
|
|
||||||
yield runIncrementTest(marginPropEditor, view, {
|
|
||||||
1: {alt: true, start: "0px", end: "0.1px", selectAll: true},
|
|
||||||
2: {start: "0px", end: "1px", selectAll: true},
|
|
||||||
3: {shift: true, start: "0px", end: "10px", selectAll: true},
|
|
||||||
4: {down: true, alt: true, start: "0.1px", end: "0px", selectAll: true},
|
|
||||||
5: {down: true, start: "0px", end: "-1px", selectAll: true},
|
|
||||||
6: {down: true, shift: true, start: "0px", end: "-10px", selectAll: true},
|
|
||||||
7: {pageUp: true, shift: true, start: "0px", end: "100px", selectAll: true},
|
|
||||||
8: {pageDown: true, shift: true, start: "0px", end: "-100px", selectAll: true}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testVariousUnitIncrements(view) {
|
|
||||||
info("Testing keyboard increments on values with various units");
|
|
||||||
|
|
||||||
let idRuleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
let paddingPropEditor = idRuleEditor.rule.textProps[1].editor;
|
|
||||||
|
|
||||||
yield runIncrementTest(paddingPropEditor, view, {
|
|
||||||
1: {start: "0px", end: "1px", selectAll: true},
|
|
||||||
2: {start: "0pt", end: "1pt", selectAll: true},
|
|
||||||
3: {start: "0pc", end: "1pc", selectAll: true},
|
|
||||||
4: {start: "0em", end: "1em", selectAll: true},
|
|
||||||
5: {start: "0%", end: "1%", selectAll: true},
|
|
||||||
6: {start: "0in", end: "1in", selectAll: true},
|
|
||||||
7: {start: "0cm", end: "1cm", selectAll: true},
|
|
||||||
8: {start: "0mm", end: "1mm", selectAll: true},
|
|
||||||
9: {start: "0ex", end: "1ex", selectAll: true}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function* testHexIncrements(view) {
|
|
||||||
info("Testing keyboard increments with hex colors");
|
|
||||||
|
|
||||||
let idRuleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
let hexColorPropEditor = idRuleEditor.rule.textProps[2].editor;
|
|
||||||
|
|
||||||
yield runIncrementTest(hexColorPropEditor, view, {
|
|
||||||
1: {start: "#CCCCCC", end: "#CDCDCD", selectAll: true},
|
|
||||||
2: {shift: true, start: "#CCCCCC", end: "#DCDCDC", selectAll: true},
|
|
||||||
3: {start: "#CCCCCC", end: "#CDCCCC", selection: [1,3]},
|
|
||||||
4: {shift: true, start: "#CCCCCC", end: "#DCCCCC", selection: [1,3]},
|
|
||||||
5: {start: "#FFFFFF", end: "#FFFFFF", selectAll: true},
|
|
||||||
6: {down: true, shift: true, start: "#000000", end: "#000000", selectAll: true}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function* testRgbIncrements(view) {
|
|
||||||
info("Testing keyboard increments with rgb colors");
|
|
||||||
|
|
||||||
let idRuleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
let rgbColorPropEditor = idRuleEditor.rule.textProps[3].editor;
|
|
||||||
|
|
||||||
yield runIncrementTest(rgbColorPropEditor, view, {
|
|
||||||
1: {start: "rgb(0,0,0)", end: "rgb(0,1,0)", selection: [6,7]},
|
|
||||||
2: {shift: true, start: "rgb(0,0,0)", end: "rgb(0,10,0)", selection: [6,7]},
|
|
||||||
3: {start: "rgb(0,255,0)", end: "rgb(0,255,0)", selection: [6,9]},
|
|
||||||
4: {shift: true, start: "rgb(0,250,0)", end: "rgb(0,255,0)", selection: [6,9]},
|
|
||||||
5: {down: true, start: "rgb(0,0,0)", end: "rgb(0,0,0)", selection: [6,7]},
|
|
||||||
6: {down: true, shift: true, start: "rgb(0,5,0)", end: "rgb(0,0,0)", selection: [6,7]}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function* testShorthandIncrements(view) {
|
|
||||||
info("Testing keyboard increments within shorthand values");
|
|
||||||
|
|
||||||
let idRuleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
let paddingPropEditor = idRuleEditor.rule.textProps[1].editor;
|
|
||||||
|
|
||||||
yield runIncrementTest(paddingPropEditor, view, {
|
|
||||||
1: {start: "0px 0px 0px 0px", end: "0px 1px 0px 0px", selection: [4,7]},
|
|
||||||
2: {shift: true, start: "0px 0px 0px 0px", end: "0px 10px 0px 0px", selection: [4,7]},
|
|
||||||
3: {start: "0px 0px 0px 0px", end: "1px 0px 0px 0px", selectAll: true},
|
|
||||||
4: {shift: true, start: "0px 0px 0px 0px", end: "10px 0px 0px 0px", selectAll: true},
|
|
||||||
5: {down: true, start: "0px 0px 0px 0px", end: "0px 0px -1px 0px", selection: [8,11]},
|
|
||||||
6: {down: true, shift: true, start: "0px 0px 0px 0px", end: "-10px 0px 0px 0px", selectAll: true}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function* testOddCases(view) {
|
|
||||||
info("Testing some more odd cases");
|
|
||||||
|
|
||||||
let idRuleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
let marginPropEditor = idRuleEditor.rule.textProps[0].editor;
|
|
||||||
|
|
||||||
yield runIncrementTest(marginPropEditor, view, {
|
|
||||||
1: {start: "98.7%", end: "99.7%", selection: [3,3]},
|
|
||||||
2: {alt: true, start: "98.7%", end: "98.8%", selection: [3,3]},
|
|
||||||
3: {start: "0", end: "1"},
|
|
||||||
4: {down: true, start: "0", end: "-1"},
|
|
||||||
5: {start: "'a=-1'", end: "'a=0'", selection: [4,4]},
|
|
||||||
6: {start: "0 -1px", end: "0 0px", selection: [2,2]},
|
|
||||||
7: {start: "url(-1)", end: "url(-1)", selection: [4,4]},
|
|
||||||
8: {start: "url('test1.1.png')", end: "url('test1.2.png')", selection: [11,11]},
|
|
||||||
9: {start: "url('test1.png')", end: "url('test2.png')", selection: [9,9]},
|
|
||||||
10: {shift: true, start: "url('test1.1.png')", end: "url('test11.1.png')", selection: [9,9]},
|
|
||||||
11: {down: true, start: "url('test-1.png')", end: "url('test-2.png')", selection: [9,11]},
|
|
||||||
12: {start: "url('test1.1.png')", end: "url('test1.2.png')", selection: [11,12]},
|
|
||||||
13: {down: true, alt: true, start: "url('test-0.png')", end: "url('test--0.1.png')", selection: [10,11]},
|
|
||||||
14: {alt: true, start: "url('test--0.1.png')", end: "url('test-0.png')", selection: [10,14]}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function* runIncrementTest(propertyEditor, view, tests) {
|
|
||||||
let editor = yield focusEditableField(propertyEditor.valueSpan);
|
|
||||||
|
|
||||||
for(let test in tests) {
|
|
||||||
yield testIncrement(editor, tests[test], view);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Once properties have been set, wait for the inspector to update
|
|
||||||
yield view.inspector.once("inspector-updated");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testIncrement(editor, options, view) {
|
|
||||||
editor.input.value = options.start;
|
|
||||||
let input = editor.input;
|
|
||||||
|
|
||||||
if (options.selectAll) {
|
|
||||||
input.select();
|
|
||||||
} else if (options.selection) {
|
|
||||||
input.setSelectionRange(options.selection[0], options.selection[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
is(input.value, options.start, "Value initialized at " + options.start);
|
|
||||||
|
|
||||||
let onKeyUp = once(input, "keyup");
|
|
||||||
|
|
||||||
let key;
|
|
||||||
key = options.down ? "VK_DOWN" : "VK_UP";
|
|
||||||
key = options.pageDown ? "VK_PAGE_DOWN" : options.pageUp ? "VK_PAGE_UP" : key;
|
|
||||||
EventUtils.synthesizeKey(key, {altKey: options.alt, shiftKey: options.shift}, view.doc.defaultView);
|
|
||||||
|
|
||||||
yield onKeyUp;
|
|
||||||
input = editor.input;
|
|
||||||
is(input.value, options.end, "Value changed to " + options.end);
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Checking properties orders and overrides in the rule-view
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html;charset=utf-8,browser_ruleview_manipulation.js");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Creating the test document and getting the test node");
|
|
||||||
content.document.body.innerHTML = '<div id="testid">Styled Node</div>';
|
|
||||||
let element = getNode("#testid");
|
|
||||||
|
|
||||||
yield selectNode(element, inspector);
|
|
||||||
|
|
||||||
let elementStyle = view._elementStyle;
|
|
||||||
let elementRule = elementStyle.rules[0];
|
|
||||||
|
|
||||||
info("Checking rules insertion order and checking the applied style");
|
|
||||||
let firstProp = elementRule.createProperty("background-color", "green", "");
|
|
||||||
let secondProp = elementRule.createProperty("background-color", "blue", "");
|
|
||||||
is(elementRule.textProps[0], firstProp, "Rules should be in addition order.");
|
|
||||||
is(elementRule.textProps[1], secondProp, "Rules should be in addition order.");
|
|
||||||
yield elementRule._applyingModifications;
|
|
||||||
is(element.style.getPropertyValue("background-color"), "blue", "Second property should have been used.");
|
|
||||||
|
|
||||||
info("Removing the second property and checking the applied style again");
|
|
||||||
secondProp.remove();
|
|
||||||
yield elementRule._applyingModifications;
|
|
||||||
is(element.style.getPropertyValue("background-color"), "green", "After deleting second property, first should be used.");
|
|
||||||
|
|
||||||
info("Creating a new second property and checking that the insertion order is still the same");
|
|
||||||
secondProp = elementRule.createProperty("background-color", "blue", "");
|
|
||||||
yield elementRule._applyingModifications;
|
|
||||||
is(element.style.getPropertyValue("background-color"), "blue", "New property should be used.");
|
|
||||||
is(elementRule.textProps[0], firstProp, "Rules shouldn't have switched places.");
|
|
||||||
is(elementRule.textProps[1], secondProp, "Rules shouldn't have switched places.");
|
|
||||||
|
|
||||||
info("Disabling the second property and checking the applied style");
|
|
||||||
secondProp.setEnabled(false);
|
|
||||||
yield elementRule._applyingModifications;
|
|
||||||
is(element.style.getPropertyValue("background-color"), "green", "After disabling second property, first value should be used");
|
|
||||||
|
|
||||||
info("Disabling the first property too and checking the applied style");
|
|
||||||
firstProp.setEnabled(false);
|
|
||||||
yield elementRule._applyingModifications;
|
|
||||||
is(element.style.getPropertyValue("background-color"), "", "After disabling both properties, value should be empty.");
|
|
||||||
|
|
||||||
info("Re-enabling the second propertyt and checking the applied style");
|
|
||||||
secondProp.setEnabled(true);
|
|
||||||
yield elementRule._applyingModifications;
|
|
||||||
is(element.style.getPropertyValue("background-color"), "blue", "Value should be set correctly after re-enabling");
|
|
||||||
|
|
||||||
info("Re-enabling the first property and checking the insertion order is still respected");
|
|
||||||
firstProp.setEnabled(true);
|
|
||||||
yield elementRule._applyingModifications;
|
|
||||||
is(element.style.getPropertyValue("background-color"), "blue", "Re-enabling an earlier property shouldn't make it override a later property.");
|
|
||||||
is(elementRule.textProps[0], firstProp, "Rules shouldn't have switched places.");
|
|
||||||
is(elementRule.textProps[1], secondProp, "Rules shouldn't have switched places.");
|
|
||||||
|
|
||||||
info("Modifying the first property and checking the applied style");
|
|
||||||
firstProp.setValue("purple", "");
|
|
||||||
yield elementRule._applyingModifications;
|
|
||||||
is(element.style.getPropertyValue("background-color"), "blue", "Modifying an earlier property shouldn't override a later property.");
|
|
||||||
});
|
|
|
@ -1,78 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Testing various inplace-editor behaviors in the rule-view
|
|
||||||
// FIXME: To be split in several test files, and some of the inplace-editor
|
|
||||||
// focus/blur/commit/revert stuff should be factored out in head.js
|
|
||||||
|
|
||||||
let TEST_URL = 'url("' + TEST_URL_ROOT + 'doc_test_image.png")';
|
|
||||||
let PAGE_CONTENT = [
|
|
||||||
'<style type="text/css">',
|
|
||||||
' #testid {',
|
|
||||||
' background-color: blue;',
|
|
||||||
' }',
|
|
||||||
' .testclass {',
|
|
||||||
' background-color: green;',
|
|
||||||
' }',
|
|
||||||
'</style>',
|
|
||||||
'<div id="testid" class="testclass">Styled Node</div>'
|
|
||||||
].join("\n");
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,test rule view user changes");
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
content.document.body.innerHTML = PAGE_CONTENT;
|
|
||||||
|
|
||||||
info("Opening the rule-view");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Selecting the test element");
|
|
||||||
yield selectNode("#testid", inspector);
|
|
||||||
|
|
||||||
yield testEditProperty(view, "border-color", "red");
|
|
||||||
yield testEditProperty(view, "background-image", TEST_URL);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testEditProperty(view, name, value) {
|
|
||||||
info("Test editing existing property name/value fields");
|
|
||||||
|
|
||||||
let idRuleEditor = view.element.children[1]._ruleEditor;
|
|
||||||
let propEditor = idRuleEditor.rule.textProps[0].editor;
|
|
||||||
|
|
||||||
info("Focusing an existing property name in the rule-view");
|
|
||||||
let editor = yield focusEditableField(propEditor.nameSpan, 32, 1);
|
|
||||||
|
|
||||||
is(inplaceEditor(propEditor.nameSpan), editor, "The property name editor got focused");
|
|
||||||
let input = editor.input;
|
|
||||||
|
|
||||||
info("Entering a new property name, including : to commit and focus the value");
|
|
||||||
let onValueFocus = once(idRuleEditor.element, "focus", true);
|
|
||||||
let onModifications = idRuleEditor.rule._applyingModifications;
|
|
||||||
for (let ch of name + ":") {
|
|
||||||
EventUtils.sendChar(ch, view.doc.defaultView);
|
|
||||||
}
|
|
||||||
yield onValueFocus;
|
|
||||||
yield onModifications;
|
|
||||||
|
|
||||||
// Getting the value editor after focus
|
|
||||||
editor = inplaceEditor(view.doc.activeElement);
|
|
||||||
input = editor.input;
|
|
||||||
is(inplaceEditor(propEditor.valueSpan), editor, "Focus moved to the value.");
|
|
||||||
|
|
||||||
info("Entering a new value, including ; to commit and blur the value");
|
|
||||||
let onBlur = once(input, "blur");
|
|
||||||
let onModifications = idRuleEditor.rule._applyingModifications;
|
|
||||||
for (let ch of value + ";") {
|
|
||||||
EventUtils.sendChar(ch, view.doc.defaultView);
|
|
||||||
}
|
|
||||||
yield onBlur;
|
|
||||||
yield onModifications;
|
|
||||||
|
|
||||||
let propValue = idRuleEditor.rule.domRule._rawStyle().getPropertyValue(name);
|
|
||||||
is(propValue, value, name + " should have been set.");
|
|
||||||
is(propEditor.isValid(), true, value + " should be a valid entry");
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test several types of rule-view property edition
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html;charset=utf-8,browser_ruleview_ui.js");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Creating the test document");
|
|
||||||
let style = "" +
|
|
||||||
"#testid {" +
|
|
||||||
" background-color: blue;" +
|
|
||||||
"}" +
|
|
||||||
".testclass, .unmatched {" +
|
|
||||||
" background-color: green;" +
|
|
||||||
"}";
|
|
||||||
let styleNode = addStyle(content.document, style);
|
|
||||||
content.document.body.innerHTML = "<div id='testid' class='testclass'>Styled Node</div>" +
|
|
||||||
"<div id='testid2'>Styled Node</div>";
|
|
||||||
|
|
||||||
yield selectNode("#testid", inspector);
|
|
||||||
yield testEditProperty(inspector, view);
|
|
||||||
yield testDisableProperty(inspector, view);
|
|
||||||
yield testPropertyStillMarkedDirty(inspector, view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testEditProperty(inspector, ruleView) {
|
|
||||||
let idRuleEditor = ruleView.element.children[1]._ruleEditor;
|
|
||||||
let propEditor = idRuleEditor.rule.textProps[0].editor;
|
|
||||||
|
|
||||||
let editor = yield focusEditableField(propEditor.nameSpan);
|
|
||||||
let input = editor.input;
|
|
||||||
is(inplaceEditor(propEditor.nameSpan), editor, "Next focused editor should be the name editor.");
|
|
||||||
|
|
||||||
ok(input.selectionStart === 0 && input.selectionEnd === input.value.length, "Editor contents are selected.");
|
|
||||||
|
|
||||||
// Try clicking on the editor's input again, shouldn't cause trouble (see bug 761665).
|
|
||||||
EventUtils.synthesizeMouse(input, 1, 1, {}, ruleView.doc.defaultView);
|
|
||||||
input.select();
|
|
||||||
|
|
||||||
info("Entering property name followed by a colon to focus the value");
|
|
||||||
let onFocus = once(idRuleEditor.element, "focus", true);
|
|
||||||
for (let ch of "border-color:") {
|
|
||||||
EventUtils.sendChar(ch, ruleView.doc.defaultView);
|
|
||||||
}
|
|
||||||
yield onFocus;
|
|
||||||
yield idRuleEditor.rule._applyingModifications;
|
|
||||||
|
|
||||||
info("Verifying that the focused field is the valueSpan");
|
|
||||||
editor = inplaceEditor(ruleView.doc.activeElement);
|
|
||||||
input = editor.input;
|
|
||||||
is(inplaceEditor(propEditor.valueSpan), editor, "Focus should have moved to the value.");
|
|
||||||
ok(input.selectionStart === 0 && input.selectionEnd === input.value.length, "Editor contents are selected.");
|
|
||||||
|
|
||||||
info("Entering a value following by a semi-colon to commit it");
|
|
||||||
let onBlur = once(editor.input, "blur");
|
|
||||||
for (let ch of "red;") {
|
|
||||||
EventUtils.sendChar(ch, ruleView.doc.defaultView);
|
|
||||||
is(propEditor.warning.hidden, true,
|
|
||||||
"warning triangle is hidden or shown as appropriate");
|
|
||||||
}
|
|
||||||
yield onBlur;
|
|
||||||
yield idRuleEditor.rule._applyingModifications;
|
|
||||||
|
|
||||||
is(idRuleEditor.rule.style._rawStyle().getPropertyValue("border-color"), "red",
|
|
||||||
"border-color should have been set.");
|
|
||||||
|
|
||||||
let props = ruleView.element.querySelectorAll(".ruleview-property");
|
|
||||||
for (let i = 0; i < props.length; i++) {
|
|
||||||
is(props[i].hasAttribute("dirty"), i <= 0,
|
|
||||||
"props[" + i + "] marked dirty as appropriate");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testDisableProperty(inspector, ruleView) {
|
|
||||||
let idRuleEditor = ruleView.element.children[1]._ruleEditor;
|
|
||||||
let propEditor = idRuleEditor.rule.textProps[0].editor;
|
|
||||||
|
|
||||||
info("Disabling a property");
|
|
||||||
propEditor.enable.click();
|
|
||||||
yield idRuleEditor.rule._applyingModifications;
|
|
||||||
is(idRuleEditor.rule.style._rawStyle().getPropertyValue("border-color"), "",
|
|
||||||
"Border-color should have been unset.");
|
|
||||||
|
|
||||||
info("Enabling the property again");
|
|
||||||
propEditor.enable.click();
|
|
||||||
yield idRuleEditor.rule._applyingModifications;
|
|
||||||
is(idRuleEditor.rule.style._rawStyle().getPropertyValue("border-color"), "red",
|
|
||||||
"Border-color should have been reset.");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testPropertyStillMarkedDirty(inspector, ruleView) {
|
|
||||||
// Select an unstyled node.
|
|
||||||
yield selectNode("#testid2", inspector);
|
|
||||||
|
|
||||||
// Select the original node again.
|
|
||||||
yield selectNode("#testid", inspector);
|
|
||||||
|
|
||||||
let props = ruleView.element.querySelectorAll(".ruleview-property");
|
|
||||||
for (let i = 0; i < props.length; i++) {
|
|
||||||
is(props[i].hasAttribute("dirty"), i <= 0,
|
|
||||||
"props[" + i + "] marked dirty as appropriate");
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let doc = content.document;
|
||||||
|
|
||||||
|
function expectDone(aValue, aCommit, aNext)
|
||||||
|
{
|
||||||
|
return function(aDoneValue, aDoneCommit) {
|
||||||
|
dump("aDoneValue: " + aDoneValue + " commit: " + aDoneCommit + "\n");
|
||||||
|
|
||||||
|
is(aDoneValue, aValue, "Should get expected value");
|
||||||
|
is(aDoneCommit, aDoneCommit, "Should get expected commit value");
|
||||||
|
aNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearBody()
|
||||||
|
{
|
||||||
|
doc.body.innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSpan()
|
||||||
|
{
|
||||||
|
let span = doc.createElement("span");
|
||||||
|
span.setAttribute("tabindex", "0");
|
||||||
|
span.textContent = "Edit Me!";
|
||||||
|
doc.body.appendChild(span);
|
||||||
|
return span;
|
||||||
|
}
|
||||||
|
|
||||||
|
function testReturnCommit()
|
||||||
|
{
|
||||||
|
clearBody();
|
||||||
|
let span = createSpan();
|
||||||
|
editableField({
|
||||||
|
element: span,
|
||||||
|
initial: "explicit initial",
|
||||||
|
start: function() {
|
||||||
|
is(inplaceEditor(span).input.value, "explicit initial", "Explicit initial value should be used.");
|
||||||
|
inplaceEditor(span).input.value = "Test Value";
|
||||||
|
EventUtils.sendKey("return");
|
||||||
|
},
|
||||||
|
done: expectDone("Test Value", true, testBlurCommit)
|
||||||
|
});
|
||||||
|
span.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testBlurCommit()
|
||||||
|
{
|
||||||
|
clearBody();
|
||||||
|
let span = createSpan();
|
||||||
|
editableField({
|
||||||
|
element: span,
|
||||||
|
start: function() {
|
||||||
|
is(inplaceEditor(span).input.value, "Edit Me!", "textContent of the span used.");
|
||||||
|
inplaceEditor(span).input.value = "Test Value";
|
||||||
|
inplaceEditor(span).input.blur();
|
||||||
|
},
|
||||||
|
done: expectDone("Test Value", true, testAdvanceCharCommit)
|
||||||
|
});
|
||||||
|
span.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testAdvanceCharCommit()
|
||||||
|
{
|
||||||
|
clearBody();
|
||||||
|
let span = createSpan();
|
||||||
|
editableField({
|
||||||
|
element: span,
|
||||||
|
advanceChars: ":",
|
||||||
|
start: function() {
|
||||||
|
let input = inplaceEditor(span).input;
|
||||||
|
for each (let ch in "Test:") {
|
||||||
|
EventUtils.sendChar(ch);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
done: expectDone("Test", true, testEscapeCancel)
|
||||||
|
});
|
||||||
|
span.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testEscapeCancel()
|
||||||
|
{
|
||||||
|
clearBody();
|
||||||
|
let span = createSpan();
|
||||||
|
editableField({
|
||||||
|
element: span,
|
||||||
|
initial: "initial text",
|
||||||
|
start: function() {
|
||||||
|
inplaceEditor(span).input.value = "Test Value";
|
||||||
|
EventUtils.sendKey("escape");
|
||||||
|
},
|
||||||
|
done: expectDone("initial text", false, finishTest)
|
||||||
|
});
|
||||||
|
span.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function finishTest()
|
||||||
|
{
|
||||||
|
doc = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(testReturnCommit, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,inline editor tests";
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let ruleWindow;
|
||||||
|
let ruleView;
|
||||||
|
let inspector;
|
||||||
|
let TEST_URL = 'url("http://example.com/browser/browser/devtools/' +
|
||||||
|
'styleinspector/test/test-image.png")';
|
||||||
|
|
||||||
|
function startTest()
|
||||||
|
{
|
||||||
|
let style = '' +
|
||||||
|
'#testid {' +
|
||||||
|
' background-color: blue;' +
|
||||||
|
'} ' +
|
||||||
|
'.testclass {' +
|
||||||
|
' background-color: green;' +
|
||||||
|
'}';
|
||||||
|
|
||||||
|
let styleNode = addStyle(doc, style);
|
||||||
|
doc.body.innerHTML = '<div id="testid" class="testclass">Styled Node</div>';
|
||||||
|
let testElement = doc.getElementById("testid");
|
||||||
|
|
||||||
|
openRuleView((aInspector, aRuleView) => {
|
||||||
|
inspector = aInspector;
|
||||||
|
ruleView = aRuleView;
|
||||||
|
ruleWindow = aRuleView.doc.defaultView;
|
||||||
|
inspector.selection.setNode(testElement);
|
||||||
|
inspector.once("inspector-updated", testCancelNew);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCancelNew()
|
||||||
|
{
|
||||||
|
// Start at the beginning: start to add a rule to the element's style
|
||||||
|
// declaration, but leave it empty.
|
||||||
|
let elementRuleEditor = ruleView.element.children[0]._ruleEditor;
|
||||||
|
waitForEditorFocus(elementRuleEditor.element, function onNewElement(aEditor) {
|
||||||
|
is(inplaceEditor(elementRuleEditor.newPropSpan), aEditor, "Next focused editor should be the new property editor.");
|
||||||
|
let input = aEditor.input;
|
||||||
|
waitForEditorBlur(aEditor, function () {
|
||||||
|
ok(!elementRuleEditor.rule._applyingModifications, "Shouldn't have an outstanding request after a cancel.");
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 0, "Should have canceled creating a new text property.");
|
||||||
|
ok(!elementRuleEditor.propertyList.hasChildNodes(), "Should not have any properties.");
|
||||||
|
testCreateNew();
|
||||||
|
});
|
||||||
|
aEditor.input.blur();
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeMouse(elementRuleEditor.closeBrace, 1, 1,
|
||||||
|
{ },
|
||||||
|
ruleWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCreateNew()
|
||||||
|
{
|
||||||
|
// Create a new property.
|
||||||
|
let elementRuleEditor = ruleView.element.children[0]._ruleEditor;
|
||||||
|
waitForEditorFocus(elementRuleEditor.element, function onNewElement(aEditor) {
|
||||||
|
is(inplaceEditor(elementRuleEditor.newPropSpan), aEditor, "Next focused editor should be the new property editor.");
|
||||||
|
let input = aEditor.input;
|
||||||
|
input.value = "background-color";
|
||||||
|
|
||||||
|
waitForEditorFocus(elementRuleEditor.element, function onNewValue(aEditor) {
|
||||||
|
promiseDone(expectRuleChange(elementRuleEditor.rule).then(() => {
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 1, "Should have created a new text property.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 1, "Should have created a property editor.");
|
||||||
|
let textProp = elementRuleEditor.rule.textProps[0];
|
||||||
|
is(aEditor, inplaceEditor(textProp.editor.valueSpan), "Should be editing the value span now.");
|
||||||
|
aEditor.input.value = "#XYZ";
|
||||||
|
waitForEditorBlur(aEditor, function() {
|
||||||
|
promiseDone(expectRuleChange(elementRuleEditor.rule).then(() => {
|
||||||
|
is(textProp.value, "#XYZ", "Text prop should have been changed.");
|
||||||
|
is(textProp.editor.isValid(), false, "#XYZ should not be a valid entry");
|
||||||
|
testCreateNewEscape();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
aEditor.input.blur();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeKey("VK_RETURN", {}, ruleWindow);
|
||||||
|
});
|
||||||
|
|
||||||
|
EventUtils.synthesizeMouse(elementRuleEditor.closeBrace, 1, 1,
|
||||||
|
{ },
|
||||||
|
ruleWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCreateNewEscape()
|
||||||
|
{
|
||||||
|
// Create a new property.
|
||||||
|
let elementRuleEditor = ruleView.element.children[0]._ruleEditor;
|
||||||
|
waitForEditorFocus(elementRuleEditor.element, function onNewElement(aEditor) {
|
||||||
|
is(inplaceEditor(elementRuleEditor.newPropSpan), aEditor, "Next focused editor should be the new property editor.");
|
||||||
|
let input = aEditor.input;
|
||||||
|
input.value = "color";
|
||||||
|
|
||||||
|
waitForEditorFocus(elementRuleEditor.element, function onNewValue(aEditor) {
|
||||||
|
promiseDone(expectRuleChange(elementRuleEditor.rule).then(() => {
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 2, "Should have created a new text property.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 2, "Should have created a property editor.");
|
||||||
|
let textProp = elementRuleEditor.rule.textProps[1];
|
||||||
|
is(aEditor, inplaceEditor(textProp.editor.valueSpan), "Should be editing the value span now.");
|
||||||
|
aEditor.input.value = "red";
|
||||||
|
EventUtils.synthesizeKey("VK_ESCAPE", {}, ruleWindow);
|
||||||
|
|
||||||
|
// Make sure previous input is focused.
|
||||||
|
let focusedElement = inplaceEditor(elementRuleEditor.rule.textProps[0].editor.valueSpan).input;
|
||||||
|
is(focusedElement, focusedElement.ownerDocument.activeElement, "Correct element has focus");
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_ESCAPE", {}, ruleWindow);
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 1, "Should have removed the new text property.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 1, "Should have removed the property editor.");
|
||||||
|
|
||||||
|
testEditProperty();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
EventUtils.synthesizeKey("VK_RETURN", {}, ruleWindow);
|
||||||
|
});
|
||||||
|
|
||||||
|
EventUtils.synthesizeMouse(elementRuleEditor.closeBrace, 1, 1,
|
||||||
|
{ },
|
||||||
|
ruleWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testEditProperty()
|
||||||
|
{
|
||||||
|
let idRuleEditor = ruleView.element.children[1]._ruleEditor;
|
||||||
|
let propEditor = idRuleEditor.rule.textProps[0].editor;
|
||||||
|
waitForEditorFocus(propEditor.element, function onNewElement(aEditor) {
|
||||||
|
is(inplaceEditor(propEditor.nameSpan), aEditor, "Next focused editor should be the name editor.");
|
||||||
|
let input = aEditor.input;
|
||||||
|
waitForEditorFocus(propEditor.element, function onNewName(aEditor) {
|
||||||
|
promiseDone(expectRuleChange(idRuleEditor.rule).then(() => {
|
||||||
|
input = aEditor.input;
|
||||||
|
is(inplaceEditor(propEditor.valueSpan), aEditor, "Focus should have moved to the value.");
|
||||||
|
|
||||||
|
waitForEditorBlur(aEditor, function() {
|
||||||
|
promiseDone(expectRuleChange(idRuleEditor.rule).then(() => {
|
||||||
|
let value = idRuleEditor.rule.domRule._rawStyle().getPropertyValue("border-color");
|
||||||
|
is(value, "red", "border-color should have been set.");
|
||||||
|
is(propEditor.isValid(), true, "red should be a valid entry");
|
||||||
|
testEditPropertyWithColon();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
for (let ch of "red;") {
|
||||||
|
EventUtils.sendChar(ch, ruleWindow);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
for (let ch of "border-color:") {
|
||||||
|
EventUtils.sendChar(ch, ruleWindow);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
EventUtils.synthesizeMouse(propEditor.nameSpan, 32, 1,
|
||||||
|
{ },
|
||||||
|
ruleWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testEditPropertyWithColon()
|
||||||
|
{
|
||||||
|
let idRuleEditor = ruleView.element.children[1]._ruleEditor;
|
||||||
|
let propEditor = idRuleEditor.rule.textProps[0].editor;
|
||||||
|
waitForEditorFocus(propEditor.element, function onNewElement(aEditor) {
|
||||||
|
is(inplaceEditor(propEditor.nameSpan), aEditor, "Next focused editor should be the name editor.");
|
||||||
|
let input = aEditor.input;
|
||||||
|
waitForEditorFocus(propEditor.element, function onNewName(aEditor) {
|
||||||
|
promiseDone(expectRuleChange(idRuleEditor.rule).then(() => {
|
||||||
|
input = aEditor.input;
|
||||||
|
is(inplaceEditor(propEditor.valueSpan), aEditor, "Focus should have moved to the value.");
|
||||||
|
|
||||||
|
waitForEditorBlur(aEditor, function() {
|
||||||
|
promiseDone(expectRuleChange(idRuleEditor.rule).then(() => {
|
||||||
|
let value = idRuleEditor.rule.domRule._rawStyle().getPropertyValue("background-image");
|
||||||
|
is(value, TEST_URL, "background-image should have been set.");
|
||||||
|
is(propEditor.isValid(), true, "the test URL should be a valid entry");
|
||||||
|
finishTest();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
for (let ch of (TEST_URL + ";")) {
|
||||||
|
EventUtils.sendChar(ch, ruleWindow);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
for (let ch of "background-image:") {
|
||||||
|
EventUtils.sendChar(ch, ruleWindow);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
EventUtils.synthesizeMouse(propEditor.nameSpan, 32, 1,
|
||||||
|
{ },
|
||||||
|
ruleWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishTest()
|
||||||
|
{
|
||||||
|
inspector = ruleWindow = ruleView = null;
|
||||||
|
doc = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function changedValues_load(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, changedValues_load, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(startTest, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,test rule view user changes";
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Test that focus doesn't leave the style editor when adding a property
|
||||||
|
// (bug 719916)
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let stylePanel;
|
||||||
|
|
||||||
|
function selectNode(aInspector, aRuleView)
|
||||||
|
{
|
||||||
|
inspector = aInspector;
|
||||||
|
let node = content.document.getElementsByTagName("h1")[0];
|
||||||
|
inspector.selection.setNode(node);
|
||||||
|
inspector.once("inspector-updated", testFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFocus()
|
||||||
|
{
|
||||||
|
let win = inspector.sidebar.getWindowForTab("ruleview");
|
||||||
|
let brace = win.document.querySelectorAll(".ruleview-ruleclose")[0];
|
||||||
|
|
||||||
|
waitForEditorFocus(brace.parentNode, function onNewElement(aEditor) {
|
||||||
|
aEditor.input.value = "color";
|
||||||
|
waitForEditorFocus(brace.parentNode, function onEditingValue(aEditor) {
|
||||||
|
// If we actually get this focus we're ok.
|
||||||
|
ok(true, "We got focus.");
|
||||||
|
aEditor.input.value = "green";
|
||||||
|
|
||||||
|
// If we've retained focus, pressing return will start a new editor.
|
||||||
|
// If not, we'll wait here until we time out.
|
||||||
|
waitForEditorFocus(brace.parentNode, function onNewEditor(aEditor) {
|
||||||
|
aEditor.input.blur();
|
||||||
|
finishUp();
|
||||||
|
});
|
||||||
|
EventUtils.sendKey("return");
|
||||||
|
});
|
||||||
|
EventUtils.sendKey("return");
|
||||||
|
});
|
||||||
|
|
||||||
|
brace.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
doc = inspector = stylePanel = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
doc = content.document;
|
||||||
|
doc.title = "Rule View Test";
|
||||||
|
waitForFocus(() => openRuleView(selectNode), content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,<h1>Some header text</h1>";
|
||||||
|
}
|
|
@ -1,86 +1,116 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
"use strict";
|
let doc;
|
||||||
|
|
||||||
// Check that inherited properties appear as such in the rule-view
|
let inspector;
|
||||||
|
let view;
|
||||||
|
|
||||||
let {ELEMENT_STYLE} = devtools.require("devtools/server/actors/styles");
|
let {ELEMENT_STYLE} = devtools.require("devtools/server/actors/styles");
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function simpleInherit(aInspector, aRuleView)
|
||||||
yield addTab("data:text/html;charset=utf-8,browser_inspector_changes.js");
|
{
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
inspector = aInspector;
|
||||||
|
view = aRuleView;
|
||||||
|
|
||||||
yield simpleInherit(inspector, view);
|
|
||||||
yield emptyInherit(inspector, view);
|
|
||||||
yield elementStyleInherit(inspector, view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* simpleInherit(inspector, view) {
|
|
||||||
let style = '' +
|
let style = '' +
|
||||||
'#test2 {' +
|
'#test2 {' +
|
||||||
' background-color: green;' +
|
' background-color: green;' +
|
||||||
' color: purple;' +
|
' color: purple;' +
|
||||||
'}';
|
'}';
|
||||||
|
|
||||||
let styleNode = addStyle(content.document, style);
|
let styleNode = addStyle(doc, style);
|
||||||
content.document.body.innerHTML = '<div id="test2"><div id="test1">Styled Node</div></div>';
|
doc.body.innerHTML = '<div id="test2"><div id="test1">Styled Node</div></div>';
|
||||||
|
|
||||||
yield selectNode("#test1", inspector);
|
inspector.selection.setNode(doc.getElementById("test1"));
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
let elementStyle = view._elementStyle;
|
||||||
|
|
||||||
let elementStyle = view._elementStyle;
|
is(elementStyle.rules.length, 2, "Should have 2 rules.");
|
||||||
is(elementStyle.rules.length, 2, "Should have 2 rules.");
|
|
||||||
|
|
||||||
let elementRule = elementStyle.rules[0];
|
let elementRule = elementStyle.rules[0];
|
||||||
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
||||||
|
|
||||||
let inheritRule = elementStyle.rules[1];
|
let inheritRule = elementStyle.rules[1];
|
||||||
is(inheritRule.selectorText, "#test2", "Inherited rule should be the one that includes inheritable properties.");
|
is(inheritRule.selectorText, "#test2", "Inherited rule should be the one that includes inheritable properties.");
|
||||||
ok(!!inheritRule.inherited, "Rule should consider itself inherited.");
|
ok(!!inheritRule.inherited, "Rule should consider itself inherited.");
|
||||||
is(inheritRule.textProps.length, 1, "Should only display one inherited style");
|
is(inheritRule.textProps.length, 1, "Should only display one inherited style");
|
||||||
let inheritProp = inheritRule.textProps[0];
|
let inheritProp = inheritRule.textProps[0];
|
||||||
is(inheritProp.name, "color", "color should have been inherited.");
|
is(inheritProp.name, "color", "color should have been inherited.");
|
||||||
|
|
||||||
styleNode.remove();
|
styleNode.parentNode.removeChild(styleNode);
|
||||||
|
|
||||||
|
emptyInherit();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function* emptyInherit(inspector, view) {
|
function emptyInherit()
|
||||||
|
{
|
||||||
// No inheritable styles, this rule shouldn't show up.
|
// No inheritable styles, this rule shouldn't show up.
|
||||||
let style = '' +
|
let style = '' +
|
||||||
'#test2 {' +
|
'#test2 {' +
|
||||||
' background-color: green;' +
|
' background-color: green;' +
|
||||||
'}';
|
'}';
|
||||||
|
|
||||||
let styleNode = addStyle(content.document, style);
|
let styleNode = addStyle(doc, style);
|
||||||
content.document.body.innerHTML = '<div id="test2"><div id="test1">Styled Node</div></div>';
|
doc.body.innerHTML = '<div id="test2"><div id="test1">Styled Node</div></div>';
|
||||||
|
|
||||||
yield selectNode("#test1", inspector);
|
inspector.selection.setNode(doc.getElementById("test1"));
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
let elementStyle = view._elementStyle;
|
||||||
|
|
||||||
let elementStyle = view._elementStyle;
|
is(elementStyle.rules.length, 1, "Should have 1 rule.");
|
||||||
is(elementStyle.rules.length, 1, "Should have 1 rule.");
|
|
||||||
|
|
||||||
let elementRule = elementStyle.rules[0];
|
let elementRule = elementStyle.rules[0];
|
||||||
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
||||||
|
|
||||||
styleNode.parentNode.removeChild(styleNode);
|
styleNode.parentNode.removeChild(styleNode);
|
||||||
|
|
||||||
|
elementStyleInherit();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function* elementStyleInherit(inspector, view) {
|
function elementStyleInherit()
|
||||||
content.document.body.innerHTML = '<div id="test2" style="color: red"><div id="test1">Styled Node</div></div>';
|
{
|
||||||
|
doc.body.innerHTML = '<div id="test2" style="color: red"><div id="test1">Styled Node</div></div>';
|
||||||
|
|
||||||
yield selectNode("#test1", inspector);
|
inspector.selection.setNode(doc.getElementById("test1"));
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
let elementStyle = view._elementStyle;
|
||||||
|
|
||||||
let elementStyle = view._elementStyle;
|
is(elementStyle.rules.length, 2, "Should have 2 rules.");
|
||||||
is(elementStyle.rules.length, 2, "Should have 2 rules.");
|
|
||||||
|
|
||||||
let elementRule = elementStyle.rules[0];
|
let elementRule = elementStyle.rules[0];
|
||||||
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
||||||
|
|
||||||
let inheritRule = elementStyle.rules[1];
|
let inheritRule = elementStyle.rules[1];
|
||||||
is(inheritRule.domRule.type, ELEMENT_STYLE, "Inherited rule should be an element style, not a rule.");
|
is(inheritRule.domRule.type, ELEMENT_STYLE, "Inherited rule should be an element style, not a rule.");
|
||||||
ok(!!inheritRule.inherited, "Rule should consider itself inherited.");
|
ok(!!inheritRule.inherited, "Rule should consider itself inherited.");
|
||||||
is(inheritRule.textProps.length, 1, "Should only display one inherited style");
|
is(inheritRule.textProps.length, 1, "Should only display one inherited style");
|
||||||
let inheritProp = inheritRule.textProps[0];
|
let inheritProp = inheritRule.textProps[0];
|
||||||
is(inheritProp.name, "color", "color should have been inherited.");
|
is(inheritProp.name, "color", "color should have been inherited.");
|
||||||
|
|
||||||
|
finishTest();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishTest()
|
||||||
|
{
|
||||||
|
doc = inspector = view = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(() => openRuleView(simpleInherit), content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html;charset=utf-8,browser_inspector_changes.js";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that focus doesn't leave the style editor when adding a property
|
|
||||||
// (bug 719916)
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,<h1>Some header text</h1>");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("h1", inspector);
|
|
||||||
|
|
||||||
info("Getting the ruleclose brace element");
|
|
||||||
let brace = view.doc.querySelector(".ruleview-ruleclose");
|
|
||||||
|
|
||||||
info("Clicking on the brace element to focus the new property field");
|
|
||||||
let onFocus = once(brace.parentNode, "focus", true);
|
|
||||||
brace.click();
|
|
||||||
yield onFocus;
|
|
||||||
|
|
||||||
info("Entering a property name");
|
|
||||||
let editor = getCurrentInplaceEditor(view);
|
|
||||||
editor.input.value = "color";
|
|
||||||
|
|
||||||
info("Typing ENTER to focus the next field: property value");
|
|
||||||
let onFocus = once(brace.parentNode, "focus", true);
|
|
||||||
EventUtils.sendKey("return");
|
|
||||||
yield onFocus;
|
|
||||||
ok(true, "The value field was focused");
|
|
||||||
|
|
||||||
info("Entering a property value");
|
|
||||||
let editor = getCurrentInplaceEditor(view);
|
|
||||||
editor.input.value = "green";
|
|
||||||
|
|
||||||
info("Typing ENTER again should focus a new property name");
|
|
||||||
let onFocus = once(brace.parentNode, "focus", true);
|
|
||||||
EventUtils.sendKey("return");
|
|
||||||
yield onFocus;
|
|
||||||
ok(true, "The new property name field was focused");
|
|
||||||
getCurrentInplaceEditor(view).input.blur();
|
|
||||||
});
|
|
||||||
|
|
||||||
function getCurrentInplaceEditor(view) {
|
|
||||||
return inplaceEditor(view.doc.activeElement);
|
|
||||||
}
|
|
|
@ -1,17 +1,21 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that changes are previewed when editing a property value
|
// Test that changes are previewed when editing a property value
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let testElement;
|
||||||
|
let ruleWindow;
|
||||||
|
let ruleView;
|
||||||
|
let inspector;
|
||||||
|
|
||||||
// Format
|
// Format
|
||||||
// {
|
// {
|
||||||
// value : what to type in the field
|
// value : what to type in the field
|
||||||
// expected : expected computed style on the targeted element
|
// expected : expected computed style on the targeted element
|
||||||
// }
|
// }
|
||||||
const TEST_DATA = [
|
let testData = [
|
||||||
{value: "inline", expected: "inline"},
|
{value: "inline", expected: "inline"},
|
||||||
{value: "inline-block", expected: "inline-block"},
|
{value: "inline-block", expected: "inline-block"},
|
||||||
|
|
||||||
|
@ -22,45 +26,77 @@ const TEST_DATA = [
|
||||||
{escape: true, value: "inline", expected: "block"}
|
{escape: true, value: "inline", expected: "block"}
|
||||||
];
|
];
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
function startTest()
|
||||||
yield addTab("data:text/html,test rule view live preview on user changes");
|
{
|
||||||
|
|
||||||
let style = '#testid {display:block;}';
|
let style = '#testid {display:block;}';
|
||||||
let styleNode = addStyle(content.document, style);
|
|
||||||
content.document.body.innerHTML = '<div id="testid">Styled Node</div><span>inline element</span>';
|
|
||||||
let testElement = getNode("#testid");
|
|
||||||
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
let styleNode = addStyle(doc, style);
|
||||||
yield selectNode(testElement, inspector);
|
doc.body.innerHTML = '<div id="testid">Styled Node</div><span>inline element</span>';
|
||||||
|
testElement = doc.getElementById("testid");
|
||||||
|
|
||||||
for (let data of TEST_DATA) {
|
openRuleView((aInspector, aRuleView) => {
|
||||||
yield testLivePreviewData(data, view, testElement);
|
inspector = aInspector;
|
||||||
|
ruleView = aRuleView;
|
||||||
|
ruleWindow = aRuleView.doc.defaultView;
|
||||||
|
inspector.selection.setNode(testElement);
|
||||||
|
inspector.once("inspector-updated", () => loopTestData(0));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loopTestData(index)
|
||||||
|
{
|
||||||
|
if(index === testData.length) {
|
||||||
|
finishTest();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
function* testLivePreviewData(data, ruleView, testElement) {
|
|
||||||
let idRuleEditor = ruleView.element.children[1]._ruleEditor;
|
let idRuleEditor = ruleView.element.children[1]._ruleEditor;
|
||||||
let propEditor = idRuleEditor.rule.textProps[0].editor;
|
let propEditor = idRuleEditor.rule.textProps[0].editor;
|
||||||
|
waitForEditorFocus(propEditor.element, function(aEditor) {
|
||||||
|
is(inplaceEditor(propEditor.valueSpan), aEditor, "Focused editor should be the value.");
|
||||||
|
|
||||||
info("Focusing the property value inplace-editor");
|
let thisTest = testData[index];
|
||||||
let editor = yield focusEditableField(propEditor.valueSpan);
|
|
||||||
is(inplaceEditor(propEditor.valueSpan), editor, "The focused editor is the value");
|
|
||||||
|
|
||||||
info("Enter a value in the editor")
|
// Entering a correct value for the property
|
||||||
for (let ch of data.value) {
|
for (let ch of thisTest.value) {
|
||||||
EventUtils.sendChar(ch, ruleView.doc.defaultView);
|
EventUtils.sendChar(ch, ruleWindow);
|
||||||
}
|
}
|
||||||
if (data.escape) {
|
if (thisTest.escape) {
|
||||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||||
} else {
|
} else {
|
||||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||||
}
|
}
|
||||||
|
|
||||||
yield wait(1);
|
// While the editor is still focused in, the display should have changed already
|
||||||
|
executeSoon(() => {
|
||||||
|
is(content.getComputedStyle(testElement).display,
|
||||||
|
testData[index].expected,
|
||||||
|
"Element should be previewed as " + testData[index].expected);
|
||||||
|
|
||||||
// While the editor is still focused in, the display should have changed already
|
loopTestData(index + 1);
|
||||||
is(content.getComputedStyle(testElement).display,
|
});
|
||||||
data.expected,
|
});
|
||||||
"Element should be previewed as " + data.expected);
|
|
||||||
|
EventUtils.synthesizeMouse(propEditor.valueSpan, 1, 1, {}, ruleWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishTest()
|
||||||
|
{
|
||||||
|
inspector = ruleWindow = ruleView = null;
|
||||||
|
doc = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function changedValues_load(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, changedValues_load, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(startTest, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,test rule view live preview on user changes";
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
|
||||||
|
function simpleOverride(aInspector, aRuleView)
|
||||||
|
{
|
||||||
|
doc.body.innerHTML = '<div id="testid">Styled Node</div>';
|
||||||
|
let element = doc.getElementById("testid");
|
||||||
|
|
||||||
|
aInspector.selection.setNode(element);
|
||||||
|
aInspector.once("inspector-updated", () => {
|
||||||
|
let elementStyle = aRuleView._elementStyle;
|
||||||
|
|
||||||
|
let elementRule = elementStyle.rules[0];
|
||||||
|
let firstProp = elementRule.createProperty("background-color", "green", "");
|
||||||
|
let secondProp = elementRule.createProperty("background-color", "blue", "");
|
||||||
|
is(elementRule.textProps[0], firstProp, "Rules should be in addition order.");
|
||||||
|
is(elementRule.textProps[1], secondProp, "Rules should be in addition order.");
|
||||||
|
|
||||||
|
promiseDone(elementRule._applyingModifications.then(() => {
|
||||||
|
is(element.style.getPropertyValue("background-color"), "blue", "Second property should have been used.");
|
||||||
|
|
||||||
|
secondProp.remove();
|
||||||
|
return elementRule._applyingModifications;
|
||||||
|
}).then(() => {
|
||||||
|
is(element.style.getPropertyValue("background-color"), "green", "After deleting second property, first should be used.");
|
||||||
|
|
||||||
|
secondProp = elementRule.createProperty("background-color", "blue", "");
|
||||||
|
return elementRule._applyingModifications;
|
||||||
|
}).then(() => {
|
||||||
|
is(element.style.getPropertyValue("background-color"), "blue", "New property should be used.");
|
||||||
|
|
||||||
|
is(elementRule.textProps[0], firstProp, "Rules shouldn't have switched places.");
|
||||||
|
is(elementRule.textProps[1], secondProp, "Rules shouldn't have switched places.");
|
||||||
|
|
||||||
|
secondProp.setEnabled(false);
|
||||||
|
return elementRule._applyingModifications;
|
||||||
|
}).then(() => {
|
||||||
|
is(element.style.getPropertyValue("background-color"), "green", "After disabling second property, first value should be used");
|
||||||
|
|
||||||
|
firstProp.setEnabled(false);
|
||||||
|
return elementRule._applyingModifications;
|
||||||
|
}).then(() => {
|
||||||
|
is(element.style.getPropertyValue("background-color"), "", "After disabling both properties, value should be empty.");
|
||||||
|
|
||||||
|
secondProp.setEnabled(true);
|
||||||
|
return elementRule._applyingModifications;
|
||||||
|
}).then(() => {
|
||||||
|
is(element.style.getPropertyValue("background-color"), "blue", "Value should be set correctly after re-enabling");
|
||||||
|
|
||||||
|
firstProp.setEnabled(true);
|
||||||
|
return elementRule._applyingModifications;
|
||||||
|
}).then(() => {
|
||||||
|
is(element.style.getPropertyValue("background-color"), "blue", "Re-enabling an earlier property shouldn't make it override a later property.");
|
||||||
|
is(elementRule.textProps[0], firstProp, "Rules shouldn't have switched places.");
|
||||||
|
is(elementRule.textProps[1], secondProp, "Rules shouldn't have switched places.");
|
||||||
|
|
||||||
|
firstProp.setValue("purple", "");
|
||||||
|
return elementRule._applyingModifications;
|
||||||
|
}).then(() => {
|
||||||
|
is(element.style.getPropertyValue("background-color"), "blue", "Modifying an earlier property shouldn't override a later property.");
|
||||||
|
finishTest();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishTest()
|
||||||
|
{
|
||||||
|
doc = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(() => openRuleView(simpleOverride), content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html;charset=utf-8,browser_ruleview_manipulation.js";
|
||||||
|
}
|
|
@ -1,54 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Tests that the rule-view displays correctly on MathML elements
|
|
||||||
|
|
||||||
const TEST_URL = [
|
|
||||||
"data:text/html,",
|
|
||||||
"<div>",
|
|
||||||
" <math xmlns=\"http://www.w3.org/1998/Math/MathML\">",
|
|
||||||
" <mfrac>",
|
|
||||||
" <msubsup>",
|
|
||||||
" <mi>a</mi>",
|
|
||||||
" <mi>i</mi>",
|
|
||||||
" <mi>j</mi>",
|
|
||||||
" </msubsup>",
|
|
||||||
" <msub>",
|
|
||||||
" <mi>x</mi>",
|
|
||||||
" <mn>0</mn>",
|
|
||||||
" </msub>",
|
|
||||||
" </mfrac>",
|
|
||||||
" </math>",
|
|
||||||
"</div>"
|
|
||||||
].join("");
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab(TEST_URL);
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Select the DIV node and verify the rule-view shows rules");
|
|
||||||
yield selectNode("div", inspector);
|
|
||||||
ok(view.element.querySelectorAll(".ruleview-rule").length,
|
|
||||||
"The rule-view shows rules for the div element");
|
|
||||||
|
|
||||||
info("Select various MathML nodes and verify the rule-view is empty");
|
|
||||||
yield selectNode("math", inspector);
|
|
||||||
ok(!view.element.querySelectorAll(".ruleview-rule").length,
|
|
||||||
"The rule-view is empty for the math element");
|
|
||||||
|
|
||||||
yield selectNode("msubsup", inspector);
|
|
||||||
ok(!view.element.querySelectorAll(".ruleview-rule").length,
|
|
||||||
"The rule-view is empty for the msubsup element");
|
|
||||||
|
|
||||||
yield selectNode("mn", inspector);
|
|
||||||
ok(!view.element.querySelectorAll(".ruleview-rule").length,
|
|
||||||
"The rule-view is empty for the mn element");
|
|
||||||
|
|
||||||
info("Select again the DIV node and verify the rule-view shows rules");
|
|
||||||
yield selectNode("div", inspector);
|
|
||||||
ok(view.element.querySelectorAll(".ruleview-rule").length,
|
|
||||||
"The rule-view shows rules for the div element");
|
|
||||||
});
|
|
|
@ -1,31 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Tests that we correctly display appropriate media query titles in the
|
|
||||||
// rule view.
|
|
||||||
|
|
||||||
const TEST_URI = TEST_URL_ROOT + "doc_media_queries.html";
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab(TEST_URI);
|
|
||||||
let {inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
yield selectNode("div", inspector);
|
|
||||||
|
|
||||||
let elementStyle = view._elementStyle;
|
|
||||||
|
|
||||||
let _strings = Services.strings
|
|
||||||
.createBundle("chrome://global/locale/devtools/styleinspector.properties");
|
|
||||||
|
|
||||||
let inline = _strings.GetStringFromName("rule.sourceInline");
|
|
||||||
|
|
||||||
is(elementStyle.rules.length, 3, "Should have 3 rules.");
|
|
||||||
is(elementStyle.rules[0].title, inline, "check rule 0 title");
|
|
||||||
is(elementStyle.rules[1].title, inline +
|
|
||||||
":15 @media screen and (min-width: 1px)", "check rule 1 title");
|
|
||||||
is(elementStyle.rules[2].title, inline + ":8", "check rule 2 title");
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that the rule-view behaves correctly when entering mutliple and/or
|
|
||||||
// unfinished properties/values in inplace-editors
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,test rule view user changes");
|
|
||||||
content.document.body.innerHTML = "<h1>Testing Multiple Properties</h1>";
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Creating the test element");
|
|
||||||
let newElement = content.document.createElement("div");
|
|
||||||
newElement.textContent = "Test Element";
|
|
||||||
content.document.body.appendChild(newElement);
|
|
||||||
yield selectNode(newElement, inspector);
|
|
||||||
let ruleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
|
|
||||||
yield testCreateNewMultiDuplicates(inspector, ruleEditor);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCreateNewMultiDuplicates(inspector, ruleEditor) {
|
|
||||||
yield createNewRuleViewProperty(ruleEditor,
|
|
||||||
"color:red;color:orange;color:yellow;color:green;color:blue;color:indigo;color:violet;");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps.length, 7, "Should have created new text properties.");
|
|
||||||
is(ruleEditor.propertyList.children.length, 8, "Should have created new property editors.");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[0].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[0].value, "red", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[1].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[1].value, "orange", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[2].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[2].value, "yellow", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[3].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[3].value, "green", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[4].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[4].value, "blue", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[5].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[5].value, "indigo", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[6].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[6].value, "violet", "Should have correct property value");
|
|
||||||
|
|
||||||
yield inspector.once("inspector-updated");
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that the rule-view behaves correctly when entering mutliple and/or
|
|
||||||
// unfinished properties/values in inplace-editors
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,test rule view user changes");
|
|
||||||
content.document.body.innerHTML = "<h1>Testing Multiple Properties</h1>";
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Creating the test element");
|
|
||||||
let newElement = content.document.createElement("div");
|
|
||||||
newElement.textContent = "Test Element";
|
|
||||||
content.document.body.appendChild(newElement);
|
|
||||||
yield selectNode(newElement, inspector);
|
|
||||||
let ruleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
|
|
||||||
yield testCreateNewMultiPriority(inspector, ruleEditor);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCreateNewMultiPriority(inspector, ruleEditor) {
|
|
||||||
yield createNewRuleViewProperty(ruleEditor,
|
|
||||||
"color:red;width:100px;height: 100px;");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps.length, 3, "Should have created new text properties.");
|
|
||||||
is(ruleEditor.propertyList.children.length, 4, "Should have created new property editors.");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[0].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[0].value, "red", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[1].name, "width", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[1].value, "100px", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[2].name, "height", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[2].value, "100px", "Should have correct property value");
|
|
||||||
|
|
||||||
yield inspector.once("inspector-updated");
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that the rule-view behaves correctly when entering mutliple and/or
|
|
||||||
// unfinished properties/values in inplace-editors
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,test rule view user changes");
|
|
||||||
content.document.body.innerHTML = "<h1>Testing Multiple Properties</h1>";
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Creating the test element");
|
|
||||||
let newElement = content.document.createElement("div");
|
|
||||||
newElement.textContent = "Test Element";
|
|
||||||
content.document.body.appendChild(newElement);
|
|
||||||
yield selectNode(newElement, inspector);
|
|
||||||
let ruleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
|
|
||||||
yield testCreateNewMultiUnfinished(inspector, ruleEditor, view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCreateNewMultiUnfinished(inspector, ruleEditor, view) {
|
|
||||||
yield createNewRuleViewProperty(ruleEditor,
|
|
||||||
"color:blue;background : orange ; text-align:center; border-color: ");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps.length, 4, "Should have created new text properties.");
|
|
||||||
is(ruleEditor.propertyList.children.length, 4, "Should have created property editors.");
|
|
||||||
|
|
||||||
for (let ch of "red") {
|
|
||||||
EventUtils.sendChar(ch, view.doc.defaultView);
|
|
||||||
}
|
|
||||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps.length, 4, "Should have the same number of text properties.");
|
|
||||||
is(ruleEditor.propertyList.children.length, 5, "Should have added the changed value editor.");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[0].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[0].value, "blue", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[1].name, "background", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[1].value, "orange", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[2].name, "text-align", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[2].value, "center", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[3].name, "border-color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[3].value, "red", "Should have correct property value");
|
|
||||||
|
|
||||||
yield inspector.once("inspector-updated");
|
|
||||||
}
|
|
|
@ -1,52 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that the rule-view behaves correctly when entering mutliple and/or
|
|
||||||
// unfinished properties/values in inplace-editors
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,test rule view user changes");
|
|
||||||
content.document.body.innerHTML = "<h1>Testing Multiple Properties</h1>";
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Creating the test element");
|
|
||||||
let newElement = content.document.createElement("div");
|
|
||||||
newElement.textContent = "Test Element";
|
|
||||||
content.document.body.appendChild(newElement);
|
|
||||||
yield selectNode(newElement, inspector);
|
|
||||||
let ruleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
|
|
||||||
yield testCreateNewMultiPartialUnfinished(inspector, ruleEditor, view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCreateNewMultiPartialUnfinished(inspector, ruleEditor, view) {
|
|
||||||
yield createNewRuleViewProperty(ruleEditor, "width: 100px; heig");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps.length, 2, "Should have created a new text property.");
|
|
||||||
is(ruleEditor.propertyList.children.length, 2, "Should have created a property editor.");
|
|
||||||
|
|
||||||
// Value is focused, lets add multiple rules here and make sure they get added
|
|
||||||
let valueEditor = ruleEditor.propertyList.children[1].querySelector("input");
|
|
||||||
valueEditor.value = "10px;background:orangered;color: black;";
|
|
||||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps.length, 4, "Should have added the changed value.");
|
|
||||||
is(ruleEditor.propertyList.children.length, 5, "Should have added the changed value editor.");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[0].name, "width", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[0].value, "100px", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[1].name, "heig", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[1].value, "10px", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[2].name, "background", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[2].value, "orangered", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[3].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[3].value, "black", "Should have correct property value");
|
|
||||||
|
|
||||||
yield inspector.once("inspector-updated");
|
|
||||||
}
|
|
|
@ -0,0 +1,276 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let ruleWindow;
|
||||||
|
let ruleView;
|
||||||
|
let inspector;
|
||||||
|
let elementRuleEditor;
|
||||||
|
|
||||||
|
function startTest()
|
||||||
|
{
|
||||||
|
doc.body.innerHTML = '<h1>Testing Multiple Properties</h1>';
|
||||||
|
|
||||||
|
openRuleView((aInspector, aRuleView) => {
|
||||||
|
inspector = aInspector;
|
||||||
|
ruleView = aRuleView;
|
||||||
|
ruleWindow = aRuleView.doc.defaultView;
|
||||||
|
selectNewElement().then(testCreateNewMulti);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a new node to the DOM and resolve the promise once it is ready to use
|
||||||
|
*/
|
||||||
|
function selectNewElement()
|
||||||
|
{
|
||||||
|
let newElement = doc.createElement("div");
|
||||||
|
newElement.textContent = "Test Element";
|
||||||
|
doc.body.appendChild(newElement);
|
||||||
|
|
||||||
|
inspector.selection.setNode(newElement, "test");
|
||||||
|
let def = promise.defer();
|
||||||
|
ruleView.element.addEventListener("CssRuleViewRefreshed", function changed() {
|
||||||
|
ruleView.element.removeEventListener("CssRuleViewRefreshed", changed);
|
||||||
|
elementRuleEditor = ruleView.element.children[0]._ruleEditor;
|
||||||
|
def.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
|
return def.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Begin the creation of a new property, resolving after the editor
|
||||||
|
* has been created.
|
||||||
|
*/
|
||||||
|
function beginNewProp()
|
||||||
|
{
|
||||||
|
let def = promise.defer();
|
||||||
|
waitForEditorFocus(elementRuleEditor.element, function onNewElement(aEditor) {
|
||||||
|
|
||||||
|
is(inplaceEditor(elementRuleEditor.newPropSpan), aEditor, "Next focused editor should be the new property editor.");
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 0, "Should be starting with one new text property.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 1, "Should be starting with two property editors.");
|
||||||
|
|
||||||
|
def.resolve(aEditor);
|
||||||
|
});
|
||||||
|
elementRuleEditor.closeBrace.scrollIntoView();
|
||||||
|
EventUtils.synthesizeMouse(elementRuleEditor.closeBrace, 1, 1,
|
||||||
|
{ },
|
||||||
|
ruleWindow);
|
||||||
|
return def.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fully create a new property, given some text input
|
||||||
|
*/
|
||||||
|
function createNewProp(inputValue)
|
||||||
|
{
|
||||||
|
let def = promise.defer();
|
||||||
|
beginNewProp().then((aEditor)=>{
|
||||||
|
aEditor.input.value = inputValue;
|
||||||
|
|
||||||
|
waitForEditorFocus(elementRuleEditor.element, function onNewValue(aEditor) {
|
||||||
|
promiseDone(expectRuleChange(elementRuleEditor.rule).then(() => {
|
||||||
|
def.resolve();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_RETURN", {}, ruleWindow);
|
||||||
|
});
|
||||||
|
|
||||||
|
return def.promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCreateNewMulti()
|
||||||
|
{
|
||||||
|
createNewProp(
|
||||||
|
"color:blue;background : orange ; text-align:center; border-color: green;"
|
||||||
|
).then(()=>{
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 4, "Should have created a new text property.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 5, "Should have created a new property editor.");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[0].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[0].value, "blue", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[1].name, "background", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[1].value, "orange", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[2].name, "text-align", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[2].value, "center", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[3].name, "border-color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[3].value, "green", "Should have correct property value");
|
||||||
|
|
||||||
|
selectNewElement().then(testCreateNewMultiDuplicates);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCreateNewMultiDuplicates()
|
||||||
|
{
|
||||||
|
createNewProp(
|
||||||
|
"color:red;color:orange;color:yellow;color:green;color:blue;color:indigo;color:violet;"
|
||||||
|
).then(()=>{
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 7, "Should have created new text properties.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 8, "Should have created new property editors.");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[0].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[0].value, "red", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[1].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[1].value, "orange", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[2].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[2].value, "yellow", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[3].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[3].value, "green", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[4].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[4].value, "blue", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[5].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[5].value, "indigo", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[6].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[6].value, "violet", "Should have correct property value");
|
||||||
|
|
||||||
|
selectNewElement().then(testCreateNewMultiPriority);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCreateNewMultiPriority()
|
||||||
|
{
|
||||||
|
createNewProp(
|
||||||
|
"color:red;width:100px;height: 100px;"
|
||||||
|
).then(()=>{
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 3, "Should have created new text properties.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 4, "Should have created new property editors.");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[0].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[0].value, "red", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[1].name, "width", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[1].value, "100px", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[2].name, "height", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[2].value, "100px", "Should have correct property value");
|
||||||
|
|
||||||
|
selectNewElement().then(testCreateNewMultiUnfinished);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCreateNewMultiUnfinished()
|
||||||
|
{
|
||||||
|
createNewProp(
|
||||||
|
"color:blue;background : orange ; text-align:center; border-color: "
|
||||||
|
).then(()=>{
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 4, "Should have created new text properties.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 4, "Should have created property editors.");
|
||||||
|
|
||||||
|
for (let ch of "red") {
|
||||||
|
EventUtils.sendChar(ch, ruleWindow);
|
||||||
|
}
|
||||||
|
EventUtils.synthesizeKey("VK_RETURN", {}, ruleWindow);
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 4, "Should have the same number of text properties.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 5, "Should have added the changed value editor.");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[0].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[0].value, "blue", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[1].name, "background", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[1].value, "orange", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[2].name, "text-align", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[2].value, "center", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[3].name, "border-color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[3].value, "red", "Should have correct property value");
|
||||||
|
|
||||||
|
selectNewElement().then(testCreateNewMultiPartialUnfinished);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function testCreateNewMultiPartialUnfinished()
|
||||||
|
{
|
||||||
|
createNewProp(
|
||||||
|
"width: 100px; heig"
|
||||||
|
).then(()=>{
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 2, "Should have created a new text property.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 2, "Should have created a property editor.");
|
||||||
|
|
||||||
|
// Value is focused, lets add multiple rules here and make sure they get added
|
||||||
|
let valueEditor = elementRuleEditor.propertyList.children[1].querySelector("input");
|
||||||
|
valueEditor.value = "10px;background:orangered;color: black;";
|
||||||
|
EventUtils.synthesizeKey("VK_RETURN", {}, ruleWindow);
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 4, "Should have added the changed value.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 5, "Should have added the changed value editor.");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[0].name, "width", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[0].value, "100px", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[1].name, "heig", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[1].value, "10px", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[2].name, "background", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[2].value, "orangered", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[3].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[3].value, "black", "Should have correct property value");
|
||||||
|
|
||||||
|
selectNewElement().then(testMultiValues);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testMultiValues()
|
||||||
|
{
|
||||||
|
createNewProp(
|
||||||
|
"width:"
|
||||||
|
).then(()=>{
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 1, "Should have created a new text property.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 1, "Should have created a property editor.");
|
||||||
|
|
||||||
|
// Value is focused, lets add multiple rules here and make sure they get added
|
||||||
|
let valueEditor = elementRuleEditor.propertyList.children[0].querySelector("input");
|
||||||
|
valueEditor.value = "height: 10px;color:blue"
|
||||||
|
EventUtils.synthesizeKey("VK_RETURN", {}, ruleWindow);
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps.length, 2, "Should have added the changed value.");
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 3, "Should have added the changed value editor.");
|
||||||
|
|
||||||
|
EventUtils.synthesizeKey("VK_ESCAPE", {}, ruleWindow);
|
||||||
|
is(elementRuleEditor.propertyList.children.length, 2, "Should have removed the value editor.");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[0].name, "width", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[0].value, "height: 10px", "Should have correct property value");
|
||||||
|
|
||||||
|
is(elementRuleEditor.rule.textProps[1].name, "color", "Should have correct property name");
|
||||||
|
is(elementRuleEditor.rule.textProps[1].value, "blue", "Should have correct property value");
|
||||||
|
|
||||||
|
finishTest();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishTest()
|
||||||
|
{
|
||||||
|
inspector = ruleWindow = ruleView = doc = elementRuleEditor = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function changedValues_load(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, changedValues_load, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(startTest, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,test rule view user changes";
|
||||||
|
}
|
|
@ -1,45 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that the rule-view behaves correctly when entering mutliple and/or
|
|
||||||
// unfinished properties/values in inplace-editors
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,test rule view user changes");
|
|
||||||
content.document.body.innerHTML = "<h1>Testing Multiple Properties</h1>";
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Creating the test element");
|
|
||||||
let newElement = content.document.createElement("div");
|
|
||||||
newElement.textContent = "Test Element";
|
|
||||||
content.document.body.appendChild(newElement);
|
|
||||||
yield selectNode(newElement, inspector);
|
|
||||||
let ruleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
|
|
||||||
yield testCreateNewMulti(inspector, ruleEditor);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testCreateNewMulti(inspector, ruleEditor) {
|
|
||||||
yield createNewRuleViewProperty(ruleEditor,
|
|
||||||
"color:blue;background : orange ; text-align:center; border-color: green;");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps.length, 4, "Should have created a new text property.");
|
|
||||||
is(ruleEditor.propertyList.children.length, 5, "Should have created a new property editor.");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[0].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[0].value, "blue", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[1].name, "background", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[1].value, "orange", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[2].name, "text-align", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[2].value, "center", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[3].name, "border-color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[3].value, "green", "Should have correct property value");
|
|
||||||
|
|
||||||
yield inspector.once("inspector-updated");
|
|
||||||
}
|
|
|
@ -1,49 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that the rule-view behaves correctly when entering mutliple and/or
|
|
||||||
// unfinished properties/values in inplace-editors
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html,test rule view user changes");
|
|
||||||
content.document.body.innerHTML = "<h1>Testing Multiple Properties</h1>";
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Creating the test element");
|
|
||||||
let newElement = content.document.createElement("div");
|
|
||||||
newElement.textContent = "Test Element";
|
|
||||||
content.document.body.appendChild(newElement);
|
|
||||||
yield selectNode(newElement, inspector);
|
|
||||||
let ruleEditor = view.element.children[0]._ruleEditor;
|
|
||||||
|
|
||||||
yield testMultiValues(inspector, ruleEditor, view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testMultiValues(inspector, ruleEditor, view) {
|
|
||||||
yield createNewRuleViewProperty(ruleEditor, "width:");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps.length, 1, "Should have created a new text property.");
|
|
||||||
is(ruleEditor.propertyList.children.length, 1, "Should have created a property editor.");
|
|
||||||
|
|
||||||
// Value is focused, lets add multiple rules here and make sure they get added
|
|
||||||
let valueEditor = ruleEditor.propertyList.children[0].querySelector("input");
|
|
||||||
valueEditor.value = "height: 10px;color:blue"
|
|
||||||
EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView);
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps.length, 2, "Should have added the changed value.");
|
|
||||||
is(ruleEditor.propertyList.children.length, 3, "Should have added the changed value editor.");
|
|
||||||
|
|
||||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView);
|
|
||||||
is(ruleEditor.propertyList.children.length, 2, "Should have removed the value editor.");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[0].name, "width", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[0].value, "height: 10px", "Should have correct property value");
|
|
||||||
|
|
||||||
is(ruleEditor.rule.textProps[1].name, "color", "Should have correct property name");
|
|
||||||
is(ruleEditor.rule.textProps[1].value, "blue", "Should have correct property value");
|
|
||||||
|
|
||||||
yield inspector.once("inspector-updated");
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that the stylesheet links in the rule view are correct when source maps
|
|
||||||
// are involved
|
|
||||||
|
|
||||||
const TESTCASE_URI = TEST_URL_ROOT + "doc_sourcemaps.html";
|
|
||||||
const PREF = "devtools.styleeditor.source-maps-enabled";
|
|
||||||
const SCSS_LOC = "doc_sourcemaps.scss:4";
|
|
||||||
const CSS_LOC = "doc_sourcemaps.css:1";
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
info("Setting the " + PREF + " pref to true");
|
|
||||||
Services.prefs.setBoolPref(PREF, true);
|
|
||||||
|
|
||||||
info("Opening the test page and opening the inspector");
|
|
||||||
yield addTab(TESTCASE_URI);
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Selecting the test node");
|
|
||||||
yield selectNode("div", inspector);
|
|
||||||
|
|
||||||
yield verifyLinkText(SCSS_LOC, view);
|
|
||||||
|
|
||||||
info("Setting the " + PREF + " pref to false");
|
|
||||||
Services.prefs.setBoolPref(PREF, false);
|
|
||||||
yield verifyLinkText(CSS_LOC, view);
|
|
||||||
|
|
||||||
info("Setting the " + PREF + " pref to true again");
|
|
||||||
Services.prefs.setBoolPref(PREF, true);
|
|
||||||
|
|
||||||
yield testClickingLink(toolbox, view);
|
|
||||||
yield checkDisplayedStylesheet(toolbox);
|
|
||||||
|
|
||||||
info("Clearing the " + PREF + " pref");
|
|
||||||
Services.prefs.clearUserPref(PREF);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testClickingLink(toolbox, view) {
|
|
||||||
info("Listening for switch to the style editor");
|
|
||||||
let onStyleEditorReady = toolbox.once("styleeditor-ready");
|
|
||||||
|
|
||||||
info("Finding the stylesheet link and clicking it");
|
|
||||||
let link = getRuleViewLinkByIndex(view, 1);
|
|
||||||
link.scrollIntoView();
|
|
||||||
link.click();
|
|
||||||
yield onStyleEditorReady;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkDisplayedStylesheet(toolbox) {
|
|
||||||
let def = promise.defer();
|
|
||||||
|
|
||||||
let panel = toolbox.getCurrentPanel();
|
|
||||||
panel.UI.on("editor-selected", (event, editor) => {
|
|
||||||
// The style editor selects the first sheet at first load before
|
|
||||||
// selecting the desired sheet.
|
|
||||||
if (editor.styleSheet.href.endsWith("scss")) {
|
|
||||||
info("Original source editor selected");
|
|
||||||
editor.getSourceEditor().then(editorSelected).then(def.resolve, def.reject);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return def.promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
function editorSelected(editor) {
|
|
||||||
let href = editor.styleSheet.href;
|
|
||||||
ok(href.endsWith("doc_sourcemaps.scss"), "selected stylesheet is correct one");
|
|
||||||
|
|
||||||
let {line, col} = editor.sourceEditor.getCursor();
|
|
||||||
is(line, 3, "cursor is at correct line number in original source");
|
|
||||||
}
|
|
||||||
|
|
||||||
function verifyLinkText(text, view) {
|
|
||||||
info("Verifying that the rule-view stylesheet link is " + text);
|
|
||||||
let label = getRuleViewLinkByIndex(view, 1).querySelector("label");
|
|
||||||
return waitForSuccess(
|
|
||||||
() => label.getAttribute("value") == text,
|
|
||||||
"Link text changed to display correct location: " + text
|
|
||||||
);
|
|
||||||
}
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let win;
|
||||||
|
let doc;
|
||||||
|
let contentWindow;
|
||||||
|
let inspector;
|
||||||
|
let toolbox;
|
||||||
|
|
||||||
|
const TESTCASE_URI = TEST_BASE_HTTPS + "sourcemaps.html";
|
||||||
|
const PREF = "devtools.styleeditor.source-maps-enabled";
|
||||||
|
|
||||||
|
const SCSS_LOC = "sourcemaps.scss:4";
|
||||||
|
const CSS_LOC = "sourcemaps.css:1";
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
Services.prefs.setBoolPref(PREF, true);
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
|
||||||
|
true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(openToolbox, content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = TESTCASE_URI;
|
||||||
|
}
|
||||||
|
|
||||||
|
function openToolbox() {
|
||||||
|
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||||
|
|
||||||
|
gDevTools.showToolbox(target, "inspector").then(function(aToolbox) {
|
||||||
|
toolbox = aToolbox;
|
||||||
|
inspector = toolbox.getCurrentPanel();
|
||||||
|
inspector.sidebar.select("ruleview");
|
||||||
|
highlightNode();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function highlightNode()
|
||||||
|
{
|
||||||
|
// Highlight a node.
|
||||||
|
let div = content.document.getElementsByTagName("div")[0];
|
||||||
|
|
||||||
|
inspector.selection.setNode(div, "test");
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
is(inspector.selection.node, div, "selection matches the div element");
|
||||||
|
testRuleViewLink();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testRuleViewLink() {
|
||||||
|
verifyLinkText(SCSS_LOC, testTogglePref);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTogglePref() {
|
||||||
|
Services.prefs.setBoolPref(PREF, false);
|
||||||
|
|
||||||
|
verifyLinkText(CSS_LOC, () => {
|
||||||
|
Services.prefs.setBoolPref(PREF, true);
|
||||||
|
|
||||||
|
testClickingLink();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function testClickingLink() {
|
||||||
|
toolbox.once("styleeditor-ready", function(id, aToolbox) {
|
||||||
|
let panel = toolbox.getCurrentPanel();
|
||||||
|
panel.UI.on("editor-selected", (event, editor) => {
|
||||||
|
// The style editor selects the first sheet at first load before
|
||||||
|
// selecting the desired sheet.
|
||||||
|
if (editor.styleSheet.href.endsWith("scss")) {
|
||||||
|
info("original source editor selected");
|
||||||
|
editor.getSourceEditor().then(editorSelected);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let link = getLinkByIndex(1);
|
||||||
|
|
||||||
|
info("clicking rule view link");
|
||||||
|
link.scrollIntoView();
|
||||||
|
link.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function editorSelected(editor) {
|
||||||
|
let href = editor.styleSheet.href;
|
||||||
|
ok(href.endsWith("sourcemaps.scss"), "selected stylesheet is correct one");
|
||||||
|
|
||||||
|
let {line, col} = editor.sourceEditor.getCursor();
|
||||||
|
is(line, 3, "cursor is at correct line number in original source");
|
||||||
|
|
||||||
|
finishUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helpers */
|
||||||
|
|
||||||
|
function verifyLinkText(text, callback) {
|
||||||
|
let label = getLinkByIndex(1).querySelector("label");
|
||||||
|
|
||||||
|
waitForSuccess({
|
||||||
|
name: "link text changed to display correct location: " + text,
|
||||||
|
validatorFn: function()
|
||||||
|
{
|
||||||
|
return label.getAttribute("value") == text;
|
||||||
|
},
|
||||||
|
successFn: callback,
|
||||||
|
failureFn: callback,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLinkByIndex(aIndex)
|
||||||
|
{
|
||||||
|
let contentDoc = ruleView().doc;
|
||||||
|
contentWindow = contentDoc.defaultView;
|
||||||
|
let links = contentDoc.querySelectorAll(".ruleview-rule-source");
|
||||||
|
return links[aIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishUp()
|
||||||
|
{
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
contentWindow = doc = inspector = toolbox = win = null;
|
||||||
|
Services.prefs.clearUserPref(PREF);
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -1,67 +1,60 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
"use strict";
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let view;
|
||||||
|
|
||||||
// Test the display of overridden declarations in the rule-view
|
function simpleOverride(aInspector, aRuleView)
|
||||||
|
{
|
||||||
let test = asyncTest(function*() {
|
inspector = aInspector;
|
||||||
yield addTab("data:text/html;charset=utf-8,browser_ruleview_override.js");
|
view = aRuleView;
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
let style = '' +
|
||||||
|
|
||||||
yield simpleOverride(inspector, view);
|
|
||||||
yield partialOverride(inspector, view);
|
|
||||||
yield importantOverride(inspector, view);
|
|
||||||
yield disableOverride(inspector, view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* createTestContent(inspector, style) {
|
|
||||||
let onMutated = inspector.once("markupmutation");
|
|
||||||
let styleNode = addStyle(content.document, style);
|
|
||||||
content.document.body.innerHTML = '<div id="testid" class="testclass">Styled Node</div>';
|
|
||||||
yield onMutated;
|
|
||||||
yield selectNode("#testid", inspector);
|
|
||||||
return styleNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
function* simpleOverride(inspector, view) {
|
|
||||||
let styleNode = yield createTestContent(inspector, '' +
|
|
||||||
'#testid {' +
|
'#testid {' +
|
||||||
' background-color: blue;' +
|
' background-color: blue;' +
|
||||||
'} ' +
|
'} ' +
|
||||||
'.testclass {' +
|
'.testclass {' +
|
||||||
' background-color: green;' +
|
' background-color: green;' +
|
||||||
'}');
|
'}';
|
||||||
|
|
||||||
let elementStyle = view._elementStyle;
|
let styleNode = addStyle(doc, style);
|
||||||
|
doc.body.innerHTML = '<div id="testid" class="testclass">Styled Node</div>';
|
||||||
|
inspector.once("markupmutation", () => {
|
||||||
|
inspector.selection.setNode(doc.getElementById("testid"));
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
let elementStyle = view._elementStyle;
|
||||||
|
|
||||||
let idRule = elementStyle.rules[1];
|
let idRule = elementStyle.rules[1];
|
||||||
let idProp = idRule.textProps[0];
|
let idProp = idRule.textProps[0];
|
||||||
is(idProp.name, "background-color", "First ID prop should be background-color");
|
is(idProp.name, "background-color", "First ID prop should be background-color");
|
||||||
ok(!idProp.overridden, "ID prop should not be overridden.");
|
ok(!idProp.overridden, "ID prop should not be overridden.");
|
||||||
|
|
||||||
let classRule = elementStyle.rules[2];
|
let classRule = elementStyle.rules[2];
|
||||||
let classProp = classRule.textProps[0];
|
let classProp = classRule.textProps[0];
|
||||||
is(classProp.name, "background-color", "First class prop should be background-color");
|
is(classProp.name, "background-color", "First class prop should be background-color");
|
||||||
ok(classProp.overridden, "Class property should be overridden.");
|
ok(classProp.overridden, "Class property should be overridden.");
|
||||||
|
|
||||||
// Override background-color by changing the element style.
|
// Override background-color by changing the element style.
|
||||||
let elementRule = elementStyle.rules[0];
|
let elementRule = elementStyle.rules[0];
|
||||||
elementRule.createProperty("background-color", "purple", "");
|
elementRule.createProperty("background-color", "purple", "");
|
||||||
yield elementRule._applyingModifications;
|
promiseDone(elementRule._applyingModifications.then(() => {
|
||||||
|
let elementProp = elementRule.textProps[0];
|
||||||
|
is(classProp.name, "background-color", "First element prop should now be background-color");
|
||||||
|
ok(!elementProp.overridden, "Element style property should not be overridden");
|
||||||
|
ok(idProp.overridden, "ID property should be overridden");
|
||||||
|
ok(classProp.overridden, "Class property should be overridden");
|
||||||
|
|
||||||
let elementProp = elementRule.textProps[0];
|
styleNode.parentNode.removeChild(styleNode);
|
||||||
is(classProp.name, "background-color", "First element prop should now be background-color");
|
partialOverride();
|
||||||
ok(!elementProp.overridden, "Element style property should not be overridden");
|
}));
|
||||||
ok(idProp.overridden, "ID property should be overridden");
|
});
|
||||||
ok(classProp.overridden, "Class property should be overridden");
|
});
|
||||||
|
|
||||||
styleNode.remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function* partialOverride(inspector, view) {
|
function partialOverride()
|
||||||
let styleNode = yield createTestContent(inspector, '' +
|
{
|
||||||
|
let style = '' +
|
||||||
// Margin shorthand property...
|
// Margin shorthand property...
|
||||||
'.testclass {' +
|
'.testclass {' +
|
||||||
' margin: 2px;' +
|
' margin: 2px;' +
|
||||||
|
@ -69,28 +62,36 @@ function* partialOverride(inspector, view) {
|
||||||
// ... will be partially overridden.
|
// ... will be partially overridden.
|
||||||
'#testid {' +
|
'#testid {' +
|
||||||
' margin-left: 1px;' +
|
' margin-left: 1px;' +
|
||||||
'}');
|
'}';
|
||||||
|
|
||||||
let elementStyle = view._elementStyle;
|
let styleNode = addStyle(doc, style);
|
||||||
|
doc.body.innerHTML = '<div id="testid" class="testclass">Styled Node</div>';
|
||||||
|
inspector.once("markupmutation", () => {
|
||||||
|
inspector.selection.setNode(doc.getElementById("testid"));
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
let elementStyle = view._elementStyle;
|
||||||
|
|
||||||
let classRule = elementStyle.rules[2];
|
let classRule = elementStyle.rules[2];
|
||||||
let classProp = classRule.textProps[0];
|
let classProp = classRule.textProps[0];
|
||||||
ok(!classProp.overridden,
|
ok(!classProp.overridden, "Class prop shouldn't be overridden, some props are still being used.");
|
||||||
"Class prop shouldn't be overridden, some props are still being used.");
|
for (let computed of classProp.computed) {
|
||||||
|
if (computed.name.indexOf("margin-left") == 0) {
|
||||||
|
ok(computed.overridden, "margin-left props should be overridden.");
|
||||||
|
} else {
|
||||||
|
ok(!computed.overridden, "Non-margin-left props should not be overridden.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (let computed of classProp.computed) {
|
styleNode.parentNode.removeChild(styleNode);
|
||||||
if (computed.name.indexOf("margin-left") == 0) {
|
|
||||||
ok(computed.overridden, "margin-left props should be overridden.");
|
|
||||||
} else {
|
|
||||||
ok(!computed.overridden, "Non-margin-left props should not be overridden.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
styleNode.remove();
|
importantOverride();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function* importantOverride(inspector, view) {
|
function importantOverride()
|
||||||
let styleNode = yield createTestContent(inspector, '' +
|
{
|
||||||
|
let style = '' +
|
||||||
// Margin shorthand property...
|
// Margin shorthand property...
|
||||||
'.testclass {' +
|
'.testclass {' +
|
||||||
' background-color: green !important;' +
|
' background-color: green !important;' +
|
||||||
|
@ -98,49 +99,84 @@ function* importantOverride(inspector, view) {
|
||||||
// ... will be partially overridden.
|
// ... will be partially overridden.
|
||||||
'#testid {' +
|
'#testid {' +
|
||||||
' background-color: blue;' +
|
' background-color: blue;' +
|
||||||
'}');
|
'}';
|
||||||
|
let styleNode = addStyle(doc, style);
|
||||||
|
doc.body.innerHTML = '<div id="testid" class="testclass">Styled Node</div>';
|
||||||
|
inspector.once("markupmutation", () => {
|
||||||
|
inspector.selection.setNode(doc.getElementById("testid"));
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
let elementStyle = view._elementStyle;
|
||||||
|
|
||||||
let elementStyle = view._elementStyle;
|
let idRule = elementStyle.rules[1];
|
||||||
|
let idProp = idRule.textProps[0];
|
||||||
|
ok(idProp.overridden, "Not-important rule should be overridden.");
|
||||||
|
|
||||||
let idRule = elementStyle.rules[1];
|
let classRule = elementStyle.rules[2];
|
||||||
let idProp = idRule.textProps[0];
|
let classProp = classRule.textProps[0];
|
||||||
ok(idProp.overridden, "Not-important rule should be overridden.");
|
ok(!classProp.overridden, "Important rule should not be overridden.");
|
||||||
|
|
||||||
let classRule = elementStyle.rules[2];
|
styleNode.parentNode.removeChild(styleNode);
|
||||||
let classProp = classRule.textProps[0];
|
|
||||||
ok(!classProp.overridden, "Important rule should not be overridden.");
|
|
||||||
|
|
||||||
styleNode.remove();
|
let elementRule = elementStyle.rules[0];
|
||||||
|
let elementProp = elementRule.createProperty("background-color", "purple", "important");
|
||||||
|
promiseDone(elementRule._applyingModifications.then(() => {
|
||||||
|
ok(classProp.overridden, "New important prop should override class property.");
|
||||||
|
ok(!elementProp.overridden, "New important prop should not be overriden.");
|
||||||
|
|
||||||
let elementRule = elementStyle.rules[0];
|
disableOverride();
|
||||||
let elementProp = elementRule.createProperty("background-color", "purple", "important");
|
}));
|
||||||
yield elementRule._applyingModifications;
|
});
|
||||||
|
});
|
||||||
ok(classProp.overridden, "New important prop should override class property.");
|
|
||||||
ok(!elementProp.overridden, "New important prop should not be overriden.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function* disableOverride(inspector, view) {
|
function disableOverride()
|
||||||
let styleNode = yield createTestContent(inspector, '' +
|
{
|
||||||
|
let style = '' +
|
||||||
'#testid {' +
|
'#testid {' +
|
||||||
' background-color: blue;' +
|
' background-color: blue;' +
|
||||||
'}' +
|
'}' +
|
||||||
'.testclass {' +
|
'.testclass {' +
|
||||||
' background-color: green;' +
|
' background-color: green;' +
|
||||||
'}');
|
'}';
|
||||||
|
let styleNode = addStyle(doc, style);
|
||||||
|
doc.body.innerHTML = '<div id="testid" class="testclass">Styled Node</div>';
|
||||||
|
inspector.once("markupmutation", () => {
|
||||||
|
inspector.selection.setNode(doc.getElementById("testid"));
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
let elementStyle = view._elementStyle;
|
||||||
|
|
||||||
let elementStyle = view._elementStyle;
|
let idRule = elementStyle.rules[1];
|
||||||
|
let idProp = idRule.textProps[0];
|
||||||
|
idProp.setEnabled(false);
|
||||||
|
promiseDone(idRule._applyingModifications.then(() => {
|
||||||
|
let classRule = elementStyle.rules[2];
|
||||||
|
let classProp = classRule.textProps[0];
|
||||||
|
ok(!classProp.overridden, "Class prop should not be overridden after id prop was disabled.");
|
||||||
|
|
||||||
let idRule = elementStyle.rules[1];
|
styleNode.parentNode.removeChild(styleNode);
|
||||||
let idProp = idRule.textProps[0];
|
|
||||||
|
|
||||||
idProp.setEnabled(false);
|
finishTest();
|
||||||
yield idRule._applyingModifications;
|
}));
|
||||||
|
});
|
||||||
let classRule = elementStyle.rules[2];
|
});
|
||||||
let classProp = classRule.textProps[0];
|
}
|
||||||
ok(!classProp.overridden, "Class prop should not be overridden after id prop was disabled.");
|
|
||||||
|
function finishTest()
|
||||||
styleNode.remove();
|
{
|
||||||
yield inspector.once("inspector-updated");
|
doc = inspector = view = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(() => openRuleView(simpleOverride), content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html;charset=utf-8,browser_ruleview_override.js";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,275 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that pseudoelements are displayed correctly in the rule view
|
|
||||||
|
|
||||||
const TEST_URI = TEST_URL_ROOT + "doc_pseudoelement.html";
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab(TEST_URI);
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
yield testTopLeft(inspector, view);
|
|
||||||
yield testTopRight(inspector, view);
|
|
||||||
yield testBottomRight(inspector, view);
|
|
||||||
yield testBottomLeft(inspector, view);
|
|
||||||
yield testParagraph(inspector, view);
|
|
||||||
yield testBody(inspector, view);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testTopLeft(inspector, view) {
|
|
||||||
let {
|
|
||||||
rules,
|
|
||||||
element,
|
|
||||||
elementStyle
|
|
||||||
} = yield assertPseudoElementRulesNumbers("#topleft", inspector, view, {
|
|
||||||
elementRulesNb: 4,
|
|
||||||
afterRulesNb: 1,
|
|
||||||
beforeRulesNb: 2,
|
|
||||||
firstLineRulesNb: 0,
|
|
||||||
firstLetterRulesNb: 0,
|
|
||||||
selectionRulesNb: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
let gutters = assertGutters(view);
|
|
||||||
|
|
||||||
// Make sure that clicking on the twisty hides pseudo elements
|
|
||||||
let expander = gutters[0].querySelector(".ruleview-expander");
|
|
||||||
ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded");
|
|
||||||
expander.click();
|
|
||||||
ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by twisty");
|
|
||||||
expander.click();
|
|
||||||
ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded again");
|
|
||||||
|
|
||||||
// Make sure that dblclicking on the header container also toggles the pseudo elements
|
|
||||||
EventUtils.synthesizeMouseAtCenter(gutters[0], {clickCount: 2}, inspector.sidebar.getWindowForTab("ruleview"));
|
|
||||||
ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by dblclicking");
|
|
||||||
|
|
||||||
let defaultView = element.ownerDocument.defaultView;
|
|
||||||
let elementRule = rules.elementRules[0];
|
|
||||||
let elementRuleView = [].filter.call(view.element.children, e => {
|
|
||||||
return e._ruleEditor && e._ruleEditor.rule === elementRule;
|
|
||||||
})[0]._ruleEditor;
|
|
||||||
|
|
||||||
let elementAfterRule = rules.afterRules[0];
|
|
||||||
let elementAfterRuleView = [].filter.call(view.element.children, (e) => {
|
|
||||||
return e._ruleEditor && e._ruleEditor.rule === elementAfterRule;
|
|
||||||
})[0]._ruleEditor;
|
|
||||||
|
|
||||||
is
|
|
||||||
(
|
|
||||||
convertTextPropsToString(elementAfterRule.textProps),
|
|
||||||
"background: none repeat scroll 0% 0% red; content: \" \"; position: absolute; " +
|
|
||||||
"border-radius: 50%; height: 32px; width: 32px; top: 50%; left: 50%; margin-top: -16px; margin-left: -16px",
|
|
||||||
"TopLeft after properties are correct"
|
|
||||||
);
|
|
||||||
|
|
||||||
let elementBeforeRule = rules.beforeRules[0];
|
|
||||||
let elementBeforeRuleView = [].filter.call(view.element.children, (e) => {
|
|
||||||
return e._ruleEditor && e._ruleEditor.rule === elementBeforeRule;
|
|
||||||
})[0]._ruleEditor;
|
|
||||||
|
|
||||||
is
|
|
||||||
(
|
|
||||||
convertTextPropsToString(elementBeforeRule.textProps),
|
|
||||||
"top: 0px; left: 0px",
|
|
||||||
"TopLeft before properties are correct"
|
|
||||||
);
|
|
||||||
|
|
||||||
let firstProp = elementAfterRuleView.addProperty("background-color", "rgb(0, 255, 0)", "");
|
|
||||||
let secondProp = elementAfterRuleView.addProperty("padding", "100px", "");
|
|
||||||
|
|
||||||
is (firstProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 2],
|
|
||||||
"First added property is on back of array");
|
|
||||||
is (secondProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 1],
|
|
||||||
"Second added property is on back of array");
|
|
||||||
|
|
||||||
yield elementAfterRule._applyingModifications;
|
|
||||||
|
|
||||||
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"),
|
|
||||||
"rgb(0, 255, 0)", "Added property should have been used.");
|
|
||||||
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"),
|
|
||||||
"100px", "Added property should have been used.");
|
|
||||||
is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"),
|
|
||||||
"32px", "Added property should not apply to element");
|
|
||||||
|
|
||||||
secondProp.setEnabled(false);
|
|
||||||
yield elementAfterRule._applyingModifications;
|
|
||||||
|
|
||||||
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "0px",
|
|
||||||
"Disabled property should have been used.");
|
|
||||||
is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px",
|
|
||||||
"Added property should not apply to element");
|
|
||||||
|
|
||||||
secondProp.setEnabled(true);
|
|
||||||
yield elementAfterRule._applyingModifications;
|
|
||||||
|
|
||||||
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "100px",
|
|
||||||
"Enabled property should have been used.");
|
|
||||||
is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px",
|
|
||||||
"Added property should not apply to element");
|
|
||||||
|
|
||||||
let firstProp = elementRuleView.addProperty("background-color", "rgb(0, 0, 255)", "");
|
|
||||||
yield elementRule._applyingModifications;
|
|
||||||
|
|
||||||
is(defaultView.getComputedStyle(element).getPropertyValue("background-color"), "rgb(0, 0, 255)",
|
|
||||||
"Added property should have been used.");
|
|
||||||
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), "rgb(0, 255, 0)",
|
|
||||||
"Added prop does not apply to pseudo");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testTopRight(inspector, view) {
|
|
||||||
let {
|
|
||||||
rules,
|
|
||||||
element,
|
|
||||||
elementStyle
|
|
||||||
} = yield assertPseudoElementRulesNumbers("#topright", inspector, view, {
|
|
||||||
elementRulesNb: 4,
|
|
||||||
afterRulesNb: 1,
|
|
||||||
beforeRulesNb: 2,
|
|
||||||
firstLineRulesNb: 0,
|
|
||||||
firstLetterRulesNb: 0,
|
|
||||||
selectionRulesNb: 0
|
|
||||||
});
|
|
||||||
|
|
||||||
let gutters = assertGutters(view);
|
|
||||||
|
|
||||||
let expander = gutters[0].querySelector(".ruleview-expander");
|
|
||||||
ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements remain collapsed after switching element");
|
|
||||||
expander.scrollIntoView();
|
|
||||||
expander.click();
|
|
||||||
ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are shown again after clicking twisty");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testBottomRight(inspector, view) {
|
|
||||||
yield assertPseudoElementRulesNumbers("#bottomright", inspector, view, {
|
|
||||||
elementRulesNb: 4,
|
|
||||||
afterRulesNb: 1,
|
|
||||||
beforeRulesNb: 3,
|
|
||||||
firstLineRulesNb: 0,
|
|
||||||
firstLetterRulesNb: 0,
|
|
||||||
selectionRulesNb: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testBottomLeft(inspector, view) {
|
|
||||||
yield assertPseudoElementRulesNumbers("#bottomleft", inspector, view, {
|
|
||||||
elementRulesNb: 4,
|
|
||||||
afterRulesNb: 1,
|
|
||||||
beforeRulesNb: 2,
|
|
||||||
firstLineRulesNb: 0,
|
|
||||||
firstLetterRulesNb: 0,
|
|
||||||
selectionRulesNb: 0
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testParagraph(inspector, view) {
|
|
||||||
let {
|
|
||||||
rules,
|
|
||||||
element,
|
|
||||||
elementStyle
|
|
||||||
} = yield assertPseudoElementRulesNumbers("#bottomleft p", inspector, view, {
|
|
||||||
elementRulesNb: 3,
|
|
||||||
afterRulesNb: 0,
|
|
||||||
beforeRulesNb: 0,
|
|
||||||
firstLineRulesNb: 1,
|
|
||||||
firstLetterRulesNb: 1,
|
|
||||||
selectionRulesNb: 1
|
|
||||||
});
|
|
||||||
|
|
||||||
let gutters = assertGutters(view);
|
|
||||||
|
|
||||||
let elementFirstLineRule = rules.firstLineRules[0];
|
|
||||||
let elementFirstLineRuleView = [].filter.call(view.element.children, (e) => {
|
|
||||||
return e._ruleEditor && e._ruleEditor.rule === elementFirstLineRule;
|
|
||||||
})[0]._ruleEditor;
|
|
||||||
|
|
||||||
is
|
|
||||||
(
|
|
||||||
convertTextPropsToString(elementFirstLineRule.textProps),
|
|
||||||
"background: none repeat scroll 0% 0% blue",
|
|
||||||
"Paragraph first-line properties are correct"
|
|
||||||
);
|
|
||||||
|
|
||||||
let elementFirstLetterRule = rules.firstLetterRules[0];
|
|
||||||
let elementFirstLetterRuleView = [].filter.call(view.element.children, (e) => {
|
|
||||||
return e._ruleEditor && e._ruleEditor.rule === elementFirstLetterRule;
|
|
||||||
})[0]._ruleEditor;
|
|
||||||
|
|
||||||
is
|
|
||||||
(
|
|
||||||
convertTextPropsToString(elementFirstLetterRule.textProps),
|
|
||||||
"color: red; font-size: 130%",
|
|
||||||
"Paragraph first-letter properties are correct"
|
|
||||||
);
|
|
||||||
|
|
||||||
let elementSelectionRule = rules.selectionRules[0];
|
|
||||||
let elementSelectionRuleView = [].filter.call(view.element.children, (e) => {
|
|
||||||
return e._ruleEditor && e._ruleEditor.rule === elementSelectionRule;
|
|
||||||
})[0]._ruleEditor;
|
|
||||||
|
|
||||||
is
|
|
||||||
(
|
|
||||||
convertTextPropsToString(elementSelectionRule.textProps),
|
|
||||||
"color: white; background: none repeat scroll 0% 0% black",
|
|
||||||
"Paragraph first-letter properties are correct"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testBody(inspector, view) {
|
|
||||||
let {element, elementStyle} = yield testNode("body", inspector, view);
|
|
||||||
|
|
||||||
let gutters = view.element.querySelectorAll(".theme-gutter");
|
|
||||||
is (gutters.length, 0, "There are no gutter headings");
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertTextPropsToString(textProps) {
|
|
||||||
return textProps.map(t => t.name + ": " + t.value).join("; ");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testNode(selector, inspector, view) {
|
|
||||||
let element = getNode(selector);
|
|
||||||
yield selectNode(element, inspector);
|
|
||||||
let elementStyle = view._elementStyle;
|
|
||||||
return {element: element, elementStyle: elementStyle};
|
|
||||||
}
|
|
||||||
|
|
||||||
function* assertPseudoElementRulesNumbers(selector, inspector, view, ruleNbs) {
|
|
||||||
let {element, elementStyle} = yield testNode(selector, inspector, view);
|
|
||||||
|
|
||||||
let rules = {
|
|
||||||
elementRules: elementStyle.rules.filter(rule => !rule.pseudoElement),
|
|
||||||
afterRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":after"),
|
|
||||||
beforeRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":before"),
|
|
||||||
firstLineRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":first-line"),
|
|
||||||
firstLetterRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":first-letter"),
|
|
||||||
selectionRules: elementStyle.rules.filter(rule => rule.pseudoElement === ":-moz-selection")
|
|
||||||
};
|
|
||||||
|
|
||||||
is(rules.elementRules.length, ruleNbs.elementRulesNb, selector +
|
|
||||||
" has the correct number of non pseudo element rules");
|
|
||||||
is(rules.afterRules.length, ruleNbs.afterRulesNb, selector +
|
|
||||||
" has the correct number of :after rules");
|
|
||||||
is(rules.beforeRules.length, ruleNbs.beforeRulesNb, selector +
|
|
||||||
" has the correct number of :before rules");
|
|
||||||
is(rules.firstLineRules.length, ruleNbs.firstLineRulesNb, selector +
|
|
||||||
" has the correct number of :first-line rules");
|
|
||||||
is(rules.firstLetterRules.length, ruleNbs.firstLetterRulesNb, selector +
|
|
||||||
" has the correct number of :first-letter rules");
|
|
||||||
is(rules.selectionRules.length, ruleNbs.selectionRulesNb, selector +
|
|
||||||
" has the correct number of :selection rules");
|
|
||||||
|
|
||||||
return {rules: rules, element: element, elementStyle: elementStyle};
|
|
||||||
}
|
|
||||||
|
|
||||||
function assertGutters(view) {
|
|
||||||
let gutters = view.element.querySelectorAll(".theme-gutter");
|
|
||||||
is (gutters.length, 3, "There are 3 gutter headings");
|
|
||||||
is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct");
|
|
||||||
is (gutters[1].textContent, "This Element", "Gutter heading is correct");
|
|
||||||
is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct");
|
|
||||||
return gutters;
|
|
||||||
}
|
|
|
@ -0,0 +1,320 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
let doc;
|
||||||
|
let inspector;
|
||||||
|
let view;
|
||||||
|
|
||||||
|
const TEST_URI = "http://example.com/browser/browser/" +
|
||||||
|
"devtools/styleinspector/test/" +
|
||||||
|
"browser_ruleview_pseudoelement.html";
|
||||||
|
|
||||||
|
function testPseudoElements(aInspector, aRuleView)
|
||||||
|
{
|
||||||
|
inspector = aInspector;
|
||||||
|
view = aRuleView;
|
||||||
|
|
||||||
|
testTopLeft();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTopLeft()
|
||||||
|
{
|
||||||
|
testNode(doc.querySelector("#topleft"), (element, elementStyle) => {
|
||||||
|
let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
|
||||||
|
let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
|
||||||
|
let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
|
||||||
|
let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
|
||||||
|
let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
|
||||||
|
let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
|
||||||
|
|
||||||
|
is(elementRules.length, 4, "TopLeft has the correct number of non psuedo element rules");
|
||||||
|
is(afterRules.length, 1, "TopLeft has the correct number of :after rules");
|
||||||
|
is(beforeRules.length, 2, "TopLeft has the correct number of :before rules");
|
||||||
|
is(firstLineRules.length, 0, "TopLeft has the correct number of :first-line rules");
|
||||||
|
is(firstLetterRules.length, 0, "TopLeft has the correct number of :first-letter rules");
|
||||||
|
is(selectionRules.length, 0, "TopLeft has the correct number of :selection rules");
|
||||||
|
|
||||||
|
let gutters = view.element.querySelectorAll(".theme-gutter");
|
||||||
|
is (gutters.length, 3, "There are three gutter headings");
|
||||||
|
is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct");
|
||||||
|
is (gutters[1].textContent, "This Element", "Gutter heading is correct");
|
||||||
|
is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct");
|
||||||
|
|
||||||
|
// Make sure that clicking on the twisty hides pseudo elements
|
||||||
|
let expander = gutters[0].querySelector(".ruleview-expander");
|
||||||
|
ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded");
|
||||||
|
expander.click();
|
||||||
|
ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by twisty");
|
||||||
|
expander.click();
|
||||||
|
ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded again");
|
||||||
|
|
||||||
|
// Make sure that dblclicking on the header container also toggles the pseudo elements
|
||||||
|
EventUtils.synthesizeMouseAtCenter(gutters[0], {clickCount: 2}, inspector.sidebar.getWindowForTab("ruleview"));
|
||||||
|
ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by dblclicking");
|
||||||
|
|
||||||
|
let defaultView = element.ownerDocument.defaultView;
|
||||||
|
let elementRule = elementRules[0];
|
||||||
|
let elementRuleView = [].filter.call(view.element.children, (e) => {
|
||||||
|
return e._ruleEditor && e._ruleEditor.rule === elementRule;
|
||||||
|
})[0]._ruleEditor;
|
||||||
|
|
||||||
|
let elementAfterRule = afterRules[0];
|
||||||
|
let elementAfterRuleView = [].filter.call(view.element.children, (e) => {
|
||||||
|
return e._ruleEditor && e._ruleEditor.rule === elementAfterRule;
|
||||||
|
})[0]._ruleEditor;
|
||||||
|
|
||||||
|
is
|
||||||
|
(
|
||||||
|
convertTextPropsToString(elementAfterRule.textProps),
|
||||||
|
"background: none repeat scroll 0% 0% red; content: \" \"; position: absolute; " +
|
||||||
|
"border-radius: 50%; height: 32px; width: 32px; top: 50%; left: 50%; margin-top: -16px; margin-left: -16px",
|
||||||
|
"TopLeft after properties are correct"
|
||||||
|
);
|
||||||
|
|
||||||
|
let elementBeforeRule = beforeRules[0];
|
||||||
|
let elementBeforeRuleView = [].filter.call(view.element.children, (e) => {
|
||||||
|
return e._ruleEditor && e._ruleEditor.rule === elementBeforeRule;
|
||||||
|
})[0]._ruleEditor;
|
||||||
|
|
||||||
|
is
|
||||||
|
(
|
||||||
|
convertTextPropsToString(elementBeforeRule.textProps),
|
||||||
|
"top: 0px; left: 0px",
|
||||||
|
"TopLeft before properties are correct"
|
||||||
|
);
|
||||||
|
|
||||||
|
let firstProp = elementAfterRuleView.addProperty("background-color", "rgb(0, 255, 0)", "");
|
||||||
|
let secondProp = elementAfterRuleView.addProperty("padding", "100px", "");
|
||||||
|
|
||||||
|
is (firstProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 2],
|
||||||
|
"First added property is on back of array");
|
||||||
|
is (secondProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 1],
|
||||||
|
"Second added property is on back of array");
|
||||||
|
|
||||||
|
promiseDone(elementAfterRule._applyingModifications.then(() => {
|
||||||
|
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"),
|
||||||
|
"rgb(0, 255, 0)", "Added property should have been used.");
|
||||||
|
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"),
|
||||||
|
"100px", "Added property should have been used.");
|
||||||
|
is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"),
|
||||||
|
"32px", "Added property should not apply to element");
|
||||||
|
|
||||||
|
secondProp.setEnabled(false);
|
||||||
|
|
||||||
|
return elementAfterRule._applyingModifications;
|
||||||
|
}).then(() => {
|
||||||
|
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "0px",
|
||||||
|
"Disabled property should have been used.");
|
||||||
|
is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px",
|
||||||
|
"Added property should not apply to element");
|
||||||
|
|
||||||
|
secondProp.setEnabled(true);
|
||||||
|
|
||||||
|
return elementAfterRule._applyingModifications;
|
||||||
|
}).then(() => {
|
||||||
|
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "100px",
|
||||||
|
"Enabled property should have been used.");
|
||||||
|
is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px",
|
||||||
|
"Added property should not apply to element");
|
||||||
|
|
||||||
|
let firstProp = elementRuleView.addProperty("background-color", "rgb(0, 0, 255)", "");
|
||||||
|
|
||||||
|
return elementRule._applyingModifications;
|
||||||
|
}).then(() => {
|
||||||
|
is(defaultView.getComputedStyle(element).getPropertyValue("background-color"), "rgb(0, 0, 255)",
|
||||||
|
"Added property should have been used.");
|
||||||
|
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), "rgb(0, 255, 0)",
|
||||||
|
"Added prop does not apply to pseudo");
|
||||||
|
|
||||||
|
testTopRight();
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testTopRight()
|
||||||
|
{
|
||||||
|
testNode(doc.querySelector("#topright"), (element, elementStyle) => {
|
||||||
|
|
||||||
|
let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
|
||||||
|
let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
|
||||||
|
let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
|
||||||
|
let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
|
||||||
|
let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
|
||||||
|
let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
|
||||||
|
|
||||||
|
is(elementRules.length, 4, "TopRight has the correct number of non psuedo element rules");
|
||||||
|
is(afterRules.length, 1, "TopRight has the correct number of :after rules");
|
||||||
|
is(beforeRules.length, 2, "TopRight has the correct number of :before rules");
|
||||||
|
is(firstLineRules.length, 0, "TopRight has the correct number of :first-line rules");
|
||||||
|
is(firstLetterRules.length, 0, "TopRight has the correct number of :first-letter rules");
|
||||||
|
is(selectionRules.length, 0, "TopRight has the correct number of :selection rules");
|
||||||
|
|
||||||
|
let gutters = view.element.querySelectorAll(".theme-gutter");
|
||||||
|
is (gutters.length, 3, "There are three gutter headings");
|
||||||
|
is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct");
|
||||||
|
is (gutters[1].textContent, "This Element", "Gutter heading is correct");
|
||||||
|
is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct");
|
||||||
|
|
||||||
|
let expander = gutters[0].querySelector(".ruleview-expander");
|
||||||
|
ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements remain collapsed after switching element");
|
||||||
|
expander.scrollIntoView();
|
||||||
|
expander.click();
|
||||||
|
ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are shown again after clicking twisty");
|
||||||
|
|
||||||
|
testBottomRight();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testBottomRight()
|
||||||
|
{
|
||||||
|
testNode(doc.querySelector("#bottomright"), (element, elementStyle) => {
|
||||||
|
|
||||||
|
let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
|
||||||
|
let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
|
||||||
|
let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
|
||||||
|
let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
|
||||||
|
let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
|
||||||
|
let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
|
||||||
|
|
||||||
|
is(elementRules.length, 4, "BottomRight has the correct number of non psuedo element rules");
|
||||||
|
is(afterRules.length, 1, "BottomRight has the correct number of :after rules");
|
||||||
|
is(beforeRules.length, 3, "BottomRight has the correct number of :before rules");
|
||||||
|
is(firstLineRules.length, 0, "BottomRight has the correct number of :first-line rules");
|
||||||
|
is(firstLetterRules.length, 0, "BottomRight has the correct number of :first-letter rules");
|
||||||
|
is(selectionRules.length, 0, "BottomRight has the correct number of :selection rules");
|
||||||
|
|
||||||
|
testBottomLeft();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testBottomLeft()
|
||||||
|
{
|
||||||
|
testNode(doc.querySelector("#bottomleft"), (element, elementStyle) => {
|
||||||
|
|
||||||
|
let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
|
||||||
|
let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
|
||||||
|
let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
|
||||||
|
let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
|
||||||
|
let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
|
||||||
|
let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
|
||||||
|
|
||||||
|
is(elementRules.length, 4, "BottomLeft has the correct number of non psuedo element rules");
|
||||||
|
is(afterRules.length, 1, "BottomLeft has the correct number of :after rules");
|
||||||
|
is(beforeRules.length, 2, "BottomLeft has the correct number of :before rules");
|
||||||
|
is(firstLineRules.length, 0, "BottomLeft has the correct number of :first-line rules");
|
||||||
|
is(firstLetterRules.length, 0, "BottomLeft has the correct number of :first-letter rules");
|
||||||
|
is(selectionRules.length, 0, "BottomLeft has the correct number of :selection rules");
|
||||||
|
|
||||||
|
testParagraph();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testParagraph()
|
||||||
|
{
|
||||||
|
testNode(doc.querySelector("#bottomleft p"), (element, elementStyle) => {
|
||||||
|
|
||||||
|
let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
|
||||||
|
let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
|
||||||
|
let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
|
||||||
|
let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
|
||||||
|
let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
|
||||||
|
let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
|
||||||
|
|
||||||
|
is(elementRules.length, 3, "Paragraph has the correct number of non psuedo element rules");
|
||||||
|
is(afterRules.length, 0, "Paragraph has the correct number of :after rules");
|
||||||
|
is(beforeRules.length, 0, "Paragraph has the correct number of :before rules");
|
||||||
|
is(firstLineRules.length, 1, "Paragraph has the correct number of :first-line rules");
|
||||||
|
is(firstLetterRules.length, 1, "Paragraph has the correct number of :first-letter rules");
|
||||||
|
is(selectionRules.length, 1, "Paragraph has the correct number of :selection rules");
|
||||||
|
|
||||||
|
let gutters = view.element.querySelectorAll(".theme-gutter");
|
||||||
|
is (gutters.length, 3, "There are three gutter headings");
|
||||||
|
is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct");
|
||||||
|
is (gutters[1].textContent, "This Element", "Gutter heading is correct");
|
||||||
|
is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct");
|
||||||
|
|
||||||
|
let elementFirstLineRule = firstLineRules[0];
|
||||||
|
let elementFirstLineRuleView = [].filter.call(view.element.children, (e) => {
|
||||||
|
return e._ruleEditor && e._ruleEditor.rule === elementFirstLineRule;
|
||||||
|
})[0]._ruleEditor;
|
||||||
|
|
||||||
|
is
|
||||||
|
(
|
||||||
|
convertTextPropsToString(elementFirstLineRule.textProps),
|
||||||
|
"background: none repeat scroll 0% 0% blue",
|
||||||
|
"Paragraph first-line properties are correct"
|
||||||
|
);
|
||||||
|
|
||||||
|
let elementFirstLetterRule = firstLetterRules[0];
|
||||||
|
let elementFirstLetterRuleView = [].filter.call(view.element.children, (e) => {
|
||||||
|
return e._ruleEditor && e._ruleEditor.rule === elementFirstLetterRule;
|
||||||
|
})[0]._ruleEditor;
|
||||||
|
|
||||||
|
is
|
||||||
|
(
|
||||||
|
convertTextPropsToString(elementFirstLetterRule.textProps),
|
||||||
|
"color: red; font-size: 130%",
|
||||||
|
"Paragraph first-letter properties are correct"
|
||||||
|
);
|
||||||
|
|
||||||
|
let elementSelectionRule = selectionRules[0];
|
||||||
|
let elementSelectionRuleView = [].filter.call(view.element.children, (e) => {
|
||||||
|
return e._ruleEditor && e._ruleEditor.rule === elementSelectionRule;
|
||||||
|
})[0]._ruleEditor;
|
||||||
|
|
||||||
|
is
|
||||||
|
(
|
||||||
|
convertTextPropsToString(elementSelectionRule.textProps),
|
||||||
|
"color: white; background: none repeat scroll 0% 0% black",
|
||||||
|
"Paragraph first-letter properties are correct"
|
||||||
|
);
|
||||||
|
|
||||||
|
testBody();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testBody() {
|
||||||
|
|
||||||
|
testNode(doc.querySelector("body"), (element, elementStyle) => {
|
||||||
|
|
||||||
|
let gutters = view.element.querySelectorAll(".theme-gutter");
|
||||||
|
is (gutters.length, 0, "There are no gutter headings");
|
||||||
|
|
||||||
|
finishTest();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
function convertTextPropsToString(textProps) {
|
||||||
|
return textProps.map((t) => {
|
||||||
|
return t.name + ": " + t.value;
|
||||||
|
}).join("; ");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNode(node, cb)
|
||||||
|
{
|
||||||
|
inspector.once("inspector-updated", () => {
|
||||||
|
cb(node, view._elementStyle)
|
||||||
|
});
|
||||||
|
inspector.selection.setNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishTest()
|
||||||
|
{
|
||||||
|
doc = inspector = view = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
|
||||||
|
doc = content.document;
|
||||||
|
waitForFocus(() => openRuleView(testPseudoElements), content);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = TEST_URI;
|
||||||
|
}
|
|
@ -1,58 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that changing the current element's attributes refreshes the rule-view
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html;charset=utf-8,browser_ruleview_refresh-on-attribute-change.js");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
info("Preparing the test document and node");
|
|
||||||
let style = '' +
|
|
||||||
'#testid {' +
|
|
||||||
' background-color: blue;' +
|
|
||||||
'} ' +
|
|
||||||
'.testclass {' +
|
|
||||||
' background-color: green;' +
|
|
||||||
'}';
|
|
||||||
let styleNode = addStyle(content.document, style);
|
|
||||||
content.document.body.innerHTML = '<div id="testid" class="testclass">Styled Node</div>';
|
|
||||||
let testElement = getNode("#testid");
|
|
||||||
let elementStyle = 'margin-top: 1px; padding-top: 5px;'
|
|
||||||
testElement.setAttribute("style", elementStyle);
|
|
||||||
yield selectNode(testElement, inspector);
|
|
||||||
|
|
||||||
info("Checking that the rule-view has the element, #testid and .testclass selectors");
|
|
||||||
checkRuleViewContent(view, ["element", "#testid", ".testclass"]);
|
|
||||||
|
|
||||||
info("Changing the node's ID attribute and waiting for the rule-view refresh");
|
|
||||||
let ruleViewRefreshed = inspector.once("rule-view-refreshed");
|
|
||||||
testElement.setAttribute("id", "differentid");
|
|
||||||
yield ruleViewRefreshed;
|
|
||||||
|
|
||||||
info("Checking that the rule-view doesn't have the #testid selector anymore");
|
|
||||||
checkRuleViewContent(view, ["element", ".testclass"]);
|
|
||||||
|
|
||||||
info("Reverting the ID attribute change");
|
|
||||||
let ruleViewRefreshed = inspector.once("rule-view-refreshed");
|
|
||||||
testElement.setAttribute("id", "testid");
|
|
||||||
yield ruleViewRefreshed;
|
|
||||||
|
|
||||||
info("Checking that the rule-view has all the selectors again");
|
|
||||||
checkRuleViewContent(view, ["element", "#testid", ".testclass"]);
|
|
||||||
});
|
|
||||||
|
|
||||||
function checkRuleViewContent(view, expectedSelectors) {
|
|
||||||
let selectors = view.doc.querySelectorAll(".ruleview-selector");
|
|
||||||
|
|
||||||
is(selectors.length, expectedSelectors.length,
|
|
||||||
expectedSelectors.length + " selectors are displayed");
|
|
||||||
|
|
||||||
for (let i = 0; i < expectedSelectors.length; i ++) {
|
|
||||||
is(selectors[i].textContent.indexOf(expectedSelectors[i]), 0,
|
|
||||||
"Selector " + (i + 1) + " is " + expectedSelectors[i]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,122 +0,0 @@
|
||||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Test that changing the current element's style attribute refreshes the rule-view
|
|
||||||
|
|
||||||
let test = asyncTest(function*() {
|
|
||||||
yield addTab("data:text/html;charset=utf-8,browser_ruleview_update.js");
|
|
||||||
let {toolbox, inspector, view} = yield openRuleView();
|
|
||||||
|
|
||||||
content.document.body.innerHTML = '<div id="testid" class="testclass">Styled Node</div>';
|
|
||||||
let testElement = getNode("#testid");
|
|
||||||
testElement.setAttribute("style", "margin-top: 1px; padding-top: 5px;");
|
|
||||||
yield selectNode(testElement, inspector);
|
|
||||||
|
|
||||||
yield testPropertyChanges(inspector, view, testElement);
|
|
||||||
yield testPropertyChange0(inspector, view, testElement);
|
|
||||||
yield testPropertyChange1(inspector, view, testElement);
|
|
||||||
yield testPropertyChange2(inspector, view, testElement);
|
|
||||||
yield testPropertyChange3(inspector, view, testElement);
|
|
||||||
yield testPropertyChange4(inspector, view, testElement);
|
|
||||||
yield testPropertyChange5(inspector, view, testElement);
|
|
||||||
yield testPropertyChange6(inspector, view, testElement);
|
|
||||||
});
|
|
||||||
|
|
||||||
function* testPropertyChanges(inspector, ruleView, testElement) {
|
|
||||||
info("Adding a second margin-top value in the element selector");
|
|
||||||
let ruleEditor = ruleView._elementStyle.rules[0].editor;
|
|
||||||
let onRefreshed = inspector.once("rule-view-refreshed");
|
|
||||||
ruleEditor.addProperty("margin-top", "5px", "");
|
|
||||||
yield onRefreshed;
|
|
||||||
|
|
||||||
let rule = ruleView._elementStyle.rules[0];
|
|
||||||
validateTextProp(rule.textProps[0], false, "margin-top", "1px", "Original margin property active");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testPropertyChange0(inspector, ruleView, testElement) {
|
|
||||||
yield changeElementStyle(testElement, "margin-top: 1px; padding-top: 5px", inspector);
|
|
||||||
|
|
||||||
let rule = ruleView._elementStyle.rules[0];
|
|
||||||
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
|
|
||||||
validateTextProp(rule.textProps[0], true, "margin-top", "1px", "First margin property re-enabled");
|
|
||||||
validateTextProp(rule.textProps[2], false, "margin-top", "5px", "Second margin property disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testPropertyChange1(inspector, ruleView, testElement) {
|
|
||||||
info("Now set it back to 5px, the 5px value should be re-enabled.");
|
|
||||||
yield changeElementStyle(testElement, "margin-top: 5px; padding-top: 5px;", inspector);
|
|
||||||
|
|
||||||
let rule = ruleView._elementStyle.rules[0];
|
|
||||||
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
|
|
||||||
validateTextProp(rule.textProps[0], false, "margin-top", "1px", "First margin property re-enabled");
|
|
||||||
validateTextProp(rule.textProps[2], true, "margin-top", "5px", "Second margin property disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testPropertyChange2(inspector, ruleView, testElement) {
|
|
||||||
info("Set the margin property to a value that doesn't exist in the editor.");
|
|
||||||
info("Should reuse the currently-enabled element (the second one.)");
|
|
||||||
yield changeElementStyle(testElement, "margin-top: 15px; padding-top: 5px;", inspector);
|
|
||||||
|
|
||||||
let rule = ruleView._elementStyle.rules[0];
|
|
||||||
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
|
|
||||||
validateTextProp(rule.textProps[0], false, "margin-top", "1px", "First margin property re-enabled");
|
|
||||||
validateTextProp(rule.textProps[2], true, "margin-top", "15px", "Second margin property disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testPropertyChange3(inspector, ruleView, testElement) {
|
|
||||||
info("Remove the padding-top attribute. Should disable the padding property but not remove it.");
|
|
||||||
yield changeElementStyle(testElement, "margin-top: 5px;", inspector);
|
|
||||||
|
|
||||||
let rule = ruleView._elementStyle.rules[0];
|
|
||||||
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
|
|
||||||
validateTextProp(rule.textProps[1], false, "padding-top", "5px", "Padding property disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testPropertyChange4(inspector, ruleView, testElement) {
|
|
||||||
info("Put the padding-top attribute back in, should re-enable the padding property.");
|
|
||||||
yield changeElementStyle(testElement, "margin-top: 5px; padding-top: 25px", inspector);
|
|
||||||
|
|
||||||
let rule = ruleView._elementStyle.rules[0];
|
|
||||||
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 3, "Correct number of properties");
|
|
||||||
validateTextProp(rule.textProps[1], true, "padding-top", "25px", "Padding property enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testPropertyChange5(inspector, ruleView, testElement) {
|
|
||||||
info("Add an entirely new property");
|
|
||||||
yield changeElementStyle(testElement, "margin-top: 5px; padding-top: 25px; padding-left: 20px;", inspector);
|
|
||||||
|
|
||||||
let rule = ruleView._elementStyle.rules[0];
|
|
||||||
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 4, "Added a property");
|
|
||||||
validateTextProp(rule.textProps[3], true, "padding-left", "20px", "Padding property enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* testPropertyChange6(inspector, ruleView, testElement) {
|
|
||||||
info("Add an entirely new property again");
|
|
||||||
yield changeElementStyle(testElement, "background: url(\"chrome://branding/content/about-logo.png\") repeat scroll 0% 0% red", inspector);
|
|
||||||
|
|
||||||
let rule = ruleView._elementStyle.rules[0];
|
|
||||||
is(rule.editor.element.querySelectorAll(".ruleview-property").length, 5, "Added a property");
|
|
||||||
validateTextProp(rule.textProps[4], true, "background",
|
|
||||||
"url(\"chrome://branding/content/about-logo.png\") repeat scroll 0% 0% red",
|
|
||||||
"shortcut property correctly set",
|
|
||||||
"url('chrome://branding/content/about-logo.png') repeat scroll 0% 0% #F00");
|
|
||||||
}
|
|
||||||
|
|
||||||
function* changeElementStyle(testElement, style, inspector) {
|
|
||||||
let onRefreshed = inspector.once("rule-view-refreshed");
|
|
||||||
testElement.setAttribute("style", style);
|
|
||||||
yield onRefreshed;
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateTextProp(aProp, aEnabled, aName, aValue, aDesc, valueSpanText) {
|
|
||||||
is(aProp.enabled, aEnabled, aDesc + ": enabled.");
|
|
||||||
is(aProp.name, aName, aDesc + ": name.");
|
|
||||||
is(aProp.value, aValue, aDesc + ": value.");
|
|
||||||
|
|
||||||
is(aProp.editor.enable.hasAttribute("checked"), aEnabled, aDesc + ": enabled checkbox.");
|
|
||||||
is(aProp.editor.nameSpan.textContent, aName, aDesc + ": name span.");
|
|
||||||
is(aProp.editor.valueSpan.textContent, valueSpanText || aValue, aDesc + ": value span.");
|
|
||||||
}
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче