Fix link & brand-primary color HC & ie11

Closes: CNVS-38498 CORE-25 CORE-338

test plan:
* turn on high contrast
* using ie11, make sure that all the links and things that should
  be the brand-primary color look right. (Dark, not light, blue)
* make sure they also look good in edge 15 and chrome with HC on.

Change-Id: I83cb35aa40c774bcd8e4c0a1a18b8cb0875e9a0c
Reviewed-on: https://gerrit.instructure.com/129911
Tested-by: Jenkins
Reviewed-by: Clay Diffrient <cdiffrient@instructure.com>
QA-Review: Jeremy Putnam <jeremyp@instructure.com>
Product-Review: Ryan Shaw <ryan@instructure.com>
This commit is contained in:
Ryan Shaw 2017-10-16 16:07:03 -06:00
parent fed8499d1c
commit cc49521daa
15 changed files with 105 additions and 276 deletions

View File

@ -117,12 +117,12 @@ class ApplicationController < ActionController::Base
# set some defaults
unless @js_env
editor_css = [
active_brand_config_css_url,
active_brand_config_url('css'),
view_context.stylesheet_path(css_url_for('what_gets_loaded_inside_the_tinymce_editor'))
]
@js_env = {
ASSET_HOST: Canvas::Cdn.config.host,
active_brand_config_json_url: active_brand_config_json_url,
active_brand_config_json_url: active_brand_config_url('json'),
url_to_what_gets_loaded_inside_the_tinymce_editor_css: editor_css,
current_user_id: @current_user.try(:id),
current_user: Rails.cache.fetch(['user_display_json', @current_user].cache_key, :expires_in => 1.hour) { user_display_json(@current_user, :profile) },

View File

@ -30,6 +30,6 @@ class BrandConfigsApiController < ApplicationController
# curl 'https://<canvas>/api/v1/brand_variables'
def show
headers['Access-Control-Allow-Origin'] = '*'
redirect_to active_brand_config_json_url
redirect_to active_brand_config_url('json')
end
end
end

View File

@ -638,21 +638,9 @@ module ApplicationHelper
end
end
def active_brand_config_json_url(opts={})
path = active_brand_config(opts).try(:public_json_path)
path ||= BrandableCSS.public_default_json_path
"#{Canvas::Cdn.config.host}/#{path}"
end
def active_brand_config_js_url(opts={})
path = active_brand_config(opts).try(:public_js_path)
path ||= BrandableCSS.public_default_js_path
"#{Canvas::Cdn.config.host}/#{path}"
end
def active_brand_config_css_url(opts={})
path = active_brand_config(opts).try(:public_css_path)
path ||= BrandableCSS.public_default_css_path
def active_brand_config_url(type, opts={})
path = active_brand_config(opts).try("public_#{type}_path")
path ||= BrandableCSS.public_default_path(type, @current_user&.prefers_high_contrast?)
"#{Canvas::Cdn.config.host}/#{path}"
end

View File

@ -113,18 +113,6 @@ class BrandConfig < ActiveRecord::Base
BrandableCSS.all_brand_variable_values_as_css(self)
end
def json_file
public_brand_dir.join("variables-#{BrandableCSS.default_variables_md5}.json")
end
def js_file
public_brand_dir.join("variables-#{BrandableCSS.default_variables_md5}.js")
end
def css_file
public_brand_dir.join("variables-#{BrandableCSS.default_variables_md5}.css")
end
def public_brand_dir
BrandableCSS.public_brandable_css_folder.join(md5)
end
@ -133,63 +121,30 @@ class BrandConfig < ActiveRecord::Base
"dist/brandable_css/#{md5}"
end
def public_json_path
"#{public_folder}/variables-#{BrandableCSS.default_variables_md5}.json"
end
def public_js_path
"#{public_folder}/variables-#{BrandableCSS.default_variables_md5}.js"
end
def public_css_path
"#{public_folder}/variables-#{BrandableCSS.default_variables_md5}.css"
end
def save_json_file!
logger.info "saving brand variables json file: #{json_file}"
public_brand_dir.mkpath
json_file.write(to_json)
move_json_to_s3_if_enabled!
end
def save_js_file!
logger.info "saving brand variables js file: #{js_file}"
public_brand_dir.mkpath
js_file.write(to_js)
move_js_to_s3_if_enabled!
end
def save_css_file!
logger.info "saving brand variables css file: #{css_file}"
public_brand_dir.mkpath
css_file.write(to_css)
move_css_to_s3_if_enabled!
end
def move_json_to_s3_if_enabled!
return unless Canvas::Cdn.enabled?
s3_uploader.upload_file(public_json_path)
begin
File.delete(json_file)
rescue Errno::ENOENT # continue if something else deleted it in another process
[:json, :js, :css].each do |type|
define_method :"public_#{type}_path" do
"#{public_folder}/variables-#{BrandableCSS.default_variables_md5}.#{type}"
end
end
def move_js_to_s3_if_enabled!
return unless Canvas::Cdn.enabled?
s3_uploader.upload_file(public_js_path)
begin
File.delete(json_file)
rescue Errno::ENOENT # continue if something else deleted it in another process
define_method :"#{type}_file" do
public_brand_dir.join("variables-#{BrandableCSS.default_variables_md5}.#{type}")
end
end
def move_css_to_s3_if_enabled!
return unless Canvas::Cdn.enabled?
s3_uploader.upload_file(public_css_path)
begin
File.delete(css_file)
rescue Errno::ENOENT # continue if something else deleted it in another process
define_method :"save_#{type}_file!" do
file = send(:"#{type}_file")
logger.info "saving brand variables #{type} file: #{file}"
public_brand_dir.mkpath
file.write(send(:"to_#{type}"))
send :"move_#{type}_to_s3_if_enabled!"
end
define_method :"move_#{type}_to_s3_if_enabled!" do
return unless Canvas::Cdn.enabled?
s3_uploader.upload_file(send(:"public_#{type}_path"))
begin
File.delete(send(:"#{type}_file"))
rescue Errno::ENOENT # continue if something else deleted it in another process
end
end
end

View File

@ -61,28 +61,6 @@ $fire: #FC5E13; // orange
//====================================
// Default Functional Swatches
//====================================
// this just needs to be defined outside of this @if $use_high_contrast {...} block
// so its scope is global and not just inside that @if, so other sheets can use it.
$ic-brand-primary-high-contrast: null;
$variables-have-been-defined: false !default;
@if $use_high_contrast {
$ic-brand-primary-high-contrast: #0770A3;
$ic-link-color-high-contrast: #0073A7;
@if not $variables-have-been-defined { // makes sure this is only output once
$variables-have-been-defined: true;
:root {
--ic-brand-primary: $ic-brand-primary-high-contrast;
--ic-brand-primary-darkened-5: darken($ic-brand-primary-high-contrast, 5);
--ic-brand-primary-darkened-10: darken($ic-brand-primary-high-contrast, 10);
--ic-brand-primary-lightened-15: lighten($ic-brand-primary-high-contrast, 15);
--ic-link-color: $ic-link-color-high-contrast;
--ic-link-color-darkened-10: darken($ic-link-color-high-contrast, 10);
--ic-link-color-lightened-10: darken($ic-link-color-high-contrast, 10);
}
}
}
$ic-color-success: $shamrock;
$ic-color-action: $barney;
$ic-color-danger: $crimson;
@ -119,7 +97,7 @@ $ic-bg-light-neutral-text: #394B58;
$ic-bg-light-primary: #E5F2F8;
@if $use_high_contrast { $ic-bg-light-primary: #E6F1F7;}
$ic-bg-light-primary-text: #0078BD;
@if $use_high_contrast { $ic-bg-light-primary-text: $ic-brand-primary-high-contrast; }
@if $use_high_contrast { $ic-bg-light-primary-text: #0770A3; }
$ic-bg-light-success: #E8F6E9;
@if $use_high_contrast { $ic-bg-light-success: #E8F2E9; }
$ic-bg-light-success-text: #008A13;

View File

@ -244,7 +244,7 @@ input[type="button"] {
.btn-primary, // <-- deprecated- do not use
.Button--primary {
@if $use_high_contrast {
@include canvas-button($ic-brand-primary-high-contrast, $ic-color-light);
@include canvas-button(#0770A3, $ic-color-light);
} @else {
@include canvas-button(
var(--ic-brand-button--primary-bgd),

View File

@ -31,7 +31,7 @@ $menu-item-keyboard-shortcut-color: $ic-font-color-dark;
.mce-container .mce-primary {
@if $use_high_contrast {
@include canvas-button($ic-brand-primary-high-contrast, $ic-color-light);
@include canvas-button(#0770A3, $ic-color-light);
} @else {
@include canvas-button(
var(--ic-brand-button--primary-bgd),

View File

@ -31,7 +31,7 @@
<%= favicon_link_tag(favicon) %>
<%= favicon_link_tag(brand_variable('ic-brand-apple-touch-icon'), rel: 'apple-touch-icon', type: nil) %>
<%= yield :auto_discovery %>
<%= stylesheet_link_tag(active_brand_config_css_url, media: "all") %>
<%= stylesheet_link_tag(active_brand_config_url('css'), media: "all") %>
<%= yield :head %>
<%=
# polyfill browsers that don't have a baseline of features we use like Promise or Object.assign
@ -86,6 +86,6 @@
}
document.addEventListener('click', _earlyClick)
</script>
<%= javascript_include_tag(active_brand_config_js_url, defer: true) %>
<%= javascript_include_tag(active_brand_config_url('js'), defer: true) %>
<%= include_head_js %>
</head>

View File

@ -205,8 +205,12 @@ module BrandableCSS
end
end
def all_brand_variable_values_as_json(active_brand_config=nil)
all_brand_variable_values(active_brand_config).to_json
end
def all_brand_variable_values_as_js(active_brand_config=nil)
"CANVAS_ACTIVE_BRAND_VARIABLES = #{all_brand_variable_values(active_brand_config).to_json};"
"CANVAS_ACTIVE_BRAND_VARIABLES = #{all_brand_variable_values_as_json(active_brand_config)};"
end
def all_brand_variable_values_as_css(active_brand_config=nil)
@ -223,77 +227,40 @@ module BrandableCSS
public_brandable_css_folder.join('default')
end
def default_brand_json_file
default_brand_folder.join("variables-#{default_variables_md5}.json")
def default_brand_file(type, high_contrast=false)
default_brand_folder.join("variables#{high_contrast ? '-high_contrast' : ''}-#{default_variables_md5}.#{type}")
end
def default_brand_js_file
default_brand_folder.join("variables-#{default_variables_md5}.js")
def high_contrast_overrides
Class.new do
def get_value(variable_name)
{"ic-brand-primary" => "#0770A3", "ic-link-color" => "#0073A7"}[variable_name]
end
end.new
end
def default_brand_css_file
default_brand_folder.join("variables-#{default_variables_md5}.css")
def default(type, high_contrast=false)
bc = high_contrast ? high_contrast_overrides : nil
send("all_brand_variable_values_as_#{type}", bc)
end
def default_json
all_brand_variable_values.to_json
end
def default_js
all_brand_variable_values_as_js
end
def default_css
all_brand_variable_values_as_css
end
def save_default_json!
def save_default!(type, high_contrast=false)
default_brand_folder.mkpath
default_brand_json_file.write(default_json)
move_default_json_to_s3_if_enabled!
end
def save_default_js!
default_brand_folder.mkpath
default_brand_js_file.write(default_js)
move_default_js_to_s3_if_enabled!
end
def save_default_css!
default_brand_folder.mkpath
default_brand_css_file.write(default_css)
move_default_css_to_s3_if_enabled!
default_brand_file(type, high_contrast).write(default(type, high_contrast))
move_default_to_s3_if_enabled!(type, high_contrast)
end
def save_default_files!
save_default_json!
save_default_js!
save_default_css!
end
def move_default_json_to_s3_if_enabled!
return unless defined?(Canvas) && Canvas::Cdn.enabled?
s3_uploader.upload_file(public_default_json_path)
begin
File.delete(default_brand_json_file)
rescue Errno::ENOENT # continue if something else deleted it in another process
[true, false].each do |high_contrast|
['js', 'css', 'json'].each { |type| save_default!(type, high_contrast) }
end
end
def move_default_js_to_s3_if_enabled!
def move_default_to_s3_if_enabled!(type, high_contrast=false)
return unless defined?(Canvas) && Canvas::Cdn.enabled?
s3_uploader.upload_file(public_default_js_path)
s3_uploader.upload_file(public_default_path(type, high_contrast))
begin
File.delete(default_brand_js_file)
rescue Errno::ENOENT # continue if something else deleted it in another process
end
end
def move_default_css_to_s3_if_enabled!
return unless defined?(Canvas) && Canvas::Cdn.enabled?
s3_uploader.upload_file(public_default_css_path)
begin
File.delete(default_brand_css_file)
File.delete(default_brand_file(type, high_contrast))
rescue Errno::ENOENT # continue if something else deleted it in another process
end
end
@ -302,16 +269,8 @@ module BrandableCSS
@s3_uploaderer ||= Canvas::Cdn::S3Uploader.new
end
def public_default_json_path
"dist/brandable_css/default/variables-#{default_variables_md5}.json"
end
def public_default_js_path
"dist/brandable_css/default/variables-#{default_variables_md5}.js"
end
def public_default_css_path
"dist/brandable_css/default/variables-#{default_variables_md5}.css"
def public_default_path(type, high_contrast=false)
"dist/brandable_css/default/variables#{high_contrast ? '-high_contrast' : ''}-#{default_variables_md5}.#{type}"
end
def variants

View File

@ -374,7 +374,7 @@ module Lti
# http://example.url/path.json
# ```
register_expansion 'com.instructure.brandConfigJSON.url', [],
-> { @controller.active_brand_config_json_url },
-> { @controller.active_brand_config_url('json') },
CONTROLLER_GUARD
# returns the brand config JSON itself for the launching context.
@ -395,7 +395,7 @@ module Lti
# http://example.url/path.js
# ```
register_expansion 'com.instructure.brandConfigJS.url', [],
-> { @controller.active_brand_config_js_url },
-> { @controller.active_brand_config_url('js') },
CONTROLLER_GUARD
# returns the URL for the common css file.

View File

@ -22,7 +22,7 @@ describe BrandConfigsApiController do
it "should redirect to the default when nothing is set" do
get :show
expect(response).to redirect_to("#{Canvas::Cdn.config.host}/#{BrandableCSS.public_default_json_path}")
expect(response).to redirect_to("#{Canvas::Cdn.config.host}/#{BrandableCSS.public_default_path('json')}")
end
it "should redirect to the one for @domain_root_account's brand config if set" do

View File

@ -68,8 +68,8 @@ describe BrandableCSS do
describe "all_brand_variable_values_as_js" do
it "eports the default js to the right global variable" do
expected_js = "CANVAS_ACTIVE_BRAND_VARIABLES = #{BrandableCSS.default_json};"
expect(BrandableCSS.default_js).to eq expected_js
expected_js = "CANVAS_ACTIVE_BRAND_VARIABLES = #{BrandableCSS.default('json')};"
expect(BrandableCSS.default('js')).to eq expected_js
end
end
@ -78,107 +78,56 @@ describe BrandableCSS do
expected_css = ":root {
#{BrandableCSS.all_brand_variable_values(nil, true).map{ |k, v| "--#{k}: #{v};"}.join("\n")}
}"
expect(BrandableCSS.default_css).to eq expected_css
expect(BrandableCSS.default('css')).to eq expected_css
end
end
describe "default_json" do
it "includes default variables not found in brand config" do
brand_variables = JSON.parse(BrandableCSS.default_json)
brand_variables = JSON.parse(BrandableCSS.default('json'))
expect(brand_variables["ic-link-color"]).to eq '#008EE2'
end
it "it has high contrast overrides for link and brand-primary" do
brand_variables = JSON.parse(BrandableCSS.default('json', !!:high_contrast))
expect(brand_variables["ic-brand-primary"]).to eq "#0770A3"
expect(brand_variables["ic-link-color"]).to eq "#0073A7"
end
end
describe "save_default_json!" do
it "writes the default json representation to the default json file" do
allow(Canvas::Cdn).to receive(:enabled?).and_return(false)
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_json_file).and_return(file)
BrandableCSS.save_default_json!
expect(file.string).to eq BrandableCSS.default_json
end
[true, false].each do |high_contrast|
['js', 'json', 'css'].each do |type|
describe "save_default!(#{type})" do
it "writes the default json representation to the default json file" do
allow(Canvas::Cdn).to receive(:enabled?).and_return(false)
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_file).with(type, high_contrast).and_return(file)
BrandableCSS.save_default!(type, high_contrast)
expect(file.string).to eq BrandableCSS.default(type, high_contrast)
end
it 'uploads json file to s3 if cdn is enabled' do
allow(Canvas::Cdn).to receive(:enabled?).and_return(true)
allow(Canvas::Cdn).to receive(:config).and_return(ActiveSupport::OrderedOptions.new.merge(region: 'us-east-1', aws_access_key_id: 'id', aws_secret_access_key: 'secret', bucket: 'cdn'))
it 'uploads json file to s3 if cdn is enabled' do
allow(Canvas::Cdn).to receive(:enabled?).and_return(true)
allow(Canvas::Cdn).to receive(:config).and_return(ActiveSupport::OrderedOptions.new.merge(region: 'us-east-1', aws_access_key_id: 'id', aws_secret_access_key: 'secret', bucket: 'cdn'))
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_json_file).and_return(file)
allow(File).to receive(:delete)
expect(BrandableCSS.s3_uploader).to receive(:upload_file).with(BrandableCSS.public_default_json_path)
BrandableCSS.save_default_json!
end
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_file).with(type, high_contrast).and_return(file)
allow(File).to receive(:delete)
expect(BrandableCSS.s3_uploader).to receive(:upload_file).with(BrandableCSS.public_default_path(type, high_contrast))
BrandableCSS.save_default!(type, high_contrast)
end
it 'deletes the local json file if cdn is enabled' do
allow(Canvas::Cdn).to receive(:enabled?).and_return(true)
allow(Canvas::Cdn).to receive(:config).and_return(ActiveSupport::OrderedOptions.new.merge(region: 'us-east-1', aws_access_key_id: 'id', aws_secret_access_key: 'secret', bucket: 'cdn'))
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_json_file).and_return(file)
expect(File).to receive(:delete).with(BrandableCSS.default_brand_json_file)
expect(BrandableCSS.s3_uploader).to receive(:upload_file)
BrandableCSS.save_default_json!
end
end
describe "save_default_js!" do
it "writes the default javascript representation to the default js file" do
allow(Canvas::Cdn).to receive(:enabled?).and_return(false)
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_js_file).and_return(file)
BrandableCSS.save_default_js!
expect(file.string).to eq BrandableCSS.default_js
end
it 'uploads javascript file to s3 if cdn is enabled' do
allow(Canvas::Cdn).to receive(:enabled?).and_return(true)
allow(Canvas::Cdn).to receive(:config).and_return(ActiveSupport::OrderedOptions.new.merge(region: 'us-east-1', aws_access_key_id: 'id', aws_secret_access_key: 'secret', bucket: 'cdn'))
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_js_file).and_return(file)
allow(File).to receive(:delete)
expect(BrandableCSS.s3_uploader).to receive(:upload_file).with(BrandableCSS.public_default_js_path)
BrandableCSS.save_default_js!
end
it 'deletes the local javascript file if cdn is enabled' do
allow(Canvas::Cdn).to receive(:enabled?).and_return(true)
allow(Canvas::Cdn).to receive(:config).and_return(ActiveSupport::OrderedOptions.new.merge(region: 'us-east-1', aws_access_key_id: 'id', aws_secret_access_key: 'secret', bucket: 'cdn'))
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_js_file).and_return(file)
expect(File).to receive(:delete).with(BrandableCSS.default_brand_js_file)
expect(BrandableCSS.s3_uploader).to receive(:upload_file)
BrandableCSS.save_default_js!
end
end
describe "save_default_css!" do
it "writes the default css variables to the default css file" do
allow(Canvas::Cdn).to receive(:enabled?).and_return(false)
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_css_file).and_return(file)
BrandableCSS.save_default_css!
expect(file.string).to eq BrandableCSS.default_css
end
it 'uploads css file to s3 if cdn is enabled' do
allow(Canvas::Cdn).to receive(:enabled?).and_return(true)
allow(Canvas::Cdn).to receive(:config).and_return(ActiveSupport::OrderedOptions.new.merge(region: 'us-east-1', aws_access_key_id: 'id', aws_secret_access_key: 'secret', bucket: 'cdn'))
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_css_file).and_return(file)
allow(File).to receive(:delete)
expect(BrandableCSS.s3_uploader).to receive(:upload_file).with(BrandableCSS.public_default_css_path)
BrandableCSS.save_default_css!
end
it 'deletes the local css file if cdn is enabled' do
allow(Canvas::Cdn).to receive(:enabled?).and_return(true)
allow(Canvas::Cdn).to receive(:config).and_return(ActiveSupport::OrderedOptions.new.merge(region: 'us-east-1', aws_access_key_id: 'id', aws_secret_access_key: 'secret', bucket: 'cdn'))
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_css_file).and_return(file)
expect(File).to receive(:delete).with(BrandableCSS.default_brand_css_file)
expect(BrandableCSS.s3_uploader).to receive(:upload_file)
BrandableCSS.save_default_css!
it 'deletes the local json file if cdn is enabled' do
allow(Canvas::Cdn).to receive(:enabled?).and_return(true)
allow(Canvas::Cdn).to receive(:config).and_return(ActiveSupport::OrderedOptions.new.merge(region: 'us-east-1', aws_access_key_id: 'id', aws_secret_access_key: 'secret', bucket: 'cdn'))
file = StringIO.new
allow(BrandableCSS).to receive(:default_brand_file).with(type, high_contrast).and_return(file)
expect(File).to receive(:delete).with(BrandableCSS.default_brand_file(type, high_contrast))
expect(BrandableCSS.s3_uploader).to receive(:upload_file)
BrandableCSS.save_default!(type, high_contrast)
end
end
end
end
end

