Skip to content

Commit 4731802

Browse files
committed
Remove dependency on Ruby Sass
1 parent ca59746 commit 4731802

20 files changed

+2451
-94
lines changed

LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2015 Ryan Boland
1+
Copyright (c) Ryan Boland & Contributors
22

33
MIT License
44

lib/sassc.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,23 @@ module SassC
22
end
33

44
require_relative "sassc/version"
5+
require_relative "sassc/root"
56
require_relative "sassc/native"
67
require_relative "sassc/import_handler"
78
require_relative "sassc/importer"
9+
require_relative "sassc/util"
10+
require_relative "sassc/util/normalized_map"
11+
require_relative "sassc/util/subset_map"
812
require_relative "sassc/script"
13+
require_relative "sassc/script/value"
14+
require_relative "sassc/script/value/bool"
15+
require_relative "sassc/script/value/number"
16+
require_relative "sassc/script/value/color"
17+
require_relative "sassc/script/value/string"
18+
require_relative "sassc/script/value/list"
19+
require_relative "sassc/script/value/map"
20+
require_relative "sassc/script/functions"
21+
require_relative "sassc/script/value_conversion"
922
require_relative "sassc/functions_handler"
1023
require_relative "sassc/cache_stores"
1124
require_relative "sassc/dependency"

lib/sassc/error.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
require 'pathname'
2-
require 'sass/error'
1+
require "pathname"
32

43
module SassC
4+
55
class BaseError < StandardError; end
66
class NotRenderedError < BaseError; end
77
class InvalidStyleError < BaseError; end
88
class UnsupportedValue < BaseError; end
99

1010
# When dealing with SyntaxErrors,
1111
# it's important to provide filename and line number information.
12-
# This will be used in various error reports to users, including backtraces;
12+
# This will be used in various error reports to users, including backtraces.
13+
1314
class SyntaxError < BaseError
15+
1416
def initialize(message, filename: nil, line: nil)
1517
@filename = filename
1618
@line = line
@@ -27,5 +29,7 @@ def sass_backtrace
2729
return [] unless @filename && @line
2830
["#{@filename}:#{@line}"]
2931
end
32+
3033
end
34+
3135
end

lib/sassc/functions_handler.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,7 @@ def arguments_from_native_list(native_argument_list)
5454
def to_native_value(sass_value)
5555
# if the custom function returns nil, we provide a "default" return
5656
# value of an empty string
57-
sass_value ||= Script::String.new("")
58-
57+
sass_value ||= SassC::Script::Value::String.new("")
5958
sass_value.options = @options
6059
Script::ValueConversion.to_native(sass_value)
6160
end

lib/sassc/root.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module SassC
2+
ROOT_DIR = File.expand_path(File.join(__FILE__, "../../.."))
3+
end

lib/sassc/script.rb

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
module SassC
22
module Script
3+
34
def self.custom_functions
45
Functions.instance_methods.select do |function|
56
Functions.public_method_defined?(function)
@@ -8,42 +9,9 @@ def self.custom_functions
89

910
def self.formatted_function_name(function_name)
1011
params = Functions.instance_method(function_name).parameters
11-
params = params.map { |param_type, name| "$#{name}#{': null' if param_type == :opt}" }
12-
.join(", ")
13-
14-
"#{function_name}(#{params})"
15-
end
16-
17-
module Value
12+
params = params.map { |param_type, name| "$#{name}#{': null' if param_type == :opt}" }.join(", ")
13+
return "#{function_name}(#{params})"
1814
end
19-
end
20-
end
2115

22-
require_relative "script/functions"
23-
require_relative "script/value_conversion"
24-
25-
module Sass
26-
module Script
2716
end
2817
end
29-
30-
require 'sass/util'
31-
32-
begin
33-
require 'sass/deprecation'
34-
rescue LoadError
35-
end
36-
37-
require 'sass/script/value/base'
38-
require 'sass/script/value/string'
39-
require 'sass/script/value/color'
40-
require 'sass/script/value/bool'
41-
42-
SassC::Script::String = Sass::Script::Value::String
43-
SassC::Script::Value::String = Sass::Script::Value::String
44-
45-
SassC::Script::Color = Sass::Script::Value::Color
46-
SassC::Script::Value::Color = Sass::Script::Value::Color
47-
48-
SassC::Script::Bool = Sass::Script::Value::Bool
49-
SassC::Script::Value::Bool = Sass::Script::Value::Bool