View File

@ -61,8 +61,8 @@ module Lti
allow(m).to receive(:request).and_return(request_mock)
allow(m).to receive(:logged_in_user).and_return(user)
allow(m).to receive(:named_context_url).and_return('url')
allow(m).to receive(:active_brand_config_json_url).and_return('http://example.com/brand_config.json')
allow(m).to receive(:active_brand_config_js_url).and_return('http://example.com/brand_config.js')
allow(m).to receive(:active_brand_config_url).with('json').and_return('http://example.com/brand_config.json')
allow(m).to receive(:active_brand_config_url).with('js').and_return('http://example.com/brand_config.js')
allow(m).to receive(:active_brand_config).and_return(double(to_json: '{"ic-brand-primary-darkened-5":"#0087D7"}'))
allow(m).to receive(:polymorphic_url).and_return('url')
view_context_mock = double('view_context')

View File

@ -113,7 +113,7 @@ describe 'new ui' do
end
it 'should not override high contrast theme', priority: "2", test_id: 244898 do
BrandableCSS.save_default_css! # make sure variable css file is up to date
BrandableCSS.save_default!('css') # make sure variable css file is up to date
get '/profile/settings'
f('.ic-Super-toggle__switch').click
wait_for_ajaximations

View File

@ -23,7 +23,7 @@ describe "section tabs on the left side" do
context "as a teacher" do
it "should highlight which tab is active" do
BrandableCSS.save_default_css! # make sure variable css file is up to date
BrandableCSS.save_default!('css') # make sure variable css file is up to date
course_with_teacher_logged_in
%w{assignments quizzes settings}.each do |feature|
get "/courses/#{@course.id}/#{feature}"