lib/sassc/script/value.rb

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# frozen_string_literal: true
2+
3+
# The abstract superclass for SassScript objects.
4+
# Many of these methods, especially the ones that correspond to SassScript operations,
5+
# are designed to be overridden by subclasses which may change the semantics somewhat.
6+
# The operations listed here are just the defaults.
7+
8+
class SassC::Script::Value
9+
10+
# Returns the pure Ruby value of the value.
11+
# The type of this value varies based on the subclass.
12+
attr_reader :value
13+
14+
# The source range in the document on which this node appeared.
15+
attr_accessor :source_range
16+
17+
# Creates a new value.
18+
def initialize(value = nil)
19+
value.freeze unless value.nil? || value == true || value == false
20+
@value = value
21+
@options = nil
22+
end
23+
24+
# Sets the options hash for this node,
25+
# as well as for all child nodes.
26+
# See the official Sass reference for options.
27+
attr_writer :options
28+
29+
# Returns the options hash for this node.
30+
# Raises SassC::SyntaxError if the value was created
31+
# outside of the parser and \{#to\_s} was called on it
32+
def options
33+
return @options if @options
34+
raise SassC::SyntaxError.new("The #options attribute is not set on this #{self.class}. This error is probably occurring because #to_s was called on this value within a custom Sass function without first setting the #options attribute.")
35+
end
36+
37+
# Returns the hash code of this value. Two objects' hash codes should be
38+
# equal if the objects are equal.
39+
def hash
40+
value.hash
41+
end
42+
43+
# True if this Value is the same as `other`
44+
def eql?(other)
45+
self == other
46+
end
47+
48+
# Returns a system inspect value for this object
49+
def inspect
50+
value.inspect
51+
end
52+
53+
# Returns `true` (all Values are truthy)
54+
def to_bool
55+
true
56+
end
57+
58+
# Compares this object to `other`
59+
def ==(other)
60+
self.class == other.class && value == other.value
61+
end
62+
63+
# Returns the integer value of this value.
64+
# Raises SassC::SyntaxError if this value doesn’t implment integer conversion.
65+
def to_i
66+
raise SassC::SyntaxError.new("#{inspect} is not an integer.")
67+
end
68+
69+
# @raise [SassC::SyntaxError] if this value isn't an integer
70+
def assert_int!; to_i; end
71+
72+
# Returns the separator for this value. For non-list-like values or the
73+
# empty list, this will be `nil`. For lists or maps, it will be `:space` or `:comma`.
74+
def separator
75+
nil
76+
end
77+
78+
# Whether the value is surrounded by square brackets. For non-list values,
79+
# this will be `false`.
80+
def bracketed
81+
false
82+
end
83+
84+
# Returns the value of this Value as an array.
85+
# Single Values are considered the same as single-element arrays.
86+
def to_a
87+
[self]
88+
end
89+
90+
# Returns the value of this value as a hash. Most values don't have hash
91+
# representations, but [Map]s and empty [List]s do.
92+
#
93+
# @return [Hash<Value, Value>] This value as a hash
94+
# @raise [SassC::SyntaxError] if this value doesn't have a hash representation
95+
def to_h
96+
raise SassC::SyntaxError.new("#{inspect} is not a map.")
97+
end
98+
99+
# Returns the string representation of this value
100+
# as it would be output to the CSS document.
101+
#
102+
# @options opts :quote [String]
103+
# The preferred quote style for quoted strings. If `:none`, strings are
104+
# always emitted unquoted.
105+
# @return [String]
106+
def to_s(opts = {})
107+
SassC::Util.abstract(self)
108+
end
109+
alias_method :to_sass, :to_s
110+
111+
# Returns `false` (all Values are truthy)
112+
def null?
113+
false
114+
end
115+
116+
# Creates a new list containing `contents` but with the same brackets and
117+
# separators as this object, when interpreted as a list.
118+
#
119+
# @param contents [Array<Value>] The contents of the new list.
120+
# @param separator [Symbol] The separator of the new list. Defaults to \{#separator}.
121+
# @param bracketed [Boolean] Whether the new list is bracketed. Defaults to \{#bracketed}.
122+
# @return [Sass::Script::Value::List]
123+
def with_contents(contents, separator: self.separator, bracketed: self.bracketed)
124+
SassC::Script::Value::List.new(contents, separator: separator, bracketed: bracketed)
125+
end
126+
127+
protected
128+
129+
# Evaluates the value.
130+
#
131+
# @param environment [Sass::Environment] The environment in which to evaluate the SassScript
132+
# @return [Value] This value
133+
def _perform(environment)
134+
self
135+
end
136+
137+
end

lib/sassc/script/value/bool.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# frozen_string_literal: true
2+
3+
# A SassScript object representing a boolean (true or false) value.
4+
5+
class SassC::Script::Value::Bool < SassC::Script::Value
6+
7+
# The true value in SassScript.
8+
# This is assigned before new is overridden below so that we use the default implementation.
9+
TRUE = new(true).freeze
10+
11+
# The false value in SassScript.
12+
# This is assigned before new is overridden below so that we use the default implementation.
13+
FALSE = new(false).freeze
14+
15+
# We override object creation so that users of the core API
16+
# will not need to know that booleans are specific constants.
17+
# Tests `value` for truthiness and returns the TRUE or FALSE constant.
18+
def self.new(value)
19+
value ? TRUE : FALSE
20+
end
21+
22+
# The pure Ruby value of this Boolean
23+
attr_reader :value
24+
alias_method :to_bool, :value
25+
26+
# Returns the string "true" or "false" for this value
27+
def to_s(opts = {})
28+
@value.to_s
29+
end
30+
alias_method :to_sass, :to_s
31+
32+
end

0 commit comments

Comments
 (0)